Exemplo n.º 1
0
def biatomic(atoms, A, B, R1=3.0, calc_energy=False):
    r"""This routine analyzes atomic structure
    by the calculation of coordination numbers
    in cluster with atoms of two types (A and B).

    Parameters
    ----------
    atoms: ase.Atoms
        ase Atoms object, containing atomic cluster.
    A: string
        atom type, like 'Ag', 'Pt', etc.
    B: string
        atom type, like 'Ag', 'Pt', etc.
    R1: float
        First coordination shell will icnlude all atoms
        with distance less then R1 [Angstrom].
        Default value is 3.
    calc_energy: bool
        Flag used for calculation of potential energy with EMT
        calculator.  The default value is False, so that
        energy is not calculated.

    Returns
    -------
    N: int
        number of atoms in cluster
    nA:
        number of atoms of type A
    R: float
        radius of the cluster
    CN_AA: float
        average number of atoms A around atom A
    CN_AB: float
        average number of atoms A around atom B
    CN_BB: float
        average number of atoms B around atom B
    CN_BA: float
        average number of atoms B around atom A
    etha: float
        parameter of local ordering, -1 < etha < 1.
        Returns 999 if concentration of one of the
        component is too low.
    E: float
        potential energy
    NAcore:
        number of A atoms in core
    NBcore:
        number of B atoms in core
    CNshellAA:
        average CN of A-A for surface atoms only
    CNshellAB:
        average CN of A-B for surface atoms only
    CNshellBB:
        average CN of B-B for surface atoms only
    CNshellBA:
        average CN of B-A for surface atoms only

    Notes
    -----
        The radius of the cluster is roughly determined as
        maximum the distance from the center to most distant atom
        in the cluster.

    Example
    --------
    >>> atoms = FaceCenteredCubic('Ag',
      [(1, 0, 0), (1, 1, 0), (1, 1, 1)], [7,8,7], 4.09)
    >>> atoms = CoreShellFCC(atoms, 'Pt', 'Ag', 0.6, 4.09)
    >>> [N, nA, R, CN_AA, CN_AB, CN_BB, CN_BA, etha] =
      biatomic(atoms, 'Pt', 'Ag')
    >>> print "Short range order parameter: ", etha
    """
    N = len(atoms)
    nA = 0
    nB = 0
    for element in atoms.get_chemical_symbols():
        if element == A:
            nA += 1
        elif element == B:
            nB += 1
        else:
            raise Exception('Extra element ' + element)
    if (nA + nB != N):
        raise Exception('Number of A (' + str(nA) + ') ' +
          'and B (' + str(nB) + ') artoms mismatch!')
    nl = NeighborList([R1 / 2.0] * N, self_interaction=False, bothways=True)
    nl.build(atoms)

    # initialize counters:
    CN_AA = 0    # averaged total coord. numbers
    CN_AB = 0
    CN_BB = 0
    CN_BA = 0
    NAcore = 0  # number of atoms in core region
    NBcore = 0
    CNshellAA = 0  # average coord. numbers for surface atoms
    CNshellAB = 0
    CNshellBB = 0
    CNshellBA = 0
    for iatom in xrange(0, N):
        indeces, offsets = nl.get_neighbors(iatom)
        if atoms[iatom].symbol == B:
            CN_BB_temp = 0
            CN_BA_temp = 0
            for ii in indeces:
                if atoms[ii].symbol == B:
                    CN_BB_temp += 1
                else:  # atoms[i].symbol == A :
                    CN_BA_temp += 1
            CN_BB += CN_BB_temp
            CN_BA += CN_BA_temp
            if len(indeces) < 12:
                # SHELL
                CNshellBB += CN_BB_temp
                CNshellBA += CN_BA_temp
            else:
                # CORE
                NBcore += 1
        else:  # atoms[iatom].symbol == A :
            CN_AA_temp = 0
            CN_AB_temp = 0
            for i in indeces:
                if atoms[i].symbol == A:
                    CN_AA_temp += 1
                else:  # atoms[i].symbol==B :
                    CN_AB_temp += 1
            CN_AA += CN_AA_temp
            CN_AB += CN_AB_temp
            if len(indeces) < 12:
                # SHELL
                CNshellAA += CN_AA_temp
                CNshellAB += CN_AB_temp
            else:
                # CORE
                NAcore += 1
    # averaging:
    CN_AA = CN_AA * 1.0 / nA
    CN_AB = CN_AB * 1.0 / nA
    CN_BB = CN_BB * 1.0 / nB
    CN_BA = CN_BA * 1.0 / nB
    znam = (nA - NAcore)
    if znam > 0.0001:
        CNshellAA = CNshellAA * 1.0 / znam
        CNshellAB = CNshellAB * 1.0 / znam
    else:
        CNshellAA = 0
        CNshellAB = 0
    znam = (nB - NBcore)
    if znam > 0.0001:
        CNshellBB = CNshellBB * 1.0 / znam
        CNshellBA = CNshellBA * 1.0 / znam
    else:
        CNshellBB = 0
        CNshellBA = 0

    # calc concentrations:
    concB = nB * 1.0 / N
    if concB < 0.0001:
        #print "WARNING! Too low B concentration: ",concB
        etha = 999
    else:
        etha = 1 - CN_AB / (concB * (CN_AA + CN_AB))
    R = atoms.positions.max() / 2.0
    if calc_energy:
        #from asap3 import EMT
        from ase.calculators.emt import EMT
        atoms.set_calculator(EMT())
        E = atoms.get_potential_energy()
    else:
        E = -1
    return N, nA, R, CN_AA, CN_AB, CN_BB, CN_BA, etha, E, NAcore, \
      NBcore, CNshellAA, CNshellAB, CNshellBB, CNshellBA
