예제 #1
0
    def test_unit_cells(self):
        """Tests if arbitrary unit cells are accepted"""
        desc = SOAP(species=[1, 6, 8], rcut=10.0, nmax=2, lmax=0, periodic=False, crossover=True)

        molecule = H2O.copy()

        molecule.set_cell([
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0]
        ])

        nocell = desc.create(molecule, positions=[[0, 0, 0]])

        desc = SOAP(species=[1, 6, 8], rcut=10.0, nmax=2, lmax=0, periodic=True, crossover=True,)

        # Invalid unit cell
        molecule.set_cell([
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0]
        ])
        with self.assertRaises(ValueError):
            desc.create(molecule, positions=[[0, 0, 0]])

        molecule.set_pbc(True)
        molecule.set_cell([
            [20.0, 0.0, 0.0],
            [0.0, 30.0, 0.0],
            [0.0, 0.0, 40.0],
        ])

        largecell = desc.create(molecule, positions=[[0, 0, 0]])

        molecule.set_cell([
            [2.0, 0.0, 0.0],
            [0.0, 2.0, 0.0],
            [0.0, 0.0, 2.0]
        ])

        cubic_cell = desc.create(molecule, positions=[[0, 0, 0]])

        molecule.set_cell([
            [0.0, 2.0, 2.0],
            [2.0, 0.0, 2.0],
            [2.0, 2.0, 0.0]
        ])

        triclinic_smallcell = desc.create(molecule, positions=[[0, 0, 0]])
예제 #2
0
    def test_periodic_images(self):
        """Tests the periodic images seen by the descriptor"""
        desc = SOAP(
            species=[1, 6, 8], rcut=10.0, nmax=2, lmax=0, periodic=False, crossover=True
        )

        molecule = H2O.copy()

        # Non-periodic for comparison
        molecule.set_cell([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])
        nocell = desc.create(molecule, positions=[[0, 0, 0]])

        # Make periodic
        desc = SOAP(
            species=[1, 6, 8], rcut=10.0, nmax=2, lmax=0, periodic=True, crossover=True
        )
        molecule.set_pbc(True)

        # Cubic
        molecule.set_cell([[3.0, 0.0, 0.0], [0.0, 3.0, 0.0], [0.0, 0.0, 3.0]])
        cubic_cell = desc.create(molecule, positions=[[0, 0, 0]])
        suce = molecule * (2, 1, 1)
        cubic_suce = desc.create(suce, positions=[[0, 0, 0]])

        # Triclinic
        molecule.set_cell([[0.0, 2.0, 2.0], [2.0, 0.0, 2.0], [2.0, 2.0, 0.0]])
        triclinic_cell = desc.create(molecule, positions=[[0, 0, 0]])
        suce = molecule * (2, 1, 1)
        triclinic_suce = desc.create(suce, positions=[[0, 0, 0]])

        self.assertTrue(np.sum(np.abs((nocell[:3] - cubic_suce[:3]))) > 0.1)
        self.assertAlmostEqual(np.sum(cubic_cell[:3] - cubic_suce[:3]), 0)
        self.assertAlmostEqual(np.sum(triclinic_cell[:3] - triclinic_suce[:3]), 0)
예제 #3
0
    def test_unit_cells(self):
        """Tests that arbitrary unit cells are accepted.
        """
        desc = copy.deepcopy(default_desc_k1_k2_k3)
        desc.periodic = False
        desc.species = ["H", "O"]
        molecule = H2O.copy()

        # No cell needed for finite systems
        molecule.set_cell([
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0],
            [0.0, 0.0, 0.0]
        ])
        nocell = desc.create(molecule)

        # Different periodic cells
        desc.periodic = True
        molecule.set_cell([
            [2.0, 0.0, 0.0],
            [0.0, 2.0, 0.0],
            [0.0, 0.0, 2.0]
        ])
        cubic_cell = desc.create(molecule)

        molecule.set_cell([
            [0.0, 2.0, 2.0],
            [2.0, 0.0, 2.0],
            [2.0, 2.0, 0.0]
        ])
        triclinic_smallcell = desc.create(molecule)
예제 #4
0
    def test_unit_cells(self):
        """Tests if arbitrary unit cells are accepted.
        """
        # No cell
        molecule = H2O.copy()
        molecule.set_cell([[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 0.0, 0.0]])
        nocell = default_desc.create(molecule)

        # Large cell
        molecule.set_pbc(True)
        molecule.set_cell([[20.0, 0.0, 0.0], [0.0, 30.0, 0.0],
                           [0.0, 0.0, 40.0]])
        largecell = default_desc.create(molecule)

        # Cubic cell
        molecule.set_cell([[2.0, 0.0, 0.0], [0.0, 2.0, 0.0], [0.0, 0.0, 2.0]])
        cubic_cell = default_desc.create(molecule)

        # Triclinic cell
        molecule.set_cell([[0.0, 2.0, 2.0], [2.0, 0.0, 2.0], [2.0, 2.0, 0.0]])
        triclinic_smallcell = default_desc.create(molecule)
