Пример #1
0
def _core_val_ryd_list(mol):
    from pyscf.gto.ecp import core_configuration
    count = numpy.zeros((mol.natm, 9), dtype=int)
    core_lst = []
    val_lst = []
    rydbg_lst = []
    k = 0
    for ib in range(mol.nbas):
        ia = mol.bas_atom(ib)
        # Avoid calling mol.atom_charge because we should include ECP core electrons here
        nuc = mole.charge(mol.atom_symbol(ia))
        l = mol.bas_angular(ib)
        nc = mol.bas_nctr(ib)

        nelec_ecp = mol.atom_nelec_core(ia)
        ecpcore = core_configuration(nelec_ecp)
        coreshell = [int(x) for x in AOSHELL[nuc][0][::2]]
        cvshell = [int(x) for x in AOSHELL[nuc][1][::2]]
        if mol.cart:
            deg = (l + 1) * (l + 2) // 2
        else:
            deg = 2 * l + 1
        for n in range(nc):
            if l > 3:
                rydbg_lst.extend(range(k, k + deg))
            elif ecpcore[l] + count[ia, l] + n < coreshell[l]:
                core_lst.extend(range(k, k + deg))
            elif ecpcore[l] + count[ia, l] + n < cvshell[l]:
                val_lst.extend(range(k, k + deg))
            else:
                rydbg_lst.extend(range(k, k + deg))
            k = k + deg
        count[ia, l] += nc
    return core_lst, val_lst, rydbg_lst
Пример #2
0
def _core_val_ryd_list(mol):
    from pyscf.gto.ecp import core_configuration
    count = numpy.zeros((mol.natm, 9), dtype=int)
    core_lst = []
    val_lst = []
    rydbg_lst = []
    k = 0
    for ib in range(mol.nbas):
        ia = mol.bas_atom(ib)
# Avoid calling mol.atom_charge because we should include ECP core electrons here
        nuc = mole.charge(mol.atom_symbol(ia))
        l = mol.bas_angular(ib)
        nc = mol.bas_nctr(ib)
        symb = mol.atom_symbol(ia)
        nelec_ecp = mol.atom_nelec_core(ia)
        ecpcore = core_configuration(nelec_ecp)
        coreshell = [int(x) for x in AOSHELL[nuc][0][::2]]
        cvshell = [int(x) for x in AOSHELL[nuc][1][::2]]
        if mol.cart:
            deg = (l + 1) * (l + 2) // 2
        else:
            deg = 2 * l + 1
        for n in range(nc):
            if l > 3:
                rydbg_lst.extend(range(k, k+deg))
            elif ecpcore[l]+count[ia,l]+n < coreshell[l]:
                core_lst.extend(range(k, k+deg))
            elif ecpcore[l]+count[ia,l]+n < cvshell[l]:
                val_lst.extend(range(k, k+deg))
            else:
                rydbg_lst.extend(range(k, k+deg))
            k = k + deg
        count[ia,l] += nc
    return core_lst, val_lst, rydbg_lst
Пример #3
0
    def __init__(self, atoms, basis=None):
        self.atomtypes = mole.atom_types(atoms, basis)
        # fake systems, which treates the atoms of different basis as different atoms.
        # the fake systems do not have the same symmetry as the potential
        # it's only used to determine the main (Z-)axis
        chg1 = numpy.pi - 2
        coords = []
        fake_chgs = []
        idx = []
        for k, lst in self.atomtypes.items():
            idx.append(lst)
            coords.append([atoms[i][1] for i in lst])
            ksymb = mole._rm_digit(k)
            if ksymb != k:
                # Put random charges on the decorated atoms
                fake_chgs.append([chg1] * len(lst))
                chg1 *= numpy.pi - 2
            elif mole.is_ghost_atom(k):
                if ksymb == 'X' or ksymb.upper() == 'GHOST':
                    fake_chgs.append([.3] * len(lst))
                elif ksymb[0] == 'X':
                    fake_chgs.append([mole.charge(ksymb[1:]) + .3] * len(lst))
                elif ksymb[:5] == 'GHOST':
                    fake_chgs.append([mole.charge(ksymb[5:]) + .3] * len(lst))
            else:
                fake_chgs.append([mole.charge(ksymb)] * len(lst))
        coords = numpy.array(numpy.vstack(coords), dtype=float)
        fake_chgs = numpy.hstack(fake_chgs)
        self.charge_center = numpy.einsum('i,ij->j', fake_chgs,
                                          coords) / fake_chgs.sum()
        coords = coords - self.charge_center

        idx = numpy.argsort(numpy.hstack(idx))
        self.atoms = numpy.hstack((fake_chgs.reshape(-1, 1), coords))[idx]

        self.group_atoms_by_distance = []
        decimals = int(-numpy.log10(TOLERANCE)) - 1
        for index in self.atomtypes.values():
            index = numpy.asarray(index)
            c = self.atoms[index, 1:]
            dists = numpy.around(norm(c, axis=1), decimals)
            u, idx = numpy.unique(dists, return_inverse=True)
            for i, s in enumerate(u):
                self.group_atoms_by_distance.append(index[idx == i])
