def get_atoms_adsorbate(): # We need the relaxed slab here! slab = Atoms([ Atom('Cu', [-1.028468159509163, -0.432387156877267, -0.202086055768265]), Atom('Cu', [0.333333333333333, 0.333333333333333, -2.146500000000000]), Atom('Cu', [1.671531840490805, -0.432387156877287, -0.202086055768242]), Atom('Cu', [3.033333333333334, 0.333333333333333, -2.146500000000000]), Atom('Cu', [4.371531840490810, -0.432387156877236, -0.202086055768261]), Atom('Cu', [5.733333333333333, 0.333333333333333, -2.146500000000000]), Atom('Cu', [7.071531840490944, -0.432387156877258, -0.202086055768294]), Atom('Cu', [8.433333333333335, 0.333333333333333, -2.146500000000000]), Atom('Cu', [0.321531840490810, 1.905881433340708, -0.202086055768213]), Atom('Cu', [1.683333333333333, 2.671601923551318, -2.146500000000000]), Atom('Cu', [3.021531840490771, 1.905881433340728, -0.202086055768250]), Atom('Cu', [4.383333333333334, 2.671601923551318, -2.146500000000000]), Atom('Cu', [5.721531840490857, 1.905881433340735, -0.202086055768267]), Atom('Cu', [7.083333333333333, 2.671601923551318, -2.146500000000000]), Atom('Cu', [8.421531840490820, 1.905881433340739, -0.202086055768265]), Atom('Cu', [9.783333333333335, 2.671601923551318, -2.146500000000000]), Atom('Cu', [1.671531840490742, 4.244150023558601, -0.202086055768165]), Atom('Cu', [3.033333333333334, 5.009870513769302, -2.146500000000000]), Atom('Cu', [4.371531840490840, 4.244150023558694, -0.202086055768265]), Atom('Cu', [5.733333333333333, 5.009870513769302, -2.146500000000000]), Atom('Cu', [7.071531840490880, 4.244150023558786, -0.202086055768352]), Atom('Cu', [8.433333333333335, 5.009870513769302, -2.146500000000000]), Atom('Cu', [9.771531840491031, 4.244150023558828, -0.202086055768371]), Atom('Cu', [11.133333333333335, 5.009870513769302, -2.146500000000000]), Atom('Cu', [3.021531840490714, 6.582418613776583, -0.202086055768197]), Atom('Cu', [4.383333333333334, 7.348139103987287, -2.146500000000000]), Atom('Cu', [5.721531840490814, 6.582418613776629, -0.202086055768203]), Atom('Cu', [7.083333333333333, 7.348139103987287, -2.146500000000000]), Atom('Cu', [8.421531840490985, 6.582418613776876, -0.202086055768357]), Atom('Cu', [9.783333333333335, 7.348139103987287, -2.146500000000000]), Atom('Cu', [11.121531840490929, 6.582418613776676, -0.202086055768221]), Atom('Cu', [12.483333333333334, 7.348139103987287, -2.146500000000000]), ]) mask = [a.position[2] < -1 for a in slab] slab.set_constraint(FixAtoms(mask=mask)) a = 2.70 c = 1.59 * a h = 1.85 d = 1.10 x = slab.positions[0, 2] / (c / 2) * 100 molecule = Atoms('2N', positions=[(0., 0., h), (0., 0., h + d)]) molecule.set_calculator(EMT()) slab.extend(molecule) return slab
def get_atoms_surf(): a = 2.70 c = 1.59 * a h = 1.85 d = 1.10 slab = Atoms('2Cu', [(0., 0., 0.), (1 / 3., 1 / 3., -0.5 * c)], tags=(0, 1), pbc=(1, 1, 0)) slab.set_cell([(a, 0, 0), (a / 2, 3**0.5 * a / 2, 0), (0, 0, 1)]) slab = slab.repeat((4, 4, 1)) mask = [a.tag == 1 for a in slab] slab.set_constraint(FixAtoms(mask=mask)) return slab
def get_atoms(): atoms = Atoms([ Atom('Pd', [5.078689759346383, 5.410678028467162, 4.000000000000000]), Atom('Pd', [7.522055777772603, 4.000000000000000, 4.000000000000000]), Atom('Pd', [7.522055777772603, 6.821356056934325, 4.000000000000000]), Atom('Pd', [6.707600438297196, 5.410678028467162, 6.303627574066606]), Atom('N', [4.807604264052752, 5.728625577716107, 5.919407072553396]), Atom('H', [4.000000000000000, 5.965167390141987, 6.490469524180266]), ]) constraint = FixAtoms(mask=[a.symbol == 'Pd' for a in atoms]) atoms.set_constraint(constraint) atoms.center(vacuum=4.0) atoms.set_pbc(False) return atoms
def get_atoms(): srf = Atoms('Cu64', [(1.2763, 1.2763, 4.0000), (3.8290, 1.2763, 4.0000), (6.3816, 1.2763, 4.0000), (8.9343, 1.2763, 4.0000), (1.2763, 3.8290, 4.0000), (3.8290, 3.8290, 4.0000), (6.3816, 3.8290, 4.0000), (8.9343, 3.8290, 4.0000), (1.2763, 6.3816, 4.0000), (3.8290, 6.3816, 4.0000), (6.3816, 6.3816, 4.0000), (8.9343, 6.3816, 4.0000), (1.2763, 8.9343, 4.0000), (3.8290, 8.9343, 4.0000), (6.3816, 8.9343, 4.0000), (8.9343, 8.9343, 4.0000), (0.0000, 0.0000, 5.8050), (2.5527, 0.0000, 5.8050), (5.1053, 0.0000, 5.8050), (7.6580, 0.0000, 5.8050), (0.0000, 2.5527, 5.8050), (2.5527, 2.5527, 5.8050), (5.1053, 2.5527, 5.8050), (7.6580, 2.5527, 5.8050), (0.0000, 5.1053, 5.8050), (2.5527, 5.1053, 5.8050), (5.1053, 5.1053, 5.8050), (7.6580, 5.1053, 5.8050), (0.0000, 7.6580, 5.8050), (2.5527, 7.6580, 5.8050), (5.1053, 7.6580, 5.8050), (7.6580, 7.6580, 5.8050), (1.2409, 1.2409, 7.6081), (3.7731, 1.2803, 7.6603), (6.3219, 1.3241, 7.6442), (8.8935, 1.2669, 7.6189), (1.2803, 3.7731, 7.6603), (3.8188, 3.8188, 7.5870), (6.3457, 3.8718, 7.6649), (8.9174, 3.8340, 7.5976), (1.3241, 6.3219, 7.6442), (3.8718, 6.3457, 7.6649), (6.3945, 6.3945, 7.6495), (8.9576, 6.3976, 7.6213), (1.2669, 8.8935, 7.6189), (3.8340, 8.9174, 7.5976), (6.3976, 8.9576, 7.6213), (8.9367, 8.9367, 7.6539), (0.0582, 0.0582, 9.4227), (2.5965, -0.2051, 9.4199), (5.1282, 0.0663, 9.4037), (7.6808, -0.0157, 9.4235), (-0.2051, 2.5965, 9.4199), (2.1913, 2.1913, 9.6123), (5.0046, 2.5955, 9.4873), (7.5409, 2.5336, 9.4126), (0.0663, 5.1282, 9.4037), (2.5955, 5.0046, 9.4873), (5.3381, 5.3381, 9.6106), (7.8015, 5.0682, 9.4237), (-0.0157, 7.6808, 9.4235), (2.5336, 7.5409, 9.4126), (5.0682, 7.8015, 9.4237), (7.6155, 7.6155, 9.4317)]) c2 = Atoms('C2', [(3.2897, 3.2897, 10.6627), (4.2113, 4.2113, 10.6493)]) srf.extend(c2) srf.pbc = (1, 1, 0) srf.set_cell([10.2106, 10.2106, 20.6572], scale_atoms=False) mask = [a.index < 32 for a in srf] c1 = FixedPlane(-1, (1 / np.sqrt(2), 1 / np.sqrt(2), 1)) c2 = FixedPlane(-2, (1 / np.sqrt(2), 1 / np.sqrt(2), 1)) constraint = FixAtoms(mask=mask) srf.set_constraint([constraint, c1, c2]) return srf
def read_aims(filename): """Import FHI-aims geometry type files. Reads unitcell, atom positions and constraints from a geometry.in file. """ from ase_ext import Atoms from ase_ext.constraints import FixAtoms, FixCartesian import numpy as np atoms = Atoms() fd = open(filename, 'r') lines = fd.readlines() fd.close() positions = [] cell = [] symbols = [] fix = [] fix_cart = [] xyz = np.array([0, 0, 0]) i = -1 n_periodic = -1 periodic = np.array([False, False, False]) for n, line in enumerate(lines): inp = line.split() if inp == []: continue if inp[0] == 'atom': if xyz.all(): fix.append(i) elif xyz.any(): print(1) fix_cart.append(FixCartesian(i, xyz)) floatvect = float(inp[1]), float(inp[2]), float(inp[3]) positions.append(floatvect) symbols.append(inp[-1]) i += 1 xyz = np.array([0, 0, 0]) elif inp[0] == 'lattice_vector': floatvect = float(inp[1]), float(inp[2]), float(inp[3]) cell.append(floatvect) n_periodic = n_periodic + 1 periodic[n_periodic] = True if inp[0] == 'constrain_relaxation': if inp[1] == '.true.': fix.append(i) elif inp[1] == 'x': xyz[0] = 1 elif inp[1] == 'y': xyz[1] = 1 elif inp[1] == 'z': xyz[2] = 1 if xyz.all(): fix.append(i) elif xyz.any(): fix_cart.append(FixCartesian(i, xyz)) atoms = Atoms(symbols, positions) if periodic.all(): atoms.set_cell(cell) atoms.set_pbc(periodic) if len(fix): atoms.set_constraint([FixAtoms(indices=fix)] + fix_cart) else: atoms.set_constraint(fix_cart) return atoms
from ase_ext import Atoms from ase_ext.calculators.emt import EMT from ase_ext.constraints import FixBondLength from ase_ext.io import PickleTrajectory from ase_ext.optimize import BFGS a = 3.6 b = a / 2 cu = Atoms('Cu2Ag', positions=[(0, 0, 0), (b, b, 0), (a, a, b)], calculator=EMT()) e0 = cu.get_potential_energy() print(e0) d0 = cu.get_distance(0, 1) cu.set_constraint(FixBondLength(0, 1)) t = PickleTrajectory('cu2ag.traj', 'w', cu) qn = BFGS(cu) qn.attach(t.write) def f(): print(cu.get_distance(0, 1)) qn.attach(f) qn.run(fmax=0.01) assert abs(cu.get_distance(0, 1) - d0) < 1e-14
def read_vasp(filename='CONTCAR'): """Import POSCAR/CONTCAR type file. Reads unitcell, atom positions and constraints from the POSCAR/CONTCAR file and tries to read atom types from POSCAR/CONTCAR header, if this fails the atom types are read from OUTCAR or POTCAR file. """ from ase_ext import Atoms, Atom from ase_ext.constraints import FixAtoms, FixScaled from ase_ext.data import chemical_symbols import numpy as np if isinstance(filename, str): f = open(filename) else: # Assume it's a file-like object f = filename # First line should contain the atom symbols , eg. "Ag Ge" in # the same order # as later in the file (and POTCAR for the full vasp run) atomtypes = f.readline().split() lattice_constant = float(f.readline()) # Now the lattice vectors a = [] for ii in range(3): s = f.readline().split() floatvect = float(s[0]), float(s[1]), float(s[2]) a.append(floatvect) basis_vectors = np.array(a) * lattice_constant # Number of atoms. Again this must be in the same order as # in the first line # or in the POTCAR or OUTCAR file atom_symbols = [] numofatoms = f.readline().split() #vasp5.1 has an additional line which gives the atom types #the following try statement skips this line try: int(numofatoms[0]) except ValueError: numofatoms = f.readline().split() numsyms = len(numofatoms) if len(atomtypes) < numsyms: # First line in POSCAR/CONTCAR didn't contain enough symbols. atomtypes = atomtypes_outpot(f.name, numsyms) else: try: for atype in atomtypes[:numsyms]: if not atype in chemical_symbols: raise KeyError except KeyError: atomtypes = atomtypes_outpot(f.name, numsyms) for i, num in enumerate(numofatoms): numofatoms[i] = int(num) [atom_symbols.append(atomtypes[i]) for na in range(numofatoms[i])] # Check if Selective dynamics is switched on sdyn = f.readline() selective_dynamics = sdyn[0].lower() == "s" # Check if atom coordinates are cartesian or direct if selective_dynamics: ac_type = f.readline() else: ac_type = sdyn cartesian = ac_type[0].lower() == "c" or ac_type[0].lower() == "k" tot_natoms = sum(numofatoms) atoms_pos = np.empty((tot_natoms, 3)) if selective_dynamics: selective_flags = np.empty((tot_natoms, 3), dtype=bool) for atom in range(tot_natoms): ac = f.readline().split() atoms_pos[atom] = (float(ac[0]), float(ac[1]), float(ac[2])) if selective_dynamics: curflag = [] for flag in ac[3:6]: curflag.append(flag == 'F') selective_flags[atom] = curflag # Done with all reading if type(filename) == str: f.close() if cartesian: atoms_pos *= lattice_constant atoms = Atoms(symbols=atom_symbols, cell=basis_vectors, pbc=True) if cartesian: atoms.set_positions(atoms_pos) else: atoms.set_scaled_positions(atoms_pos) if selective_dynamics: constraints = [] indices = [] for ind, sflags in enumerate(selective_flags): if sflags.any() and not sflags.all(): constraints.append(FixScaled(atoms.get_cell(), ind, sflags)) elif sflags.all(): indices.append(ind) if indices: constraints.append(FixAtoms(indices)) if constraints: atoms.set_constraint(constraints) return atoms