Exemplo n.º 2
0
def monoatomic(atoms, R1=3, calc_energy=False):
    r"""This routine analyzes atomic structure
    by the calculation of coordination numbers
    in cluster with only one type of atom.

    Parameters
    ----------
    atoms: ase.Atoms
        ase Atoms object, containing atomic cluster.
    R1: float
        First coordination shell will icnlude all atoms
        with distance less then R1 [Angstrom].
        Default value is 3.
    calc_energy: bool
        Flag used for calculation of potential energy with EMT
        calculator.  The default value is False, so that
        energy is not calculated.

    Returns
    -------
    N: int
        number of atoms in cluster
    R: float
        radius of the cluster
    CN: float
        average coord number
    E: float
        potential energy, -1 if calc_energy is False
    Ncore:
        number of atoms in core region (number of atoms with
        all 12 neighbors)
    CNshell:
        average coordination number for surface atoms only

    Notes
    -----
        The radius of the cluster is roughly determined as
        maximum the distance from the center to most distant atom
        in the cluster.

    Example
    --------
    >>> atoms = FaceCenteredCubic('Ag',
      [(1, 0, 0), (1, 1, 0), (1, 1, 1)], [7,8,7], 4.09)
    >>> [N, R, CN] = monoatomic(atoms)
    >>> print "average CN is ", CN
    """
    N = len(atoms)
    nl = NeighborList([R1 / 2.0] * N, self_interaction=False, bothways=True)
    nl.build(atoms)
    CN = 0
    Ncore = 0
    Nshell = 0
    CNshell = 0  # average CN of surface atoms
    for i in xrange(0, N):
        indeces, offsets = nl.get_neighbors(i)
        CN += len(indeces)
        if len(indeces) < 12:
            Nshell += 1
            CNshell += len(indeces)
        else:
            Ncore += 1
    CN = CN * 1.0 / N
    CNshell = CNshell * 1.0 / Nshell
    atoms.center()
    R = atoms.positions.max() / 2.0
    if calc_energy:
        #from asap3 import EMT
        from ase.calculators.emt import EMT
        atoms.set_calculator(EMT())
        E = atoms.get_potential_energy()
    else:
        E = -1
    return N, R, CN, E, Ncore, CNshell