Пример #4
0
    def __init__(self, atoms, basis=None):
        self.atomtypes = mole.atom_types(atoms, basis)
        # fake systems, which treates the atoms of different basis as different atoms.
        # the fake systems do not have the same symmetry as the potential
        # it's only used to determine the main (Z-)axis
        chg1 = numpy.pi - 2
        coords = []
        fake_chgs = []
        idx = []
        for k, lst in self.atomtypes.items():
            idx.append(lst)
            coords.append([atoms[i][1] for i in lst])
            ksymb = mole._rm_digit(k)
            if ksymb != k:
                # Put random charges on the decorated atoms
                fake_chgs.append([chg1] * len(lst))
                chg1 *= numpy.pi-2
            elif mole.is_ghost_atom(k):
                if ksymb == 'X' or ksymb.upper() == 'GHOST':
                    fake_chgs.append([.3] * len(lst))
                elif ksymb[0] == 'X':
                    fake_chgs.append([mole.charge(ksymb[1:])+.3] * len(lst))
                elif ksymb[:5] == 'GHOST':
                    fake_chgs.append([mole.charge(ksymb[5:])+.3] * len(lst))
            else:
                fake_chgs.append([mole.charge(ksymb)] * len(lst))
        coords = numpy.array(numpy.vstack(coords), dtype=float)
        fake_chgs = numpy.hstack(fake_chgs)
        self.charge_center = numpy.einsum('i,ij->j', fake_chgs, coords)/fake_chgs.sum()
        coords = coords - self.charge_center

        idx = numpy.argsort(numpy.hstack(idx))
        self.atoms = numpy.hstack((fake_chgs.reshape(-1,1), coords))[idx]

        self.group_atoms_by_distance = []
        decimals = int(-numpy.log10(TOLERANCE)) - 1
        for index in self.atomtypes.values():
            index = numpy.asarray(index)
            c = self.atoms[index,1:]
            dists = numpy.around(norm(c, axis=1), decimals)
            u, idx = numpy.unique(dists, return_inverse=True)
            for i, s in enumerate(u):
                self.group_atoms_by_distance.append(index[idx == i])
Пример #5
0
def set_atom_conf(element, description):
    '''Change the default atomic core and valence configuration to the one
    given by "description".
    See data/elements.py for the default configuration.

    Args:
        element : str or int
            Element symbol or nuclear charge
        description : str or a list of str
            | "double p" : double p shell
            | "double d" : double d shell
            | "double f" : double f shell
            | "polarize" : add one polarized shell
            | "1s1d"     : keep core unchanged and set 1 s 1 d shells for valence
            | ("3s2p","1d") : 3 s, 2 p shells for core and 1 d shells for valence
    '''
    charge = mole.charge(element)

    def to_conf(desc):
        desc = desc.replace(' ', '').replace('-', '').replace('_', '').lower()
        if "doublep" in desc:
            desc = '2p'
        elif "doubled" in desc:
            desc = '2d'
        elif "doublef" in desc:
            desc = '2f'
        elif "polarize" in desc:
            loc = AOSHELL[charge][1].find('0')
            desc = '1' + AOSHELL[charge][1][loc + 1]
        return desc

    if isinstance(description, str):
        c_desc, v_desc = AOSHELL[charge][0], to_conf(description)
    else:
        c_desc, v_desc = to_conf(description[0]), to_conf(description[1])

    ncore = [int(x) for x in AOSHELL[charge][0][::2]]
    ncv = [int(x) for x in AOSHELL[charge][1][::2]]
    for i, s in enumerate(('s', 'p', 'd', 'f')):
        if s in c_desc:
            ncore[i] = int(c_desc.split(s)[0][-1])
        if s in v_desc:
            ncv[i] = ncore[i] + int(v_desc.split(s)[0][-1])
    c_conf = '%ds%dp%dd%df' % tuple(ncore)
    cv_conf = '%ds%dp%dd%df' % tuple(ncv)
    AOSHELL[charge] = [c_conf, cv_conf]
    sys.stderr.write('Update %s conf: core %s core+valence %s\n' %
                     (element, c_conf, cv_conf))
