Exemplo n.º 1
0
    def compute(self, function, data):
        """ Compute descriptor for one structure to the database. """

        if function['type'] in ['BehlerParrinello', 'ACSF']:
            from pyxtal_ff.descriptors.ACSF import ACSF
            d = ACSF(function['parameters'], function['Rc'], function['force'],
                     function['stress'], False).calculate(data['structure'])
        elif function['type'] in ['wACSF', 'wacsf']:
            from pyxtal_ff.descriptors.ACSF import ACSF
            d = ACSF(function['parameters'], function['Rc'], function['force'],
                     function['stress'], True).calculate(data['structure'])

        elif function['type'] in ['SO4', 'Bispectrum', 'bispectrum']:
            from pyxtal_ff.descriptors.SO4 import SO4_Bispectrum
            d = SO4_Bispectrum(
                function['parameters']['lmax'],
                function['Rc'],
                derivative=function['force'],
                stress=function['stress'],
                normalize_U=function['parameters']['normalize_U']).calculate(
                    data['structure'])

        elif function['type'] in ['SO3', 'SOAP', 'soap']:
            from pyxtal_ff.descriptors.SO3 import SO3
            d = SO3(function['parameters']['nmax'],
                    function['parameters']['lmax'],
                    function['Rc'],
                    derivative=function['force'],
                    stress=function['stress']).calculate(data['structure'])

        elif function['type'] in ['EAMD', 'eamd']:
            from pyxtal_ff.descriptors.EAMD import EAMD
            d = EAMD(function['parameters'], function['Rc'], function['force'],
                     function['stress']).calculate(data['structure'])

        else:
            msg = f"{function['type']} is not implemented"
            raise NotImplementedError(msg)
        if d['rdxdr'] is not None:
            N = d['x'].shape[0]
            L = d['x'].shape[1]
            rdxdr = np.zeros([N, L, 3, 3])
            for _m in range(N):
                ids = np.where(d['seq'][:, 0] == _m)[0]
                rdxdr[_m, :, :, :] += np.einsum('ijkl->jkl',
                                                d['rdxdr'][ids, :, :, :])
            d['rdxdr'] = rdxdr.reshape([N, L, 9])[:, :, [0, 4, 8, 1, 2, 5]]
            #d['rdxdr'] = np.einsum('ijklm->iklm', d['rdxdr'])\
            #.reshape([shp[0], shp[2], shp[3]*shp[4]])[:, :, [0, 4, 8, 1, 2, 5]]  #need to change

        d['energy'] = np.asarray(data['energy'])
        d['force'] = np.asarray(data['force'])
        if data['stress'] is not None:
            d['stress'] = np.asarray(data['stress'])
        else:
            d['stress'] = data['stress']
        d['group'] = data['group']

        return d
Exemplo n.º 2
0
class TestwACSF(unittest.TestCase):
    struc = get_rotated_struc(nacl)
    wACSF0 = ACSF(symmetry_parameters=acsf_params,
                  Rc=rc,
                  derivative=True,
                  atom_weighted=True).calculate(struc)
    struc = get_rotated_struc(nacl, 10, 'x')
    wACSF1 = ACSF(symmetry_parameters=acsf_params,
                  Rc=rc,
                  derivative=True,
                  atom_weighted=True).calculate(struc)

    def test_wACSF_rotation_variance(self):
        array1 = self.wACSF0['x']
        array2 = self.wACSF1['x']
        self.assertTrue(np.allclose(array1, array2))

    def test_dwACSFdR_rotation_variance(self):
        for i in range(len(self.wACSF0['x'])):
            array1 = np.linalg.norm(self.wACSF0['dxdr'][i, :, :], axis=1)
            array2 = np.linalg.norm(self.wACSF1['dxdr'][i, :, :], axis=1)
            self.assertTrue(np.allclose(array1, array2))

    def test_dwACSFdR_vs_numerical(self):
        shp = self.wACSF0['x'].shape
        array1 = np.zeros([shp[0], shp[0], shp[1], 3])
        for _m in range(shp[0]):
            ids = np.where(self.wACSF0['seq'][:, 1] == _m)[0]
            array1[self.wACSF0['seq'][ids, 0],
                   _m, :, :] += self.wACSF0['dxdr'][ids, :, :]

        for j in range(shp[0]):
            for k in range(3):
                struc = get_perturbed_struc(nacl, j, k, eps)
                wACSF2 = ACSF(symmetry_parameters=acsf_params,
                              Rc=rc,
                              derivative=False,
                              atom_weighted=True).calculate(struc)
                array2 = (wACSF2['x'] - self.wACSF0['x']) / eps
                self.assertTrue(
                    np.allclose(array1[:, j, :, k], array2, atol=1e-6))