예제 #5
0
    def test_periodic_images(self):
        """Tests that periodic images are handled correctly.
        """
        decay = 1
        desc = MBTR(
            species=[1],
            periodic=True,
            k1={
                "geometry": {"function": "atomic_number"},
                "grid": {"min": 0, "max": 2, "sigma": 0.1, "n": 21}
            },
            k2={
                "geometry": {"function": "inverse_distance"},
                "grid": {"min": 0, "max": 1.0, "sigma": 0.02, "n": 21},
                "weighting": {"function": "exp", "scale": decay, "cutoff": 1e-4}
            },
            k3={
                "geometry": {"function": "cosine"},
                "grid": {"min": -1.0, "max": 1.0, "sigma": 0.02, "n": 21},
                "weighting": {"function": "exp", "scale": decay, "cutoff": 1e-4},
            },
            normalization="l2_each",  # This normalizes the spectrum
            flatten=True
        )

        # Tests that a system has the same spectrum as the supercell of
        # the same system.
        molecule = H.copy()
        a = 1.5
        molecule.set_cell([
            [a, 0.0, 0.0],
            [0.0, a, 0.0],
            [0.0, 0.0, a]
        ])
        cubic_cell = desc.create(molecule)
        suce = molecule * (2, 1, 1)
        cubic_suce = desc.create(suce)

        diff = abs(np.sum(cubic_cell[0, :] - cubic_suce[0, :]))
        cubic_sum = abs(np.sum(cubic_cell[0, :]))
        self.assertTrue(diff/cubic_sum < 0.05)  # A 5% error is tolerated

        # Same test but for triclinic cell
        molecule.set_cell([
            [0.0, 2.0, 1.0],
            [1.0, 0.0, 1.0],
            [1.0, 2.0, 0.0]
        ])

        triclinic_cell = desc.create(molecule)
        suce = molecule * (2, 1, 1)
        triclinic_suce = desc.create(suce)

        diff = abs(np.sum(triclinic_cell[0, :] - triclinic_suce[0, :]))
        tricl_sum = abs(np.sum(triclinic_cell[0, :]))
        self.assertTrue(diff/tricl_sum < 0.05)

        # Testing that the same crystal, but different unit cells will have a
        # similar spectrum when they are normalized. There will be small
        # differences in the shape (due to not double counting distances)
        a1 = bulk('H', 'fcc', a=2.0)
        a2 = bulk('H', 'fcc', a=2.0, orthorhombic=True)
        a3 = bulk('H', 'fcc', a=2.0, cubic=True)

        triclinic_cell = desc.create(a1)
        orthorhombic_cell = desc.create(a2)
        cubic_cell = desc.create(a3)

        diff1 = abs(np.sum(triclinic_cell[0, :] - orthorhombic_cell[0, :]))
        diff2 = abs(np.sum(triclinic_cell[0, :] - cubic_cell[0, :]))
        tricl_sum = abs(np.sum(triclinic_cell[0, :]))
        self.assertTrue(diff1/tricl_sum < 0.05)
        self.assertTrue(diff2/tricl_sum < 0.05)

        # Tests that the correct peak locations are present in a cubic periodic
        desc = MBTR(
            species=["H"],
            periodic=True,
            k3={
                "geometry": {"function": "cosine"},
                "grid": {"min": -1.1, "max": 1.1, "sigma": 0.010, "n": 600},
                "weighting": {"function": "exp", "scale": decay, "cutoff": 1e-4}
            },
            normalization="l2_each",  # This normalizes the spectrum
            flatten=True
        )
        a = 2.2
        system = Atoms(
            cell=[
                [a, 0.0, 0.0],
                [0.0, a, 0.0],
                [0.0, 0.0, a]
            ],
            positions=[
                [0, 0, 0],
            ],
            symbols=["H"],
        )
        cubic_spectrum = desc.create(system)[0, :]
        x3 = desc.get_k3_axis()

        peak_ids = find_peaks_cwt(cubic_spectrum, [2])
        peak_locs = x3[peak_ids]

        assumed_peaks = np.cos(np.array(
            [
                180,
                90,
                np.arctan(np.sqrt(2))*180/np.pi,
                45,
                np.arctan(np.sqrt(2)/2)*180/np.pi,
                0
            ])*np.pi/180
        )
        self.assertTrue(np.allclose(peak_locs, assumed_peaks, rtol=0, atol=5*np.pi/180))

        # Tests that the correct peak locations are present in a system with a
        # non-cubic basis
        desc = MBTR(
            species=["H"],
            periodic=True,
            k3={
                "geometry": {"function": "cosine"},
                "grid": {"min": -1.0, "max": 1.0, "sigma": 0.030, "n": 200},
                "weighting": {"function": "exp", "scale": 1.5, "cutoff": 1e-4}
            },
            normalization="l2_each",  # This normalizes the spectrum
            flatten=True,
            sparse=False
        )
        a = 2.2
        system = Atoms(
            cell=[
                [a, 0.0, 0.0],
                [0.0, a, 0.0],
                [0.0, 0.0, a]
            ],
            positions=[
                [0, 0, 0],
            ],
            symbols=["H"],
        )
        angle = 30
        system = Atoms(
            cell=ase.geometry.cellpar_to_cell([3*a, a, a, angle, 90, 90]),
            positions=[
                [0, 0, 0],
            ],
            symbols=["H"],
        )
        tricl_spectrum = desc.create(system)
        x3 = desc.get_k3_axis()

        peak_ids = find_peaks_cwt(tricl_spectrum[0, :], [3])
        peak_locs = x3[peak_ids]

        angle = (6)/(np.sqrt(5)*np.sqrt(8))
        assumed_peaks = np.cos(np.array([180, 105, 75, 51.2, 30, 0])*np.pi/180)
        self.assertTrue(np.allclose(peak_locs, assumed_peaks, rtol=0, atol=5*np.pi/180))