def relax(dim=2, submit=True, force_overwrite=False): """ Writes input files and (optionally) submits a self-consistent relaxation. Should be run before pretty much anything else, in order to get the right energy and structure of the material. Args: dim (int): 2 for relaxing a 2D material, 3 for a 3D material. submit (bool): Whether or not to submit the job. force_overwrite (bool): Whether or not to overwrite files if an already converged vasprun.xml exists in the directory. """ if force_overwrite or not utl.is_converged(os.getcwd()): directory = os.getcwd().split('/')[-1] # vdw_kernel.bindat file required for VDW calculations. if VDW_KERNEL: os.system('cp {} .'.format(VDW_KERNEL)) # KPOINTS Kpoints.automatic_density(Structure.from_file('POSCAR'), 1000).write_file('KPOINTS') # INCAR INCAR_DICT.update( {'MAGMOM': utl.get_magmom_string(Structure.from_file('POSCAR'))} ) Incar.from_dict(INCAR_DICT).write_file('INCAR') # POTCAR utl.write_potcar() # Special tasks only performed for 2D materials. if dim == 2: # Ensure 20A interlayer vacuum utl.ensure_vacuum(Structure.from_file('POSCAR'), 20) # Remove all z k-points. kpts_lines = open('KPOINTS').readlines() with open('KPOINTS', 'w') as kpts: for line in kpts_lines[:3]: kpts.write(line) kpts.write(kpts_lines[3].split()[0] + ' ' + kpts_lines[3].split()[1] + ' 1') # Submission script if dim == 2: binary = VASP_TWOD_BIN elif dim == 3: binary = VASP_STD_BIN if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob(directory, 1, 16, '800mb', '6:00:00', binary) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob(directory, 16, '800mb', '6:00:00', binary) submission_command = 'sbatch runjob' if submit: os.system(submission_command)
def relax(dim=2, submit=True, force_overwrite=False): """ Writes input files and (optionally) submits a self-consistent relaxation. Should be run before pretty much anything else, in order to get the right energy and structure of the material. Args: dim (int): 2 for relaxing a 2D material, 3 for a 3D material. submit (bool): Whether or not to submit the job. force_overwrite (bool): Whether or not to overwrite files if an already converged vasprun.xml exists in the directory. """ if force_overwrite or not utl.is_converged(os.getcwd()): directory = os.getcwd().split('/')[-1] # vdw_kernel.bindat file required for VDW calculations. if VDW_KERNEL: os.system('cp {} .'.format(VDW_KERNEL)) # KPOINTS Kpoints.automatic_density(Structure.from_file('POSCAR'), 1000).write_file('KPOINTS') # INCAR INCAR_DICT.update( {'MAGMOM': utl.get_magmom_string(Structure.from_file('POSCAR'))}) Incar.from_dict(INCAR_DICT).write_file('INCAR') # POTCAR utl.write_potcar() # Special tasks only performed for 2D materials. if dim == 2: # Ensure 20A interlayer vacuum utl.ensure_vacuum(Structure.from_file('POSCAR'), 20) # Remove all z k-points. kpts_lines = open('KPOINTS').readlines() with open('KPOINTS', 'w') as kpts: for line in kpts_lines[:3]: kpts.write(line) kpts.write(kpts_lines[3].split()[0] + ' ' + kpts_lines[3].split()[1] + ' 1') # Submission script if dim == 2: binary = VASP_TWOD_BIN elif dim == 3: binary = VASP_STD_BIN if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob(directory, 1, 16, '800mb', '6:00:00', binary) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob(directory, 16, '800mb', '6:00:00', binary) submission_command = 'sbatch runjob' if submit: os.system(submission_command)
def run_hse_prep_calculation(dim=2, submit=True): """ Submits a quick static calculation to calculate the IBZKPT file using a smaller number of k-points (200/atom instead of 1000/atom). The other outputs from this calculation are essentially useless. Args: dim (int): 2 for relaxing a 2D material, 3 for a 3D material. submit (bool): Whether or not to submit the job. """ if not os.path.isdir('hse_prep'): os.mkdir('hse_prep') os.chdir('hse_prep') shutil.copy('../CONTCAR', 'POSCAR') if os.path.isfile('../POTCAR'): shutil.copy('POTCAR', '.') relax(dim=2, submit=False) incar_dict = Incar.from_file('INCAR').as_dict() incar_dict.update({ 'NSW': 0, 'NELM': 1, 'LWAVE': False, 'LCHARG': False, 'LAECHG': False }) Incar.from_dict(incar_dict).write_file('INCAR') Kpoints.automatic_density(Structure.from_file('POSCAR'), 200).write_file('KPOINTS') if dim == 2: kpts_lines = open('KPOINTS').readlines() with open('KPOINTS', 'w') as kpts: for line in kpts_lines[:3]: kpts.write(line) kpts.write(kpts_lines[3].split()[0] + ' ' + kpts_lines[3].split()[1] + ' 1') if QUEUE_SYSTEM == 'pbs': write_pbs_runjob('{}_prep'.format(os.getcwd().split('/')[-2]), 1, 16, '800mb', '6:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': write_slurm_runjob('{}_prep'.format(os.getcwd().split('/')[-2]), 16, '800mb', '6:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: _ = subprocess.check_output(submission_command.split()) os.chdir('../')
def run_pbe_calculation(dim=2, submit=True, force_overwrite=False): """ Setup and submit a normal PBE calculation for band structure along high symmetry k-paths. Args: dim (int): 2 for relaxing a 2D material, 3 for a 3D material. submit (bool): Whether or not to submit the job. force_overwrite (bool): Whether or not to overwrite files if an already converged vasprun.xml exists in the directory. """ PBE_INCAR_DICT = { 'EDIFF': 1e-6, 'IBRION': 2, 'ISIF': 3, 'ISMEAR': 1, 'NSW': 0, 'LVTOT': True, 'LVHAR': True, 'LORBIT': 1, 'LREAL': 'Auto', 'NPAR': 4, 'PREC': 'Accurate', 'LWAVE': True, 'SIGMA': 0.1, 'ENCUT': 500, 'ISPIN': 2 } directory = os.path.basename(os.getcwd()) if not os.path.isdir('pbe_bands'): os.mkdir('pbe_bands') if force_overwrite or not is_converged('pbe_bands'): shutil.copy("CONTCAR", "pbe_bands/POSCAR") if os.path.isfile('POTCAR'): shutil.copy("POTCAR", "pbe_bands") PBE_INCAR_DICT.update( {'MAGMOM': get_magmom_string(Structure.from_file('POSCAR'))}) Incar.from_dict(PBE_INCAR_DICT).write_file('pbe_bands/INCAR') structure = Structure.from_file('POSCAR') kpath = HighSymmKpath(structure) Kpoints.automatic_linemode(20, kpath).write_file('pbe_bands/KPOINTS') os.chdir('pbe_bands') if dim == 2: remove_z_kpoints() if QUEUE_SYSTEM == 'pbs': write_pbs_runjob(directory, 1, 16, '800mb', '6:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': write_slurm_runjob(directory, 16, '800mb', '6:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: _ = subprocess.check_output(submission_command.split()) os.chdir('../')
def run_hse_calculation(dim=2, submit=True, force_overwrite=False, destroy_prep_directory=False): """ Setup/submit an HSE06 calculation to get an accurate band structure. Requires a previous IBZKPT from a standard DFT run. See http://cms.mpi.univie.ac.at/wiki/index.php/Si_bandstructure for more details. Args: dim (int): 2 for relaxing a 2D material, 3 for a 3D material. submit (bool): Whether or not to submit the job. force_overwrite (bool): Whether or not to overwrite files if an already converged vasprun.xml exists in the directory. destroy_prep_directory (bool): whether or not to remove (rm -r) the hse_prep directory, if it exists. This can help to automatically clean up and save space. """ HSE_INCAR_DICT = { 'LHFCALC': True, 'HFSCREEN': 0.2, 'AEXX': 0.25, 'ALGO': 'D', 'TIME': 0.4, 'NSW': 0, 'LVTOT': True, 'LVHAR': True, 'LORBIT': 11, 'LWAVE': True, 'NPAR': 8, 'PREC': 'Accurate', 'EDIFF': 1e-4, 'ENCUT': 450, 'ICHARG': 2, 'ISMEAR': 1, 'SIGMA': 0.1, 'IBRION': 2, 'ISIF': 3, 'ISPIN': 2 } if not os.path.isdir('hse_bands'): os.mkdir('hse_bands') if force_overwrite or not is_converged('hse_bands'): os.chdir('hse_bands') os.system('cp ../CONTCAR ./POSCAR') if os.path.isfile('../POTCAR'): os.system('cp ../POTCAR .') HSE_INCAR_DICT.update( {'MAGMOM': get_magmom_string(Structure.from_file('POSCAR'))}) Incar.from_dict(HSE_INCAR_DICT).write_file('INCAR') # Re-use the irreducible brillouin zone KPOINTS from a # previous standard DFT run. if os.path.isdir('../hse_prep'): ibz_lines = open('../hse_prep/IBZKPT').readlines() if destroy_prep_directory: os.system('rm -r ../hse_prep') else: ibz_lines = open('../IBZKPT').readlines() n_ibz_kpts = int(ibz_lines[1].split()[0]) kpath = HighSymmKpath(Structure.from_file('POSCAR')) Kpoints.automatic_linemode(20, kpath).write_file('KPOINTS') if dim == 2: remove_z_kpoints() linemode_lines = open('KPOINTS').readlines() abs_path = [] i = 4 while i < len(linemode_lines): start_kpt = linemode_lines[i].split() end_kpt = linemode_lines[i + 1].split() increments = [(float(end_kpt[0]) - float(start_kpt[0])) / 20, (float(end_kpt[1]) - float(start_kpt[1])) / 20, (float(end_kpt[2]) - float(start_kpt[2])) / 20] abs_path.append(start_kpt[:3] + ['0', start_kpt[4]]) for n in range(1, 20): abs_path.append([ str(float(start_kpt[0]) + increments[0] * n), str(float(start_kpt[1]) + increments[1] * n), str(float(start_kpt[2]) + increments[2] * n), '0' ]) abs_path.append(end_kpt[:3] + ['0', end_kpt[4]]) i += 3 n_linemode_kpts = len(abs_path) with open('KPOINTS', 'w') as kpts: kpts.write('Automatically generated mesh\n') kpts.write('{}\n'.format(n_ibz_kpts + n_linemode_kpts)) kpts.write('Reciprocal Lattice\n') for line in ibz_lines[3:]: kpts.write(line) for point in abs_path: kpts.write('{}\n'.format(' '.join(point))) if QUEUE_SYSTEM == 'pbs': write_pbs_runjob('{}_hsebands'.format(os.getcwd().split('/')[-2]), 2, 64, '1800mb', '50:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': write_slurm_runjob( '{}_hsebands'.format(os.getcwd().split('/')[-2]), 64, '1800mb', '50:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: _ = subprocess.check_output(submission_command.split()) os.chdir('../')
def run_gamma_calculations(submit=True, step_size=0.5): """ Setup a 2D grid of static energy calculations to plot the Gamma surface between two layers of the 2D material. These calculations are run and stored in subdirectories under 'friction/lateral'. Args: submit (bool): Whether or not to submit the jobs. step_size (float): the distance between grid points in Angstroms. """ if not os.path.isdir('friction'): os.mkdir('friction') os.chdir('friction') if not os.path.isdir('lateral'): os.mkdir('lateral') os.chdir('lateral') os.system('cp ../../CONTCAR POSCAR') # Pad the bottom layer with 20 Angstroms of vacuum. utl.ensure_vacuum(Structure.from_file('POSCAR'), 20) structure = Structure.from_file('POSCAR') n_sites_per_layer = structure.num_sites n_divs_x = int(math.ceil(structure.lattice.a / step_size)) n_divs_y = int(math.ceil(structure.lattice.b / step_size)) # Get the thickness of the material. max_height = max([site.coords[2] for site in structure.sites]) min_height = min([site.coords[2] for site in structure.sites]) thickness = max_height - min_height # Make a new layer. species, coords = [], [] for site in structure.sites: # Original site species.append(site.specie) coords.append(site.coords) # New layer site species.append(site.specie) coords.append( [site.coords[0], site.coords[1], site.coords[2] + thickness + 3.5]) Structure(structure.lattice, species, coords, coords_are_cartesian=True).to('POSCAR', 'POSCAR') for x in range(n_divs_x): for y in range(n_divs_y): dir = '{}x{}'.format(x, y) if not os.path.isdir(dir): os.mkdir(dir) # Copy input files os.chdir(dir) os.system('cp ../../../INCAR .') os.system('cp ../../../KPOINTS .') os.system('cp ../POSCAR .') if VDW_KERNEL: os.system('cp {} .'.format(VDW_KERNEL)) # Shift the top layer structure = Structure.from_file("POSCAR") all_z_coords = [s.coords[2] for s in structure.sites] top_layer = [ s for s in structure.sites if s.coords[2] > np.mean(all_z_coords) ] structure.remove_sites( [i for i, s in enumerate(structure.sites) if s in top_layer]) for site in top_layer: structure.append(site.specie, [ site.coords[0] + float(x) / float(n_divs_x), site.coords[1] + float(y) / float(n_divs_y), site.coords[2] ], coords_are_cartesian=True) structure = structure.get_sorted_structure() structure.to("POSCAR", "POSCAR") utl.write_potcar() incar_dict = Incar.from_file('INCAR').as_dict() incar_dict.update({ 'NSW': 0, 'LAECHG': False, 'LCHARG': False, 'LWAVE': False, 'LVTOT': False, 'MAGMOM': utl.get_magmom_string(structure) }) incar_dict.pop('NPAR', None) Incar.from_dict(incar_dict).write_file('INCAR') if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob(dir, 1, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob(dir, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../') os.chdir('../../')
def run_normal_force_calculations(basin_and_saddle_dirs, spacings=np.arange(1.5, 4.25, 0.25), submit=True): """ Set up and run static calculations of the basin directory and saddle directory at specified interlayer spacings to get f_N and f_F. Args: basin_and_saddle_dirs (tuple): Can be obtained by the get_basin_and_peak_locations() function under friction.analysis. For example, run_normal_force_calculations(('0x0', '3x6')) or run_normal_force_calculations(get_basin_and_peak_locations()) will both work. spacings (tuple): list of interlayer spacings (in Angstroms, as floats) at which to run the calculations. submit (bool): Whether or not to submit the jobs. """ spacings = [str(spc) for spc in spacings] os.chdir('friction') if not os.path.isdir('normal'): os.mkdir('normal') os.chdir('normal') for spacing in spacings: if not os.path.isdir(spacing): os.mkdir(spacing) for subdirectory in basin_and_saddle_dirs: os.system('cp -r ../lateral/{} {}/'.format(subdirectory, spacing)) os.chdir('{}/{}'.format(spacing, subdirectory)) structure = Structure.from_file('POSCAR') n_sites = len(structure.sites) all_z_coords = [s.coords[2] for s in structure.sites] top_layer = [ s for s in structure.sites if s.coords[2] > np.mean(all_z_coords) ] bottom_of_top_layer = min([site.coords[2] for site in top_layer]) remove_indices = [ i for i, s in enumerate(structure.sites) if s in top_layer ] structure.remove_sites(remove_indices) top_of_bottom_layer = max( [site.coords[2] for site in structure.sites]) for site in top_layer: structure.append(site.specie, [ site.coords[0], site.coords[1], site.coords[2] - bottom_of_top_layer + top_of_bottom_layer + float(spacing) ], coords_are_cartesian=True) structure = structure.get_sorted_structure() structure.to('POSCAR', 'POSCAR') utl.write_potcar() incar_dict = Incar.from_file('INCAR').as_dict() incar_dict.update({"MAGMOM": utl.get_magmom_string(structure)}) Incar.from_dict(incar_dict).write_file("INCAR") if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob('{}_{}'.format(subdirectory, spacing), 1, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob('{}_{}'.format(subdirectory, spacing), 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../../') os.chdir('../../')
def run_gamma_calculations(submit=True, step_size=0.5): """ Setup a 2D grid of static energy calculations to plot the Gamma surface between two layers of the 2D material. These calculations are run and stored in subdirectories under 'friction/lateral'. Args: submit (bool): Whether or not to submit the jobs. step_size (float): the distance between grid points in Angstroms. """ if not os.path.isdir('friction'): os.mkdir('friction') os.chdir('friction') if not os.path.isdir('lateral'): os.mkdir('lateral') os.chdir('lateral') try: os.system('cp ../../CONTCAR POSCAR') except: try: os.system('cp ../../POSCAR .') except: raise IOError('No POSCAR or CONTCAR found in ' + os.path.dirname(os.path.dirname(os.getcwd()))) # Pad the bottom layer with 20 Angstroms of vacuum. utl.ensure_vacuum(Structure.from_file('POSCAR'), 20) structure = Structure.from_file('POSCAR') n_sites_per_layer = structure.num_sites n_divs_x = int(math.ceil(structure.lattice.a / step_size)) n_divs_y = int(math.ceil(structure.lattice.b / step_size)) # Get the thickness of the material. max_height = max([site.coords[2] for site in structure.sites]) min_height = min([site.coords[2] for site in structure.sites]) thickness = max_height - min_height # Make a new layer. species, coords = [], [] for site in structure.sites: # Original site species.append(site.specie) coords.append(site.coords) # New layer site species.append(site.specie) coords.append( [site.coords[0], site.coords[1], site.coords[2] + thickness + 3.5]) Structure(structure.lattice, species, coords).to('POSCAR', 'POSCAR') for x in range(n_divs_x): for y in range(n_divs_y): dir = '{}x{}'.format(x, y) if not os.path.isdir(dir): os.mkdir(dir) # Copy input files os.chdir(dir) if not os.path.exists('../../INCAR'): raise IOError('No INCAR found in ' + os.path.dirname(os.path.dirname(os.getcwd()))) if not os.path.exists('../../KPOINTS'): raise IOError('No KPOINTS found in ' + os.path.dirname(os.path.dirname(os.getcwd()))) os.system('cp ../../../INCAR .') os.system('cp ../../../KPOINTS .') os.system('cp ../POSCAR .') if VDW_KERNEL: os.system('cp {} .'.format(VDW_KERNEL)) utl.write_potcar() incar_dict = Incar.from_file('INCAR').as_dict() incar_dict.update({ 'NSW': 0, 'LAECHG': False, 'LCHARG': False, 'LWAVE': False, 'LVTOT': False, 'MAGMOM': utl.get_magmom_string(Structure.from_file('POSCAR')) }) incar_dict.pop('NPAR', None) Incar.from_dict(incar_dict).write_file('INCAR') # Shift the top layer poscar_lines = open('POSCAR').readlines() with open('POSCAR', 'w') as poscar: for line in poscar_lines[:8 + n_sites_per_layer]: poscar.write(line) for line in poscar_lines[8 + n_sites_per_layer:]: split_line = line.split() new_coords = [ float(split_line[0]) + float(x) / float(n_divs_x), float(split_line[1]) + float(y) / float(n_divs_y), float(split_line[2]) ] poscar.write(' '.join([str(i) for i in new_coords]) + '\n') sub_exe = True if VASP_STD_BIN == 'None': print 'Executable is missing in ' + os.getcwd() + '/runjob' print 'Configure mpint_config.yaml file with your executable!' sub_exe = False if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob(dir, 1, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob(dir, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit and sub_exe: os.system(submission_command) os.chdir('../') os.chdir('../../')
def run_normal_force_calculations(basin_and_saddle_dirs, spacings=(1.5, 4.25, 0.25), submit=True): """ Set up and run static calculations of the basin directory and saddle directory at specified interlayer spacings to get f_N and f_F. Args: basin_and_saddle_dirs (tuple): Can be obtained by the get_basin_and_peak_locations() function under friction.analysis. For example, run_normal_force_calculations(('0x0', '3x6')) or run_normal_force_calculations(get_basin_and_peak_locations()) will both work. spacings (tuple): list of interlayer spacings (in Angstroms, as floats) at which to run the calculations. submit (bool): Whether or not to submit the jobs. """ spacings = [str(spc) for spc in spacings] os.chdir('friction') if not os.path.isdir('normal'): os.mkdir('normal') os.chdir('normal') for spacing in spacings: if not os.path.isdir(spacing): os.mkdir(spacing) for subdirectory in basin_and_saddle_dirs: os.system('cp -r ../lateral/{} {}/'.format(subdirectory, spacing)) os.chdir('{}/{}'.format(spacing, subdirectory)) structure = Structure.from_file('POSCAR') n_sites = len(structure.sites) top_layer = structure.sites[int(n_sites / 2):] bottom_of_top_layer = min([ z_coord for z_coord in [site.coords[2] for site in top_layer] ]) remove_indices = range(int(n_sites / 2), n_sites) structure.remove_sites(remove_indices) max_height = max([site.coords[2] for site in structure.sites]) for site in top_layer: structure.append(site.specie, [ site.coords[0], site.coords[1], site.coords[2] - bottom_of_top_layer + max_height + float(spacing) ], coords_are_cartesian=True) structure.to('POSCAR', 'POSCAR') if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob('{}_{}'.format(subdirectory, spacing), 1, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob('{}_{}'.format(subdirectory, spacing), 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../../') os.chdir('../../')
def run_hse_calculation(dim=2, submit=True, force_overwrite=False): """ Setup/submit an HSE06 calculation to get an accurate band structure. See http://cms.mpi.univie.ac.at/wiki/index.php/Si_bandstructure for more details. Args: dim (int): 2 for relaxing a 2D material, 3 for a 3D material. submit (bool): Whether or not to submit the job. force_overwrite (bool): Whether or not to overwrite files if an already converged vasprun.xml exists in the directory. """ HSE_INCAR_DICT = { 'LHFCALC': True, 'HFSCREEN': 0.2, 'AEXX': 0.25, 'ALGO': 'D', 'TIME': 0.4, 'NSW': 0, 'LVTOT': True, 'LVHAR': True, 'LORBIT': 11, 'LWAVE': True, 'NPAR': 8, 'PREC': 'Accurate', 'EDIFF': 1e-4, 'ENCUT': 450, 'ICHARG': 2, 'ISMEAR': 1, 'SIGMA': 0.1, 'IBRION': 2, 'ISIF': 3, 'ISPIN': 2 } if not os.path.isdir('hse_bands'): os.mkdir('hse_bands') if force_overwrite or not is_converged('hse_bands'): os.chdir('hse_bands') os.system('cp ../CONTCAR ./POSCAR') structure = Structure.from_file("POSCAR") if os.path.isfile('../POTCAR'): os.system('cp ../POTCAR .') HSE_INCAR_DICT.update({'MAGMOM': get_magmom_string(structure)}) Incar.from_dict(HSE_INCAR_DICT).write_file('INCAR') # Re-use the irreducible brillouin zone KPOINTS from a # previous standard DFT run. write_band_structure_kpoints(structure, dim=dim) if QUEUE_SYSTEM == 'pbs': write_pbs_runjob('{}_hsebands'.format(os.getcwd().split('/')[-2]), 2, 64, '1800mb', '50:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': write_slurm_runjob( '{}_hsebands'.format(os.getcwd().split('/')[-2]), 64, '1800mb', '50:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: _ = subprocess.check_output(submission_command.split()) os.chdir('../')
def run_gamma_calculations(submit=True, step_size=0.5): """ Setup a 2D grid of static energy calculations to plot the Gamma surface between two layers of the 2D material. These calculations are run and stored in subdirectories under 'friction/lateral'. Args: submit (bool): Whether or not to submit the jobs. step_size (float): the distance between grid points in Angstroms. """ if not os.path.isdir('friction'): os.mkdir('friction') os.chdir('friction') if not os.path.isdir('lateral'): os.mkdir('lateral') os.chdir('lateral') os.system('cp ../../CONTCAR POSCAR') # Pad the bottom layer with 20 Angstroms of vacuum. utl.ensure_vacuum(Structure.from_file('POSCAR'), 20) structure = Structure.from_file('POSCAR') n_sites_per_layer = structure.num_sites n_divs_x = int(math.ceil(structure.lattice.a / step_size)) n_divs_y = int(math.ceil(structure.lattice.b / step_size)) # Get the thickness of the material. max_height = max([site.coords[2] for site in structure.sites]) min_height = min([site.coords[2] for site in structure.sites]) thickness = max_height - min_height # Make a new layer. species, coords = [], [] for site in structure.sites: # Original site species.append(site.specie) coords.append(site.coords) # New layer site species.append(site.specie) coords.append([site.coords[0], site.coords[1], site.coords[2] + thickness + 3.5]) Structure(structure.lattice, species, coords, coords_are_cartesian=True).to('POSCAR', 'POSCAR') for x in range(n_divs_x): for y in range(n_divs_y): dir = '{}x{}'.format(x, y) if not os.path.isdir(dir): os.mkdir(dir) # Copy input files os.chdir(dir) os.system('cp ../../../INCAR .') os.system('cp ../../../KPOINTS .') os.system('cp ../POSCAR .') if VDW_KERNEL: os.system('cp {} .'.format(VDW_KERNEL)) # Shift the top layer structure = Structure.from_file("POSCAR") all_z_coords = [s.coords[2] for s in structure.sites] top_layer = [s for s in structure.sites if s.coords[2] > np.mean(all_z_coords)] structure.remove_sites([i for i, s in enumerate(structure.sites) if s in top_layer]) for site in top_layer: structure.append( site.specie, [site.coords[0]+float(x)/float(n_divs_x), site.coords[1]+float(y)/float(n_divs_y), site.coords[2]], coords_are_cartesian=True ) structure = structure.get_sorted_structure() structure.to("POSCAR", "POSCAR") utl.write_potcar() incar_dict = Incar.from_file('INCAR').as_dict() incar_dict.update({'NSW': 0, 'LAECHG': False, 'LCHARG': False, 'LWAVE': False, 'LVTOT': False, 'MAGMOM': utl.get_magmom_string(structure)}) incar_dict.pop('NPAR', None) Incar.from_dict(incar_dict).write_file('INCAR') if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob(dir, 1, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob(dir, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../') os.chdir('../../')
def run_normal_force_calculations(basin_and_saddle_dirs, spacings=np.arange(1.5, 4.25, 0.25), submit=True): """ Set up and run static calculations of the basin directory and saddle directory at specified interlayer spacings to get f_N and f_F. Args: basin_and_saddle_dirs (tuple): Can be obtained by the get_basin_and_peak_locations() function under friction.analysis. For example, run_normal_force_calculations(('0x0', '3x6')) or run_normal_force_calculations(get_basin_and_peak_locations()) will both work. spacings (tuple): list of interlayer spacings (in Angstroms, as floats) at which to run the calculations. submit (bool): Whether or not to submit the jobs. """ spacings = [str(spc) for spc in spacings] os.chdir('friction') if not os.path.isdir('normal'): os.mkdir('normal') os.chdir('normal') for spacing in spacings: if not os.path.isdir(spacing): os.mkdir(spacing) for subdirectory in basin_and_saddle_dirs: os.system('cp -r ../lateral/{} {}/'.format(subdirectory, spacing)) os.chdir('{}/{}'.format(spacing, subdirectory)) structure = Structure.from_file('POSCAR') n_sites = len(structure.sites) all_z_coords = [s.coords[2] for s in structure.sites] top_layer = [s for s in structure.sites if s.coords[2] > np.mean(all_z_coords)] bottom_of_top_layer = min([site.coords[2] for site in top_layer]) remove_indices = [i for i, s in enumerate(structure.sites) if s in top_layer] structure.remove_sites(remove_indices) top_of_bottom_layer = max( [site.coords[2] for site in structure.sites] ) for site in top_layer: structure.append( site.specie, [site.coords[0], site.coords[1], site.coords[2] - bottom_of_top_layer + top_of_bottom_layer + float(spacing)], coords_are_cartesian=True) structure = structure.get_sorted_structure() structure.to('POSCAR', 'POSCAR') utl.write_potcar() incar_dict = Incar.from_file('INCAR').as_dict() incar_dict.update({"MAGMOM": utl.get_magmom_string(structure)}) Incar.from_dict(incar_dict).write_file("INCAR") if QUEUE_SYSTEM == 'pbs': utl.write_pbs_runjob('{}_{}'.format( subdirectory, spacing), 1, 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'qsub runjob' elif QUEUE_SYSTEM == 'slurm': utl.write_slurm_runjob('{}_{}'.format( subdirectory, spacing), 8, '1000mb', '2:00:00', VASP_STD_BIN) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../../') os.chdir('../../')