Exemplo n.º 3
0
class TestACSF(unittest.TestCase):
    from pyxtal_ff.descriptors.ACSF import ACSF
    symmetry = {'G2': {'eta': [0.003214], 'Rs': [0]},
                'G4': {'lambda': [1], 'zeta':[1], 'eta': [0.000357]},
                'G5': {'lambda': [-1], 'zeta':[1], 'eta': [0.004]},
                }
    struc = get_rotated_struc(cu)
    g0 = ACSF(symmetry, rcut, derivative=True).calculate(struc)
    struc = get_rotated_struc(cu, 10, 'x')
    g1 = ACSF(symmetry, rcut, derivative=True).calculate(struc)
    struc = get_perturbed_struc(cu, eps)
    g2 = ACSF(symmetry, rcut, derivative=False).calculate(struc)

    def test_G2_value(self):
        self.assertAlmostEqual(self.g0['x'][0,0], 0.36925589)

    def test_G4_value(self):
        self.assertAlmostEqual(self.g0['x'][0,1], 0.00232827)

    def test_G_rotation_variance(self):
        array1 = self.g0['x'].flatten()
        array2 = self.g1['x'].flatten()
        self.assertTrue(np.allclose(array1, array2))

    def test_dGdR_rotation_variance(self):
        array1 = np.linalg.norm(self.g0['dxdr'][0,:,:], axis=1)
        array2 = np.linalg.norm(self.g1['dxdr'][0,:,:], axis=1)
        self.assertTrue(np.allclose(array1, array2))

    def test_dGdR_vs_numerical(self):
        array1 = (self.g2['x'][0] - self.g0['x'][0]).flatten()/eps
        array2 = self.g0['dxdr'][0, :, 0].flatten()
        if not np.allclose(array1, array2):
            print('\n Numerical dGdR')
            print((self.g2['x'][0] - self.g0['x'][0])/eps)
            print('\n precompute')
            print(array2)
        self.assertTrue(np.allclose(array1, array2))
Exemplo n.º 4
0
    def test_dACSFdR_vs_numerical(self):
        shp = self.ACSF0['x'].shape
        array1 = np.zeros([shp[0], shp[0], shp[1], 3])
        for _m in range(shp[0]):
            ids = np.where(self.ACSF0['seq'][:, 1] == _m)[0]
            array1[self.ACSF0['seq'][ids, 0],
                   _m, :, :] += self.ACSF0['dxdr'][ids, :, :]

        for j in range(shp[0]):
            for k in range(3):
                struc = get_perturbed_struc(nacl, j, k, eps)
                ACSF2 = ACSF(symmetry_parameters=acsf_params,
                             Rc=rc,
                             derivative=False).calculate(struc)
                array2 = (ACSF2['x'] - self.ACSF0['x']) / eps
                self.assertTrue(
                    np.allclose(array1[:, j, :, k], array2, atol=1e-6))
Exemplo n.º 5
0
def compute_descriptor(function, structure):
    """ Compute descriptor for one structure. """

    if function['type'] in ['BehlerParrinello', 'ACSF']:
        from pyxtal_ff.descriptors.ACSF import ACSF
        d = ACSF(function['parameters'], function['Rc'], function['force'],
                 function['stress'], function['cutoff'],
                 False).calculate(structure)

    elif function['type'] in ['wACSF', 'wacsf']:
        from pyxtal_ff.descriptors.ACSF import ACSF
        d = ACSF(function['parameters'], function['Rc'], function['force'],
                 function['stress'], function['cutoff'],
                 True).calculate(structure)

    elif function['type'] in ['SO4', 'Bispectrum', 'bispectrum']:
        from pyxtal_ff.descriptors.SO4 import SO4_Bispectrum
        d = SO4_Bispectrum(
            function['parameters']['lmax'],
            function['Rc'],
            derivative=True,
            stress=True,
            normalize_U=function['parameters']['normalize_U'],
            cutoff_function=function['cutoff']).calculate(structure)

    elif function['type'] in ['SO3', 'SOAP', 'soap']:
        from pyxtal_ff.descriptors.SO3 import SO3
        d = SO3(function['parameters']['nmax'],
                function['parameters']['lmax'],
                function['Rc'],
                derivative=True,
                stress=True).calculate(structure)

    elif function['type'] in ['EAD', 'ead']:
        from pyxtal_ff.descriptors.EAD import EAD
        d = EAMD(function['parameters'], function['Rc'], True, True,
                 function['cutoff']).calculate(structure)

    elif function['type'] in ['SNAP', 'snap']:
        from pyxtal_ff.descriptors.SNAP import SO4_Bispectrum
        d = SO4_Bispectrum(
            function['weights'],
            function['parameters']['lmax'],
            function['Rc'],
            derivative=True,
            stress=True,
            normalize_U=function['parameters']['normalize_U'],
            cutoff_function=function['cutoff']).calculate(structure)

    else:
        msg = f"{function['type']} is not implemented"
        raise NotImplementedError(msg)

    if d['rdxdr'] is not None:
        #shp = d['rdxdr'].shape
        #d['rdxdr'] = np.einsum('ijklm->iklm', d['rdxdr'])\
        #    .reshape([shp[0], shp[2], shp[3]*shp[4]])[:, :, [0,4,8,1,2,5]]

        N = d['x'].shape[0]
        L = d['x'].shape[1]
        rdxdr = np.zeros([N, L, 3, 3])
        for _m in range(N):
            ids = np.where(d['seq'][:, 0] == _m)[0]
            rdxdr[_m, :, :, :] += np.einsum('ijkl->jkl',
                                            d['rdxdr'][ids, :, :, :])
        d['rdxdr'] = rdxdr.reshape([N, L, 9])[:, :, [0, 4, 8, 1, 2, 5]]

    return d