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 != '/path/to/vdw_kernel.bindat': 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()}) 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.add_vacuum(20 - utl.get_spacing(), 0.9) # 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 QUEUE == 'pbs': utl.write_pbs_runjob(directory, 1, 16, '800mb', '6:00:00', VASP_2D) submission_command = 'qsub runjob' elif QUEUE == 'slurm': utl.write_slurm_runjob(directory, 16, '800mb', '6:00:00', VASP_2D) submission_command = 'sbatch runjob' if submit: os.system(submission_command)
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.add_vacuum(20 - utl.get_spacing(), 0.8) 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. new_sites = [] for site in structure.sites: new_sites.append((site.specie, [site.coords[0], site.coords[1], site.coords[2] + thickness + 3.5])) for site in new_sites: structure.append(site[0], site[1], coords_are_cartesian=True) #structure.get_sorted_structure().to('POSCAR', 'POSCAR') structure.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 != '/path/to/vdw_kernel.bindat': 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, 'MAGMOM': utl.get_magmom_string()}) 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') if QUEUE == 'pbs': utl.write_pbs_runjob(dir, 1, 4, '800mb', '1:00:00', VASP) submission_command = 'qsub runjob' elif QUEUE == 'slurm': utl.write_slurm_runjob(dir, 4, '800mb', '1:00:00', VASP) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../') os.chdir('../../')
def prepare(self, submit=False): """ Set up calculation directories to calibrate the ion corrections to match a specified framework of INCAR parameters, k-points, and potcar hashes. Args: submit (bool): whether or not to submit each job after preparing it. """ for elt in self._potcar_dict: # Set up reference directory for the pure element. if not os.path.isdir(elt): os.mkdir(elt) os.chdir(elt) # Poscar s = MPR.get_structure_by_material_id( self._config['Mpids'][elt]['self']) s.to('POSCAR', 'POSCAR') plines = open('POSCAR').readlines() elements = plines[5].split() # Kpoints kp = Kpoints.automatic_density(s, self._n_kpts_per_atom) kp.write_file('KPOINTS') # Incar incar = Incar.from_dict(self._incar_dict) incar.write_file('INCAR') # Potcar utl.write_potcar(types=[self._potcar_dict[el] for el in elements]) # Runjob if QUEUE == 'pbs': utl.write_pbs_runjob('{}_cal'.format(elt), self._ncores, self._nprocs, self._pmem, self._walltime, self._binary) submission_command = 'qsub runjob' elif QUEUE == 'slurm': utl.write_slurm_runjob('{}_cal'.format(elt), self._nprocs, self._pmem, self._walltime, self._binary) submission_command = 'sbatch runjob' if submit: os.system(submission_command) # Set up reference oxide compound subdirectory. if elt not in ['O', 'S', 'F', 'Cl', 'Br', 'I']: if not os.path.isdir('ref'): os.mkdir('ref') os.chdir('ref') # Poscar s = MPR.get_structure_by_material_id( self._config['Mpids'][elt]['ref']) s.to('POSCAR', 'POSCAR') plines = open('POSCAR').readlines() elements = plines[5].split() # Kpoints kp = Kpoints.automatic_density(s, self._n_kpts_per_atom) kp.write_file('KPOINTS') # Incar incar = Incar.from_dict(self._incar_dict) incar.write_file('INCAR') # Potcar utl.write_potcar( types=[self._potcar_dict[el] for el in elements]) # Runjob if QUEUE == 'slurm': utl.write_pbs_runjob('{}_cal'.format(elt), self._ncores, self._nprocs, self._pmem, self._walltime, self._binary) submission_command = 'qsub runjob' elif QUEUE == 'pbs': utl.write_slurm_runjob('{}_cal'.format(elt), self._nprocs, self._pmem, self._walltime, self._binary) 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') os.system('cp ../../CONTCAR POSCAR') # Pad the bottom layer with 20 Angstroms of vacuum. utl.add_vacuum(20 - utl.get_spacing(), 0.8) 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. new_sites = [] for site in structure.sites: new_sites.append((site.specie, [site.coords[0], site.coords[1], site.coords[2] + thickness + 3.5])) for site in new_sites: structure.append(site[0], site[1], coords_are_cartesian=True) #structure.get_sorted_structure().to('POSCAR', 'POSCAR') structure.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 != '/path/to/vdw_kernel.bindat': 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()}) 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') if QUEUE == 'pbs': utl.write_pbs_runjob(dir, 1, 8, '1000mb', '2:00:00', VASP) submission_command = 'qsub runjob' elif QUEUE == 'slurm': utl.write_slurm_runjob(dir, 8, '1000mb', '2:00:00', VASP) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../') os.chdir('../../')