Пример #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
Пример #2
0
class TestSO4(unittest.TestCase):
    from pyxtal_ff.descriptors.SO4 import SO4_Bispectrum
    struc = get_rotated_struc(cu)
    b0_poly = SO4_Bispectrum(lmax=1, rcut=rcut, stress=True, derivative=True).calculate(struc)#, backend='pymatgen')
    struc = get_rotated_struc(cu, 20, 'x')
    b1_poly = SO4_Bispectrum(lmax=1, rcut=rcut, stress=True, derivative=True).calculate(struc)#, backend='pymatgen')
    struc = get_perturbed_struc(cu, eps)
    b2_poly = SO4_Bispectrum(lmax=1, rcut=rcut, derivative=False).calculate(struc)#, backend='pymatgen')

    def test_B_poly_rotation_variance(self):
        array1 = self.b0_poly['x'].flatten()
        array2 = self.b1_poly['x'].flatten()
        self.assertTrue(np.allclose(array1, array2))

    def test_dBdr_poly_rotation_variance(self):
        array1 = np.linalg.norm(self.b0_poly['dxdr'][0,:,:], axis=1)
        array2 = np.linalg.norm(self.b1_poly['dxdr'][0,:,:], axis=1)
        self.assertTrue(np.allclose(array1, array2))

    def test_dBdr_poly_vs_numerical(self):
        array1 = (self.b2_poly['x'][0] - self.b0_poly['x'][0]).flatten()/eps
        array2 = self.b0_poly['dxdr'][0, :, 0].flatten()
        self.assertTrue(np.allclose(array1, array2, rtol=1e-2, atol=1e-2))
Пример #3
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