Пример #1
0
Файл: ase.py Проект: sroet/PLAMS
def toASE(molecule):
    """Convert a PLAMS |Molecule| to an ASE molecule (``ase.Atoms`` instance). Translate coordinates, atomic numbers, and lattice vectors (if present). The order of atoms is preserved."""
    aseMol = aseAtoms()

    #iterate over PLAMS atoms
    for atom in molecule:

        #check if coords only consists of floats or ints
        if not all(isinstance(x, (int,float)) for x in atom.coords):
            raise ValueError("Non-Number in Atomic Coordinates, not compatible with ASE")

        #append atom to aseMol
        aseMol.append(aseAtom(atom.atnum, atom.coords))

    #get lattice info if any
    lattice = npz((3,3))
    pbc = [False,False,False]
    for i,vec in enumerate(molecule.lattice):

        #check if lattice only consists of floats or ints
        if not all(isinstance(x, (int,float)) for x in vec):
            raise ValueError("Non-Number in Lattice Vectors, not compatible with ASE")

        pbc[i] = True
        lattice[i] = npa(vec)

    #save lattice info to aseMol
    if any(pbc):
        aseMol.set_pbc(pbc)
        aseMol.set_cell(lattice)

    return aseMol
Пример #2
0
    def gen_quad_smart(self, dis_type="easy"):
        alat = 2.82893
        a1 = (1./3.)*alat*np.array([-1,-1,2])
        a2 = (1.0/2.0)*alat*np.array([1,-1,0])
        a3 = alat*0.5*np.array([1, 1, 1])
        M = np.array([a1,a2,a3])
        print M
        latt_1 = alat*np.array([-1.0,-1.0,2.0])
        latt_2 = alat*np.array([1.0, 0.0,-1.0])
        basis_1 = alat*np.array([0.0,0.0,0.0])
        basis_2 = alat*np.array([0.0,0.0,1.0])
        basis_3 = alat*np.array([0.5, 0.5, 0.5])
        #basis_1 = alat*np.array([0.0,0.0,0.0])
        #basis_2 = alat*np.array([0.81625, 0.0, 0.57734])
        #basis_3 = alat*np.array([1.6329, 0.0, 0.288675])
        #latt_1 = np.array([6.93206,0.0,0.0])
        #latt_2 = np.array([-3.46603,2.00111,0.0])
        #basis_2 = alat*np.sqrt(3.)*0.5*np.array([1.0,1.0,1.0])
        print 'new latt 1', np.dot(np.linalg.inv(M.T), basis_1)
        print 'new latt 2', np.dot(np.linalg.inv(M.T), basis_2)


        #as integeres
        if dis_type == "easy":
            n = 15.
            m = 9.
            c1 = n*a1 - (1.0/(3.0*m))*a3
            c2 = (n/2.)*a1 + m*a2 + (0.5 - (1.0/6*m))*a3
            c3 = a3
        elif dis_type == "hard":
            n = 21.
            m = 13.
            c1 = n*a1 + (1.0/(3*m))*a3
            c2 = (n/2.)*a1 + m*a2 + (0.5 + 1./(6.*m))*a3
            c3 = a3
        #screw_slab_unit = BodyCenteredCubic(directions = [c1,c2,c3],
        #                                    size = (1,1,1), symbol='Fe', pbc=(1,1,1),
        #                                    latticeconstant = 2.83)
        screw_slab_unit = aseAtoms()
        for x in range(-30,30):
            for y in range(-30,30):
                latt = x*(latt_1) + y*(latt_2)
                Fe_1 = latt
                Fe_2 = latt + basis_2
                Fe_3 = latt + basis_3
                #latt_norm = np.linalg.norm(latt)
                #c1_norm = np.linalg.norm(c1)
                #c2_norm = np.linalg.norm(c2)
                #c1_arg = np.arccos((np.dot(c1,latt)/(c1_norm*latt_norm))) 
                #c2_arg = np.dot(c2,latt)/(np.linalg.norm(c2)*np.linalg.norm(latt))
                #c1_comp = np.linalg.norm(np.dot(c1,latt)*(c1_norm*latt_norm))
                #c2_comp = np.linalg.norm(np.dot(c2,latt)*(c2_norm*latt_norm))
                screw_slab_unit.append(Atom(symbol='Fe', position=Fe_1))
                screw_slab_unit.append(Atom(symbol='Fe', position=Fe_2))
                screw_slab_unit.append(Atom(symbol='Fe', position=Fe_3))

        screw_slab_unit.set_cell([c1,c2,c3])
        screw_slab_unit.write('screw.xyz')
