def fcc111_root(symbol, root, size, a=None, vacuum=None, orthogonal=False): """FCC(111) surface maniupulated to have a x unit side length of *root* before repeating. This also results in *root* number of repetitions of the cell. The first 20 valid roots for nonorthogonal are... 1, 3, 4, 7, 9, 12, 13, 16, 19, 21, 25, 27, 28, 31, 36, 37, 39, 43, 48, 49""" atoms = fcc111(symbol=symbol, size=(1, 1, size[2]), a=a, vacuum=vacuum, orthogonal=orthogonal) atoms = root_surface(atoms, root) atoms *= (size[0], size[1], 1) return atoms
def get_atoms(): zpos = cos(134.3/2.0*pi/180.0)*1.197 xpos = sin(134.3/2.0*pi/180.0)*1.19 no2 =Atoms('CO', positions=[(-xpos+1.2,0,-zpos), (-xpos+1.2,-1.1,-zpos)]) # Surface slab slab =fcc111('Au', size=(2, 2, 4),vacuum=2*5, orthogonal = True ) slab.center() add_adsorbate(slab,no2,1.5,'bridge') slab.set_pbc((True,True,False)) #constraints constraint = FixAtoms(mask=[(a.tag == 4) or (a.tag == 3) or (a.tag==2) for a in slab]) slab.set_constraint(constraint) return slab
def test_singlepointcalc(testdir): """This test makes sure that the forces returned from a SinglePointCalculator are immutable. Previously, successive calls to atoms.get_forces(apply_constraint=x), with x alternating between True and False, would get locked into the constrained variation.""" def check_forces(): """Makes sure the unconstrained forces stay that way.""" forces = atoms.get_forces(apply_constraint=False) funconstrained = float(forces[0, 0]) forces = atoms.get_forces(apply_constraint=True) forces = atoms.get_forces(apply_constraint=False) funconstrained2 = float(forces[0, 0]) assert funconstrained2 == funconstrained atoms = fcc111('Cu', (2, 2, 1), vacuum=10.) atoms[0].x += 0.2 atoms.set_constraint(FixAtoms(indices=[atom.index for atom in atoms])) # First run the tes with EMT and save a force component. atoms.calc = EMT() check_forces() f = float(atoms.get_forces(apply_constraint=False)[0, 0]) # Save and reload with a SinglePointCalculator. atoms.write('singlepointtest.traj') atoms = read('singlepointtest.traj') check_forces() # Manually change a value. forces = atoms.get_forces(apply_constraint=False) forces[0, 0] = 42. forces = atoms.get_forces(apply_constraint=False) assert forces[0, 0] == f
def example_emt(ase_code): import ase # see script.py for wrapped ASE instructions script = SinglefileData(file=os.path.abspath('./script.py')) structure = StructureData # structure from ase.build import fcc111 h = 1.85 d = 1.10 atoms = fcc111('Cu', size=(4, 4, 2), vacuum=10.0) #structure = StructureData(ase=atoms) atoms.write('atoms_in.json', format='json') structure = SinglefileData(file=os.path.abspath('./atoms_in.json')) # set up calculation inputs = { 'code': ase_code, 'script': script, 'files': { 'structure': structure, }, 'metadata': { 'description': "Test ASE EMT calculator", }, } # Note: in order to submit your calculation to the aiida daemon, do: # from aiida.engine import submit # future = submit(CalculationFactory('ase_basic'), **inputs) result = run(CalculationFactory('ase_basic'), **inputs) #import pdb; pdb.set_trace() new_coords = result['files']['atoms_out'].get_content() print("Relaxed coordinates: \n{}".format(new_coords))
import sys from ase.build import molecule, fcc111, add_adsorbate from ase.optimize import QuasiNewton from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.vibrations import Vibrations sys.path.append("..") from __init__ import AnharmonicModes slab = fcc111('Au', size=(2, 2, 2), vacuum=4.0) H = molecule('H') add_adsorbate(slab, H, 3.0, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Au' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) QuasiNewton(slab).run(fmax=0.001) vib = Vibrations(slab, indices=[8]) vib.run() vib.summary() vib.clean() AM = AnharmonicModes( vibrations_object=vib, settings={
def test_bravais_check(): import numpy as np from ase.cell import Cell from ase.lattice import bravais_lattices, UnsupportedLattice from ase.build import bulk, fcc111 from ase.test.testsuite import must_raise bravais = {} for name in bravais_lattices: bravais[name.lower()] = bravais_lattices[name] def check_single(name, cell, pbc=None): c = Cell(cell) try: print('TEST', c, pbc) if pbc[:2].all() or sum(pbc) == 1: lattice = c.get_bravais_lattice(pbc=pbc) else: with must_raise(UnsupportedLattice): lattice = c.get_bravais_lattice(pbc=pbc) return except RuntimeError: print('error checking {}'.format(name)) raise name1 = lattice.name.lower() latname = name.split('@')[0] ok = latname == name1 print(name, '-->', name1, 'OK' if ok else 'ERR', c.cellpar()) assert ok, 'Expected {} but found {}'.format(latname, name1) def check(name, cell, pbc=None): if pbc is None: pbc = cell.any(1) pbc = np.asarray(pbc) cell = Cell(cell) # Check all three positive permutations: check_single(name + '@012', cell[[0, 1, 2]], pbc=pbc[[0, 1, 2]]) # 2D lattice determination only supports pbc=(1,1,0) and hence we # check the permutations only for 3D lattices: if cell.rank == 3 and pbc.sum() != 1: check_single(name + '@201', cell[[2, 0, 1]], pbc=pbc[[2, 0, 1]]) check_single(name + '@120', cell[[1, 2, 0]], pbc=pbc[[1, 2, 0]]) check('cub', bravais['cub'](3.3).tocell()) check('fcc', bravais['fcc'](3.4).tocell()) check('fcc', bulk('Au').cell) check('bcc', bravais['bcc'](3.5).tocell()) check('bcc', bulk('Fe').cell) check('tet', bravais['tet'](4., 5.).tocell()) check('tet', np.diag([4., 5., 5.])) check('tet', np.diag([5., 4., 5.])) check('tet', np.diag([5., 5., 4.])) check('bct', bravais['bct'](3., 4.).tocell()) check('orc', bravais['orc'](3., 4., 5.).tocell()) check('orcf', bravais['orcf'](4., 5., 7.).tocell()) check('orci', bravais['orci'](2., 5., 6.).tocell()) check('orcc', bravais['orcc'](3., 4., 5.).tocell()) check('hex', fcc111('Au', size=(1, 1, 3), periodic=True).cell) check('hex', bravais['hex'](5., 6.).tocell()) check('rhl', bravais['rhl'](4., 54.).tocell()) check('mcl', bravais['mcl'](2., 3., 4., 62.).tocell()) check('mclc', bravais['mclc'](3., 4., 5., 75.).tocell()) check('tri', bravais['tri'](7., 6., 5., 65., 70., 80.).tocell()) # For 2D materials we have to check both the tocell() method # but also for realistic cell nonzero nonperiodic axis. check('sqr', bravais['sqr'](3.).tocell()) check('sqr', Cell(np.diag([3., 3., 10.])), pbc=np.array([True, True, False])) check('crect', bravais['crect'](3., 40).tocell()) alpha = 40 / 360 * 2 * np.pi a = 3 x = np.cos(alpha) y = np.sin(alpha) crectcell = np.array([[a, 0, 0], [a * x, a * y, 0], [0, 0, 10]]) check('crect', Cell(crectcell), pbc=[1, 1, 0]) check('rect', bravais['rect'](3., 4.).tocell()) check('rect', Cell.new([3, 4, 10]), pbc=[1, 1, 0]) check('hex2d', bravais['hex2d'](3.).tocell()) x = 0.5 * np.sqrt(3) hexcell = np.array([[a, 0, 0], [-0.5 * a, x * a, 0], [0., 0., 0.]]) check('hex2d', Cell(hexcell)) check('obl', bravais['obl'](3., 4., 40).tocell()) b = 4 x = np.cos(alpha) y = np.sin(alpha) oblcell = np.array([[a, 0, 0], [b * x, b * y, 0], [0, 0, 10]]) check('obl', Cell(oblcell), pbc=np.array([True, True, False])) # 1-d: check('line', Cell(np.diag([a, 0, 0.0]))) check('line', Cell(np.diag([a, 1, 1.0])), pbc=np.array([1, 0, 0])) check('line', Cell(np.diag([0.0, 0, a]))) check('line', Cell(np.diag([1.0, 1, a])), pbc=np.array([0, 0, 1]))
from ase.ga.data import PrepareDB from ase.ga.startgenerator import StartGenerator from ase.ga.utilities import closest_distances_generator from ase.ga.utilities import get_all_atom_types from ase.constraints import FixAtoms import numpy as np from ase.build import fcc111 db_file = 'gadb.db' # create the surface slab = fcc111('Au', size=(4, 4, 1), vacuum=10.0, orthogonal=True) slab.set_constraint(FixAtoms(mask=len(slab) * [True])) # define the volume in which the adsorbed cluster is optimized # the volume is defined by a corner position (p0) # and three spanning vectors (v1, v2, v3) pos = slab.get_positions() cell = slab.get_cell() p0 = np.array([0., 0., max(pos[:, 2]) + 2.]) v1 = cell[0, :] * 0.8 v2 = cell[1, :] * 0.8 v3 = cell[2, :] v3[2] = 3. # Define the composition of the atoms to optimize atom_numbers = 2 * [47] + 2 * [79] # define the closest distance two atoms of a given species can be to each other unique_atom_types = get_all_atom_types(slab, atom_numbers) blmin = closest_distances_generator(atom_numbers=unique_atom_types,
label = 'test' # for integration with AMPTorch module forcetraining = True # for integration with AMPTorch module. # if forcetraining is set to False, it will drop the derivatives of fingerprints. cores = 1 # Define Gs variables for fps. Gs = {} Gs["G2_etas"] = np.logspace(np.log10(0.05), np.log10(5.0), num=10) Gs["G2_rs_s"] = [0] * 10 Gs["G4_etas"] = np.logspace(np.log10(0.005), np.log10(0.5), num=4) Gs["G4_zetas"] = [1.0] Gs["G4_gammas"] = [+1.0, -1.0] Gs["cutoff"] = 6.5 # Generate ase.Atoms objects. slab = fcc111('Al', size=(2, 2, 4)) add_adsorbate(slab, 'H', 1.5, 'ontop') slab.center(vacuum=10.0, axis=2) # Define elements to calculate fps for elements = ['Al', 'H'] # Step 1: obtain output from cffi as cffi_out traj, calculated, cffi_out = make_simple_nn_fps(slab, Gs, elements=elements, label=label) # Step 2: reorganize into AMP input format fps, fp_primes = convert_simple_nn_fps(traj, Gs, cffi_out, forcetraining, cores, save=False) # Print the output if needed. print(fps) print(fp_primes)
from ase.constraints import FixAtoms def check_forces(): """Makes sure the unconstrained forces stay that way.""" forces = atoms.get_forces(apply_constraint=False) funconstrained = float(forces[0, 0]) forces = atoms.get_forces(apply_constraint=True) forces = atoms.get_forces(apply_constraint=False) funconstrained2 = float(forces[0, 0]) assert funconstrained2 == funconstrained atoms = fcc111('Cu', (2, 2, 1), vacuum=10.) atoms[0].x += 0.2 atoms.set_constraint(FixAtoms(indices=[atom.index for atom in atoms])) # First run the tes with EMT and save a force component. atoms.set_calculator(EMT()) check_forces() f = float(atoms.get_forces(apply_constraint=False)[0, 0]) # Save and reload with a SinglePointCalculator. atoms.write('singlepointtest.traj') atoms = read('singlepointtest.traj') check_forces() # Manually change a value. forces = atoms.get_forces(apply_constraint=False)
from math import pi, cos, sin from ase import Atoms from ase.calculators.emt import EMT from ase.constraints import FixBondLengths from ase.optimize import BFGS from ase.build import fcc111, add_adsorbate for wrap in [False, True]: zpos = cos(134.3 / 2.0 * pi / 180.0) * 1.197 xpos = sin(134.3 / 2.0 * pi / 180.0) * 1.19 co2 = Atoms('COO', positions=[(-xpos + 1.2, 0, -zpos), (-xpos + 1.2, -1.1, -zpos), (-xpos + 1.2, 1.1, -zpos)]) slab = fcc111('Au', size=(2, 2, 4), vacuum=2 * 5, orthogonal=True) slab.center() add_adsorbate(slab, co2, 1.5, 'bridge') slab.set_pbc((True, True, False)) d0 = co2.get_distance(-3, -2) d1 = co2.get_distance(-3, -1) calc = EMT() slab.set_calculator(calc) if wrap: # Remap into the cell so bond is actually wrapped: slab.set_scaled_positions(slab.get_scaled_positions() % 1.0) constraint = FixBondLengths([[-3, -2], [-3, -1]]) slab.set_constraint(constraint) dyn = BFGS(slab, trajectory='relax_%d.traj' % wrap) dyn.run(fmax=0.05)
def test_geometry(): """Test the ase.geometry module and ase.build.cut() function.""" import numpy as np from ase.build import cut, bulk, fcc111 from ase.cell import Cell from ase.geometry import get_layers, wrap_positions from ase.spacegroup import crystal, get_spacegroup al = crystal('Al', [(0, 0, 0)], spacegroup=225, cellpar=4.05) # Cut out slab of 5 Al(001) layers al001 = cut(al, nlayers=5) correct_pos = np.array([[0., 0., 0.], [0., 0.5, 0.2], [0.5, 0., 0.2], [0.5, 0.5, 0.], [0., 0., 0.4], [0., 0.5, 0.6], [0.5, 0., 0.6], [0.5, 0.5, 0.4], [0., 0., 0.8], [0.5, 0.5, 0.8]]) assert np.allclose(correct_pos, al001.get_scaled_positions()) # Check layers along 001 tags, levels = get_layers(al001, (0, 0, 1)) assert np.allclose(tags, [0, 1, 1, 0, 2, 3, 3, 2, 4, 4]) assert np.allclose(levels, [0., 2.025, 4.05, 6.075, 8.1]) # Check layers along 101 tags, levels = get_layers(al001, (1, 0, 1)) assert np.allclose(tags, [0, 1, 5, 3, 2, 4, 8, 7, 6, 9]) assert np.allclose(levels, [0.000, 0.752, 1.504, 1.880, 2.256, 2.632, 3.008, 3.384, 4.136, 4.888], atol=0.001) # Check layers along 111 tags, levels = get_layers(al001, (1, 1, 1)) assert np.allclose(tags, [0, 2, 2, 4, 1, 5, 5, 6, 3, 7]) assert np.allclose(levels, [0.000, 1.102, 1.929, 2.205, 2.756, 3.031, 3.858, 4.960], atol=0.001) # Cut out slab of three Al(111) layers al111 = cut(al, (1, -1, 0), (0, 1, -1), nlayers=3) correct_pos = np.array([[0.5, 0., 0.], [0., 0.5, 0.], [0.5, 0.5, 0.], [0., 0., 0.], [1 / 6., 1 / 3., 1 / 3.], [1 / 6., 5 / 6., 1 / 3.], [2 / 3., 5 / 6., 1 / 3.], [2 / 3., 1 / 3., 1 / 3.], [1 / 3., 1 / 6., 2 / 3.], [5 / 6., 1 / 6., 2 / 3.], [5 / 6., 2 / 3., 2 / 3.], [1 / 3., 2 / 3., 2 / 3.]]) assert np.allclose(correct_pos, al111.get_scaled_positions()) # Cut out cell including all corner and edge atoms (non-periodic structure) al = cut(al, extend=1.1) correct_pos = np.array([[0., 0., 0.], [0., 2.025, 2.025], [2.025, 0., 2.025], [2.025, 2.025, 0.], [0., 0., 4.05], [2.025, 2.025, 4.05], [0., 4.05, 0.], [2.025, 4.05, 2.025], [0., 4.05, 4.05], [4.05, 0., 0.], [4.05, 2.025, 2.025], [4.05, 0., 4.05], [4.05, 4.05, 0.], [4.05, 4.05, 4.05]]) assert np.allclose(correct_pos, al.positions) # Create an Ag(111)/Si(111) interface ag = crystal(['Ag'], basis=[(0, 0, 0)], spacegroup=225, cellpar=4.09) si = crystal(['Si'], basis=[(0, 0, 0)], spacegroup=227, cellpar=5.43) try: assert get_spacegroup(ag).no == 225 assert get_spacegroup(si).no == 227 except ImportError: pass ag111 = cut(ag, a=(4, -4, 0), b=(4, 4, -8), nlayers=5) # noqa si111 = cut(si, a=(3, -3, 0), b=(3, 3, -6), nlayers=5) # noqa # # interface = stack(ag111, si111) # assert len(interface) == 1000 # assert np.allclose(interface.positions[::100], # [[ 4.08125 , -2.040625 , -2.040625 ], # [ 8.1625 , 6.121875 , -14.284375 ], # [ 10.211875 , 0.00875 , 2.049375 ], # [ 24.49041667, -4.07833333, -16.32208333], # [ 18.37145833, 14.29020833, -24.48166667], # [ 24.49916667, 12.25541667, -20.39458333], # [ 18.36854167, 16.32791667, -30.60645833], # [ 19.0575 , 0.01166667, 5.45333333], # [ 23.13388889, 6.80888889, 1.36722222], # [ 35.3825 , 5.45333333, -16.31333333]]) # # Test the wrap_positions function. positions = np.array([ [4.0725, -4.0725, -1.3575], [1.3575, -1.3575, -1.3575], [2.715, -2.715, 0.], [4.0725, 1.3575, -1.3575], [0., 0., 0.], [2.715, 2.715, 0.], [6.7875, -1.3575, -1.3575], [5.43, 0., 0.]]) cell = np.array([[5.43, 5.43, 0.0], [5.43, -5.43, 0.0], [0.00, 0.00, 40.0]]) positions += np.array([6.1, -0.1, 10.1]) result_positions = wrap_positions(positions=positions, cell=cell) correct_pos = np.array([ [4.7425, 1.2575, 8.7425], [7.4575, -1.4575, 8.7425], [3.385, 2.615, 10.1], [4.7425, -4.1725, 8.7425], [6.1, -0.1, 10.1], [3.385, -2.815, 10.1], [2.0275, -1.4575, 8.7425], [0.67, -0.1, 10.1]]) assert np.allclose(correct_pos, result_positions) positions = wrap_positions(positions, cell, pbc=[False, True, False]) correct_pos = np.array([ [4.7425, 1.2575, 8.7425], [7.4575, -1.4575, 8.7425], [3.385, 2.615, 10.1], [10.1725, 1.2575, 8.7425], [6.1, -0.1, 10.1], [8.815, 2.615, 10.1], [7.4575, 3.9725, 8.7425], [6.1, 5.33, 10.1]]) assert np.allclose(correct_pos, positions) # Test center away from values 0, 0.5 result_positions = wrap_positions(positions, cell, pbc=[True, True, False], center=0.2) correct_pos = [[4.7425, 1.2575, 8.7425], [2.0275, 3.9725, 8.7425], [3.385, 2.615, 10.1], [-0.6875, 1.2575, 8.7425], [6.1, -0.1, 10.1], [3.385, -2.815, 10.1], [2.0275, -1.4575, 8.7425], [0.67, -0.1, 10.1]] assert np.allclose(correct_pos, result_positions) # Test pretty_translation keyword positions = np.array([ [0, 0, 0], [0, 1, 1], [1, 0, 1], [1, 1, 0.]]) cell = np.diag([2, 2, 2]) result = wrap_positions(positions, cell, pbc=[True, True, True], pretty_translation=True) assert np.max(result) < 1 + 1E-10 assert np.min(result) > -1E-10 result = wrap_positions(positions - 5, cell, pbc=[True, True, True], pretty_translation=True) assert np.max(result) < 1 + 1E-10 result = wrap_positions(positions - 5, cell, pbc=[False, True, True], pretty_translation=True) assert np.max(result[:, 0]) < -3 assert np.max(result[:, 1:]) < 1 + 1E-10 # Get the correct crystal structure from a range of different cells def checkcell(cell, name): cell = Cell.ascell(cell) lat = cell.get_bravais_lattice() assert lat.name == name, (lat.name, name) checkcell(bulk('Al').cell, 'FCC') checkcell(bulk('Fe').cell, 'BCC') checkcell(bulk('Zn').cell, 'HEX') checkcell(fcc111('Au', size=(1, 1, 3), periodic=True).cell, 'HEX') checkcell([[1, 0, 0], [0, 1, 0], [0, 0, 1]], 'CUB') checkcell([[1, 0, 0], [0, 1, 0], [0, 0, 2]], 'TET') checkcell([[1, 0, 0], [0, 2, 0], [0, 0, 3]], 'ORC') checkcell([[1, 0, 0], [0, 2, 0], [0.5, 0, 3]], 'ORCC') checkcell([[1, 0, 0], [0, 2, 0], [0.501, 0, 3]], 'MCL') checkcell([[1, 0, 0], [0.5, 3**0.5 / 2, 0], [0, 0, 3]], 'HEX')
import numpy as np from ase.calculators.eam import EAM from ase.test.eam_pot import Pt_u3 from ase.build import fcc111 import os # test to read EAM potential from *.eam file (aka funcfl format) - for one element pot_fn = 'Pt_u3.eam' f = open(pot_fn,'w') f.write(Pt_u3) f.close() eam = EAM(potential='Pt_u3.eam', elements=['Pt']) slab = fcc111('Pt', size=(4, 4, 2), vacuum=10.0) slab.set_calculator(eam) assert( abs(-164.277599313 - slab.get_potential_energy()) < 1E-8 ) assert( abs(6.36379627645 - np.linalg.norm(slab.get_forces())) < 1E-8 ) os.remove(pot_fn)
# creates: io1.png io2.png io3.png from ase import Atoms from ase.build import fcc111, add_adsorbate from ase.io import write, read adsorbate = Atoms('CO') adsorbate[1].z = 1.1 a = 3.61 slab = fcc111('Cu', (2, 2, 3), a=a, vacuum=7.0) add_adsorbate(slab, adsorbate, 1.8, 'ontop') write('io1.png', slab * (3, 3, 1), rotation='10z,-80x') write('io2.pov', slab * (3, 3, 1), rotation='10z,-80x', transparent=False, display=False, run_povray=True) d = a / 2**0.5 write('io3.pov', slab * (2, 2, 1), bbox=(d, 0, 3 * d, d * 3**0.5), transparent=False, display=False, run_povray=True) write('slab.xyz', slab) a = read('slab.xyz') a.get_cell() a.get_pbc() write('slab.traj', slab) b = read('slab.traj') b.get_cell() b.get_pbc()
from ase.build import fcc111 from ase.constraints import (FixAtoms, FixBondLengths, FixInternals, Hookean, constrained_indices) slab = fcc111('Pt', (4, 4, 4)) C1 = FixAtoms([0, 2, 4]) C2 = FixBondLengths([[0, 1], [0, 2]]) C3 = FixInternals(bonds=[[1, [7, 8]], [1, [8, 9]]]) C4 = Hookean(a1=30, a2=40, rt=1.79, k=5.) slab.set_constraint([C1, C2, C3, C4]) assert all(constrained_indices(slab, (FixAtoms, FixBondLengths)) == [0, 1, 2, 4]) assert all(constrained_indices(slab) == [0, 1, 2, 4, 7, 8, 9, 30, 40])
the tolerance is extremely loose, beause different sk files give different results """ import os from ase import Atoms from ase.calculators.dftb import Dftb from ase.constraints import FixAtoms from ase.optimize import QuasiNewton from ase.build import fcc111, add_adsorbate h = 1.85 d = 1.10 slab = fcc111("Ni", size=(2, 2, 3), vacuum=10.0) calc1 = Dftb( label="slab", kpts=[2, 2, 1], Hamiltonian_MaxAngularMomentum_="", Hamiltonian_MaxAngularMomentum_Ni='"d"', Hamiltonian_SCC="YES", ) slab.set_calculator(calc1) dyn = QuasiNewton(slab, trajectory="slab.traj") dyn.run(fmax=0.05) e_slab = slab.get_potential_energy() os.system("rm dftb_in.hsd") molecule = Atoms("2N", positions=[(0.0, 0.0, 0.0), (0.0, 0.0, d)]) calc2 = Dftb( label="n2", Hamiltonian_MaxAngularMomentum_="", Hamiltonian_MaxAngularMomentum_N='"p"', Hamiltonian_SCC="YES"
from ase.ga.data import PrepareDB from ase.ga.data import DataConnection import os import numpy as np db_file = 'gadb.db' if os.path.isfile(db_file): os.remove(db_file) from ase.build import fcc111 atom_numbers = np.array([78, 78, 79, 79]) slab = fcc111('Ag', size=(4, 4, 2), vacuum=10.) d = PrepareDB(db_file_name=db_file, simulation_cell=slab, stoichiometry=atom_numbers) assert os.path.isfile(db_file) dc = DataConnection(db_file) slab_get = dc.get_slab() an_get = dc.get_atom_numbers_to_optimize() assert len(slab) == len(slab_get) assert np.all(slab.numbers == slab_get.numbers) assert np.all(slab.get_positions() == slab_get.get_positions()) assert np.all(an_get == atom_numbers)
write(name + '.png', slab, show_unit_cell=2, radii=radii[name[:3]], scale=10) for name in surfaces: f = getattr(surface, name) for kwargs in [{}, {'orthogonal': False}, {'orthogonal': True}]: print(name, kwargs) try: slab = f(symbols[name[:3]], size=(3, 4, 5), vacuum=4, **kwargs) except (TypeError, NotImplementedError): continue try: for site in slab.adsorbate_info['sites']: if site.endswith('bridge'): h = 1.5 else: h = 1.2 surface.add_adsorbate(slab, adsorbates.get(site, 'F'), h, site) except KeyError: pass if kwargs.get('orthogonal', None): name += 'o' save(name, slab) for site, symbol in adsorbates.items(): write('%s-site.png' % site, Atoms(symbol), radii=1.08, scale=10) fcc111_primitive = fcc111("Ag", (1, 1, 3)) fcc111_root = root_surface(fcc111_primitive, 27) save("fcc111_root", fcc111_root)
import sys sys.path.append("..") from ase.build import molecule, fcc111, add_adsorbate from ase.optimize import QuasiNewton from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.vibrations import Vibrations from __init__ import AnharmonicModes slab = fcc111('Al', size=(2, 2, 2), vacuum=3.0) CH3 = molecule('CH3') add_adsorbate(slab, CH3, 2.5, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) dyn = QuasiNewton(slab, logfile='/dev/null') dyn.run(fmax=0.05) vib = Vibrations(slab, indices=[8, 9, 10, 11]) vib.run() vib.summary(log='/dev/null') vib.clean() AM = AnharmonicModes(vibrations_object=vib) rot_mode = AM.define_rotation( basepos=[0., 0., -1.], branch=[9, 10, 11],
from ase.io import read, write from ase.build import fcc111 exec(compile(open('WL.py').read(), 'WL.py', 'exec')) # Use ase.io.read to load atoms object W = read('WL.traj') # View the water unit or print the unit cell size. write('WL.png', W, show_unit_cell=2) # We will need cellW later. cellW = W.get_cell() print(cellW) # We will need as close a lattice match as possible. lets try this slab. # Using the ase.build module, we make the fcc111 slab. slab = fcc111('Ni', size=[2, 4, 3], a=3.55, orthogonal=True) cell = slab.get_cell() write('Ni111slab2x2.png', slab, show_unit_cell=2) print(cell) # Rotate the unit cell first to get the close lattice match with the slab. W.set_cell([[cellW[1, 1], 0, 0], [0, cellW[0, 0], 0], cellW[2]], scale_atoms=False) write('WL_rot_c.png', W, show_unit_cell=2) # Now rotate atoms just like the unit cell W.rotate(90, 'z', center=(0, 0, 0)) write('WL_rot_a.png', W, show_unit_cell=2)
from ase.build import fcc111, add_adsorbate from ase.atoms import Atoms from ase.build import bulk from ase.visualize import view from blase.tools import get_bondpairs, write_blender bulk = bulk('Pt') bulk.write('pt.in') adsorbate = Atoms('CO') adsorbate[1].z = 1.1 atoms = fcc111('Pt', (2, 2, 3), a=3.96, vacuum=7.0) add_adsorbate(atoms, adsorbate, 1.8, 'ontop') # atoms = atoms*[5, 5, 1] # view(atoms) kwargs = {'show_unit_cell': 0, 'radii': 0.6, 'bond_cutoff': 1.0, 'display': True, 'make_real': True, 'outfile': 'figs/pt-111-co', } write_blender(atoms, **kwargs)
import sys from ase.build import molecule, fcc111, add_adsorbate from ase.optimize import QuasiNewton from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.vibrations import Vibrations sys.path.append("..") from __init__ import AnharmonicModes slab = fcc111('Au', size=(2, 2, 2), vacuum=4.0) H = molecule('H') add_adsorbate(slab, H, 3.0, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Au' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) QuasiNewton(slab).run(fmax=0.001) vib = Vibrations(slab, indices=[8]) vib.run() vib.summary() vib.clean() AM = AnharmonicModes(vibrations_object=vib, settings={ 'plot_mode': True, })
from ase.build import fcc111 from ase.build import bcc111 from ase.build import hcp0001 from ase.build import fcc111_root from ase.build import root_surface from ase.build import root_surface_analysis # Make samples of primitive cell prim_fcc111 = fcc111("H", (1, 1, 2), a=1) prim_bcc111 = bcc111("H", (1, 1, 2), a=1) prim_hcp0001 = hcp0001("H", (1, 1, 2), a=1) # Check valid roots up to root 21 (the 10th root cell) valid_fcc111 = root_surface_analysis(prim_fcc111, 21) valid_bcc111 = root_surface_analysis(prim_bcc111, 21) valid_hcp0001 = root_surface_analysis(prim_hcp0001, 21) # These should have different positions, but the same # cell geometry. assert valid_fcc111 == valid_bcc111 == valid_hcp0001 # Make an easy sample to check code errors atoms1 = root_surface(prim_fcc111, 7) # Ensure the valid roots are the roots are valid against # a set of manually checked roots for this system assert valid_fcc111 == [1.0, 3.0, 4.0, 7.0, 9.0, 12.0, 13.0, 16.0, 19.0, 21.0] # Remake easy sample using surface function atoms2 = fcc111_root("H", 7, (1, 1, 2), a=1)
from ase.build import bulk, fcc111 from ase.visualize import view from xespresso import Espresso from xespresso.dos import DOS from xespresso.tools import get_nbnd import matplotlib.pyplot as plt atoms = fcc111('Al', size=(1, 1, 2), vacuum=4.0) view(atoms) print(atoms) pseudopotentials = { 'Al': 'Al.pbe-n-rrkjus_psl.1.0.0.UPF', } calc = Espresso(pseudopotentials=pseudopotentials, label='scf/al', ecutwfc=40, occupations='smearing', degauss=0.01, kpts=(4, 4, 1)) atoms.calc = calc e = atoms.get_potential_energy() calc.read_results() e = calc.results['energy'] fermi = calc.get_fermi_level() print('Energy: {0:1.3f}'.format(e)) #=============================================================== # post calculation calc.post(package='pp', plot_num=5, sample_bias=0.0735, iflag=3,
write(name + '.png', slab, show_unit_cell=2, radii=radii[name[:3]], scale=10) for name in surfaces: f = getattr(surface, name) for kwargs in [{}, {'orthogonal': False}, {'orthogonal': True}]: print(name, kwargs) try: slab = f(symbols[name[:3]], size=(3, 4, 5), vacuum=4, **kwargs) except (TypeError, NotImplementedError): continue try: for site in slab.info['adsorbate_info']['sites']: if site.endswith('bridge'): h = 1.5 else: h = 1.2 surface.add_adsorbate(slab, adsorbates.get(site, 'F'), h, site) except KeyError: pass if kwargs.get('orthogonal', None): name += 'o' save(name, slab) for site, symbol in adsorbates.items(): write('%s-site.png' % site, Atoms(symbol), radii=1.08, scale=10) fcc111_primitive = fcc111("Ag", (1, 1, 3)) fcc111_root = root_surface(fcc111_primitive, 27) save("fcc111_root", fcc111_root)
import numpy as np from ase import Atoms, Atom from ase.build import fcc111, fcc211, add_adsorbate atoms = fcc211('Au', (3, 5, 8), vacuum=10.) assert len(atoms) == 120 atoms = atoms.repeat((2, 1, 1)) assert np.allclose(atoms.get_distance(0, 130), 2.88499566724) atoms = fcc111('Ni', (2, 2, 4), orthogonal=True) add_adsorbate(atoms, 'H', 1, 'bridge') add_adsorbate(atoms, Atom('O'), 1, 'fcc') add_adsorbate(atoms, Atoms('F'), 1, 'hcp') # The next test ensures that a simple string of multiple atoms cannot be used, # which should fail with a KeyError that reports the name of the molecule due # to the string failing to work with Atom(). failed = False try: add_adsorbate(atoms, 'CN', 1, 'ontop') except KeyError as e: failed = True assert e.args[0] == 'CN' assert failed
def build(): p = OptionParser(usage='%prog [options] [ads@]surf [output file]', version='%prog 0.1', description='Example ads/surf: fcc-CO@2x2Ru0001') p.add_option('-l', '--layers', type='int', default=4, help='Number of layers.') p.add_option('-v', '--vacuum', type='float', default=5.0, help='Vacuum.') p.add_option('-x', '--crystal-structure', help='Crystal structure.', choices=['sc', 'fcc', 'bcc', 'hcp']) p.add_option('-a', '--lattice-constant', type='float', help='Lattice constant in Angstrom.') p.add_option('--c-over-a', type='float', help='c/a ratio.') p.add_option('--height', type='float', help='Height of adsorbate over surface.') p.add_option('--distance', type='float', help='Distance between adsorbate and nearest surface atoms.') p.add_option('-M', '--magnetic-moment', type='float', default=0.0, help='Magnetic moment.') p.add_option('-G', '--gui', action='store_true', help="Pop up ASE's GUI.") p.add_option('-P', '--python', action='store_true', help="Write Python script.") opt, args = p.parse_args() if not 1 <= len(args) <= 2: p.error("incorrect number of arguments") if '@' in args[0]: ads, surf = args[0].split('@') else: ads = None surf = args[0] if surf[0].isdigit(): i1 = surf.index('x') n = int(surf[:i1]) i2 = i1 + 1 while surf[i2].isdigit(): i2 += 1 m = int(surf[i1 + 1:i2]) surf = surf[i2:] else: n = 1 m = 1 if surf[-1].isdigit(): if surf[1].isdigit(): face = surf[1:] surf = surf[0] else: face = surf[2:] surf = surf[:2] else: face = None Z = atomic_numbers[surf] state = reference_states[Z] if opt.crystal_structure: x = opt.crystal_structure else: x = state['symmetry'] if opt.lattice_constant: a = opt.lattice_constant else: a = estimate_lattice_constant(surf, x, opt.c_over_a) script = ['from ase.build import ', 'vac = %r' % opt.vacuum, 'a = %r' % a] if x == 'fcc': if face is None: face = '111' slab = fcc111(surf, (n, m, opt.layers), a, opt.vacuum) script[0] += 'fcc111' script += ['slab = fcc111(%r, (%d, %d, %d), a, vac)' % (surf, n, m, opt.layers)] r = a / np.sqrt(2) / 2 elif x == 'bcc': if face is None: face = '110' if face == '110': slab = bcc110(surf, (n, m, opt.layers), a, opt.vacuum) elif face == '100': slab = bcc100(surf, (n, m, opt.layers), a, opt.vacuum) script[0] += 'bcc' + face script += ['slab = bcc%s(%r, (%d, %d, %d), a, vac)' % (face, surf, n, m, opt.layers)] r = a * np.sqrt(3) / 4 elif x == 'hcp': if face is None: face = '0001' if opt.c_over_a is None: c = np.sqrt(8 / 3.0) * a else: c = opt.c_over_a * a slab = hcp0001(surf, (n, m, opt.layers), a, c, opt.vacuum) script[0] += 'hcp0001' script += ['c = %r * a' % (c / a), 'slab = hcp0001(%r, (%d, %d, %d), a, c, vac)' % (surf, n, m, opt.layers)] r = a / 2 elif x == 'diamond': if face is None: face = '111' slab = diamond111(surf, (n, m, opt.layers), a, opt.vacuum) script[0] += 'diamond111' script += ['slab = diamond111(%r, (%d, %d, %d), a, vac)' % (surf, n, m, opt.layers)] r = a * np.sqrt(3) / 8 else: raise NotImplementedError magmom = opt.magnetic_moment if magmom is None: magmom = {'Ni': 0.6, 'Co': 1.2, 'Fe': 2.3}.get(surf, 0.0) slab.set_initial_magnetic_moments([magmom] * len(slab)) if magmom != 0: script += ['slab.set_initial_magnetic_moments([%r] * len(slab))' % magmom] slab.pbc = 1 script += ['slab.pbc = True'] name = '%dx%d%s%s' % (n, m, surf, face) if ads: site = 'ontop' if '-' in ads: site, ads = ads.split('-') name = site + '-' + ads + '@' + name symbols = string2symbols(ads) nads = len(symbols) if nads == 1: script[:0] = ['from ase import Atoms'] script += ['ads = Atoms(%r)' % ads] ads = Atoms(ads) else: script[:0] = ['from ase.build import molecule'] script += ['ads = molecule(%r)' % ads] ads = molecule(ads) add_adsorbate(slab, ads, 0.0, site) d = opt.distance if d is None: d = r + covalent_radii[ads[0].number] / 2 h = opt.height if h is None: R = slab.positions y = ((R[:-nads] - R[-nads])**2).sum(1).min()**0.5 h = (d**2 - y**2)**0.5 else: assert opt.distance is None slab.positions[-nads:, 2] += h script[1] += ', add_adsorbate' script += ['add_adsorbate(slab, ads, %r, %r)' % (h, site)] if len(args) == 2: write(args[1], slab) script[1:1] = ['from ase.io import write'] script += ['write(%r, slab)' % args[1]] elif not opt.gui: write(name + '.traj', slab) script[1:1] = ['from ase.io import write'] script += ['write(%r, slab)' % (name + '.traj')] if opt.gui: view(slab) script[1:1] = ['from ase.visualize import view'] script += ['view(slab)'] if opt.python: print('\n'.join(script))
h=0.2, xc='RPBE', kpts=(8, 6, 1), eigensolver='cg', spinpol=True, mixer=MixerSum(nmaxold=5, beta=0.1, weight=100), convergence={ 'energy': 100, 'density': 100, 'eigenstates': 1.0e-7, 'bands': -10 }, txt=filename + '.txt') # Import Slab with relaxed CO slab = fcc111('Pt', size=(1, 2, 3), orthogonal=True) add_adsorbate(slab, 'C', 2.0, 'ontop') add_adsorbate(slab, 'O', 3.15, 'ontop') slab.center(axis=2, vacuum=4.0) view(slab) molecule = slab.copy() del molecule[:-2] # Molecule molecule.set_calculator(c_mol) molecule.get_potential_energy() # H**o wavefunction
from ase import Atoms, Atom from ase.build import fcc111 from ase.optimize.minimahopping import MinimaHopping from ase.calculators.emt import EMT from ase.constraints import FixAtoms, Hookean # Make Pt 111 slab with Cu2 adsorbate. atoms = fcc111('Pt', (2, 2, 1), vacuum=7., orthogonal=True) adsorbate = Atoms([Atom('Cu', atoms[2].position + (0., 0., 2.5)), Atom('Cu', atoms[2].position + (0., 0., 5.0))]) atoms.extend(adsorbate) # Constrain the surface to be fixed and a Hookean constraint between # the adsorbate atoms. constraints = [FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Pt']), Hookean(a1=4, a2=5, rt=2.6, k=15.), Hookean(a1=4, a2=(0., 0., 1., -15.), k=15.)] atoms.set_constraint(constraints) # Set the calculator. calc = EMT() atoms.set_calculator(calc) # Instantiate and run the minima hopping algorithm. hop = MinimaHopping(atoms, Ediff0=2.5, T0=2000., beta1=1.2, beta2=1.2, mdmin=1)
import sys from ase.build import molecule, fcc111, add_adsorbate from ase.optimize import QuasiNewton from ase.constraints import FixAtoms from ase.calculators.emt import EMT from ase.vibrations import Vibrations sys.path.append("../..") from __init__ import AnharmonicModes slab = fcc111('Al', size=(2, 2, 2), vacuum=3.0) CH3 = molecule('CH3') add_adsorbate(slab, CH3, 2.5, 'ontop') constraint = FixAtoms(mask=[a.symbol == 'Al' for a in slab]) slab.set_constraint(constraint) slab.set_calculator(EMT()) dyn = QuasiNewton(slab) dyn.run(fmax=0.05) # Running vibrational analysis vib = Vibrations(slab, indices=[8, 9, 10, 11]) vib.run() vib.summary() print('\n >> Anharmonics <<\n')
from ase.io import read, write from ase.build import fcc111 exec(compile(open('WL.py').read(), 'WL.py', 'exec')) # Use ase.io.read to load atoms object W = read('WL.traj') # View the water unit or print the unit cell size. write('WL.png', W, show_unit_cell=2) # We will need cellW later. cellW = W.get_cell() print(cellW) # We will need as close a lattice match as possible. lets try this slab. # Using the ase.build module, we make the fcc111 slab. slab = fcc111('Ni', size=[2, 4, 3], a=3.55, orthogonal=True) cell = slab.get_cell() write('Ni111slab2x2.png', slab, show_unit_cell=2) print(cell) # Rotate the unit cell first to get the close lattice match with the slab. W.set_cell([[cellW[1, 1], 0, 0], [0, cellW[0, 0], 0], cellW[2]], scale_atoms=False) write('WL_rot_c.png', W, show_unit_cell=2) # Now rotate atoms just like the unit cell W.rotate('z', np.pi / 2, center=(0, 0, 0)) write('WL_rot_a.png', W, show_unit_cell=2)
# creates: io1.png io2.png io3.png from ase import Atoms from ase.build import fcc111, add_adsorbate from ase.io import write, read adsorbate = Atoms('CO') adsorbate[1].z = 1.1 a = 3.61 slab = fcc111('Cu', (2, 2, 3), a=a, vacuum=7.0) add_adsorbate(slab, adsorbate, 1.8, 'ontop') write('io1.png', slab * (3, 3, 1), rotation='10z,-80x') write('io2.pov', slab * (3, 3, 1), rotation='10z,-80x', transparent=False, display=False, run_povray=True) d = a / 2**0.5 write('io3.pov', slab * (2, 2, 1), bbox=(d, 0, 3 * d, d * 3**0.5), transparent=False, display=False, run_povray=True) write('slab.xyz', slab) a = read('slab.xyz') a.get_cell() a.get_pbc()
from ase.ga.data import PrepareDB from ase.ga.data import DataConnection from ase.ga.startgenerator import StartGenerator from ase.ga.utilities import closest_distances_generator from ase.ga import set_raw_score import os import numpy as np from ase.build import fcc111 from ase.constraints import FixAtoms db_file = 'gadb_logics_test.db' slab = fcc111('Au', size=(4, 4, 2), vacuum=10.0, orthogonal=True) slab.set_constraint(FixAtoms(mask=slab.positions[:, 2] <= 10.)) # define the volume in which the adsorbed cluster is optimized # the volume is defined by a corner position (p0) # and three spanning vectors (v1, v2, v3) pos = slab.get_positions() cell = slab.get_cell() p0 = np.array([0., 0., max(pos[:, 2]) + 2.]) v1 = cell[0, :] * 0.8 v2 = cell[1, :] * 0.8 v3 = cell[2, :] v3[2] = 3. # define the closest distance between two atoms of a given species cd = closest_distances_generator(atom_numbers=[47, 79], ratio_of_covalent_radii=0.7) # Define the composition of the atoms to optimize
from ase.calculators.lammpsrun import LAMMPS from numpy.linalg import norm from ase.test.eam_pot import Pt_u3 from ase.build import fcc111 import os pot_fn = 'Pt_u3.eam' f = open(pot_fn, 'w') f.write(Pt_u3) f.close() slab = fcc111('Pt', size=(10, 10, 5), vacuum=30.0) # We use fully periodic boundary conditions because the Lammpsrun # calculator does not know if it can convert the cell correctly with # mixed ones and will give a warning. slab.pbc = 1 params = {} params['pair_style'] = 'eam' params['pair_coeff'] = ['1 1 {}'.format(pot_fn)] calc = LAMMPS(specorder=['Pt'], files=[pot_fn], **params) slab.set_calculator(calc) E = slab.get_potential_energy() F = slab.get_forces() assert abs(E - -2758.63) < 1E-2 assert abs(norm(F) - 11.3167) < 1E-4 # !TODO: tests nothing as atom postions are not set without set_atoms=True assert abs(norm(slab.positions) - 955.259) < 1E-3
opts.build = False opts.project = True from parse.xyz import Parser if not opts.infile: print("I need an input file.") sys.exit() position='hcp' try: opts.size = tuple(map(int, opts.size.strip().split(','))) except: print("Error parsing size as three comma-separated integers") sys.exit() slab=fcc111(opts.electrode, opts.size) # Needed to prevent multilayer formation slab.info['adsorbate_info']['top layer atom index'] = len(slab.positions)-1 xyz = Parser(opts,opts.infile[0]) xyz.parseZmatrix() if opts.tilt > 0: xyz.zmat.rotateAboutAxis(opts.tiltaxis,opts.tilt) mol = xyz.getZmat() print(mol) for i in range(1,opts.size[0]-1,2): add_adsorbate(slab,mol,opts.height,position,offset=[0,i],mol_index=0) firstmol = len(slab.positions) for n in range(2,opts.size[0]-1,2): add_adsorbate(slab,mol,opts.height,position,offset=[n,i],mol_index=0)
def run(symb, a, n): atoms = fcc111(symb, (1, 1, n), a=a) atoms.calc = EMT() atoms.get_forces() return atoms
from matplotlib.animation import writers from ase.test.testsuite import NotAvailable from ase.build import bulk, molecule, fcc111 from ase.io.animation import write_animation import warnings if 'html' not in writers.list(): raise NotAvailable('matplotlib html writer not present') images = [molecule('H2O'), bulk('Cu'), fcc111('Au', size=(1, 1, 1))] # gif and mp4 writers may not be available. Easiest solution is to only # test this using the html writer because it always exists whenever # matplotlib exists: with warnings.catch_warnings(): try: from matplotlib import MatplotlibDeprecationWarning except ImportError: pass else: warnings.simplefilter('ignore', MatplotlibDeprecationWarning) write_animation('things.html', images, writer='html')
import os from ase.build import molecule from ase.build import fcc111, add_adsorbate from ase.constraints import FixAtoms from ase.io import write symbol = 'Pt' folder = '01-slab' if not os.path.exists(folder): os.mkdir(folder) os.chdir(folder) slab = fcc111(symbol, size=(3,3,4), orthogonal=False) slab.center(vacuum=15.0, axis=2) c = FixAtoms(indices=[atom.index for atom in slab if atom.symbol == symbol]) slab.set_constraint(c) write('POSCAR', slab, vasp5=True, direct=True) os.chdir('..') folder = '02-h' if not os.path.exists(folder): os.mkdir(folder) os.chdir(folder) slab = fcc111(symbol, size=(3,3,4), orthogonal=False) add_adsorbate(slab, 'H', 1.0, 'fcc') slab.center(vacuum=15.0, axis=2) c = FixAtoms(indices=[atom.index for atom in slab if atom.symbol == symbol]) slab.set_constraint(c) write('POSCAR', slab, vasp5=True, direct=True) os.chdir('..')
from ase.build import fcc111 from ase.visualize import view #this allows us to quickly view atomic structures from within the script using ASE's lightweight GUI. from ase.constraints import FixAtoms #This script does not require a supercomputer, and should run from the login node (the node you first "land" on in a supercomputer) or from a desktop/laptop assuming you have python and the ASE python package installed. #create the (111) surface slab using one of ASE's handy utility functions. Note that not all surfaces are so easy to create. slab = fcc111( 'Pt', size=(1, 1, 3), vacuum=6.0, a=4.02, ) #now we need to constrain some layers to simulate bulk metal. Let's start by constraining the lower 2/3 of the slab: z_positions = [ a.z for a in slab ] #slab is an ASE Atoms object that acts like a list of atoms, allowing us to use Python's list comprehension syntax. #Each atom has some useful position attributes: a.position is the x,y,z coordinates, a.x is the x coordinate, a.y is the y coordinate, and a.z is the z coordinate. z_positions.sort() #sort the z-positions from lowest to highest cutoff_index = int( 2 * (len(slab) / 3.) ) #choose a cutoff index for the atom corresponding to 2/3 of the total atoms z_cutoff = z_positions[ cutoff_index] #find the z-coordinate of the lowest unconstrained atom constraint = FixAtoms( mask=[a.z < z_cutoff for a in slab] ) #create an ASE constraint object to fix the atoms. The "mask" argument allows using a list comprehension filter to define the atoms that are or aren't constrained. Read more here: https://wiki.fysik.dtu.dk/ase/ase/constraints.html
def create_slab_with_constraints(): slab = fcc111('Al', size=(1, 1, 3), periodic=True) slab.center(vacuum=4, axis=2) con = FixAtoms(indices=[0, 1]) slab.set_constraint(con) return slab
""" Structure relaxation of Pt heptamer island on Pt(111). Benchmark using MLMin, GPMin, LBFGS and FIRE. """ # 1. Build Atoms Object. ############################################################################### # Setup calculator: calc = EMT() # 1.1. Set up structure: # Build a 3 layers 5x5-Pt(111) slab. atoms = fcc111('Pt', size=(5, 5, 3)) c = FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Pt']) atoms.set_constraint(c) atoms.center(axis=2, vacuum=15.0) # Build heptamer island: atoms2 = fcc111('Au', size=(3, 3, 1)) atoms2.pop(0) atoms2.pop(7) atoms2.rattle(stdev=0.10, seed=0) # Add island to slab: add_adsorbate(atoms, atoms2, 2.5, offset=0.5) # 2. Benchmark.
# import calculator and set potential from ase.calculators.eam import EAM import os pot_file = os.environ.get('LAMMPS_POTENTIALS') + '/Al_zhou.eam.alloy' zhou = EAM(potential=pot_file) #create structure as FCC surface with addsorbate from ase.build import fcc111, add_adsorbate slab = fcc111('Al', size=(2, 2, 3)) add_adsorbate(slab, 'Al', 2, 'hcp') slab.center(vacuum=5.0, axis=2) #view and set calculator from ase.visualize import view view(slab, viewer='x3d') slab.set_calculator(zhou) slab.get_potential_energy() print(slab.get_calculator()) print(slab.get_potential_energy()) #relax structure from ase.optimize import BFGS dyn = BFGS(slab) dyn.run(fmax=0.0001) #make second endpoint structure, add adatom and relax slab_2 = fcc111('Al', size=(2, 2, 3)) add_adsorbate(slab_2, 'Al', 2, 'fcc') slab_2.center(vacuum=5.0, axis=2) slab_2.set_calculator(EAM(potential=pot_file))
Benchmark using MLMin, GPMin, LBFGS and FIRE. """ # 1. Build Atoms Object. ############################################################################### # Setup calculator: calc = EMT() # Create CO molecule: d = 1.1 co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)]) # Create slab: slab = fcc111('Al', size=(2,2,3), vacuum=10.0) slab = fcc111('Al', size=(2,2,3)) # Add CO on the slab: add_adsorbate(slab, co, 2., 'bridge') slab.center(vacuum=10.0, axis=2) # Set constraints: c1 = FixAtoms(indices=[atom.index for atom in slab if atom.symbol == 'Al']) c2 = FixBondLength(12, 13) slab.set_constraint([c1, c2]) atoms = slab.copy() # 2. Benchmark. ###############################################################################
def test_dynamic_neb(): # Global counter of force evaluations: force_evaluations = [0] class EMT(OrigEMT): def calculate(self, *args, **kwargs): force_evaluations[0] += 1 OrigEMT.calculate(self, *args, **kwargs) # Build Pt(111) slab with six surface atoms and add oxygen adsorbate initial = fcc111('Pt', size=(3, 2, 3), orthogonal=True) initial.center(axis=2, vacuum=10) oxygen = Atoms('O') oxygen.translate(initial[7].position + (0., 0., 3.5)) initial.extend(oxygen) # EMT potential initial.calc = EMT() # Optimize initial state opt = BFGS(initial) opt.run(fmax=0.03) # Move oxygen adsorbate to neighboring hollow site final = initial.copy() final[18].x += 2.8 final[18].y += 1.8 final.calc = EMT() opt = BFGS(final) opt.run(fmax=0.03) # NEB with seven interior images images = [initial] for i in range(7): images.append(initial.copy()) images.append(final) fmax = 0.03 # Same for NEB and optimizer for i in range(1, len(images) - 1): calc = EMT() images[i].calc = calc def run_NEB(): if method == 'dyn': neb = DyNEB(images, fmax=fmax, dynamic_relaxation=True) neb.interpolate() elif method == 'dyn_scale': neb = DyNEB(images, fmax=fmax, dynamic_relaxation=True, scale_fmax=6.) neb.interpolate() else: # Default NEB neb = DyNEB(images, dynamic_relaxation=False) neb.interpolate() # Optimize and check number of calculations. # We use a hack with a global counter to count the force evaluations: force_evaluations[0] = 0 opt = BFGS(neb) opt.run(fmax=fmax) force_calls.append(force_evaluations[0]) # Get potential energy of transition state. Emax.append( np.sort([image.get_potential_energy() for image in images[1:-1]])[-1]) force_calls, Emax = [], [] for method in ['def', 'dyn', 'dyn_scale']: run_NEB() # Check force calculation count for default and dynamic NEB implementations print('\n# Force calls with default NEB: {}'.format(force_calls[0])) print('# Force calls with dynamic NEB: {}'.format(force_calls[1])) print('# Force calls with dynamic and scaled NEB: {}\n'.format( force_calls[2])) assert force_calls[2] < force_calls[1] < force_calls[0] # Assert reaction barriers are within 1 meV of default NEB assert (abs(Emax[1] - Emax[0]) < 1e-3) assert (abs(Emax[2] - Emax[0]) < 1e-3)
header.append('</head>\n') header.append('<body>\n') header.append(body) elif datatype == 'X3D': header.append('<?xml version="1.0" encoding="UTF-8"?>\n') header.append('<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 3.2//EN" ' '"http://www.web3d.org/specifications/x3d-3.2.dtd">\n') else: raise ValueError("datatype not supported: " + str(datatype)) # tail = [] if datatype == 'X3DOM': tail.append(script) tail.append('</body>\n') tail.append('</html>\n') return header, tail, datatype #======================================================== if __name__ == "__main__": from ase.build import molecule, fcc111 from ase.io import read from x3dase.x3d import X3D from ase.io import read, write atoms = molecule('H2O') X3D(atoms, bond=1.0).write('h2o.html') atoms = fcc111('Pt', size=(20, 20, 4), vacuum=5.0) X3D(atoms).write('pt.html') # images = read('examples/datas/ti-56-63.xyz', index = ':') # X3D(images[0], bond = 1.0, rmbonds = {'Ti':['Ti', 'La'], 'La':['La', 'O', 'N']}, label = True, polyhedra = {'Ti':['O', 'N']}).write('c2h6so-ani.html')
return line.split()[-2] else: RC = True if RC: with open(DB_dir + M + '/bulk.out') as f: for line in f: if 'Lattice constant:' in line: return line.split()[-2] metal = ['Bi'] metal = sorted(metal) data = {m: get_a(m) for m in metal} print(data) db = connect('A_slab.db') for k, v in data.items(): slab = fcc111(k, (2, 2, 3), float(v), 10) c = FixAtoms(indices=[a.index for a in slab if a.tag > 1]) slab.set_constraint(c) slab.wrap() parameters['spinpol'] = False keys['metal'] = k db.write(slab, key_value_pairs=keys, data=parameters)
from math import pi, cos, sin from ase import Atoms from ase.calculators.emt import EMT from ase.constraints import FixBondLengths from ase.optimize import BFGS from ase.build import fcc111, add_adsorbate for wrap in [False, True]: zpos = cos(134.3 / 2.0 * pi / 180.0) * 1.197 xpos = sin(134.3 / 2.0 * pi / 180.0) * 1.19 co2 = Atoms('COO', positions=[(-xpos + 1.2, 0, -zpos), (-xpos + 1.2, -1.1, -zpos), (-xpos + 1.2, 1.1, -zpos)]) slab = fcc111('Au', size=(2, 2, 4), vacuum=2 * 5, orthogonal=True) slab.center() add_adsorbate(slab, co2, 1.5, 'bridge') slab.set_pbc((True, True, False)) d0 = co2.get_distance(-3, -2) d1 = co2.get_distance(-3, -1) calc = EMT() slab.set_calculator(calc) if wrap: # Remap into the cell so bond is actually wrapped: slab.set_scaled_positions(slab.get_scaled_positions() % 1.0) constraint = FixBondLengths([[-3, -2], [-3, -1]]) slab.set_constraint(constraint) dyn = BFGS(slab, trajectory='relax_%d.traj' % wrap) dyn.run(fmax=0.05) assert abs(slab.get_distance(-3, -2, mic=1) - d0) < 1e-9
def test_database_logic(seed, testdir): from ase.ga.data import PrepareDB from ase.ga.data import DataConnection from ase.ga.startgenerator import StartGenerator from ase.ga.utilities import closest_distances_generator from ase.ga import set_raw_score import numpy as np from ase.build import fcc111 from ase.constraints import FixAtoms # set up the random number generator rng = np.random.RandomState(seed) slab = fcc111('Au', size=(4, 4, 2), vacuum=10.0, orthogonal=True) slab.set_constraint(FixAtoms(mask=slab.positions[:, 2] <= 10.)) # define the volume in which the adsorbed cluster is optimized # the volume is defined by a corner position (p0) # and three spanning vectors (v1, v2, v3) pos = slab.get_positions() cell = slab.get_cell() p0 = np.array([0., 0., max(pos[:, 2]) + 2.]) v1 = cell[0, :] * 0.8 v2 = cell[1, :] * 0.8 v3 = cell[2, :] v3[2] = 3. # define the closest distance between two atoms of a given species blmin = closest_distances_generator(atom_numbers=[47, 79], ratio_of_covalent_radii=0.7) # Define the composition of the atoms to optimize atom_numbers = 2 * [47] + 2 * [79] # create the starting population sg = StartGenerator(slab=slab, blocks=atom_numbers, blmin=blmin, box_to_place_in=[p0, [v1, v2, v3]], rng=rng) # generate the starting population starting_population = [sg.get_new_candidate() for i in range(20)] d = PrepareDB(db_file_name=db_file, simulation_cell=slab, stoichiometry=atom_numbers) for a in starting_population: d.add_unrelaxed_candidate(a) # and now for the actual test dc = DataConnection(db_file) dc.get_slab() dc.get_atom_numbers_to_optimize() assert dc.get_number_of_unrelaxed_candidates() == 20 a1 = dc.get_an_unrelaxed_candidate() dc.mark_as_queued(a1) assert dc.get_number_of_unrelaxed_candidates() == 19 assert len(dc.get_all_candidates_in_queue()) == 1 set_raw_score(a1, 0.0) dc.add_relaxed_step(a1) assert dc.get_number_of_unrelaxed_candidates() == 19 assert len(dc.get_all_candidates_in_queue()) == 0 assert len(dc.get_all_relaxed_candidates()) == 1 a2 = dc.get_an_unrelaxed_candidate() dc.mark_as_queued(a2) confid = a2.info['confid'] assert dc.get_all_candidates_in_queue()[0] == confid dc.remove_from_queue(confid) assert len(dc.get_all_candidates_in_queue()) == 0
from __future__ import absolute_import, division, print_function, unicode_literals try: from builtins import (bytes, str, open, super, range, zip, round, input, int, pow, object) except ImportError: from __builtin__ import (bytes, str, open, super, range, zip, round, input, int, pow, object) import sys import numpy as np import unittest from ase.build import molecule from ase.build import fcc111 slab = fcc111('Al', size=(3, 3, 3), vacuum=10.0) atoms = slab from cluskit import Support support = Support(slab) support2 = Support(slab) class SurfaceAtomsTests(unittest.TestCase): def test_n_surface_atoms(self): """Tests the number of surface atoms. """ surface_atoms = support.get_surface_atoms() n_surface_atoms = len(surface_atoms) self.assertTrue(n_surface_atoms == 18)
def cu_slab(): a = 1 size = (2, 4, 3) p1 = fcc111('Cu', size, orthogonal=True, a=a) p1.info['confid'] = 1 return p1
from ase import Atoms from ase.build import fcc111, add_adsorbate from ase.calculators.emt import EMT from ase.constraints import FixAtoms from ase.optimize import QuasiNewton from ase.io import write # Find the initial and final states for the reaction. # Set up a (4 x 4) two layer slab of Cu: slab = fcc111('Cu',size=(4,4,2)) slab.set_pbc((1,1,0)) # Initial state. # Add the N2 molecule oriented at 60 degrees: d = 1.10 # N2 bond length N2mol = Atoms('N2',positions=[[0.0,0.0,0.0],[0.5*3**0.5*d,0.5*d,0.0]]) add_adsorbate(slab,N2mol,height=1.0,position='fcc') # Use the EMT calculator for the forces and energies: slab.set_calculator(EMT()) # We don't want to worry about the Cu degrees of freedom, # so fix these atoms: mask = [atom.symbol == 'Cu' for atom in slab] slab.set_constraint(FixAtoms(mask=mask))