def bcc100(symbol, a, layers, L): """Build a bcc(100) surface symbol: chemical symbol ('H', 'Li', ...) a : lattice constant layers: number of layers L : height of unit cell""" a = float(a) # Distance between layers: z = a / 2 assert L > layers * z, 'Unit cell too small!' # Start with an empty Atoms object with an orthorhombic unit cell: atoms = Atoms(pbc=(True, True, False), cell=(a, a, L)) # Fill in the atoms: for n in range(layers): position = [a / 2 * (n % 2), a / 2 * (n % 2), n * z] atoms.append(Atom(symbol, position)) atoms.center(axis=2) return atoms
def lmp_structure(self): atoms=Atoms() lead1=self.m.lmp_structure() self.hatom=len(lead1) lead2=lead1.copy() lead3=lead1.copy() atoms.extend(lead1) lead2.translate(lead1.cell[0]) atoms.extend(lead2) lead3.translate(lead1.cell[0]*2) atoms.extend(lead3) atoms.cell=lead1.cell.copy() atoms.cell[0]=lead1.cell[0]*3 atoms.center() return atoms
def test(): vdw = FFTVDWFunctional('vdW-DF', verbose=1) d = 3.9 x = d / sqrt(3) L = 3.0 + 2 * 4.0 dimer = Atoms('Ar2', [(0, 0, 0), (x, x, x)], cell=(L, L, L)) dimer.center() calc = GPAW(h=0.2, xc='revPBE') dimer.set_calculator(calc) e2 = dimer.get_potential_energy() niter2 = calc.get_number_of_iterations() calc.write('Ar2.gpw') e2vdw = calc.get_xc_difference(vdw) e2vdwb = GPAW('Ar2.gpw').get_xc_difference(vdw) print e2vdwb - e2vdw assert abs(e2vdwb - e2vdw) < 1e-9 del dimer[1] e = dimer.get_potential_energy() niter = calc.get_number_of_iterations() evdw = calc.get_xc_difference(vdw) E = 2 * e - e2 Evdw = E + 2 * evdw - e2vdw print E, Evdw assert abs(E - -0.0048) < 1e-4 assert abs(Evdw - +0.0223) < 1e-4 print e2, e equal(e2, -0.001581923, energy_tolerance) equal(niter2, 17, niter_tolerance) equal(e, -0.003224226, energy_tolerance) equal(niter, 14, niter_tolerance)
def create_relaxed_Na_cluster(N, view=False): print(f'************ Na{N} ************') start = time.time() #**** Initialize system ****# if N==6: clust = Atoms('Na'*6, positions=[(1,1,0),(1,-1,0),(-1,-1,0),(-1,1,0),(0,0,1),(0,0,-1)], cell=(d, d, d)) else: clust = Atoms('Na'*N, positions=[np.random.randn(3) for i in range(N)], cell=(d, d, d)) # random initialization clust.center() if view: view(clust) #**** Define the calculator ****# calc = GPAW(nbands=10, h=0.25, txt=f'Na{N}_out.txt', occupations=FermiDirac(0.05), setups={'Na': '1'}, mode='lcao', basis='dzp') #**** Relax the system ****# clust.set_calculator(calc) dyn = GPMin(clust, trajectory=f'Na{N}_relax_clust.traj', logfile='Na{N}_relax_clust.log') print(f'**** Relaxing system of {N} atoms ****') dyn.run(fmax=0.02, steps=100) #**** Calculate energy and wavefunction ****# e = clust.get_potential_energy() # Note opposite signa from ga.py e_file = open(f'Na{N}_e_cluster.txt', 'w') print(f'Na{N} cluster energy: {e} eV', file=e_file) calc.write(f'Na{N}_cluster.gpw', mode='all') end = time.time() print(f'**** Elapsed time: {end-start} s ****') print('*****************************\n')
def atomizationEnergyH2O(dbname, xc): database = db.connect(dbname) system = database.get_atoms( selection=20) # Use atom with reference 20 as structure calc = gp.GPAW(xc=xc) system.set_calculator(calc) eH2O = system.get_potential_energy() calc = gp.GPAW(xc=xc, hund=True) Hsyst = Atoms("H", positions=[[3.5, 3.5 + 0.001, 3.5 + 0.0002]]) Hsyst.set_cell([7, 7, 7]) Hsyst.center() Hsyst.set_calculator(calc) eH = Hsyst.get_potential_energy() Osyst = Atoms("O", positions=[[3.5, 3.5 + 0.001, 3.5 + 0.0002]]) Osyst.set_cell([7, 7, 7]) Osyst.center() Osyst.set_calculator(calc) eO = Osyst.get_potential_energy() print("Hydrogen energy: %.2E" % (eH)) print("Oxygen energy: %.2E" % (eO)) print("Atomization energy: %.2E" % (eH2O - 2 * eH - eO))
def ori_structure(self): lead1=self.lead1=graphene(dict(latx=1,laty=self.laty,latz=1)).lmp_structure() n=len(lead1) center=graphene(dict(latx=self.latx,laty=self.laty,latz=1)).lmp_structure() center.translate(lead1.cell[0]) lead2=lead1.copy() lead2.translate(lead1.cell[0]+center.cell[0]) atoms=Atoms() atoms.extend(lead1) atoms.extend(center) atoms.extend(lead2) atoms.cell=center.cell atoms.cell[0]=lead1.cell[0]+center.cell[0]+lead2.cell[0] lx=self.extent(atoms)[0] self.getScale(lx/2) self.center_box(atoms) self.writeatoms(atoms,'graphene') low=atoms.positions[:,0].min()+2 hi=atoms.positions[:,0].max()-2 self.leftgroup=np.arange(len(atoms),dtype='int')[:n]+1 self.rightgroup=np.arange(len(atoms),dtype='int')[-n:]+1 self.fmag=self.strain/float(len(self.leftgroup)) self.posleft=atoms.positions[self.leftgroup[0]-1].copy()+(50,50,50) self.posright=atoms.positions[self.rightgroup[0]-1].copy()+(50,50,50) self.posleft[0]*=10 self.posright[0]*=10 for atom in atoms: atom.position=self.trans(atom.position) atoms.center(vacuum=50) return atoms
def main(): if sys.version_info < (2, 7): raise NotAvailable('read_xml requires Python version 2.7 or greater') assert installed() # simple test calculation of CO molecule d = 1.14 co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True) co.center(vacuum=5.) calc = Vasp(xc='PBE', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False) co.set_calculator(calc) energy = co.get_potential_energy() forces = co.get_forces() # check that parsing of vasprun.xml file works conf = read('vasprun.xml') assert conf.calc.parameters['kpoints_generation'] assert conf.calc.parameters['sigma'] == 1.0 assert conf.calc.parameters['ialgo'] == 68 assert energy - conf.get_potential_energy() == 0.0 assert array_almost_equal(conf.get_forces(), forces, tol=1e-4) # Cleanup calc.clean()
def fcc100(symbol, a, layers, L): """Build an fcc(100) surface Parameters ---------- symbol: string Chemical symbol ('H', 'Li', ...). a: float Lattice constant. layers: int Number of layers. L: float Height of unit cell. """ # Distance between atoms: d = a / sqrt(2) # Distance between layers: z = a / 2. assert L > layers * z, 'Unit cell too small!' # Start with an empty Atoms object: atoms = Atoms(cell=(d, d, L), pbc=(True, True, False)) # Fill in the atoms: for n in range(layers): position = [d / 2 * (n % 2), d / 2 * (n % 2), n * z] atoms.append(Atom(symbol, position)) atoms.center(axis=2) return atoms
def test(): vdw = FFTVDWFunctional('vdW-DF', verbose=1) d = 3.9 x = d / sqrt(3) L = 3.0 + 2 * 4.0 dimer = Atoms('Ar2', [(0, 0, 0), (x, x, x)], cell=(L, L, L)) dimer.center() calc = GPAW(h=0.2, xc='revPBE') dimer.set_calculator(calc) e2 = dimer.get_potential_energy() niter2 = calc.get_number_of_iterations() calc.write('Ar2.gpw') e2vdw = calc.get_xc_difference(vdw) e2vdwb = GPAW('Ar2.gpw').get_xc_difference(vdw) print e2vdwb - e2vdw assert abs(e2vdwb - e2vdw) < 1e-9 del dimer[1] e = dimer.get_potential_energy() niter = calc.get_number_of_iterations() evdw = calc.get_xc_difference(vdw) E = 2 * e - e2 Evdw = E + 2 * evdw - e2vdw print E, Evdw assert abs(E - -0.0048) < 6e-3, abs(E) assert abs(Evdw - +0.0223) < 3e-2, abs(Evdw) print e2, e equal(e2, -0.001581923, energy_tolerance) equal(e, -0.003224226, energy_tolerance)
def main(): assert installed() # simple test calculation of CO molecule d = 1.14 co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True) co.center(vacuum=5.) calc = Vasp(xc='PBE', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False, ldipol=True) co.set_calculator(calc) energy = co.get_potential_energy() forces = co.get_forces() dipole_moment = co.get_dipole_moment() # check that parsing of vasprun.xml file works conf = read('vasprun.xml') assert conf.calc.parameters['kpoints_generation'] assert conf.calc.parameters['sigma'] == 1.0 assert conf.calc.parameters['ialgo'] == 68 assert energy - conf.get_potential_energy() == 0.0 assert np.allclose(conf.get_forces(), forces) assert np.allclose(conf.get_dipole_moment(), dipole_moment, atol=1e-6) # Cleanup calc.clean()
def get_system_type(atoms: ase.Atoms) -> str: """ Helpful docstring """ ############################################################################ # Parameters #------------ cutoff = 6 # A # Preprocessing atoms.center() # In case dealing with Nerds Rope & Co. minx, miny, minz, maxx, maxy, maxz = 1000, 1000, 1000, -1000, -1000, -1000 for a in atoms: if a.position[0] < minx: minx = a.position[0] if a.position[1] < miny: miny = a.position[1] if a.position[2] < minz: minz = a.position[2] if a.position[0] > maxx: maxx = a.position[0] if a.position[1] > maxy: maxy = a.position[1] if a.position[2] > maxz: maxz = a.position[2] cell_abc = list(map(np.linalg.norm, atoms.get_cell()[:3])) thickness = [maxx - minx, maxy - miny, maxz - minz] pbc = [cell_abc[i] - thickness[i] < cutoff for i in range(3)] if all(pbc): return 'bulk' elif any(pbc): return 'surface' else: return 'molecule'
def test_axis_layout(): system = Atoms('H') a = 3. system.cell = (a, a, a) system.pbc = 1 for axis in range(3): system.center() system.positions[0, axis] = 0.0 calc = Octopus(**getkwargs(label='ink-%s' % 'xyz'[axis], Output='density + potential + wfs')) system.set_calculator(calc) system.get_potential_energy() rho = calc.get_pseudo_density(pad=False) #for dim in rho.shape: # assert dim % 2 == 1, rho.shape maxpoint = np.unravel_index(rho.argmax(), rho.shape) print('axis=%d: %s/%s' % (axis, maxpoint, rho.shape)) expected_max = [dim // 2 for dim in rho.shape] expected_max[axis] = 0 assert maxpoint == tuple(expected_max), '%s vs %s' % (maxpoint, expected_max) errs = check_interface(calc) for err in errs: if err.code == 'not implemented': continue if err.methname == 'get_dipole_moment': assert isinstance(err.error, OctopusIOError) else: raise AssertionError(err.error)
def Al_atom_pair(pair_distance=pair_distance): atoms = Atoms('AlAl', positions=[[-pair_distance / 2, 0, 0], [pair_distance / 2, 0, 0]]) atoms.center(vacuum=10) atoms.calc = EMT() return atoms
def minimise(self, cluster): '''Minimise a cluster parameters: cluster- a Cluster object from bcga.cluster Using this method will overwrite the coordinates and energy of the supplied Cluster object.''' # Fix overlapping atoms to avoid NWChem errors cluster.fix_overlaps(1.5) # Set up element labels for NWChem atom_string = "" for i in range(0, len(cluster.labels)): atom_string += cluster.labels[i] + str( get_composition(cluster.atom_types)[i]) print(atom_string) mol = Atoms(atom_string, positions=cluster._coords, cell=(6.0, 6.0, 6.0)) mol.center() # Run GPAW calculation calc = GPAW(**self.GPAWargs) mol.set_calculator(calc) opt = BFGSLineSearch(mol) try: opt.run(fmax=0.25) except: sys.exit() # Get back cluster properties from GPAW cluster.energy = mol.get_potential_energy() cluster.quenched = True return cluster
def test(): vdw = VDWFunctional('vdW-DF', verbose=1) d = 3.9 x = d / sqrt(3) L = 3.0 + 2 * 4.0 dimer = Atoms('Ar2', [(0, 0, 0), (x, x, x)], cell=(L, L, L)) dimer.center() calc = GPAW(h=0.2, xc=dict(name='revPBE', stencil=1), mixer=Mixer(0.8, 7, 50.0), eigensolver=Davidson(5)) dimer.set_calculator(calc) e2 = dimer.get_potential_energy() calc.write('Ar2.gpw') e2vdw = calc.get_xc_difference(vdw) e2vdwb = GPAW('Ar2.gpw').get_xc_difference(vdw) print(e2vdwb - e2vdw) assert abs(e2vdwb - e2vdw) < 1e-9 del dimer[1] e = dimer.get_potential_energy() evdw = calc.get_xc_difference(vdw) E = 2 * e - e2 Evdw = E + 2 * evdw - e2vdw print(E, Evdw) assert abs(E - -0.0048) < 6e-3, abs(E) assert abs(Evdw - +0.0223) < 3e-2, abs(Evdw) print(e2, e) equal(e2, -0.001581923, energy_tolerance) equal(e, -0.003224226, energy_tolerance)
def make_periodic(atoms: Atoms, vacuum_buffer: float = 10) -> Atoms: """Make an atoms object periodic Required for fitting with ``fit_gap`` Args: atoms: Atoms object to be adjusted vacuum_buffer: Amount of space to buffer on either side of the molecule Returns: Atoms object made periodic """ # Give the cell periodic boundary conditions in each direction atoms.pbc = [True] * 3 # Compute the size of the cell in each direction mol_size = np.max(atoms.positions, axis=0) - np.min(atoms.positions, axis=0) # Give a cell that is big enough to have the desired buffer on each size atoms.cell = np.diag(mol_size + vacuum_buffer * 2) # Center the atoms in the middle of it atoms.center() return atoms
def energy(lamb): ############################################################# # He created from H2 and external potential # ############################################################# d = 0.74 a = 6.0 atoms_external = Atoms('H2', positions=[(0, 0, 0), (0, 0, d)], cell=(a, a, a)) atoms_external.center() pc = PointChargePotential([lamb, -lamb], [[3.0, 3.0, 2.63], [3.0, 3.0, 3.37]]) output = 'output/result' + str(lamb).replace('.', '_') + '.txt' calc = GPAW(xc='PBE', txt=output, external=pc) atoms_external.set_calculator(calc) pot_en = atoms_external.get_potential_energy() density = calc.get_all_electron_density(gridrefinement=4) write('output/density_' + str(lamb).replace('.', '_') + '.cube', atoms_external, data=density) return (pot_en)
def minimise (self,cluster): '''Minimise a cluster parameters: cluster- a Cluster object from bcga.cluster Using this method will overwrite the coordinates and energy of the supplied Cluster object.''' # Fix overlapping atoms to avoid NWChem errors cluster.fix_overlaps(1.5) # Set up element labels for NWChem atom_string="" for i in range(0,len(cluster.labels)): atom_string+=cluster.labels[i]+str(get_composition(cluster.atom_types)[i]) print(atom_string) mol = Atoms(atom_string, positions=cluster._coords, cell=(6.0,6.0,6.0)) mol.center() # Run GPAW calculation calc = GPAW(**self.GPAWargs) mol.set_calculator(calc) opt = BFGSLineSearch(mol) try: opt.run(fmax=0.25) except: sys.exit() # Get back cluster properties from GPAW cluster.energy=mol.get_potential_energy() cluster.quenched=True return cluster
def atoms_2co(): """Simple atoms object for testing with 2x CO molecules""" d = 1.14 atoms = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True) atoms.extend(Atoms('CO', positions=[(0, 2, 0), (0, 2, d)])) atoms.center(vacuum=5.) return atoms
def test_vasp2_co(): """ Run some VASP tests to ensure that the VASP calculator works. This is conditional on the existence of the VASP_COMMAND or VASP_SCRIPT environment variables """ from ase.test.vasp import installed2 as installed assert installed() from ase import Atoms from ase.io import write from ase.calculators.vasp import Vasp2 as Vasp import numpy as np def array_almost_equal(a1, a2, tol=np.finfo(type(1.0)).eps): """Replacement for old numpy.testing.utils.array_almost_equal.""" return (np.abs(a1 - a2) < tol).all() d = 1.14 co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True) co.center(vacuum=5.) calc = Vasp(xc='PBE', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False) co.set_calculator(calc) en = co.get_potential_energy() write('vasp_co.traj', co) assert abs(en + 14.918933) < 5e-3 # Secondly, check that restart from the previously created VASP output works calc2 = Vasp(restart=True) co2 = calc2.get_atoms() # Need tolerance of 1e-14 because VASP itself changes coordinates # slightly between reading POSCAR and writing CONTCAR even if no ionic # steps are made. assert array_almost_equal(co.positions, co2.positions, 1e-14) assert en - co2.get_potential_energy() == 0. assert array_almost_equal(calc.get_stress(co), calc2.get_stress(co2)) assert array_almost_equal(calc.get_forces(co), calc2.get_forces(co2)) assert array_almost_equal(calc.get_eigenvalues(), calc2.get_eigenvalues()) assert calc.get_number_of_bands() == calc2.get_number_of_bands() assert calc.get_xc_functional() == calc2.get_xc_functional() # Cleanup calc.clean()
def ellipsoid(atomlist, fill_factor=0.74, radii=None, ratio=[1, 1, 1], cell=None): """Generates a random ellipsoid by rejection sampling. Not the most efficient code but good at garaunteeing an even distribution inside the ellipsoid. Parameters ---------- fill_factor : float Determines how "close" the atoms are packed. See structopt.tools.get_particle_radius for description radii : list (3 elements) The size, in angstroms, of the ellipsoid in the x, y and z direction ratio : list (3 elements) The ratio of the dimensions of the ellipsoid in the x, y and z direction. cell : list (3 elements) The size, in angstroms, of the dimensions that holds the atoms object """ # Get the dimensions of the ellipsoid if required if radii is None: radius = get_particle_radius(atomlist, fill_factor) a = radius / ((ratio[1] / ratio[0])**(1.0 / 3.0) * (ratio[2] / ratio[0])**(1.0 / 3.0)) b = radius / ((ratio[0] / ratio[1])**(1.0 / 3.0) * (ratio[2] / ratio[1])**(1.0 / 3.0)) c = radius / ((ratio[0] / ratio[2])**(1.0 / 3.0) * (ratio[1] / ratio[2])**(1.0 / 3.0)) else: a, b, c = radii # Create a list of random order of the atoms chemical_symbols = [] for atom in atomlist: chemical_symbols += [atom[0]] * atom[1] random.shuffle(chemical_symbols) # Add atoms iteratively only if they fall inside the ellipsoid indiv = Atoms() while len(chemical_symbols) > 0: x, y, z = random.uniform(-a, a), random.uniform(-b, b), random.uniform(-c, c) if x**2 / a**2 + y**2 / b**2 + z**2 / c**2 <= 1: indiv.extend(Atom(chemical_symbols.pop(), [x, y, z])) if cell is not None: indiv.set_cell(cell) indiv.center() indiv.set_pbc(True) return indiv
def build_system(self, name): if name in extra: mol = Atoms(*extra[name]) mol.cell = self.unit_cell mol.center() else: self.bond_length = bondlengths.get(name, None) mol = MoleculeTask.build_system(self, name) return mol
def make_ase(self, species, positions): """Create ase Atoms object.""" # Get the principal axes and realign the molecule along z-axis. positions = PCA(n_components=3).fit_transform(positions) atoms = Atoms(species, positions=positions, pbc=True) atoms.cell = np.ptp(atoms.positions, axis=0) + 10 atoms.center() return atoms
def get_pointgroup(atoms: ase.Atoms) -> str: """ uses pymatgen.symmetry.analyzer """ atoms.center() symbs = atoms.get_chemical_symbols() pos = atoms.get_positions() mol = pmg.Molecule(symbs, pos) return pysym.PointGroupAnalyzer(mol).sch_symbol
def set_up_calculation(db, subdir, syms, AB_stacking, soc, vacuum_dist, D, xc, pp): # Choose separation between layers as if the system was a bulk system # where all layers are the same as the first layer here. # TODO -- is there a better strategy for this? c_sep = get_c_sep(db, syms[0]) latvecs, at_syms, cartpos = make_cell(db, syms, c_sep, vacuum_dist, AB_stacking) system = Atoms(symbols=at_syms, positions=cartpos, cell=latvecs, pbc=True) system.center(axis=2) wann_valence, num_wann = get_wann_valence(system.get_chemical_symbols(), soc) num_bands = get_num_bands(num_wann) holes_per_cell = None qe_config = make_qe_config(system, D, holes_per_cell, soc, num_bands, xc, pp) prefix = make_prefix(syms) work = _get_work(subdir, prefix) wannier_dir = os.path.join(work, "wannier") if not os.path.exists(wannier_dir): os.makedirs(wannier_dir) bands_dir = os.path.join(work, "bands") if not os.path.exists(bands_dir): os.makedirs(bands_dir) dirs = {'scf': wannier_dir, 'nscf': wannier_dir, 'bands': bands_dir} qe_input = {} for calc_type in ['scf', 'nscf', 'bands']: qe_input[calc_type] = build_qe(system, prefix, calc_type, qe_config) _write_qe_input(prefix, dirs[calc_type], qe_input, calc_type) pw2wan_input = build_pw2wan(prefix, soc) pw2wan_path = os.path.join(wannier_dir, "{}.pw2wan.in".format(prefix)) with open(pw2wan_path, 'w') as fp: fp.write(pw2wan_input) bands_post_input = build_bands(prefix) bands_post_path = os.path.join(bands_dir, "{}.bands_post.in".format(prefix)) with open(bands_post_path, 'w') as fp: fp.write(bands_post_input) wannier_input = Winfile(system, qe_config, wann_valence, num_wann) win_path = os.path.join(wannier_dir, "{}.win".format(prefix)) with open(win_path, 'w') as fp: fp.write(wannier_input) return prefix
def main(): if sys.version_info < (2, 7): raise NotAvailable('read_xml requires Python version 2.7 or greater') assert installed() # simple test calculation of CO molecule d = 1.14 co = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True) co.center(vacuum=5.) calc = Vasp(xc='LDA', prec='Low', algo='Fast', ismear=0, sigma=1., nbands=12, istart=0, nelm=3, lwave=False, lcharg=False, ldipol=True) co.set_calculator(calc) energy = co.get_potential_energy() forces = co.get_forces() dipole_moment = co.get_dipole_moment() # check that parsing of vasprun.xml file works conf = read('vasprun.xml') assert conf.calc.parameters['kpoints_generation'] assert conf.calc.parameters['sigma'] == 1.0 assert conf.calc.parameters['ialgo'] == 68 assert energy - conf.get_potential_energy() == 0.0 # Check some arrays assert np.allclose(conf.get_forces(), forces) assert np.allclose(conf.get_dipole_moment(), dipole_moment, atol=1e-6) # Check k-point-dependent properties assert len(conf.calc.get_eigenvalues(spin=0)) >= 12 assert conf.calc.get_occupation_numbers()[2] == 2 assert conf.calc.get_eigenvalues(spin=1) is None kpt = conf.calc.get_kpt(0) assert kpt.weight == 1. # Perform a spin-polarised calculation co.calc.set(ispin=2, ibrion=-1) co.get_potential_energy() conf = read('vasprun.xml') assert len(conf.calc.get_eigenvalues(spin=1)) >= 12 assert conf.calc.get_occupation_numbers(spin=1)[0] == 1. # Cleanup calc.clean()
def lmp_structure(self): ribbon=graphene(dict(latx=self.latx,laty=self.laty,latz=1,gnrtype=self.gnrtype)).lmp_structure() for atom in ribbon: atom.position=self.trans(atom.position) atoms=Atoms() atoms.extend(ribbon) atoms.center(vacuum=10) return atoms
def get_potential_energy_test(self): d = 2 # Si2 bondlength a = Atoms([14] * 4, [(d, 0, d), (0, 0, 0), (d, 0, 0), (0, 0, d)], cell=(100, 100, 100)) a.center(vacuum=10.0) calculator = KumagaiTersoff(**Kumagai_CompMaterSci_39_457_Si_py_var) a.set_calculator(calculator) ene = a.get_potential_energy() # print(ene) assert (ene + 6.956526471027033) < 0.01 # TODO: compare with LAMMPS
def pymol_2_ase(pymol): """Convert pymol object into ASE Atoms.""" species = [chemical_symbols[atm.atomicnum] for atm in pymol.atoms] pos = np.asarray([atm.coords for atm in pymol.atoms]) pca = PCA(n_components=3) posnew = pca.fit_transform(pos) atoms = Atoms(species, positions=posnew, pbc=True, cell=np.ptp(posnew, axis=0) + 10) atoms.center() return atoms
def load_data_to_atoms(system_data): atoms_list = [] for i, atom in enumerate(system_data["atoms"]): atoms_list.append(Atom(atom, np.array(system_data["coordinates"][i]))) system = Atoms(atoms_list, cell=[50, 50, 50]) system.center() calc = SinglePointCalculator(system, energy=system_data["corrected_energy"]) system.set_calculator(calc) return system
def setup_atomic_square(): """ Setup squares of 4 gold atoms with known positions :return: """ atoms1 = Atoms('Au4', [[0, 0, 0], [3, 0, 0], [0, 3, 0], [3, 3, 0]]) atoms1.center() atoms2 = atoms1.copy() scale = .75 atoms2.positions *= scale return atoms1, atoms2
def monolayer_Xene(formula, a, buckling, vacuum): if vacuum is not None: buckling=buckling/vacuum positions=[[2/3, 1/3,buckling/2.0],[1/3,2/3,-buckling/2.0]] cell=[[a, 0, 0], [-a/2, a * 3**0.5 / 2, 0], [0, 0, 0]] atoms = Atoms(formula, positions=positions, cell=cell, pbc=(1, 1, 0)) atoms.set_scaled_positions(positions) if vacuum is not None: atoms.center(vacuum, axis=2) return atoms
def pymol_2_ase(pymol): """Convert pymol object into ASE Atoms.""" asemol = Atoms() for atm in pymol.atoms: asemol.append(Atom(chemical_symbols[atm.atomicnum], atm.coords)) asemol.cell = np.amax(asemol.positions, axis=0) - np.amin( asemol.positions, axis=0) + [10] * 3 asemol.pbc = True asemol.center() return asemol
def single_atom_calculation(element, basis='szp(dzp)', xc='PBE'): atoms = Atoms(element, [(0, 0, 0)]) atoms.set_cell([7, 7, 7]) atoms.center() calc = GPAW(mode='lcao', txt=None, basis=basis, xc=xc, maxiter=1) atoms.set_calculator(calc) try: atoms.get_potential_energy() except: pass return calc
def get_top_struct(atoms): atoms_lst = [] layers = geometry.get_layers(atoms, (0, 0, 1), tolerance=0.1) lays = list(set(layers[0])) for atom in atoms: if get_layer(atoms, atom) in lays[-5:]: atoms_lst.append(atom) new_atoms = Atoms(atoms_lst) new_atoms.set_cell(np.add(atoms.get_cell(), [0, 0, 0.])) new_atoms.center(axis=2) new_atoms.set_pbc([True, True, True]) return new_atoms
def get_atoms(grid, atomlist, cell, a, v=[1, 0, 0], angle=0.0): '''Returns an atoms object from a grid''' a1 = a/2.0 * np.array([1, 1, 0]) a2 = a/2.0 * np.array([1, 0, 1]) a3 = a/2.0 * np.array([0, 1, 1]) temp_cell = np.array([a1, a2, a3]) if np.shape(v) == (3,) and not hasattr(angle, '__iter__'): vs = np.expand_dims(v, 0) angles = [angle] else: vs = v angles = angle for v, angle in zip(vs, angles): v = np.asarray(v, dtype=float) v /= np.linalg.norm(v) c = cos(angle) s = sin(angle) temp_cell[:] = (c * temp_cell - np.cross(temp_cell, s * v) + np.outer(np.dot(temp_cell, v), (1.0 - c) * v)) # Loop through each lattice point and add the atom scaled_positions = [] size = np.shape(grid) for i in range(size[0]): for j in range(size[1]): for k in range(size[2]): if grid[i][j][k] == 1: scaled_positions.append([i, j, k]) # Add the atoms to the atoms object size = len(scaled_positions) chemical_symbols = [] for i in atomlist: chemical_symbols += [i[0]] * i[1] random.shuffle(chemical_symbols) atoms = Atoms(chemical_symbols) atoms.set_cell(temp_cell) atoms.set_scaled_positions(scaled_positions) atoms.set_cell(cell) atoms.center() # Make the cell the size of the grid # A = np.array([np.shape(grid)]) # cell = np.multiply(A.T, np.array([a1, a2, a3])) # atoms.set_cell(cell) return atoms
def _make_ase(self, species, positions, smiles): """Create ase Atoms object.""" # Get the principal axes and realign the molecule along z-axis. positions = PCA(n_components=3).fit_transform(positions) atoms = Atoms(species, positions=positions, pbc=True) atoms.cell = np.ptp(atoms.positions, axis=0) + 10 atoms.center() # We're attaching this info so that it # can be later stored as an extra on AiiDA Structure node. atoms.info["smiles"] = smiles return atoms
def ring(self): # armchair ring atoms = Atoms() atom = Atoms('C', positions=[(1.0, 0.0, 0.0)]) for i in range(6): unit = atom.copy() unit.rotate('z', pi / 3 * i) atoms.extend(unit) atoms.set_cell([3.0, sqrt(3), self.az]) atoms.center() wrap(atoms) return atoms
def ellipsoid(atomlist, fill_factor=0.74, radii=None, ratio=[1, 1, 1], cell=None): """Generates a random ellipsoid by rejection sampling. Parameters ---------- atomlist : list A list of [sym, n] pairs where sym is the chemical symbol and n is the number of of sym's to include in the individual fill_factor : float Determines how "close" the atoms are packed. See structopt.tools.get_particle_radius for description radii : list The size, in angstroms, of the ellipsoid in the x, y and z direction. If None, with ratio parameters and the average atomic radii, radii is automatically calculated. ratio : list The ratio of the dimensions of the ellipsoid in the x, y and z direction. cell : list The size, in angstroms, of the dimensions that holds the atoms object. Must be an orthogonal box. """ # Get the dimensions of the ellipsoid if required if radii is None: radius = get_particle_radius(atomlist, fill_factor) a = radius / ((ratio[1]/ratio[0])**(1.0/3.0) * (ratio[2]/ratio[0])**(1.0/3.0)) b = radius / ((ratio[0]/ratio[1])**(1.0/3.0) * (ratio[2]/ratio[1])**(1.0/3.0)) c = radius / ((ratio[0]/ratio[2])**(1.0/3.0) * (ratio[1]/ratio[2])**(1.0/3.0)) else: a, b, c = radii # Create a list of random order of the atoms chemical_symbols = [] for atom in atomlist: chemical_symbols += [atom[0]] * atom[1] random.shuffle(chemical_symbols) # Add atoms iteratively only if they fall inside the ellipsoid indiv = Atoms() while len(chemical_symbols) > 0: x, y, z = random.uniform(-a, a), random.uniform(-b, b), random.uniform(-c, c) if x**2/a**2 + y**2/b**2 + z**2/c**2 <= 1: indiv.extend(Atom(chemical_symbols.pop(), [x, y, z])) if cell is not None: indiv.set_cell(cell) indiv.center() indiv.set_pbc(True) return indiv
def setup_atoms(n): """ Generate a configuration of n gold atoms with random positions Parameters ---------- n: int Number of atoms in configuration """ q = rs.random_sample((n, 3)) * 10 atoms = Atoms('Au' + str(int(n)), q) atoms.center() return atoms
def get_atoms(): atoms = Atoms('Pd4NH', [[5.078689759346383, 5.410678028467162, 4.000000000000000], [7.522055777772603, 4.000000000000000, 4.000000000000000], [7.522055777772603, 6.821356056934325, 4.000000000000000], [6.707600438297196, 5.410678028467162, 6.303627574066606], [4.807604264052752, 5.728625577716107, 5.919407072553396], [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) return atoms
def make_pamam(generations): # Make core. atoms = Atoms('NCHHCHHN') # Define connectivity of core. bonds = [ [0,1], [1,2], [1,3], [1,4], [4,5], [4,6], [4,7] ] terminal_atoms = [0, 7] opt(atoms, bonds) monomer_positions = None for generation in xrange(generations+1): new_terminal_atoms = [] for terminal_atom in terminal_atoms: for branch in xrange(2): print 'generation %i terminal atom: %3i branch: %3i' %(generation, terminal_atom, branch) # Append a monomer branch. monomer = Atoms('CHHCHHCONHCHHCHHN') monomer_bonds = [ [0,1], [0,2], [0,3], [3,4], [3,5], [3,6], [6,7], [6,8], [8,9], [8,10], [10,11], [10,12], [10,13], [13,14], [13,15], [13,16] ] if monomer_positions is None: opt(monomer, monomer_bonds) monomer_positions = monomer.get_positions() else: monomer.set_positions(monomer_positions) for bond in monomer_bonds: bond[0] += len(atoms) bond[1] += len(atoms) bonds += [[terminal_atom, len(atoms)]] + monomer_bonds dihedral = [ terminal_atom-1, terminal_atom, len(atoms), len(atoms)+1 ] atoms += monomer atoms.rotate_dihedral(dihedral, 2*numpy.pi*numpy.random.rand()) new_terminal_atoms.append(len(atoms)-1) opt(atoms, bonds) terminal_atoms = new_terminal_atoms for terminal_atom in terminal_atoms: for branch in xrange(2): atoms += Atoms('H') bonds += [[terminal_atom, len(atoms)-1]] opt(atoms, bonds) atoms.center(10) return atoms
def lmp_structure(self): atoms = Atoms() unit = graphene( dict( latx=2, laty=1, latz=1, gnrtype='zigzag')).lmp_structure() # del unit[unit.positions[:,0].argsort()[-2:]] ly = unit.cell[1][1] lidx = unit.positions[:, 0].argsort()[0] left_of_unit = unit[lidx].position # the center must be assign because the atoms are centered unit.rotate('y', 30.0 / 180 * np.pi, center=left_of_unit) ridx = unit.positions[:, 0].argsort()[-1] right_of_unit = unit[ridx].position unit1 = unit.copy() unit1.rotate('y', 120.0 / 180 * np.pi, center=right_of_unit) ridx1 = unit1.positions[:, 0].argsort()[-1] right_of_unit1 = unit1[ridx1].position # cell[0,0] lx = right_of_unit1[0] - left_of_unit[0] unit2 = unit.copy() # translate unit2 but don't traslate along y deta = right_of_unit1 - right_of_unit + [0, 0, 1.42 * np.sqrt(3) / 2] deta[1] = 0 unit2.translate(deta) lidx2 = unit2.positions[:, 0].argsort()[0] left_of_unit2 = unit2.positions[lidx2] unit3 = unit2.copy() unit3.rotate('y', 120.0 / 180 * np.pi, center=left_of_unit2) lz = left_of_unit2[2] - right_of_unit[2] + 1.42 * np.sqrt(3) / 2 atoms.extend(unit) atoms.extend(unit1) atoms.extend(unit2) atoms.extend(unit3) atoms.set_cell([lx, ly, lz]) # important for distance calculation,default all False atoms.set_pbc([True] * 3) atoms.center() atoms = atomic.get_unique_atoms(atoms) # prevent xs~=1.0 atoms.translate([0.01, 0, 0]) atomic.wrap(atoms) return atoms
def get_hydrogen_chain_dielectric_function(NH, NK): a = Atoms('H', cell=[1, 1, 1], pbc=True) a.center() a = a.repeat((1, 1, NH)) a.calc = GPAW(mode=PW(200), kpts={'size': (1, 1, NK), 'gamma': True}, parallel={'band': 1}, dtype=complex, gpts=(10, 10, 10 * NH)) a.get_potential_energy() a.calc.diagonalize_full_hamiltonian(nbands=2 * NH) a.calc.write('H_chain.gpw', 'all') DF = DielectricFunction('H_chain.gpw', ecut=1e-3, hilbert=False, omega2=np.inf, intraband=False) eps_NLF, eps_LF = DF.get_dielectric_function(direction='z') omega_w = DF.get_frequencies() return omega_w, eps_LF
def slab(m, n): atoms = Atoms() for i in range(n): if i % 2 == 0: layer = ac_unit.repeat((m, 1, 1)) if i % 2 == 1: layer = ac_unit.repeat((m, 1, 1)) layer.positions[:, 0] += 3./2 * C_C if saturated: if i == 0: sat = ac_sat_unit.repeat((m,1,1)) sat.positions[:,1] -= np.sqrt(3.) / 2 * C_H sat.positions[:,0] -= 1. / 2 * C_H layer += sat elif i == n - 1: sat = ac_sat_unit.repeat((m,1,1)) sat.positions[:,1] += np.sqrt(3.) / 2 * C_H sat.positions[:,0] -= 1. / 2 * C_H - 3./2 * C_C * (i % 2) layer += sat layer.positions[:, 1] += b / 2 * i atoms += layer xmax = np.max(atoms.positions[:,0]) for atom in atoms: if xmax - C_C/2. < atom.position[0]: atom.position[0] -= m*3*C_C if saturated: xmax = np.max(atoms.positions[:,0]) xmin = np.min(atoms.positions[:,0]) for atom in atoms: posit = atom.position if xmax - C_C/6. < posit[0] and atom.number == 6: h_posit = [posit[0] + C_H, posit[1], posit[2]] atoms += Atom('H', position = h_posit) if posit[0] < xmin + C_C/6. and atom.number == 6: h_posit = [posit[0] - C_H, posit[1], posit[2]] atoms += Atom('H', position = h_posit) atoms.cell = [m * 3 * C_C, n * b/2, 2 * vacuum] atoms.center() return atoms
def make_methylamine(): # Construct Methylamine. atoms = Atoms('NH2CH3') # Define connectivity. atoms_bonds = [ [0,1], [0,2], [0,3], [3,4], [3,5], [3,6] ] # Displace atoms so that they aren't on top of each other. atoms.rattle(0.001) # Construct VSEPR calculator. calculator = VSEPR(atoms, atoms_bonds) atoms.set_calculator(calculator) atoms.center() # Run optimization. opt = LBFGS(atoms, logfile='/dev/null') opt.run() return atoms
def create_calc(name, spinpol, pbc): # Bond lengths between H-C and C-C for ethyne (acetylene) cf. # CRC Handbook of Chemistry and Physics, 87th ed., p. 9-28 dhc = 1.060 dcc = 1.203 atoms = Atoms([Atom('H', (0, 0, 0)), Atom('C', (dhc, 0, 0)), Atom('C', (dhc+dcc, 0, 0)), Atom('H', (2*dhc+dcc, 0, 0))], pbc=pbc) atoms.center(vacuum=2.0) # Number of occupied and unoccupied bands to converge nbands = int(10/2.0) nextra = 3 #TODO use pbc and cell to calculate nkpts kwargs = {} if spinpol: kwargs['mixer'] = MixerSum(nmaxold=5, beta=0.1, weight=100) else: kwargs['mixer'] = Mixer(nmaxold=5, beta=0.1, weight=100) calc = GPAW(h=0.3, nbands=nbands+nextra, xc='PBE', spinpol=spinpol, eigensolver='cg', convergence={'energy':1e-4/len(atoms), 'density':1e-5, \ 'eigenstates': 1e-9, 'bands':-1}, txt=name+'.txt', **kwargs) atoms.set_calculator(calc) atoms.get_potential_energy() calc.write(name+'.gpw', mode='all')
def lmp_structure(self): ribbon=graphene(dict(latx=20,laty=3,latz=1,gnrtype='zigzag')).lmp_structure() self.length=ribbon.cell[0,0] self.center_box(ribbon) self.w=.2 self.getW(self.length/2) newlx=2*self.phase(self.length/2,self.w) for atom in ribbon: atom.position=self.trans(atom.position) atoms=ribbon #atoms.center(vacuum=10,axis=[1,2]) #atoms.cell[0,0]=newlx #atoms.center(axis=[0]) newatoms=Atoms() for i in range(4): atoms.rotate('z',i*pi/2,center=[0,-newlx/4,0]) newatoms.extend(atoms.copy()) newatoms.cell[0,0]=newatoms.cell[1,1]=newlx newatoms.center() atoms=newatoms#.repeat([self.latx,self.laty,1]) return atoms
from __future__ import print_function from ase import Atoms from gpaw import GPAW, restart from gpaw.test import equal from gpaw.utilities.kspot import AllElectronPotential if 1: be = Atoms(symbols='Be',positions=[(0,0,0)]) be.center(vacuum=5) calc = GPAW(gpts=(64,64,64), xc='LDA', nbands=1) #0.1 required for accuracy be.set_calculator(calc) e = be.get_potential_energy() niter = calc.get_number_of_iterations() #calc.write("be.gpw") energy_tolerance = 0.00001 niter_tolerance = 0 equal(e, 0.00246471, energy_tolerance) #be, calc = restart("be.gpw") AllElectronPotential(calc).write_spherical_ks_potentials('bepot.txt') f = open('bepot.txt') lines = f.readlines() f.close() mmax = 0 for l in lines: mmax = max(abs(eval(l.split(' ')[3])), mmax) print("Max error: ", mmax) assert mmax<0.009
#!/usr/bin/env python from ase import Atoms from gpaw import GPAW, restart from gpaw.test import equal from gpaw.utilities.kspot import CoreEigenvalues a = 7.0 calc = GPAW(h=0.1) system = Atoms('Ne', calculator=calc) system.center(vacuum=a / 2) e0 = system.get_potential_energy() niter0 = calc.get_number_of_iterations() calc.write('Ne.gpw') del calc, system atoms, calc = restart('Ne.gpw') calc.restore_state() e_j = CoreEigenvalues(calc).get_core_eigenvalues(0) assert abs(e_j[0] - (-30.344066)) * 27.21 < 0.1 # Error smaller than 0.1 eV energy_tolerance = 0.0004 equal(e0, -0.0107707223, energy_tolerance)
from gpaw import GPAW from gpaw.eigensolvers.rmm_diis_old import RMM_DIIS from ase import Atoms from gpaw.test import equal atoms = Atoms("H") atoms.center(3.0) convergence = {"eigenstates": 1e-2, "density": 1e-2} # Keep htpsit calc = GPAW(nbands=2, eigensolver=RMM_DIIS(keep_htpsit=True), convergence=convergence, maxiter=20) atoms.set_calculator(calc) e0 = atoms.get_potential_energy() # Do not keep htpsit calc = GPAW(nbands=2, eigensolver=RMM_DIIS(keep_htpsit=False), convergence=convergence, maxiter=20) atoms.set_calculator(calc) e1 = atoms.get_potential_energy() equal(e0, e1, 1e-12)
from ase import Atoms, Atom from ase.io import write from ase.data.colors import jmol_colors a = 4.0614 b = a / sqrt(2) h = b / 2 atoms = Atoms('Al2', positions=[(0, 0, 0), (a / 2, b / 2, -h)], cell=(a, b, 2 * h), pbc=(1, 1, 0)) atoms *= (2, 2, 2) atoms.append(Atom('Al', (a / 2, b / 2, 3 * h))) atoms.center(vacuum=4., axis=2) atoms *= (2, 3, 1) atoms.cell /= [2, 3, 1] rotation = '-60x, 10y' radii = 1.2 # single float specifies a uniform scaling of the covalent radii colors = jmol_colors[atoms.numbers] colors[16::17] = [1, 0, 0] write('Al110slab.pov', atoms, rotation=rotation, colors=colors, radii=radii, show_unit_cell=2, canvas_width=500,
S. Suhai: *Electron correlation in extended systems: Fourth-order many-body perturbation theory and density-functional methods applied to an infinite chain of hydrogen atoms*, Phys. Rev. B 50, 14791-14801 (1994) """ import numpy as np from ase import Atoms from gpaw import GPAW, FermiDirac k = 8 a = 6.0 d0 = 1.0 h2 = Atoms('H2', cell=(2 * d0, a, a), pbc=True, positions=[(0, 0, 0), (d0 + 0.1, 0, 0)]) h2.center(axis=1) h2.center(axis=2) h2.calc = GPAW(kpts=(k, 1, 1), usesymm=False, occupations=FermiDirac(0.01), txt='h2c.txt') for d in np.linspace(0.0, 0.4, 21): h2[1].x = d0 + d e = h2.get_potential_energy() h2.calc.write('h2c-%.2f.gpw' % d)
from ase import Atoms, Atom import numpy as np from gpaw import GPAW, FermiDirac from gpaw.test import equal h=.4 q=3 spin=True s = Atoms([Atom('Fe')]) s.center(vacuum=2.5) convergence={'eigenstates':0.01, 'density':0.1, 'energy':0.1} # use Hunds rules c = GPAW(charge=q, h=h, nbands=5, hund=True, eigensolver='rmm-diis', occupations=FermiDirac(width=0.1), convergence=convergence ) c.calculate(s) equal(c.get_magnetic_moment(0), 5, 0.1) # set magnetic moment mm = [5] s.set_initial_magnetic_moments(mm) c = GPAW(charge=q, h=h, nbands=5, occupations=FermiDirac(width=0.1, fixmagmom=True),
import matplotlib.pyplot as plt from pyiid.experiments.elasticscatter.cpu_wrappers.nxn_cpu_wrap import wrap_fq from copy import deepcopy as dc from ase.visualize import view from itertools import product from scipy.signal import argrelmax from workflow_analysis.analysis.plot import plot_pdf, colors from pyiid.sim.dynamics import classical_dynamics from pyiid.calc.calc_1d import Calc1D from ase import Atoms def null_func(atoms): return np.zeros((len(atoms), 3)) atoms = Atoms(FaceCenteredCubic('Au', [[1, 0, 0], [1, 1, 0], [1, 1, 1]], (4, 6, 4))) atoms.center() s = ElasticScatter({'qmin': 3., 'rmax': 20.}) displacement = atoms.get_positions() - atoms.get_center_of_mass() distance = np.sqrt(np.sum(displacement**2, axis=1)) print(np.max(distance)) norm_displacement = (displacement.T / distance).T adp_tensor = norm_displacement * .01 print(np.max(adp_tensor)) adp_tensor_target = adp_tensor.copy() target_atoms = atoms.copy() target_adps = ADP(atoms, adps=adp_tensor_target)