Пример #3
0
def get_localEnv(frame, centerIdx, cutoff, onlyDict=False):
    '''
    Get the local atomic environment around an atom in an atomic frame.

    :param frame: ase or quippy Atoms object
    :param centerIdx: int
    Index of the local environment center.
    :param cutoff: float
    Cutoff radius of the local environment.
    :return: ase Atoms object
    Local atomic environment. The center atom is in first position.
    '''
    import ase.atoms
    import quippy.atoms
    from ase.neighborlist import NeighborList
    from ase import Atoms as aseAtoms
    if isinstance(frame, quippy.atoms.Atoms):
        atoms = qp2ase(frame)
    elif isinstance(frame, ase.atoms.Atoms):
        atoms = frame
    else:
        raise ValueError

    n = len(atoms.get_atomic_numbers())
    nl = NeighborList([
        cutoff / 2.,
    ] * n,
                      skin=0.,
                      sorted=False,
                      self_interaction=False,
                      bothways=True)
    nl.build(atoms)

    cell = atoms.get_cell()
    pbc = atoms.get_pbc()
    pos = atoms.get_positions()
    positions = [
        pos[centerIdx],
    ]
    zList = atoms.get_atomic_numbers()
    numbers = [
        zList[centerIdx],
    ]

    indices, offsets = nl.get_neighbors(centerIdx)

    # print offsets,len(atom.get_atomic_numbers())
    for i, offset in zip(indices, offsets):
        positions.append(pos[i] + np.dot(offset, cell))
        numbers.append(zList[i])

    atomsParam = dict(numbers=numbers, cell=cell, positions=positions, pbc=pbc)

    if onlyDict:
        return atomsParam
    else:
        return aseAtoms(**atomsParam)
Пример #4
0
 def get_atom(self):
     from ase import Atoms as aseAtoms
     frame = aseAtoms(numbers=self._atomic_numbers,
                     positions=self._positions,
                     cell=self._cell,
                     pbc=self._pbc)
     for key,item in self._infoDict.iteritems():
         frame.set_array(key,item)
     return frame
Пример #5
0
    def get_centerInfo(self):

        if self.is_fast_average:
            print 'fast average -> no center'
        else:
            from ase import Atoms as aseAtoms
            info = {'z': self._atomic_number, 'position': self._position,
                    'cell': self._cell, 'idx': self._frameIdx,
                    'symbol': self._chemical_symbol, 'env': aseAtoms(**self._localEnvironementDict)}
            info.update(**self._info)
            return info
Пример #6
0
def qp2ase(qpatoms):
    from ase import Atoms as aseAtoms
    positions = qpatoms.get_positions()
    cell = qpatoms.get_cell()
    numbers = qpatoms.get_atomic_numbers()
    pbc = qpatoms.get_pbc()
    atoms = aseAtoms(numbers=numbers, cell=cell, positions=positions, pbc=pbc)

    for key, item in qpatoms.arrays.iteritems():
        if key in ['positions', 'numbers', 'species', 'map_shift', 'n_neighb']:
            continue
        atoms.set_array(key, item)

    return atoms
