def test_static_constructors(self): kpoints = Kpoints.gamma_automatic([3, 3, 3], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) self.assertEqual(kpoints.kpts, [[3, 3, 3]]) kpoints = Kpoints.monkhorst_automatic([2, 2, 2], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Monkhorst) self.assertEqual(kpoints.kpts, [[2, 2, 2]]) kpoints = Kpoints.automatic(100) self.assertEqual(kpoints.style, Kpoints.supported_modes.Automatic) self.assertEqual(kpoints.kpts, [[100]]) filepath = os.path.join(test_dir, "POSCAR") poscar = Poscar.from_file(filepath) kpoints = Kpoints.automatic_density(poscar.structure, 500) self.assertEqual(kpoints.kpts, [[2, 4, 4]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Monkhorst) kpoints = Kpoints.automatic_density(poscar.structure, 500, True) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.automatic_density_by_vol(poscar.structure, 1000) self.assertEqual(kpoints.kpts, [[6, 11, 13]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) s = poscar.structure s.make_supercell(3) kpoints = Kpoints.automatic_density(s, 500) self.assertEqual(kpoints.kpts, [[1, 1, 1]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma)
def test_static_constructors(self): kpoints = Kpoints.gamma_automatic([3, 3, 3], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) self.assertEqual(kpoints.kpts, [[3, 3, 3]]) kpoints = Kpoints.monkhorst_automatic([2, 2, 2], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Monkhorst) self.assertEqual(kpoints.kpts, [[2, 2, 2]]) kpoints = Kpoints.automatic(100) self.assertEqual(kpoints.style, Kpoints.supported_modes.Automatic) self.assertEqual(kpoints.kpts, [[100]]) filepath = os.path.join(test_dir, 'POSCAR') poscar = Poscar.from_file(filepath) kpoints = Kpoints.automatic_density(poscar.structure, 500) self.assertEqual(kpoints.kpts, [[1, 3, 3]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.automatic_density(poscar.structure, 500, True) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.automatic_density_by_vol(poscar.structure, 1000) self.assertEqual(kpoints.kpts, [[6, 10, 13]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) s = poscar.structure s.make_supercell(3) kpoints = Kpoints.automatic_density(s, 500) self.assertEqual(kpoints.kpts, [[1, 1, 1]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.from_string("""k-point mesh 0 G 10 10 10 0.5 0.5 0.5 """) self.assertArrayAlmostEqual(kpoints.kpts_shift, [0.5, 0.5, 0.5])
def test_static_constructors(self): kpoints = Kpoints.gamma_automatic([3, 3, 3], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) self.assertEqual(kpoints.kpts, [[3, 3, 3]]) kpoints = Kpoints.monkhorst_automatic([2, 2, 2], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Monkhorst) self.assertEqual(kpoints.kpts, [[2, 2, 2]]) kpoints = Kpoints.automatic(100) self.assertEqual(kpoints.style, Kpoints.supported_modes.Automatic) self.assertEqual(kpoints.kpts, [[100]]) filepath = os.path.join(test_dir, 'POSCAR') poscar = Poscar.from_file(filepath) kpoints = Kpoints.automatic_density(poscar.structure, 500) self.assertEqual(kpoints.kpts, [[2, 4, 4]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Monkhorst) kpoints = Kpoints.automatic_density(poscar.structure, 500, True) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.automatic_density_by_vol(poscar.structure, 1000) self.assertEqual(kpoints.kpts, [[6, 11, 13]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) s = poscar.structure s.make_supercell(3) kpoints = Kpoints.automatic_density(s, 500) self.assertEqual(kpoints.kpts, [[1, 1, 1]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma)
def test_static_constructors(self): kpoints = Kpoints.gamma_automatic([3, 3, 3], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) self.assertEqual(kpoints.kpts, [[3, 3, 3]]) kpoints = Kpoints.monkhorst_automatic([2, 2, 2], [0, 0, 0]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Monkhorst) self.assertEqual(kpoints.kpts, [[2, 2, 2]]) kpoints = Kpoints.automatic(100) self.assertEqual(kpoints.style, Kpoints.supported_modes.Automatic) self.assertEqual(kpoints.kpts, [[100]]) filepath = self.TEST_FILES_DIR / 'POSCAR' poscar = Poscar.from_file(filepath) kpoints = Kpoints.automatic_density(poscar.structure, 500) self.assertEqual(kpoints.kpts, [[1, 3, 3]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.automatic_density(poscar.structure, 500, True) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.automatic_density_by_vol(poscar.structure, 1000) self.assertEqual(kpoints.kpts, [[6, 10, 13]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) s = poscar.structure s.make_supercell(3) kpoints = Kpoints.automatic_density(s, 500) self.assertEqual(kpoints.kpts, [[1, 1, 1]]) self.assertEqual(kpoints.style, Kpoints.supported_modes.Gamma) kpoints = Kpoints.from_string("""k-point mesh 0 G 10 10 10 0.5 0.5 0.5 """) self.assertArrayAlmostEqual(kpoints.kpts_shift, [0.5, 0.5, 0.5])
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_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') os.system('cp ../CONTCAR ./POSCAR') if os.path.isfile('../POTCAR'): os.system('cp 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 == 'pbs': write_pbs_runjob('{}_prep'.format( os.getcwd().split('/')[-2]), 1, 16, '800mb', '6:00:00', VASP) submission_command = 'qsub runjob' elif QUEUE == 'slurm': write_slurm_runjob('{}_prep'.format( os.getcwd().split('/')[-2]), 16, '800mb', '6:00:00', VASP) submission_command = 'sbatch runjob' if submit: os.system(submission_command) os.chdir('../')
def get_kpoints_object(self, step, structure): try: kpoints_tags = self.kpoints[step] except KeyError: return None if kpoints_tags['Type'] == 'automatic_density': K = Kpoints.automatic_density(structure, kpoints_tags['Grid Density'], kpoints_tags['Force Gamma']) elif kpoints_tags['Type'] == 'automatic_density_by_vol': K = Kpoints.automatic_density_by_vol( structure, kpoints_tags['Grid Density per A^(-3) of Reciprocal Cell'], kpoints_tags['Force Gamma']) elif kpoints_tags['Type'] == 'automatic_gamma_density': K = Kpoints.automatic_gamma_density(structure, kpoints_tags['Grid Density']) elif kpoints_tags['Type'] == 'gamma_automatic': K = Kpoints.gamma_automatic(kpoints_tags["KPTS"], kpoints_tags["Shift"]) elif kpoints_tags['Type'] == 'monkhorst_automatic': K = Kpoints.monkhorst_automatic(kpoints_tags["KPTS"], kpoints_tags["Shift"]) else: print('Invalid kpoints generation type %s; fatal error' % kpoints_tags['Type']) sys.exit(1) return K
def converge_kpoints(args, console): density_values = np.linspace(args.min, args.max, args.n) mode = Kpoints_supported_modes.from_string(args.mode) structure = Poscar.from_file("POSCAR").structure table = Table(title="K-point Convergence Summary") table.add_column("Directory") table.add_column("Density (atoms^-1)", justify="right") grids = [] for density in density_values: kpoints = Kpoints.automatic_density(structure, density) kpoints.style = mode grid = (kpoints.kpts[0][0], kpoints.kpts[0][1], kpoints.kpts[0][2]) if grid in grids: console.print( "[bold yellow]WARNING:[/bold yellow] density {:.2f} does not produce a unique grid (skipping...)" .format(density)) continue grids.append(grid) dirname = "{}x{}x{}".format(grid[0], grid[1], grid[2]) os.mkdir(dirname) shutil.copy("INCAR", os.path.join(dirname, "INCAR")) shutil.copy("POSCAR", os.path.join(dirname, "POSCAR")) shutil.copy("POTCAR", os.path.join(dirname, "POTCAR")) shutil.copy(args.jobfile, os.path.join(dirname, args.jobfile)) kpoints.write_file(os.path.join(dirname, "KPOINTS")) os.chdir(dirname) #os.system("{} {}".format(args.jobcmd, args.jobfile)) os.chdir("..") table.add_row(dirname, "{:.2f}".format(density)) console.print(table)
def test_automatic_kpoint(self): # s = PymatgenTest.get_structure("Li2O") p = Poscar.from_string("""Al1 1.0 2.473329 0.000000 1.427977 0.824443 2.331877 1.427977 0.000000 0.000000 2.855955 Al 1 direct 0.000000 0.000000 0.000000 Al""") kpoints = Kpoints.automatic_density(p.structure, 1000) self.assertArrayAlmostEqual(kpoints.kpts[0], [10, 10, 10])
def test_automatic_kpoint(self): # s = PymatgenTest.get_structure("Li2O") p = Poscar.from_string("""Al1 1.0 2.473329 0.000000 1.427977 0.824443 2.331877 1.427977 0.000000 0.000000 2.855955 Al 1 direct 0.000000 0.000000 0.000000 Al""") kpoints = Kpoints.automatic_density(p.structure, 1000) self.assertArrayAlmostEqual(kpoints.kpts[0], [10, 10, 10])
def auto_kgrid(struct, dirname): ''' Generate KPOINTS according given mesh density. input the dimensionality and mesh grid density dimensionality can be 0D 1D 2D 3D 500 for low grid density 1000 for medium grid density 2000 for high grid density 3000 for accurate density input format: 1 1000 note: in 1D system, mesh grids for x & y direction = 1 in 2D system, mesh grids for z direction = 1 ''' print(" input the dimensionality and mesh grid density ") print(" dimensionality can be 0D 1D 2D 3D") print(" 500 for low grid density") print(" 1000 for medium grid density") print(" 2000 for high grid density") print(" 3000 for accurate density") print(" input format: 1 1000") wait_sep() in_str = "" while in_str == "": in_str = input().strip().split() data = [int(x) for x in in_str] dim = data[0] grid_density = data[1] kps = Kpoints.automatic_density(struct, grid_density) if dim == 0: kps.kpts = [[1, 1, 1]] if dim == 1: # 1 for x and y direction # e.g. : # "" # comment # M or G # 1 1 <density> # "" kps.kpts[0][0] = 1 kps.kpts[0][1] = 1 if dim == 2: # 1 for z direction # e.g. : # "" # comment # M or G # <dens1> <dens2> 1 # "" kps.kpts[0][2] = 1 kps.write_file(os.path.join(dirname, "KPOINTS"))
def update_spec_force_convergence(spec, user_vasp_settings=None): fw_spec = spec update_set = {"ENCUT": 700, "EDIFF": 0.000001, "ALGO":"N", "NPAR":2} if user_vasp_settings and user_vasp_settings.get("incar"): update_set.update(user_vasp_settings["incar"]) fw_spec['vasp']['incar'].update(update_set) old_struct=Poscar.from_dict(fw_spec["vasp"]["poscar"]).structure if user_vasp_settings and user_vasp_settings.get("kpoints"): kpoints_density = user_vasp_settings["kpoints"]["kpoints_density"] else: kpoints_density = 7000 k=Kpoints.automatic_density(old_struct, kpoints_density) fw_spec['vasp']['kpoints'] = k.as_dict() return fw_spec
def wf_elastic_constant(structure, c=None, order=2, sym_reduce=False): c = c or {} vasp_cmd = c.get("VASP_CMD", VASP_CMD) db_file = c.get("DB_FILE", DB_FILE) uis_optimize = {"ENCUT": 700, "EDIFF": 1e-6, "LAECHG": False} if order > 2: uis_optimize.update({"EDIFF": 1e-10, "EDIFFG": -0.001, "ADDGRID": True, "LREAL": False, "ISYM": 0}) # This ensures a consistent k-point mesh across all calculations # We also turn off symmetry to prevent VASP from changing the # mesh internally kpts_settings = Kpoints.automatic_density(structure, 40000, force_gamma=True) stencils = np.linspace(-0.075, 0.075, 7) else: kpts_settings = {'grid_density': 7000} stencils = None uis_static = uis_optimize.copy() uis_static.update({'ISIF': 2, 'IBRION': 2, 'NSW': 99, 'ISTART': 1, "PREC": "High"}) # input set for structure optimization vis_relax = MPRelaxSet(structure, force_gamma=True, user_incar_settings=uis_optimize, user_kpoints_settings=kpts_settings) # optimization only workflow wf = get_wf(structure, "optimize_only.yaml", vis=vis_relax, params=[{"vasp_cmd": vasp_cmd, "db_file": db_file, "name": "elastic structure optimization"}]) vis_static = MPStaticSet(structure, force_gamma=True, lepsilon=False, user_kpoints_settings=kpts_settings, user_incar_settings=uis_static) # deformations wflow for elasticity calculation wf_elastic = get_wf_elastic_constant(structure, vasp_cmd=vasp_cmd, db_file=db_file, order=order, stencils=stencils, copy_vasp_outputs=True, vasp_input_set=vis_static, sym_reduce=sym_reduce) wf.append_wf(wf_elastic, wf.leaf_fw_ids) wf = add_common_powerups(wf, c) if c.get("ADD_WF_METADATA", ADD_WF_METADATA): wf = add_wf_metadata(wf, structure) return wf
def gamma_float(cls): """ Initialize gamma grid using a given kpoint density. Enforces the usage of gamma grids. Example:: Automatic Kpoint Scheme 0 Gamma 5 5 5 """ # check if required input structure was given if cls.input_structure is None: raise KpointWrapperError("Missing non-optional kpoint density " "parameter 'structure'") if cls.kpoint_params['sympath'] is not None: warnings.warn("Gamma density grid mode: Ignoring defined " "high symmetry path object") structure = cls.structure_from_input() kpoints = cls.kpoint_params['kpoints'] return Kpoints.automatic_density(structure, kpoints, force_gamma=True)
def make_vasp_dielectric_files(struct, path=None, user_settings={}, hse=False): """ Generates VASP files for dielectric constant computations Args: struct: unitcell in pymatgen structure format user_settings: Settings in dict format to override the defaults used in generating vasp files. The format of the dictionary is {'INCAR':{...}, 'KPOINTS':{...}} hse: hse run or not """ # Generate vasp inputs for dielectric constant user_settings = deepcopy(user_settings) user_incar = user_settings.pop('INCAR', {}) user_incar.pop('bulk', {}) user_incar.pop('defects', {}) user_incar_diel = user_incar.pop('dielectric', {}) user_incar.update(user_incar_diel) user_kpoints = user_settings.pop('KPOINTS', {}) grid_density = user_kpoints.get('grid_density', 1000) potcar_settings = user_settings.pop('POTCAR', {}) potcar_functional = potcar_settings.pop('functional', 'PBE') dielectric_set = DielectricSet(struct, user_incar_settings=user_incar, user_potcar_settings=potcar_settings, potcar_functional=potcar_functional) if not path: path_base = struct.composition.reduced_formula path = os.path.join(path_base, 'dielectric') dielectric_set.write_input(path) kpoints = Kpoints.automatic_density(struct, grid_density, force_gamma=True) incar = dielectric_set.incar if hse else {} write_additional_files(path, incar=incar, kpoints=kpoints, hse=hse)
def monkhorst_float(cls): """ Initialize kpoint grid using a given kpoint density. If the number of subdivisions is even a Monkhorst grid is constructured whereas gamma grids are used for odd kpoint subdivisions Example:: Automatic Kpoint Scheme 0 Monkhorst 4 4 4 """ # check if required input structure was given if cls.input_structure is None: raise KpointWrapperError("Missing non-optional kpoint density " "parameter 'structure'") if cls.kpoint_params['sympath'] is not None: warnings.warn("Monkhorst density grid mode: Ignoring defined " "high symmetry path object") structure = cls.structure_from_input() kpoints = cls.kpoint_params['kpoints'] return Kpoints.automatic_density(structure, kpoints, force_gamma=False)
def auto_kgrid(struct,dirname): print(" input the dimensionality and mesh grid density ") print(" dimensionality can be 0D 1D 2D 3D") print(" 500 for low grid density") print(" 1000 for medium grid density") print(" 2000 for high grid density") print(" 3000 for accurate density") print(" input format: 1 1000") wait_sep() in_str="" while in_str=="": in_str=input().strip().split() data=[int(x) for x in in_str] dim=data[0] grid_density=data[1] kps=Kpoints.automatic_density(struct,grid_density) if dim==0: kps.kpts=[[1,1,1]] if dim==1: kps.kpts[0][0]=1 kps.kpts[0][1]=1 if dim==2: kps.kpts[0][2]=1 kps.write_file(os.path.join(dirname, "KPOINTS"))
def vac_antisite_def_struct_gen(mpid, mapi_key, cellmax): if not mpid: print("============\nERROR: Provide an mpid\n============") return # Get primitive structure from the Materials Project DB if not mapi_key: with MPRester() as mp: struct = mp.get_structure_by_material_id(mpid) else: with MPRester(mapi_key) as mp: struct = mp.get_structure_by_material_id(mpid) sga = SpacegroupAnalyzer(struct) prim_struct = sga.find_primitive() #prim_struct_sites = len(prim_struct.sites) #conv_struct = sga.get_conventional_standard_structure() #conv_struct_sites = len(conv_struct.sites) #conv_prim_ratio = int(conv_struct_sites / prim_struct_sites) # Default VASP settings def_vasp_incar_param = { 'ISIF': 2, 'EDIFF': 1e-6, 'EDIFFG': 0.001, } kpoint_den = 15000 # Create bulk structure and associated VASP files sc_scale = get_sc_scale(inp_struct=prim_struct, final_site_no=cellmax) blk_sc = prim_struct.copy() blk_sc.make_supercell(scaling_matrix=sc_scale) site_no = blk_sc.num_sites # Rescale if needed if site_no > cellmax: max_sc_dim = max(sc_scale) i = sc_scale.index(max_sc_dim) sc_scale[i] -= 1 blk_sc = prim_struct.copy() blk_sc.make_supercell(scaling_matrix=sc_scale) blk_str_sites = set(blk_sc.sites) custom_kpoints = Kpoints.automatic_density(blk_sc, kppa=kpoint_den) mpvis = MPMetalRelaxSet(blk_sc, user_incar_settings=def_vasp_incar_param, user_kpoints_settings=custom_kpoints) ptcr_flag = True try: potcar = mpvis.potcar except: print ("VASP POTCAR folder not detected.\n" \ "Only INCAR, POSCAR, KPOINTS are generated.\n" \ "If you have VASP installed on this system, \n" \ "refer to pymatgen documentation for configuring the settings.") ptcr_flag = False fin_dir = os.path.join(mpid, 'bulk') mpvis.write_input(fin_dir) # Create each defect structure and associated VASP files # First find all unique defect sites periodic_struct = sga.get_symmetrized_structure() unique_sites = list(set([periodic_struct.find_equivalent_sites(site)[0] \ for site in periodic_struct.sites])) temp_struct = Structure.from_sites(sorted(unique_sites)) prim_struct2 = SpacegroupAnalyzer(temp_struct).find_primitive() prim_struct2.lattice = prim_struct.lattice # a little hacky for i, site in enumerate(prim_struct2.sites): vac = Vacancy(structure=prim_struct, defect_site=site) vac_sc = vac.generate_defect_structure(supercell=sc_scale) # Get vacancy site information vac_str_sites = set(vac_sc.sites) vac_sites = blk_str_sites - vac_str_sites vac_site = next(iter(vac_sites)) site_mult = vac.get_multiplicity() vac_site_specie = vac_site.specie vac_symbol = vac_site_specie.symbol custom_kpoints = Kpoints.automatic_density(vac_sc, kppa=kpoint_den) mpvis = MPMetalRelaxSet(vac_sc, user_incar_settings=def_vasp_incar_param, user_kpoints_settings=custom_kpoints) vac_dir = 'vacancy_{}_mult-{}_sitespecie-{}'.format( str(i + 1), site_mult, vac_symbol) fin_dir = os.path.join(mpid, vac_dir) mpvis.write_input(fin_dir) # Antisites generation at the vacancy site struct_species = blk_sc.species for specie in set(struct_species) - set([vac_site_specie]): specie_symbol = specie.symbol anti_sc = vac_sc.copy() anti_sc.append(specie, vac_site.frac_coords) mpvis = MPMetalRelaxSet(anti_sc, user_incar_settings=def_vasp_incar_param, user_kpoints_settings=custom_kpoints) anti_dir = 'antisite_{}_mult-{}_sitespecie-{}_subspecie-{}'.format( str(i + 1), site_mult, vac_symbol, specie_symbol) fin_dir = os.path.join(mpid, anti_dir) mpvis.write_input(fin_dir)
def vac_antisite_def_struct_gen(mpid, mapi_key, cellmax, struct_file=None): if not mpid and not struct_file: print ("============\nERROR: Provide an mpid\n============") return # Get primitive structure from the Materials Project DB if not struct_file: if not mapi_key: with MPRester() as mp: struct = mp.get_structure_by_material_id(mpid) else: with MPRester(mapi_key) as mp: struct = mp.get_structure_by_material_id(mpid) else: struct = Structure.from_file(struct_file) sga = SpacegroupAnalyzer(struct) prim_struct = sga.find_primitive() #prim_struct_sites = len(prim_struct.sites) #conv_struct = sga.get_conventional_standard_structure() #conv_struct_sites = len(conv_struct.sites) #conv_prim_ratio = int(conv_struct_sites / prim_struct_sites) # Default VASP settings def_vasp_incar_param = {'ISIF':2, 'EDIFF':1e-6, 'EDIFFG':0.001,} kpoint_den = 15000 # Create bulk structure and associated VASP files sc_scale = get_sc_scale(inp_struct=prim_struct, final_site_no=cellmax) blk_sc = prim_struct.copy() blk_sc.make_supercell(scaling_matrix=sc_scale) site_no = blk_sc.num_sites # Rescale if needed while site_no > cellmax: max_sc_dim = max(sc_scale) i = sc_scale.index(max_sc_dim) sc_scale[i] -= 1 blk_sc = prim_struct.copy() blk_sc.make_supercell(scaling_matrix=sc_scale) site_no = blk_sc.num_sites blk_str_sites = set(blk_sc.sites) custom_kpoints = Kpoints.automatic_density(blk_sc, kppa=kpoint_den) mpvis = MPMetalRelaxSet(blk_sc, user_incar_settings=def_vasp_incar_param, user_kpoints_settings=custom_kpoints) if mpid: root_fldr = mpid else: root_fldr = struct.composition.reduced_formula fin_dir = os.path.join(root_fldr, 'bulk') mpvis.write_input(fin_dir) if not mpid: # write the input structure if mpid is not used struct.to(fmt='poscar', filename=os.path.join(fin_dir, 'POSCAR.uc')) # Create each defect structure and associated VASP files # First find all unique defect sites periodic_struct = sga.get_symmetrized_structure() unique_sites = list(set([periodic_struct.find_equivalent_sites(site)[0] \ for site in periodic_struct.sites])) temp_struct = Structure.from_sites(sorted(unique_sites)) prim_struct2 = SpacegroupAnalyzer(temp_struct).find_primitive() prim_struct2.lattice = prim_struct.lattice # a little hacky for i, site in enumerate(prim_struct2.sites): vac = Vacancy(structure=prim_struct, defect_site=site) vac_sc = vac.generate_defect_structure(supercell=sc_scale) # Get vacancy site information vac_str_sites = set(vac_sc.sites) vac_sites = blk_str_sites - vac_str_sites vac_site = next(iter(vac_sites)) site_mult = vac.get_multiplicity() vac_site_specie = vac_site.specie vac_symbol = vac_site_specie.symbol custom_kpoints = Kpoints.automatic_density(vac_sc, kppa=kpoint_den) mpvis = MPMetalRelaxSet(vac_sc, user_incar_settings=def_vasp_incar_param, user_kpoints_settings=custom_kpoints) vac_dir = 'vacancy_{}_mult-{}_sitespecie-{}'.format( str(i+1), site_mult, vac_symbol) fin_dir = os.path.join(root_fldr, vac_dir) mpvis.write_input(fin_dir) # Antisites generation at the vacancy site struct_species = blk_sc.species for specie in set(struct_species) - set([vac_site_specie]): specie_symbol = specie.symbol anti_sc = vac_sc.copy() anti_sc.append(specie, vac_site.frac_coords) mpvis = MPMetalRelaxSet(anti_sc, user_incar_settings=def_vasp_incar_param, user_kpoints_settings=custom_kpoints) anti_dir = 'antisite_{}_mult-{}_sitespecie-{}_subspecie-{}'.format( str(i+1), site_mult, vac_symbol, specie_symbol) fin_dir = os.path.join(root_fldr, anti_dir) mpvis.write_input(fin_dir)
def set_kpoints(self, kpoint=None, poscar=None, ibzkpth=None): """ set the kpoint """ # useful to check if a poscar is supplied from setup_poscar_jobs (most often the case) # or this is a single poscar use case if not poscar: poscar = self.poscar # splitting into two if elif branches means fewer if statements to check on # a run # Most general method of setting the k-points for # different grid types # NOTE: requires that at least one k-points value be passed # as a turn - knobs list value # this is not true for values that may be caculated out of # a database # use this part only if this is a non-database run for example # for k-points calibration if not self.database: if self.Grid_type == 'M': self.kpoints = Kpoints.monkhorst_automatic(kpts=kpoint) elif self.Grid_type == 'A': self.kpoints = Kpoints.automatic(subdivisions=kpoint) elif self.Grid_type == 'G': self.kpoints = Kpoints.gamma_automatic(kpts=kpoint) elif self.Grid_type == '3D_vol': self.kpoints = Kpoints.automatic_density_by_vol(structure=poscar.structure, kppvol=kpoint) elif self.Grid_type == 'bulk_bands_pbe': self.kpoints = Kpoints.automatic_linemode(divisions=kpoint, ibz=HighSymmKpath( poscar.structure)) elif self.Grid_type == 'D': self.kpoints = Kpoints.automatic_density(structure=poscar.structure,kppa=kpoint) elif self.Grid_type == 'Finer_G_Mesh': # kpoint is the scaling factor and self.kpoints is the old kpoint mesh self.logger.info('Setting Finer G Mesh for {0} by scale {1}'.format(kpoint, self.finer_kpoint)) self.kpoints = Kpoints.gamma_automatic(kpts = \ [i * self.finer_kpoint for i in kpoint]) self.logger.info('Finished scaling operation of k-mesh') # applicable for database runs # future constructs or settinsg can be activated via a yaml file # database yaml file or better still the input deck from its speification # decides what combination of input calibrate constructor settings to use # one of them being the grid_type tag elif self.database == 'twod': # set of kpoints settings according to the 2D database profile # the actual settings of k-points density # will in future come from any database input file set if self.Grid_type == 'hse_bands_2D_prep': kpoint_dict = Kpoints.automatic_gamma_density(poscar.structure, 200).as_dict() kpoint_dict['kpoints'][0][2] = 1 # remove z kpoints self.kpoints = Kpoints.from_dict(kpoint_dict) elif self.Grid_type == 'hse_bands_2D': # can at most return the path to the correct kpoints file # needs kpoints to be written out in instrument in a different way # not using the Kpoints object self.kpoints = get_2D_hse_kpoints(poscar.structure, ibzkpth) elif self.Grid_type == 'bands_2D': kpoint_dict = Kpoints.automatic_linemode(divisions=20, ibz=HighSymmKpath(poscar.structure)).as_dict() self.kpoints = Kpoints.from_dict(kpoint_dict) elif self.Grid_type == 'relax_2D': # general relaxation settings for 2D kpoint_dict = Kpoints.automatic_gamma_density(poscar.structure, 1000).as_dict() kpoint_dict['kpoints'][0][2] = 1 self.kpoints = Kpoints.from_dict(kpoint_dict) elif self.Grid_type == 'relax_3D': # general relaxation settings for 3D kpoint_dict = Kpoints.automatic_gamma_density( poscar.structure, 1000) self.kpoints = Kpoints.from_dict(kpoint_dict)
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 substitute_def_struct_gen(mpid, solute, mapi_key, cellmax, struct_file=None): if not mpid and not struct_file: print ("============\nERROR: Provide an mpid\n============") return if not solute: print ("============\nERROR: Provide solute atom\n============") return # Get primitive structure from the Materials Project DB if not struct_file: if not mapi_key: with MPRester() as mp: struct = mp.get_structure_by_material_id(mpid) else: with MPRester(mapi_key) as mp: struct = mp.get_structure_by_material_id(mpid) else: struct = Structure.from_file(struct_file) if mpid: root_fldr = mpid else: root_fldr = struct.composition.reduced_formula sga = SpacegroupAnalyzer(struct) prim_struct = sga.find_primitive() #prim_struct_sites = len(prim_struct.sites) #conv_struct = sga.get_conventional_standard_structure() #conv_struct_sites = len(conv_struct.sites) #conv_prim_ratio = int(conv_struct_sites / prim_struct_sites) # Default VASP settings def_vasp_incar_param = {'ISIF':2, 'EDIFF':1e-6, 'EDIFFG':0.001,} kpoint_den = 15000 # Create each substitutional defect structure and associated VASP files sc_scale = get_sc_scale(inp_struct=prim_struct, final_site_no=cellmax) blk_sc = prim_struct.copy() blk_sc.make_supercell(scaling_matrix=sc_scale) site_no = blk_sc.num_sites # Rescale if needed while site_no > cellmax: max_sc_dim = max(sc_scale) i = sc_scale.index(max_sc_dim) sc_scale[i] -= 1 blk_sc = prim_struct.copy() blk_sc.make_supercell(scaling_matrix=sc_scale) site_no = blk_sc.num_sites # Create solute structures at vacancy sites # First find all unique defect sites blk_str_sites = set(blk_sc.sites) symm_struct = SpacegroupAnalyzer(prim_struct).get_symmetrized_structure() unique_sites = sorted([site[0] for site in symm_struct.equivalent_sites], \ key=lambda s: s.species_string) for i, site in enumerate(unique_sites): vac = Vacancy(structure=prim_struct, defect_site=site) vac_sc = vac.generate_defect_structure(supercell=sc_scale) # Get vacancy site information vac_str_sites = set(vac_sc.sites) vac_sites = blk_str_sites - vac_str_sites vac_site = next(iter(vac_sites)) vac_specie = vac_site.specie.symbol site_mult = vac.get_multiplicity() # Solute substitution defect generation at the vacancy site solute_struct = vac_sc.copy() solute_struct.append(solute, vac_site.frac_coords) custom_kpoints = Kpoints.automatic_density(solute_struct, kppa=kpoint_den) mpvis = MPMetalRelaxSet(solute_struct, user_incar_settings=def_vasp_incar_param, user_kpoints_settings=custom_kpoints) # Generate VASP directory sub_def_dir ='solute_{}_mult-{}_sitespecie-{}_subspecie-{}'.format( str(i+1), site_mult, vac_specie, solute) fin_dir = os.path.join(root_fldr, sub_def_dir) mpvis.write_input(fin_dir)
def get_kpts(screener, cif_file, level): """ Obtain the number of kpoints Args: screener (class): pymofscreen.screener class cif_file (string): name of CIF file level (string): accuracy level Returns: kpts (list of ints): kpoint grid gamma (bool): True for gamma-centered """ niggli = screener.niggli mofpath = screener.mofpath kpts_path = screener.kpts_path kppas = screener.kppas kpts = None if not mofpath: mofpath = '' if kpts_path == 'Auto': if level == 'low': kppa = kppas[0] elif level == 'high': kppa = kppas[1] else: raise ValueError('kpoints accuracy level not defined') filepath = os.path.join(mofpath, cif_file) if '.cif' in cif_file: parser = CifParser(filepath) pm_mof = parser.get_structures(primitive=niggli)[0] else: pm_mof = pm.Structure.from_file(filepath, primitive=niggli) pm_kpts = Kpoints.automatic_density(pm_mof, kppa) kpts = pm_kpts.kpts[0] if pm_kpts.style.name == 'Gamma': gamma = True else: gamma = None else: old_cif_name = cif_file.split('.cif')[0].split('_')[0] infile = open(kpts_path, 'r') lines = infile.read().splitlines() infile.close() for i in range(len(lines)): if old_cif_name in lines[i]: if level == 'low': kpts = lines[i + 1] gamma = lines[i + 2] elif level == 'high': kpts = lines[i + 3] gamma = lines[i + 4] else: raise ValueError('Incompatible KPPA with prior runs') break kpts = np.squeeze(np.asarray(np.matrix(kpts))).tolist() if not kpts or len(kpts) != 3: raise ValueError('Error parsing k-points for ' + cif_file) if gamma == 'True': gamma = True elif gamma == 'False': gamma = False else: raise ValueError('Error parsing gamma for ' + cif_file) return kpts, gamma