def get_incar(self, structure): incar = Incar() if self.sort_structure: structure = structure.get_sorted_structure() comp = structure.composition elements = sorted([el for el in comp.elements if comp[el] > 0], key=lambda el: el.X) most_electroneg = elements[-1].symbol poscar = Poscar(structure) for key, setting in self.incar_settings.items(): if key == "MAGMOM": mag = [] for site in structure: if hasattr(site, 'magmom'): mag.append(site.magmom) elif hasattr(site.specie, 'spin'): mag.append(site.specie.spin) elif str(site.specie) in setting: mag.append(setting.get(str(site.specie))) else: mag.append(setting.get(site.specie.symbol, 0.6)) incar[key] = mag elif key in ('LDAUU', 'LDAUJ', 'LDAUL'): if most_electroneg in setting.keys(): incar[key] = [ setting[most_electroneg].get(sym, 0) for sym in poscar.site_symbols ] else: incar[key] = [0] * len(poscar.site_symbols) elif key == "EDIFF": incar[key] = float(setting) * structure.num_sites else: incar[key] = setting has_u = ("LDAUU" in incar and sum(incar['LDAUU']) > 0) if has_u: # modify LMAXMIX if LSDA+U and you have d or f electrons # note that if the user explicitly sets LMAXMIX in settings it will # override this logic. if 'LMAXMIX' not in self.incar_settings.keys(): # contains f-electrons if any([el.Z > 56 for el in structure.composition]): incar['LMAXMIX'] = 6 # contains d-electrons elif any([el.Z > 20 for el in structure.composition]): incar['LMAXMIX'] = 4 else: for key in incar.keys(): if key.startswith('LDAU'): del incar[key] if self.set_nupdown: nupdown = sum([mag if mag > 0.6 else 0 for mag in incar['MAGMOM']]) incar['NUPDOWN'] = nupdown return incar
def run_aconvasp_command(command, structure): """ Helper function for calling aconvasp with different arguments """ poscar = Poscar(structure) p = subprocess.Popen(command, stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) output = p.communicate(input=poscar.get_string()) return output
def test_str(self): si = 14 coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) #Silicon structure for testing. latt = [[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]] struct = Structure(latt, [si, si], coords) poscar = Poscar(struct) expected_str = '''Si2 1.0 3.840198 0.000000 0.000000 1.920099 3.325710 0.000000 0.000000 -2.217138 3.135509 Si 2 direct 0.000000 0.000000 0.000000 Si 0.750000 0.500000 0.750000 Si ''' self.assertEquals(str(poscar), expected_str, "Wrong POSCAR output!") #Vasp 4 type with symbols at the end. poscar_string = """Test1 1.0 -3.840198 0.000000 0.000000 1.920099 3.325710 0.000000 0.000000 -2.217138 3.135509 1 1 direct 0.000000 0.000000 0.000000 Si 0.750000 0.500000 0.750000 F """ expected = """Test1 1.0 3.840198 -0.000000 -0.000000 -1.920099 -3.325710 -0.000000 -0.000000 2.217138 -3.135509 Si F 1 1 direct 0.000000 0.000000 0.000000 Si 0.750000 0.500000 0.750000 F """ poscar = Poscar.from_string(poscar_string) self.assertEqual(str(poscar), expected)
def plot_images(self, outfile): """ Generates a POSCAR with the calculated diffusion path with respect to the first endpoint. :param outfile: Output file for the POSCAR """ sum_struct = self.__images[0].sites for image in self.__images: for site_i in self.__relax_sites: sum_struct.append( PeriodicSite(image.sites[site_i].specie, image.sites[site_i].frac_coords, self.__images[0].lattice, to_unit_cell=True, coords_are_cartesian=False)) sum_struct = Structure.from_sites(sum_struct, validate_proximity=False) p = Poscar(sum_struct) p.write_file(outfile)
def test_str(self): si = 14 coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) #Silicon structure for testing. latt = [[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]] struct = Structure(latt, [si, si], coords) poscar = Poscar(struct) expected_str = '''Si2 1.0 3.840198 0.000000 0.000000 1.920099 3.325710 0.000000 0.000000 -2.217138 3.135509 Si 2 direct 0.000000 0.000000 0.000000 Si 0.750000 0.500000 0.750000 Si''' self.assertEquals(str(poscar), expected_str, "Wrong POSCAR output!")
def test_velocities(self): si = 14 coords = list() coords.append([0, 0, 0]) coords.append([0.75, 0.5, 0.75]) #Silicon structure for testing. latt = [[3.8401979337, 0.00, 0.00], [1.9200989668, 3.3257101909, 0.00], [0.00, -2.2171384943, 3.1355090603]] struct = Structure(latt, [si, si], coords) poscar = Poscar(struct) poscar.set_temperature(900) v = np.array(poscar.velocities) for x in np.sum(v, axis=0): self.assertAlmostEqual( x, 0, 7, 'Velocities initialized with a net momentum') temperature = struct[0].specie.atomic_mass * AMU_TO_KG * \ np.sum(v ** 2) / (3 * BOLTZMANN_CONST) * 1e10 self.assertAlmostEqual(temperature, 900, 4, 'Temperature instantiated incorrectly')
def get_new_poscar_lines(self): """ Pymatgen does not realize that decorated elements (species) should be treated as different sites in VASP. This routine hacks the poscar file (which has already been hacked to go from 5.x to 4.6) to include the correct number of distinct sites. """ self.check_structure_is_modified() # get a poscar consistent with the internally modified structure poscar = Poscar(self.structure) lines = poscar.get_string(vasp4_compatible=True).split('\n') hack_line = '' for element, number in self.species_dict.items(): hack_line += ' %i'%number lines[5] = hack_line return lines
def look4VacantPosition(): """ """ s = mg.Structure.from_file(sys.argv[1]) fill_s = s.copy() grid = mg.Structure(s.lattice, [], []) # grid step in frac coords step = 0.1 # radius for looking for neighbors radius = 2.5 # threshold to exclude vacant position els = s.composition.elements th = {els[0]: 1.7, els[1]: 2., els[2]: 2.} # grid ranges xmin = 0 xmax = 1 ymin = 0 ymax = 1 zmin = 0 zmax = 1 print("Parameters\n" + 10 * "-") print("Grid step : %6.2f" % step) print("Neighbors radius : %6.2f" % radius) print("threshold tolerence:") for el, dmax in th.items(): print("X - %2s : %8.3f" % (el.symbol, dmax)) vaclist = list() for xi in np.arange(xmin, xmax, step): for yi in np.arange(ymin, ymax, step): for zi in np.arange(zmin, zmax, step): vacsite = mg.PeriodicSite("X", [xi, yi, zi], s.lattice) neigh = s.get_neighbors(vacsite, radius) grid.append("X", [xi, yi, zi]) add = True nLi = 0 for neighsite, d in neigh: dmax = th[neighsite.specie] if d < dmax: add = False break if neighsite.specie.symbol == "Li": nLi += 1 if nLi >= 2: print("nLi >= 2") add = False if add: fill_s.append(vacsite.specie, vacsite.frac_coords) vaclist.append([xi, yi, zi]) print("\nResults\n" + 7 * "-") print( "Write file 'POSCAR_fill.vasp': initial structure + vacant positions") Poscar(fill_s).write_file("POSCAR_fill.vasp") print("Write file 'POSCAR_grid.vasp': grid positions (%d atoms)" % len(grid)) Poscar(grid).write_file("POSCAR_grid.vasp") print("\nNumber of positions : %d" % len(vaclist)) if len(vaclist) < 30: for xyz in vaclist: print((3 * "%8.3f") % tuple(xyz))
#separate slab iface_slab = iface.slab iface_slab.sort() #set selective dynamics flags as required true_site= [1, 1, 1] false_site= [0, 0, 0] sd_flag_iface= [] j= 0 sd_flag_slab= [] for i in iface.sites: sd_flag_iface.append(false_site) for i in iface_slab.sites: sd_flag_slab.append(false_site) #POSCAR and POTCAR construction, pending setting of exact flags for POSCAR interface_poscar = Poscar(iface, selective_dynamics= sd_flag_iface) interface_potcar= Potcar(interface_poscar.site_symbols) slab_poscar = Poscar(iface_slab, selective_dynamics= sd_flag_slab) slab_potcar= Potcar(slab_poscar.site_symbols) #write the files in appropriate directories interface_poscar.write_file("./Interface/POSCAR_PbS100DMF_interface_with_sd.vasp") slab_poscar.write_file("./Slab/POSCAR_PbS100_slab_with_sd.vasp") interface_potcar.write_file("./Interface_with_vdw/POTCAR") slab_potcar.write_file("./Slab_with_vdw/POTCAR") #set the common INCAR file and KPOINTS incar_dict = { 'SYSTEM': 'ligand_PbS', 'ENCUT': 600, 'ISIF': 2,
def get_poscar(self, structure): """ Returns Poscar from a structure. """ return Poscar(structure)
def get_VASP_inputs(structure, workdir, job_name, nproc=64, kppa=500, extra_incar_dict = None): if os.path.exists(workdir): print 'WORKDIR ALREADY EXISTS. DELETE TO LAUNCH NEW JOB' return -1 poscar = Poscar(structure) list_potcar_singles, potcar= get_POTCAR(poscar) kpoints = Kpoints.automatic_density(structure, kppa=kppa) # Default values incar_dict = dict( SYSTEM = structure.formula, # Name of job LREAL = 'Auto', # Should projections be done in real space? Let VASP decide ENCUT = 520., # 520. eV, just like Ceder IBRION = 2, # Controls ionic relataxion: 1-> DISS, 2 -> CG, 3-> MD EDIFF = 1E-7, # criterion to stop SCF loop, in eV EDIFFG = -1E-3, # criterion to stop ionic relaxations. Negative means FORCES < |EDIFFG| PREC = 'HIGH', # level of precision AMIX = 0.2, AMIX_MAG= 0.8, BMIX = 0.001, BMIX_MAG= 0.001, NSW = 150, # Maximum number of ionic steps ISMEAR = 0, # smearing scheme. Use 0 for insulators, as suggested by VASPWIKI ISPIN = 2, # spin polarized NPAR = 8, # VASPWIKI recommends sqrt(ncore) LSCALU = False, # Don't use scalapack. Probably a can of worms. ALGO = 'NORMAL', # what ionic relaxation scheme to use? LORBIT = 11, # 11 prints out the DOS ISIF = 3, # Controls the computation of stress tensor. 3 computes everything NSIM = 4, # how many bands to treat in parallel? Default is 4, probably fine. SIGMA = 0.025, # smearing in eV LMAXMIX = 4, # Description: LMAXMIX controls up to which l-quantum number the one-center PAW charge densities are passed through the charge density mixer. MaterialsProject uses 4. LCHARG = False, # Write charge densities? LWAVE = False, # write out the wavefunctions? LPLANE = True, # Plane distribution of FFT coefficients. Reduces communications in FFT. NELM = 100, # maximum number of SCF cycles. NELMDL = -10, # since initial orbitals may be random, fixes hamiltonian for |NELM| SCF cycles to give wf a chance to simmer down. ISTART = 0, # begin from scratch! ISYM = 2) # use symmetry if extra_incar_dict != None: incar_dict.update( extra_incar_dict ) incar = Incar.from_dict(incar_dict ) incar.write_file(workdir+'INCAR') poscar.write_file(workdir+'POSCAR', vasp4_compatible = True) kpoints.write_file(workdir+'KPOINTS') potcar.write_file(workdir+'POTCAR') potcar.sort() hack_potcar_file(workdir,list_potcar_singles) with open(workdir+'job.sh','w') as f: f.write(submit_template.format(job_name,nproc)) with open(workdir+'clean.sh','w') as f: f.write(clean_template) return 0
def get_poscar(self, structure): sym_finder = SymmetryFinder(structure, symprec=0.01) return Poscar(sym_finder.get_primitive_standard_structure())
def get_poscar(self, structure): if self.sort_structure: structure = structure.get_sorted_structure() return Poscar(structure)
def get_poscar(self, structure): return Poscar(structure)
def get_calibration_task(structure, phase="CalibrateBulk", \ slab_interface_params={'hkl':[1,0,0], 'ligand': None},\ turn_knobs={}, incar_params={}, other_params={}): """ returns general calibration task for a structure Args: structure : pymatgen structure to be calibrated (can be a bulk, ligand, slab or interface) phase : calibration type, viz. CalibrateBulk, CalibrateMolecule, CalibrateSlab, CalibrateInterface hkl : in case of Slab and Interface miller indices of facet turn_knobs : specifies the parameters to be calibrated incar_params : dictionary of additional incar parameters, refer defined incar_dict for defaults other_params : other parameters for calibration, viz. job_dir, is_matrix, etc. described in the calibrate module """ #structure definition poscar = Poscar(structure) incar_dict = { 'SYSTEM': 'slab', 'ENCUT': 500, 'ISIF': 2, 'IBRION': 2, 'ISMEAR': 1, 'EDIFF': 1e-05, 'NPAR': 4, 'SIGMA': 0.1, 'PREC': 'Accurate' } if incar_params: incar_dict.update(incar_params) incar = Incar.from_dict(incar_dict) kpoints = Kpoints.monkhorst_automatic(kpts=(8, 8, 1)) que = { 'nnodes': 1, 'nprocs': 16, 'walltime': '48:00:00', 'job_bin': '/home/km468/Software/VASP/vaspsol_kappa.5.3.5/vasp' } # calibration task: relax hkl calparams = {} calparams['calibrate'] = phase calparams['incar'] = incar.as_dict() calparams['poscar'] = poscar.as_dict() calparams['kpoints'] = kpoints.as_dict() calparams['que_params'] = que calparams['turn_knobs'] = turn_knobs if phase == 'CalibrateSlab': calparams['system'] = { 'hkl': slab_interface_params['hkl'], 'ligand': slab_interface_params['ligand'] } elif phase == 'CalibrateInterface': calparams['system'] = { 'hkl': hkl, 'ligand': structure.ligand.reduced_formula } calparams['other_params'] = { 'is_matrix': False, 'from_ase': True, 'Grid_type': 'M' } if other_params: calparams['other_params'].update(other_params) return MPINTCalibrateTask(calparams)