Пример #7
0
def decorate_interface():
    ats = Atoms('interface.xyz')
    dataset = spglib.get_symmetry_dataset(ats, symprec=1e-5)

    with open('unique_lattice_sites.json', 'w') as f:
        json.dump([
            list(ats[site_num].position)
            for site_num in np.unique(dataset['equivalent_atoms'])
        ], f)

    unique_atoms = []
    for at in ats:
        unique_atoms.append(at.position)
    voronoi = Voronoi(limits=tuple(np.diag(ats.cell)),
                      periodic=(True, True, False))
    cntr = voronoi.compute_voronoi(unique_atoms)
    ints_list = []
    for site_num in np.unique(dataset['equivalent_atoms']):
        for vert in voronoi.get_vertices(site_num, cntr):
            ints_list.append(vert.tolist())

    for unique in ints_list:
        ats.add_atoms(unique, 1)
    for i in range(len(ats)):
        ats.id[i] = i
    #remove voronoi duplicates
    print 'Fe_H atoms', len(ats)
    ats.wrap()
    del_ats = aseAtoms()
    for at in ats:
        del_ats.append(at)
    geometry.get_duplicate_atoms(del_ats, cutoff=0.2, delete=True)
    ats = del_ats.copy()
    print 'Fe_H atoms remove duplicates', len(ats)
    #select unique hydrogens
    #for i in range(len(ats)):
    #  ats.id[i] = i
    ints_list = [at.position for at in ats if at.number == 1]
    with open('unique_h_sites.json', 'w') as f:
        json.dump([list(u) for u in ints_list], f)
    ats.write('hydrogenated_grain.xyz')
Пример #8
0
def toASE(molecule):
    """
    Converts a PLAMS molecule to an ASE molecule. The following attributes are converted, conserving the order of atoms:
    -Coordinates
    -Atomic Number (Symbol is derived automaticaly)
    -Periodicity and Cell Vectors
    """
    aseMol = aseAtoms()

    #iterate over PLAMS atoms
    for atom in molecule:

        #check if coords only consists of floats or ints
        if not all(isinstance(x, (int, float)) for x in atom.coords):
            raise ValueError(
                "Non-Number in Atomic Coordinates, not compatible with ASE")

        #append atom to aseMol
        aseMol.append(aseAtom(atom.atnum, atom.coords))

    #get lattice info if any
    lattice = npz((3, 3))
    pbc = [False, False, False]
    for i, vec in enumerate(molecule.lattice):

        #check if lattice only consists of floats or ints
        if not all(isinstance(x, (int, float)) for x in vec):
            raise ValueError(
                "Non-Number in Lattice Vectors, not compatible with ASE")

        pbc[i] = True
        lattice[i] = npa(vec)

    #save lattice info to aseMol
    if any(pbc):
        aseMol.set_pbc(pbc)
        aseMol.set_cell(lattice)

    return aseMol
Пример #9
0
def calc_bulk_dissolution(args):
    """Calculate the bulk dissolution energy for hydrogen
    in a tetrahedral position in bcc iron.
    Args:
      args(list): determine applied strain to unit cell.
    """
    POT_DIR = os.path.join(app.root_path, 'potentials')
    eam_pot = os.path.join(POT_DIR, 'PotBH.xml')
    r_scale = 1.00894848312
    pot = Potential(
        'IP EAM_ErcolAd do_rescale_r=T r_scale={0}'.format(r_scale),
        param_filename=eam_pot)
    alat = 2.83

    gb = BodyCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                           size=(6, 6, 6),
                           symbol='Fe',
                           pbc=(1, 1, 1),
                           latticeconstant=alat)
    cell = gb.get_cell()
    print 'Fe Cell', cell

    e1 = np.array([1, 0, 0])
    e2 = np.array([0, 1, 0])
    e3 = np.array([0, 0, 1])

    if args.hydrostatic != 0.0:
        strain_tensor = np.eye(3) + args.hydrostatic * np.eye(3)
        cell = cell * strain_tensor
        gb.set_cell(cell, scale_atoms=True)
        print 'Hydrostatic strain', args.hydrostatic
        print 'strain tensor', strain_tensor
        print gb.get_cell()
    elif args.stretch != 0.0:
        strain_tensor = np.tensordot(e2, e2, axes=0)
        strain_tensor = np.eye(3) + args.stretch * strain_tensor
        cell = strain_tensor * cell
        print 'Stretch strain'
        print 'Cell:', cell
        gb.set_cell(cell, scale_atoms=True)
    elif args.shear != 0.0:
        strain_tensor = np.tensordot(e1, e2, axes=0)
        strain_tensor = np.eye(3) + args.shear * strain_tensor
        cell = strain_tensor.dot(cell)
        print 'Shear Strain', strain_tensor
        print 'Cell:', cell
        gb.set_cell(cell, scale_atoms=True)
        gb.write('sheared.xyz')
    else:
        print 'No strain applied.'

    tetra_pos = alat * np.array([0.25, 0.0, 0.5])
    h2 = aseAtoms('H2', positions=[[0, 0, 0], [0, 0, 0.7]])
    h2 = Atoms(h2)

    gb = Atoms(gb)
    gb_h = gb.copy()
    gb_h.add_atoms(tetra_pos, 1)

    #caclulators
    gb.set_calculator(pot)
    h2.set_calculator(pot)
    gb_h.set_calculator(pot)
    gb_h.write('hydrogen_bcc.xyz')

    #Calc Hydrogen molecule energy
    opt = BFGS(h2)
    opt.run(fmax=0.0001)
    E_h2 = h2.get_potential_energy()
    h2.write('h2mol.xyz')

    #strain_mask  = [1,1,1,0,0,0]
    strain_mask = [0, 0, 0, 0, 0, 0]
    ucf = UnitCellFilter(gb_h, strain_mask)

    #opt = BFGS(gb_h)
    opt = FIRE(ucf)
    opt.run(fmax=0.0001)
    E_gb = gb.get_potential_energy()
    E_gbh = gb_h.get_potential_energy()
    E_dis = E_gbh - E_gb - 0.5 * E_h2

    print 'E_gb', E_gb
    print 'E_gbh', E_gbh
    print 'H2 Formation Energy', E_h2
    print 'Dissolution Energy', E_dis
