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 ase_vol_relax(): Al = bulk('Al', 'fcc', a=4.5, cubic=True) calc = Vasp(xc='LDA') Al.set_calculator(calc) from ase.constraints import StrainFilter sf = StrainFilter(Al) qn = QuasiNewton(sf, logfile='relaxation.log') qn.run(fmax=0.1, steps=5) print('Stress:\n', calc.read_stress()) print('Al post ASE volume relaxation\n', calc.get_atoms().get_cell()) return Al
def __init__(self, restart=None, output_template='vasp', track_output=False, tempdir=None, **kwargs): self.force_no_calc = False self.vca = None self.tempdir = tempdir Vasp2.__init__(self, restart=None, **kwargs) self.commander = None self.command = None
def test_vasp_relax(): slab = create_slab_with_constraints() calc = Vasp(xc='LDA', isif=0, nsw=3, ibrion=1, ediffg=-1e-3, lwave=False, lcharg=False) calc.calculate(slab) init_slab = create_slab_with_constraints() res = read('OUTCAR') assert np.allclose(res.positions[0], init_slab.positions[0]) assert not np.allclose(res.positions[2], init_slab.positions[2])
def _relax_with_vasp(atoms, vasp_flags): ''' Perform a DFT relaxation with VASP and then write the trajectory to the 'all.traj' file and save the log file. Args: atoms `ase.Atoms` object of the structure we want to relax vasp_flags A dictionary of settings we want to pass to the `Vasp2` calculator Returns: atoms The relaxed `ase.Atoms` structure ''' # Run the calculation calc = Vasp2(**vasp_flags) atoms.set_calculator(calc) atoms.get_potential_energy() # Read the trajectory from the output file images = [] for atoms in ase.io.read('vasprun.xml', ':'): image = atoms.copy() image = image[calc.resort] image.set_calculator(SPC(image, energy=atoms.get_potential_energy(), forces=atoms.get_forces()[calc.resort])) images += [image] # Write the trajectory with TrajectoryWriter('all.traj', 'a') as tj: for atoms in images: tj.write(atoms) return images[-1]
def __get_final_atoms_object_with_vasp_forces(launch_id): ''' This function will return an ase.Atoms object from a particular FireWorks launch ID. It will also make sure that the ase.Atoms object will have VASP-calculated forces attached to it. Arg: launch_id An integer representing the FireWorks launch ID of the atoms object you want to get Returns: atoms ase.Atoms object with the VASP-calculated forces ''' # We will be opening a temporary directory where we will unzip the # FireWorks launch directory fw_launch_file = (read_rc('fireworks_info.backup_directory') + '/%d.tar.gz' % launch_id) temp_loc = __dump_file_to_tmp(fw_launch_file) # Load the atoms object and then load the correct (DFT) forces from the # OUTCAR/etc info try: atoms = ase.io.read('%s/slab_relaxed.traj' % temp_loc) vasp2 = Vasp2(atoms, restart=True, directory=temp_loc) vasp2.read_results() # Clean up behind us finally: subprocess.call('rm -r %s' % temp_loc, shell=True) return atoms
def set_calc(self, calc=None): if calc == None: print("Attaching standard calculator.") self.valet_system.system_init.set_calculator( Vasp2(xc='PBE', kpts=self.kpts, gamma=True, directory=self.valet_system.path_out)) else: print("Attaching custom calculator.") self.valet_system.system_init.set_calculator(calc)
def vasp_vol_relax(): Al = bulk('Al', 'fcc', a=4.5, cubic=True) calc = Vasp(xc='LDA', isif=7, nsw=5, ibrion=1, ediffg=-1e-3, lwave=False, lcharg=False) calc.calculate(Al) # Explicitly parse atomic position output file from Vasp CONTCAR_Al = io.read('CONTCAR', format='vasp') print('Stress after relaxation:\n', calc.read_stress()) print('Al cell post relaxation from calc:\n', calc.get_atoms().get_cell()) print('Al cell post relaxation from atoms:\n', Al.get_cell()) print('Al cell post relaxation from CONTCAR:\n', CONTCAR_Al.get_cell()) # All the cells should be the same. assert (calc.get_atoms().get_cell() == CONTCAR_Al.get_cell()).all() assert (Al.get_cell() == CONTCAR_Al.get_cell()).all() return Al
def do_encut_autotune(self, tol=1E-4, max_steps=32, start_encut=200, encut_step=25, retune=False): logging.info("Commencing ENCUT autotune.") if (self.encut == None) or (retune): sys = read(self.poscar_init) calc = Vasp2(xc='PBE', kpts=(4, 4, 4), directory=self.path_out) tol, stop, cnt, max_steps, ENCUT, ENCUT_step, ens = self.set_encut_autotune_params( tol=tol, max_steps=max_steps, start_encut=start_encut, encut_step=encut_step) print("Autotuning ENCUT...") while not stop: if 'error' in locals(): del error if cnt < max_steps: logging.debug("Count {}".format(cnt)) calc.set(encut=ENCUT) sys.set_calculator(calc) ens.append(sys.get_potential_energy()) stop = self.check_stop(ens, tol) ENCUT += ENCUT_step cnt += 1 else: logging.debug("Maximum autotune steps reached.") error = "Maximum autotune steps reached." tip = "Tip: Increase either start_encut, encut_step, or max_steps. Decrease tol." stop = True try: print(error) print(tip) self.encut = None except NameError: print("\tENCUT auto-tuned to: {}".format(ENCUT)) logging.info("Completed ENCUT autotune.") self.encut = ENCUT print("Done.") else: print( "ENCUT already autotuned. If you would like to retune, please pass 'retune' as True to 'self.do_encut_autotune'." ) logging.info("Already autotuned ENCUT.") self.clean_up()
def write_incar(self, atoms, directory='./', **kwargs): Vasp2.write_incar(self, atoms,directory=directory, **kwargs) incar = open(join(directory, 'INCAR'), 'a') vca_written=False if self.vca is not None and not vca_written: vcalist='' for symbol in self.symbol_count: vcalist+=' %.3f'%(self.vca.get(symbol[0], 1.0)) incar.write('VCA = %s\n'%(vcalist)) #if self.vca is not None and not vca_written: # print(self.vca) # vca=self.vca[self.sort] # list = [[1, vca[0]]] # for n in range(1, len(vca)): # if vca[n] == vca[n - 1]: # list[-1][0] += 1 # else: # list.append([1, vca[n]]) # incar.write(' vca= '.upper()) # [incar.write('%i*%.4f ' % (v[0], v[1])) for v in list] # incar.write('\n') incar.close()
def fix_cell_dependence(at=None): global calculator if at is None: calculator = default_calculator try: os.unlink(os.path.join(calculator.directory, "KPOINTS")) except: pass print("fix_cell_dependence() going back to default") else: bz_cell = at.get_reciprocal_cell() n_kpts = np.floor( np.linalg.norm(bz_cell, axis=1) * 2.0 * np.pi / kspacing_value).astype(int) + 1 print("fix_cell_dependence() got n_kpts", n_kpts, "from recip cell", bz_cell) calculator = Vasp2(kpts=n_kpts, gamma=True, **vasp_keywords)
def write_vasp_input_files(atoms, outdir='.', vasp_flags=None): ''' Effectively goes through the same motions as the `run_vasp` function, except it only writes the input files instead of running. Args: atoms `ase.Atoms` object that we want to relax. outdir A string indicating where you want to save the input files. Defaults to '.' vasp_flags A dictionary of settings we want to pass to the `Vasp2` calculator. Defaults to a standerd set of values if `None` ''' if vasp_flags is None: # Immutable default vasp_flags = VASP_FLAGS.copy() atoms, vasp_flags = _clean_up_inputs(atoms, vasp_flags) calc = Vasp2(directory=outdir, **vasp_flags) calc.write_input(atoms)
def _relax_with_ase(atoms, vasp_flags): ''' Instead of letting VASP handle the relaxation autonomously, we instead use VASP only as an eletronic structure calculator and use ASE's BFGS to perform the atomic position optimization. Note that this will also write the trajectory to the 'all.traj' file and save the log file as 'relax.log'. Args: atoms `ase.Atoms` object of the structure we want to relax vasp_flags A dictionary of settings we want to pass to the `Vasp2` calculator Returns: atoms The relaxed `ase.Atoms` structure ''' vasp_flags['ibrion'] = 2 vasp_flags['nsw'] = 0 calc = Vasp2(**vasp_flags) atoms.set_calculator(calc) optimizer = BFGS(atoms, logfile='relax.log', trajectory='all.traj') optimizer.run(fmax=vasp_flags['ediffg'] if 'ediffg' in vasp_flags else 0.05) return atoms
(1.853, 1.925) ] sizes = [[[2, 0, 0], [0, 2, 0], [0, 0, 1]], [[2, 0, 0], [0, 2, 0], [0, 0, 1]], [[2, 0, 0], [0, 1, 0], [0, 0, 1]], [[2, 0, 0], [0, 1, 0], [0, 0, 1]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]], [[1, 0, 0], [0, 1, 0], [0, 0, 1]]] kpts = [[7, 7, 1], [7, 7, 1], [7, 13, 1], [7, 13, 1], [13, 13, 1], [13, 13, 1], [9, 9, 1], [9, 9, 1]] slabs = [] calc_template = Vasp2(encut=400, ismear=2, sigma=0.2, gga='PE', xc='PBE', ibrion=1, algo='FAST', potim=0.5, nsw=200, ediff=1E-6, ediffg=-2E-2, lreal='AUTO', kpts=[7, 7, 1]) # write input files for idx, mod in enumerate(modifiers): calc = copy.deepcopy(calc_template) workdir = mod + '/' calc.set_label(workdir) calc.set(kpts=kpts[idx]) slab = slabgen(terminations[idx], sizes[idx], mod, positions[idx]) slab.set_calculator(calc)
def test_vasp2_wdir(require_vasp): """ Run tests to ensure that the VASP txt and label arguments function correctly, i.e. correctly sets the working directories and works in that directory. This is conditional on the existence of the ASE_VASP_COMMAND, VASP_COMMAND or VASP_SCRIPT environment variables """ import filecmp import os from ase.test.calculator.vasp import installed2 as installed from ase import Atoms from ase.calculators.vasp import Vasp2 as Vasp assert installed() def compare_paths(path1, path2): assert os.path.abspath(path1) == os.path.abspath(path2) # Test setup system, borrowed from vasp_co.py d = 1.14 atoms = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True) atoms.center(vacuum=5.) file1 = '_vasp_dummy_str.out' file2 = '_vasp_dummy_io.out' file3 = '_vasp_dummy_2.out' testdir = '_dummy_txt_testdir' label = os.path.join(testdir, 'vasp') # Test settings = dict(label=label, xc='PBE', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False) # Make 2 copies of the calculator object calc = Vasp(**settings) calc2 = Vasp(**settings) # Check the calculator path is the expected path compare_paths(calc.directory, testdir) calc.set(txt=file1) atoms.calc = calc en1 = atoms.get_potential_energy() # Check that the output files are in the correct directory for fi in ['OUTCAR', 'CONTCAR', 'vasprun.xml']: fi = os.path.join(testdir, fi) assert os.path.isfile(fi) # We open file2 in our current directory, so we don't want it to write # in the label directory with open(file2, 'w') as f: calc2.set(txt=f) atoms.calc = calc2 atoms.get_potential_energy() # Make sure the two outputfiles are identical assert filecmp.cmp(os.path.join(calc.directory, file1), file2) # Test restarting from working directory in test directory label2 = os.path.join(testdir, file3) calc2 = Vasp(restart=label, label=label2) # Check the calculator path is the expected path compare_paths(calc2.directory, testdir) assert not calc2.calculation_required(calc2.atoms, ['energy', 'forces']) en2 = calc2.get_potential_energy() # Check that the restarted calculation didn't run, i.e. write to output file assert not os.path.isfile(os.path.join(calc.directory, file3)) # Check that we loaded energy correctly assert en1 == en2
def runVasp(fname_in, fname_out, vaspflags, npar=4): ''' This function is meant to be sent to each cluster and then used to run our rockets. As such, it has algorithms to run differently depending on the cluster that is trying to use this function. Inputs: fname_in fname_out vaspflags npar ''' fname_in = str(fname_in) fname_out = str(fname_out) # read the input atoms object atoms = read(str(fname_in)) # Check that the unit vectors obey the right-hand rule, (X x Y points in Z) and if not # Flip the order of X and Y to enforce this so that VASP is happy. if np.dot(np.cross(atoms.cell[0], atoms.cell[1]), atoms.cell[2]) < 0: atoms.set_cell(atoms.cell[[1, 0, 2], :]) # If we're on UON rcg NPROCS = int(os.environ['NCPUS']) queue = os.environ['PBS_QUEUE'] vaspflags['npar'] = 4 if 'xeon5' in str(queue): vasp_cmd = 'vasp_std' else: vasp_cmd = '/home/ajp/bin/vasp_std_5.4.intelmpi' mpicall = lambda x, y: 'mpirun -np %i %s' % (x, y) # noqa: E731 # Set the pseudopotential type by setting 'xc' in Vasp() if vaspflags['pp'].lower() == 'lda': vaspflags['xc'] = 'lda' elif vaspflags['pp'].lower() == 'pbe': vaspflags['xc'] = 'PBE' # pseudopotential = vaspflags['pp_version'] # s.environ['VASP_PP_PATH'] = os.environ['VASP_PP_BASE'] + '/' + str(pseudopotential) + '/' del vaspflags['pp_version'] os.environ['VASP_COMMAND'] = mpicall(NPROCS, vasp_cmd) # Detect whether or not there are constraints that cannot be handled by VASP allowable_constraints = ['FixAtoms'] constraint_not_allowable = [ constraint.todict()['name'] not in allowable_constraints for constraint in atoms.constraints ] vasp_incompatible_constraints = np.any(constraint_not_allowable) # If there are incompatible constraints, we need to switch to an ASE-based optimizer if vasp_incompatible_constraints: vaspflags['ibrion'] = 2 vaspflags['nsw'] = 0 calc = Vasp2(**vaspflags) atoms.set_calculator(calc) qn = BFGS(atoms, logfile='relax.log', trajectory='all.traj') qn.run(fmax=vaspflags['ediffg'] if 'ediffg' in vaspflags else 0.05) finalimage = atoms else: # set up the calculation and run calc = Vasp2(**vaspflags) atoms.set_calculator(calc) # Trigger the calculation atoms.get_potential_energy() atomslist = [] for atoms in read('vasprun.xml', ':'): catoms = atoms.copy() catoms = catoms[calc.resort] catoms.set_calculator( SPC(catoms, energy=atoms.get_potential_energy(), forces=atoms.get_forces()[calc.resort])) atomslist += [catoms] # Get the final trajectory finalimage = atoms # Write a traj file for the optimization tj = TrajectoryWriter('all.traj', 'a') for atoms in atomslist: print('writing trajectory file!') print(atoms) tj.write(atoms) tj.close() # Write the final structure finalimage.write(fname_out) # Write a text file with the energy with open('energy.out', 'w') as fhandle: fhandle.write(str(finalimage.get_potential_energy())) try: os.remove('CHGCAR') except OSError: pass try: os.remove('WAVECAR') except OSError: pass try: os.remove('CHG') except OSError: pass return str(atoms), open( 'all.traj', 'rb').read().hex(), finalimage.get_potential_energy()
testdir = '_dummy_txt_testdir' label = os.path.join(testdir, 'vasp') # Test settings = dict(label=label, xc='PBE', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False) # Make 2 copies of the calculator object calc = Vasp(**settings) calc2 = Vasp(**settings) # Check the calculator path is the expected path compare_paths(calc.directory, testdir) calc.set_txt(file1) atoms.set_calculator(calc) en1 = atoms.get_potential_energy() # Check that the output files are in the correct directory for fi in ['OUTCAR', 'CONTCAR', 'vasprun.xml']: fi = os.path.join(testdir, fi) assert os.path.isfile(fi) # We open file2 in our current directory, so we don't want it to write
d = 1.14 atoms = Atoms('CO', positions=[(0, 0, 0), (0, 0, d)], pbc=True) atoms.center(vacuum=5.) # Test settings = dict(xc='PBE', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False) calc = Vasp(**settings) atoms.set_calculator(calc) en1 = atoms.get_potential_energy() # Make a parameter change to the calculator calc.set(sigma=0.5) # Check that we capture a change for float params assert calc.check_state(atoms) == ['float_params'] assert calc.calculation_required(atoms, ['energy', 'forces']) en2 = atoms.get_potential_energy() # The change in sigma should result in a small change in energy
def test_vasp2_kpoints(require_vasp): """ Check the many ways of specifying KPOINTS """ import os from ase.calculators.vasp import Vasp2 as Vasp from ase.build import bulk from ase.test.calculator.vasp import installed2 as installed assert installed() Al = bulk('Al', 'fcc', a=4.5, cubic=True) def check_kpoints_line(n, contents): """Assert the contents of a line""" with open('KPOINTS', 'r') as f: lines = f.readlines() assert lines[n] == contents # Default to (1 1 1) calc = Vasp(gamma=True) calc.write_kpoints() check_kpoints_line(2, 'Gamma\n') check_kpoints_line(3, '1 1 1 \n') calc.clean() # 3-tuple prints mesh calc = Vasp(gamma=False, kpts=(4, 4, 4)) calc.write_kpoints() check_kpoints_line(2, 'Monkhorst-Pack\n') check_kpoints_line(3, '4 4 4 \n') calc.clean() # Auto mode calc = Vasp(kpts=20) calc.write_kpoints() check_kpoints_line(1, '0\n') check_kpoints_line(2, 'Auto\n') check_kpoints_line(3, '20 \n') calc.clean() # 1-element list ok, Gamma ok calc = Vasp(kpts=[20], gamma=True) calc.write_kpoints() check_kpoints_line(1, '0\n') check_kpoints_line(2, 'Auto\n') check_kpoints_line(3, '20 \n') calc.clean() # KSPACING suppresses KPOINTS file calc = Vasp(kspacing=0.23) calc.initialize(Al) calc.write_kpoints() calc.write_incar(Al) assert not os.path.isfile('KPOINTS') with open('INCAR', 'r') as f: assert ' KSPACING = 0.230000\n' in f.readlines() calc.clean() # Negative KSPACING raises an error calc = Vasp(kspacing=-0.5) try: calc.write_kpoints() except ValueError: pass else: raise AssertionError("Negative KSPACING did not raise ValueError") calc.clean() # Explicit weighted points with nested lists, Cartesian if not specified calc = Vasp( kpts=[[0.1, 0.2, 0.3, 2], [0.0, 0.0, 0.0, 1], [0.0, 0.5, 0.5, 2]]) calc.write_kpoints() with open('KPOINTS.ref', 'w') as f: f.write("""KPOINTS created by Atomic Simulation Environment 3 Cartesian 0.100000 0.200000 0.300000 2.000000 0.000000 0.000000 0.000000 1.000000 0.000000 0.500000 0.500000 2.000000 """) assert filecmp_ignore_whitespace('KPOINTS', 'KPOINTS.ref') os.remove('KPOINTS.ref') # Explicit points as list of tuples, automatic weighting = 1. calc = Vasp( kpts=[(0.1, 0.2, 0.3), (0.0, 0.0, 0.0), (0.0, 0.5, 0.5)], reciprocal=True) calc.write_kpoints() with open('KPOINTS.ref', 'w') as f: f.write("""KPOINTS created by Atomic Simulation Environment 3 Reciprocal 0.100000 0.200000 0.300000 1.0 0.000000 0.000000 0.000000 1.0 0.000000 0.500000 0.500000 1.0 """) assert filecmp_ignore_whitespace('KPOINTS', 'KPOINTS.ref') os.remove('KPOINTS.ref')
def test_vasp2_check_state(): """ Run tests to ensure that the VASP check_state() function call works correctly, i.e. correctly sets the working directories and works in that directory. This is conditional on the existence of the VASP_COMMAND or VASP_SCRIPT environment variables """ from ase.test.vasp import installed2 as installed import os from ase import Atoms from ase.calculators.vasp import Vasp2 as Vasp assert installed() # Test setup system, borrowed from vasp_co.py 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.) # Test settings = dict(xc='LDA', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False) s1 = atoms.get_chemical_symbols() calc = Vasp(**settings) atoms.set_calculator(calc) en1 = atoms.get_potential_energy() # Test JSON dumping and restarting works fi = 'json_test.json' calc.write_json(filename=fi) assert os.path.isfile(fi) calc2 = Vasp() calc2.read_json(fi) assert not calc2.calculation_required(atoms, ['energy', 'forces']) en2 = calc2.get_potential_energy() assert abs(en1 - en2) < 1e-8 os.remove(fi) # Clean up the JSON file # Check that the symbols remain in order (non-sorted) s2 = calc.atoms.get_chemical_symbols() assert s1 == s2 s3 = sorted(s2) assert s2 != s3 # Check that get_atoms() doesn't reset results r1 = dict(calc.results) # Force a copy calc.get_atoms() r2 = dict(calc.results) assert r1 == r2 # Make a parameter change to the calculator calc.set(sigma=0.5) # Check that we capture a change for float params assert calc.check_state(atoms) == ['float_params'] assert calc.calculation_required(atoms, ['energy', 'forces']) en2 = atoms.get_potential_energy() # The change in sigma should result in a small change in energy assert (en1 - en2) > 1e-7 # Now we make a change in input_params instead calc.kpts = 2 # Check that this requires a new calculation assert calc.check_state(atoms) == ['input_params'] assert calc.calculation_required(atoms, ['energy', 'forces']) # Clean up calc.clean()
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()
from ase.build import bulk from ase.calculators.vasp import Vasp2 import os print('=' * 72, '\n', '--> Band structure\n', '=' * 72) os.system('cp -r scf bs') calc = Vasp2(system='SrVO3', command='mpirun vasp_std', pp='PBE', setups={ 'Sr': '_sv_GW', 'V': '_sv_GW', 'O': '_GW' }, isym=0, icharg=11, kpts=dict(path='GXMGRX', npoints=200), restart=True, directory='bs', txt=False) calc.get_potential_energy()
end projections """ with open('./crpa/wannier90.win', 'w') as fd: fd.write(wannier90_win) calc = Vasp2( pp='PBE', setups={ 'Sr': '_sv_GW', 'V': '_sv_GW', 'O': '_GW' }, command='mpirun vasp_std', restart=True, algo='CRPA', ncshmem=1, precfock='Fast', ntarget_states=[1, 2, 3], lwrite_wanproj=True, lcrpaqout=True, loptics=None, nelm=None, #kpar = None, directory='crpa', txt=False) try: calc.calculate(calc.atoms) except: print('--> No energy from cRPA')
list_ads = next_ads(bare[-1], [1, 1], primitive[-1].get_cell(), coordinates[-1]) Cu_N_ads.update({term: {'1N': list_ads}}) print("Termination (" + term + ") 1N Adsorption: %d structures" % len(Cu_N_ads[term]['1N'])) # Data structure # Cu_N_ads = {'111' : {'1N' : [s1, s2, s3, ...]}} calc_template = Vasp2(encut=400, ismear=2, sigma=0.2, gga='PE', xc='PBE', algo='FAST', ispin=2, ediff=1E-6, ediffg=-2E-2, ibrion=1, nsw=200, lreal='AUTO', kpts=[5, 5, 1]) for termination, value_1 in Cu_N_ads.items(): for num_ads, value_2 in value_1.items(): t = 0 for i, slab in enumerate(value_2): label = 'Cu_N_ads/' + termination + '/' + num_ads + '/t' + str( t) + '/' calc = copy.deepcopy(calc_template) calc.set_label(label)
atoms.center(vacuum=5.) # Test settings = dict(xc='LDA', prec='Low', algo='Fast', ismear=0, sigma=1., istart=0, lwave=False, lcharg=False) s1 = atoms.get_chemical_symbols() calc = Vasp(**settings) atoms.set_calculator(calc) en1 = atoms.get_potential_energy() # Test JSON dumping and restarting works fi = 'json_test.json' calc.write_json(filename=fi) assert os.path.isfile(fi) calc2 = Vasp() calc2.read_json(fi) assert not calc2.calculation_required(atoms, ['energy', 'forces']) en2 = calc2.get_potential_energy()
def runVasp(fname_in, fname_out, vaspflags, npar=4): ''' This function is meant to be sent to each cluster and then used to run our rockets. As such, it has algorithms to run differently depending on the cluster that is trying to use this function. Inputs: fname_in fname_out vaspflags npar ''' fname_in = str(fname_in) fname_out = str(fname_out) # read the input atoms object atoms = read(str(fname_in)) # Check that the unit vectors obey the right-hand rule, (X x Y points in Z) and if not # Flip the order of X and Y to enforce this so that VASP is happy. if np.dot(np.cross(atoms.cell[0], atoms.cell[1]), atoms.cell[2]) < 0: atoms.set_cell(atoms.cell[[1, 0, 2], :]) vasp_cmd = 'vasp_std' os.environ['PBS_SERVER'] = 'gilgamesh.cheme.cmu.edu' if 'PBS_NODEFILE' in os.environ: NPROCS = NPROCS = len(open(os.environ['PBS_NODEFILE']).readlines()) elif 'SLURM_CLUSTER_NAME' in os.environ: if 'SLURM_NPROCS' in os.environ: # We're on cori haswell NPROCS = int(os.environ['SLURM_NPROCS']) else: # we're on cori KNL, just one processor NPROCS = 1 # If we're on Gilgamesh... if 'PBS_NODEFILE' in os.environ and os.environ['PBS_SERVER'] == 'gilgamesh.cheme.cmu.edu': vaspflags['npar'] = 4 vasp_cmd = '/home-research/zhongnanxu/opt/vasp-5.3.5/bin/vasp-vtst-beef-parallel' NPROCS = NPROCS = len(open(os.environ['PBS_NODEFILE']).readlines()) mpicall = lambda x, y: 'mpirun -np %i %s' % (x, y) # noqa: E731 # If we're on Arjuna... elif 'SLURM_CLUSTER_NAME' in os.environ and os.environ['SLURM_CLUSTER_NAME'] == 'arjuna': # If this is a GPU job... if os.environ['CUDA_VISIBLE_DEVICES'] != 'NoDevFiles': vaspflags['ncore'] = 1 vaspflags['kpar'] = 16 vaspflags['nsim'] = 8 vaspflags['lreal'] = 'Auto' vasp_cmd = 'vasp_gpu' mpicall = lambda x, y: 'mpirun -np %i %s' % (x, y) # noqa: E731 # If this is a CPU job... else: if NPROCS > 16: vaspflags['ncore'] = 4 vaspflags['kpar'] = 4 else: vaspflags['kpar'] = 1 vaspflags['ncore'] = 4 mpicall = lambda x, y: 'mpirun -np %i %s' % (x, y) # noqa: E731 # If we're on Cori, use SLURM. Note that we decrease the priority by 1000 # in order to prioritize other things higher, such as modeling and prediction # in GASpy_regression elif 'SLURM_CLUSTER_NAME' in os.environ and os.environ['SLURM_CLUSTER_NAME'] == 'cori': # If we're on a Haswell node... if os.environ['CRAY_CPU_TARGET'] == 'haswell' and 'knl' not in os.environ['PATH']: NNODES = int(os.environ['SLURM_NNODES']) vaspflags['kpar'] = NNODES mpicall = lambda x, y: 'srun -n %d %s' % (x, y) # noqa: E731 # If we're on a KNL node... elif 'knl' in os.environ['PATH']: mpicall = lambda x, y: 'srun -n %d -c8 --cpu_bind=cores %s' % (x*32, y) # noqa: E731 vaspflags['ncore'] = 1 # Set the pseudopotential type by setting 'xc' in Vasp() if vaspflags['pp'].lower() == 'lda': vaspflags['xc'] = 'lda' elif vaspflags['pp'].lower() == 'pbe': vaspflags['xc'] = 'PBE' pseudopotential = vaspflags['pp_version'] os.environ['VASP_PP_PATH'] = os.environ['VASP_PP_BASE'] + '/' + str(pseudopotential) + '/' del vaspflags['pp_version'] os.environ['VASP_COMMAND'] = mpicall(NPROCS, vasp_cmd) # Detect whether or not there are constraints that cannot be handled by VASP allowable_constraints = ['FixAtoms'] constraint_not_allowable = [constraint.todict()['name'] not in allowable_constraints for constraint in atoms.constraints] vasp_incompatible_constraints = np.any(constraint_not_allowable) # If there are incompatible constraints, we need to switch to an ASE-based optimizer if vasp_incompatible_constraints: vaspflags['ibrion'] = 2 vaspflags['nsw'] = 0 calc = Vasp2(**vaspflags) atoms.set_calculator(calc) qn = BFGS(atoms, logfile='relax.log', trajectory='all.traj') qn.run(fmax=vaspflags['ediffg'] if 'ediffg' in vaspflags else 0.05) finalimage = atoms else: # set up the calculation and run calc = Vasp2(**vaspflags) atoms.set_calculator(calc) # Trigger the calculation atoms.get_potential_energy() atomslist = [] for atoms in read('vasprun.xml', ':'): catoms = atoms.copy() catoms = catoms[calc.resort] catoms.set_calculator(SPC(catoms, energy=atoms.get_potential_energy(), forces=atoms.get_forces()[calc.resort])) atomslist += [catoms] # Get the final trajectory finalimage = atoms # Write a traj file for the optimization tj = TrajectoryWriter('all.traj', 'a') for atoms in atomslist: print('writing trajectory file!') print(atoms) tj.write(atoms) tj.close() # Write the final structure finalimage.write(fname_out) # Write a text file with the energy with open('energy.out', 'w') as fhandle: fhandle.write(str(finalimage.get_potential_energy())) try: os.remove('CHGCAR') except OSError: pass try: os.remove('WAVECAR') except OSError: pass try: os.remove('CHG') except OSError: pass return str(atoms), open('all.traj', 'r').read().encode('hex'), finalimage.get_potential_energy()
def __init__(self, POSCAR_init=None, path_out=None, kpts=None, calculators=None): # Initial structure handling if POSCAR_init == None: print("Please provide an initial structure file.") exit() elif os.path.isfile(POSCAR_init): self.poscar_init = POSCAR_init self.system = read(self.poscar_init) else: logging.error( "Cannot locate POSCAR file as {}".format(POSCAR_init)) self.error_read_log() exit() # Setting up some paths if path_out == None: print("Please enter a valid out directory.") exit() else: self.path_out = os.path.join("valet_workspace", path_out) self.path_log = os.path.join(self.path_out, "log") self.poscar_vol = os.path.join(self.path_out, "POSCAR_vol") # Check if user supplied kpoints if kpts != None: self.kpts = kpts else: self.kpts = [4, 4, 4] # Check if user supplied calculators self.calc_dict = { 'encut': Vasp2(xc="PBE", kpts=self.kpts, gamma=True, directory=self.path_out, setups="recommended"), 'volume': Vasp2(xc="PBE", kpts=self.kpts, gamma=True, directory=self.path_out, setups="recommended") } # 'encut':Vasp2(xc='PBE',kpts=self.kpts,gamma=True,directory=self.path_out), # 'volume':Vasp2(xc='PBE',prec='Acc', # First relaxation for curve # algo='Fast', # icharg=0, # Calc charge from initial wavefunction # nelm=100, # Max electronc SC steps # ibrion=2, # Conj. grad. ionic relax # ediff=1E-4,#0.00005*len(self.system), # nsw=100, # Max number ionic steps # isif=4, # Position,shape change. Not volume # lreal='Auto', # ismear=-5, # Tetrahedon method; requires gamma-centered # sigma=0.05, # lwave=False, # No wavecar # lorbit=11, # DOS car and lm-decomposed PROCAR, # kpts=self.kpts, gamma=True,directory=self.path_out) # # } #'volume':Vasp2(xc='PBE',kpts=self.kpts,gamma=True,directory=self.path_out)} if calculators != None: print("Attaching your calculators.") if type(calculators) != type({}): logging.error( "Calculators should be provided in dictionary form. The relevant keys are 'encut', \ 'volume', ....more to come.") self.error_read_log() exit() else: for key in calculators.keys(): self.calc_dict[key] = calculators[key] self.calc_dict[key].set( directory=self.path_out ) # Make sure output path is correct else: print("Loading default calculators.") # Initialize the rest of the attributes self.encut = None self.band_structure = None self.band_gap = None # Make output directory if not os.path.isdir(self.path_log): os.system("mkdir -p {}/".format(self.path_log)) # Start log logging.basicConfig(format='%(asctime)s : %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p', filename=os.path.join(self.path_log, "valet.log"), filemode="w", level=logging.INFO)
filename = 'clus_Cu4' #For saving the best cluster at every generation log_file = 'clus_Cu4.log' singleTypeCluster = False #calc = EMT() calc = Vasp2( kpar=1, ncore=4, encut=400, xc='PBE', #gga='PS', kpts=(1, 1, 1), gamma=True, # Gamma-centered ismear=1, sigma=0.2, ibrion=2, nsw=1000, #lorbit=11, potim=0.2, isif=0, #ediffg=-0.02, #ediff=1e-6, lcharg=False, lwave=False, lreal=False, ispin=2, isym=0) # Run between 0 and 4 1-core/1-gpu workers on the kube cluster cluster = KubeCluster.from_yaml('worker-cpu-spec.yml') client = Client(cluster) #cluster.adapt(minimum=0, maximum=10)
import pickle as pkl from ase.calculators.vasp import Vasp2 import ase from quantum_valet.valet import AutotuneBandgap import numpy as np bench_set = pkl.load(open('bench_set/pickles/bs_part_0.pkl','rb')) key = 'mp-1' bs = bench_set[key] sys = bs['structure_initial'] setup = bs['potcar'] calc = Vasp2() calc.read_incar('../calculators/INCAR.volume_scan') calc.set(xc='pbe',setups=setup,kpts=[5.,5.,5.],gamma=True) sys.set_calculator(calc) valet = AutotuneBandgap(sys,calc,key) try: valet.do_autotune_volume() error_volume = False except: error_volume = True try: valet.get_bandgap() error_bandgap = False except: error_bandgap = True if (not error_volume) and (not error_bandgap):
os.unlink(os.path.join(directory, "WAVECAR")) sys.stderr.write("wiped {}\n".format(os.path.join( directory, "WAVECAR"))) except FileNotFoundError: pass try: os.unlink(os.path.join(directory, "CHGCAR")) sys.stderr.write("wiped {}\n".format(os.path.join(directory, "CHGCAR"))) except FileNotFoundError: pass # default calculator to kspacing_value, gamma-centered default_calculator = Vasp2(kspacing=kspacing_value, kgamma=True, **vasp_keywords) calculator = default_calculator # wipe KPOINTS in case running in old dir and first run might be KSPACING based try: os.unlink(os.path.join(calculator.directory, "KPOINTS")) except FileNotFoundError: pass wipe_restart(calculator.directory) # monkey patch Vasp2.set_atoms to wipe restart files if major changes found def vasp2_set_atoms(self, atoms): sys.stderr.write("monkey-patched set_atoms checking\n") if hasattr(self, "atoms") and atoms != self.atoms: