Example #1
0
def findPeriodicallyEqualAtoms(atoms, other_atoms):
    center = atoms.positions.mean(axis=0)
    center, remain = convertToBasis(center, other_atoms.cell)
    center = (np.array([.5, .5, .5]) - center)[0]
    other_atoms = wrap(other_atoms, center=center)
    cell = other_atoms.get_cell()
    pbc = atoms.get_pbc()
    cell = atoms.cell[pbc]

    group = -np.ones(len(other_atoms), dtype=np.int)
    for i, atom in enumerate(atoms):
        diff = other_atoms.get_positions() - atom.position
        pos = minimalDistance(diff, cell)
        mask = vectorLength(pos, 1) < 1e-5
        indices = np.arange(len(other_atoms))[mask]
        group[indices] = i

    return group
Example #2
0
def makeAtomsRelaxed(atoms, relaxed_atoms, tolerance=1.0, cell=None, change=None, correct_drift=False):
    atoms = atoms.copy()
    if relaxed_atoms is None:
        return atoms
    if change is None:
        change = np.ones(len(atoms), np.bool)

    if cell is None:
        cell = atoms.get_cell()
        cell[relaxed_atoms.pbc] = relaxed_atoms.cell[relaxed_atoms.pbc]

    drift = np.zeros(3, np.float)
    used = np.zeros(len(relaxed_atoms), np.bool)
    changed = []
    if relaxed_atoms is not None:
        # Find relaxed atoms closest to originals.
        for i, atom in enumerate(atoms):
            if not change[i]:
                continue
            mask = np.array([r_atom.symbol == atom.symbol for r_atom in relaxed_atoms])
            mask = np.logical_and(mask, np.logical_not(used))

            if mask.sum() == 0:
                continue
            diff = relaxed_atoms.positions[mask] - atom.position
            diff = minimalDistance(diff, cell[relaxed_atoms.pbc])
            index = vectorLength(diff, 1).argmin()
            adjustment = diff[index]
            if vectorLength(adjustment) < tolerance:
                drift += adjustment
                real_index = np.arange(len(relaxed_atoms))[mask][index]
                used[real_index] = False
                changed.append(i)
                atom.position += adjustment

    if correct_drift:
        changed = np.array(changed)
        drift /= len(changed)
        atoms.positions[changed] -= drift

    return atoms
Example #3
0
def substitutionalDopingOfMiddleLayer(atoms, n_dopants=1, dopant_element='P', centers=None):
    assert isinstance(n_dopants, int)
    assert n_dopants > 0
    atoms = atoms.copy()
    middle_layer = list(findMiddleLayer(atoms))
    symbols = np.array(atoms.get_chemical_symbols())
    make_dopants = []
    for i in range(n_dopants):
        if centers is None:
            middle_layer_index = 0
            centers = []
        else:
            pos = atoms.positions[np.array(middle_layer, int)]
            for center in centers:
                middle_layer_index = vectorLength(minimalDistance(pos - center, atoms.cell), 1).argmax()

        index = middle_layer.pop(middle_layer_index)
        make_dopants.append(index)
        centers.append(atoms[index].position)

    symbols[np.array(make_dopants, int)] = dopant_element
    atoms.set_chemical_symbols(symbols)

    return atoms