Пример #10
0
    symbols          = unit_cell.get_chemical_symbols()
    cell             = unit_cell.get_cell()
    scaled_positions = unit_cell.get_scaled_positions()

    THZ_to_mev = 4.135665538536
    unit_cell  = PhonopyAtoms(symbols=symbols, cell=cell, scaled_positions=scaled_positions)
    phonon     = Phonopy(unit_cell, [[n_sup_x,0,0],[0,n_sup_y,0],[0,0,n_sup_z]])
    phonon.generate_displacements(distance=0.05)
    supercells = phonon.get_supercells_with_displacements()

    #We need to get the forces on these atoms...
    forces = []
    print 'There are', len(supercells), 'displacement patterns'
    for sc in supercells:
        cell = aseAtoms(symbols=sc.get_chemical_symbols(), scaled_positions=sc.get_scaled_positions(),
                        cell=sc.get_cell(), pbc=(1,1,1))
        cell = Atoms(cell)
        cell.set_calculator(pot)
        forces.append(cell.get_forces())

    phonon.set_forces(forces)
    phonon.produce_force_constants()

    mesh = [nqx, nqy, nqz]
    phonon.set_mesh(mesh, is_eigenvectors=True)
    qpoints, weights, frequencies, eigvecs = phonon.get_mesh()

    #SHOW DOS STRUCTURE
    phonon.set_total_DOS(freq_min=0.0, freq_max=12.0, tetrahedron_method=False)
    phonon.get_total_DOS()
    phonon.write_total_DOS()
Пример #11
0
POT_DIR = os.path.join(app.root_path, 'potentials')
eam_pot = os.path.join(POT_DIR, 'PotBH.xml')
r_scale = 1.00894848312
pot = Potential('IP EAM_ErcolAd do_rescale_r=T r_scale={0}'.format(r_scale),
                param_filename=eam_pot)
alat = 2.83
#Structures
gb = BodyCenteredCubic(directions=[[1, 0, 0], [0, 1, 0], [0, 0, 1]],
                       size=(4, 4, 4),
                       symbol='Fe',
                       pbc=(1, 1, 1),
                       latticeconstant=alat)

tetra_pos = alat * np.array([0.25, 0.0, 0.5])

h2 = aseAtoms('H2', positions=[[0, 0, 0], [0, 0, 0.7]])
h2 = Atoms(h2)

gb = Atoms(gb)
gb_h = gb.copy()
gb_h.add_atoms(tetra_pos, 1)

#caclulators
gb.set_calculator(pot)
h2.set_calculator(pot)
gb_h.set_calculator(pot)
gb_h.write('hydrogen_bcc.xyz')

#Calc Hydrogen molecule energy
opt = BFGS(h2)
opt.run(fmax=0.0001)
Пример #12
0
 def get_localEnvironement(self):
     if self.is_fast_average:
         print 'fast average -> no center'
     else:
         from ase import Atoms as aseAtoms
         return aseAtoms(**self._localEnvironementDict)