Пример #6
0
def set_atom_conf(element, description):
    '''Change the default atomic core and valence configuration to the one
    given by "description".
    See data/elements.py for the default configuration.

    Args:
        element : str or int
            Element symbol or nuclear charge
        description : str or a list of str
            | "double p" : double p shell
            | "double d" : double d shell
            | "double f" : double f shell
            | "polarize" : add one polarized shell
            | "1s1d"     : keep core unchanged and set 1 s 1 d shells for valence
            | ("3s2p","1d") : 3 s, 2 p shells for core and 1 d shells for valence
    '''
    charge = mole.charge(element)
    def to_conf(desc):
        desc = desc.replace(' ','').replace('-','').replace('_','').lower()
        if "doublep" in desc:
            desc = '2p'
        elif "doubled" in desc:
            desc = '2d'
        elif "doublef" in desc:
            desc = '2f'
        elif "polarize" in desc:
            loc = AOSHELL[charge][1].find('0')
            desc = '1' + AOSHELL[charge][1][loc+1]
        return desc
    if isinstance(description, str):
        c_desc, v_desc = AOSHELL[charge][0], to_conf(description)
    else:
        c_desc, v_desc = to_conf(description[0]), to_conf(description[1])

    ncore = [int(x) for x in AOSHELL[charge][0][::2]]
    ncv = [int(x) for x in AOSHELL[charge][1][::2]]
    for i, s in enumerate(('s', 'p', 'd', 'f')):
        if s in c_desc:
            ncore[i] = int(c_desc.split(s)[0][-1])
        if s in v_desc:
            ncv[i] = ncore[i] + int(v_desc.split(s)[0][-1])
    c_conf  = '%ds%dp%dd%df' % tuple(ncore)
    cv_conf = '%ds%dp%dd%df' % tuple(ncv)
    AOSHELL[charge] = [c_conf, cv_conf]
    sys.stderr.write('Update %s conf: core %s core+valence %s\n' %
                     (element, c_conf, cv_conf))
Пример #7
0
def get_nuc_g_factor(symb_or_charge, mass=None):
    if isinstance(symb_or_charge, str):
        Z = mole.charge(symb_or_charge)
    else:
        Z = symb_or_charge
# g factor of other isotopes can be found in file nuclear_g_factor.dat
    if mass is None:
        # The default isotopes
        nuc_spin, g_nuc = ISOTOPE_GYRO[Z][0][1:3]
    else:
        for isotop_mass, nuc_spin, g_nuc in ISOTOPE_GYRO[Z]:
            if isotop_mass == mass:
                break
        else:
            raise ValueError('mass=%s not found in isotopes of %s' %
                             (mass, symb_or_charge))
    #gyromag = g_factor_to_gyromagnetic_ratio(g_nuc)
    return g_nuc
Пример #8
0
def get_nuc_g_factor(symb, mass=None):
    Z = mole.charge(symb)
    # g factor of other isotopes can be found in file nuclear_g_factor.dat
    nuc_spin, g_nuc = ISOTOPE_GYRO[Z][1:3]
    #gyromag = g_factor_to_gyromagnetic_ratio(g_nuc)
    return g_nuc