def test2(pw=300, kpts=(6, 6, 6), vaspcmd='mr vasp'): """Performs a test stress-strain calculation with vasp module for fcc Pt.""" v = VASP(pw=pw, kpts=kpts, name='fccPt', vaspcmd=vaspcmd) from ASE import ListOfAtoms, Atom atoms = ListOfAtoms([ Atom('Pt', [0, 0, 0]), Atom('Pt', [0.5, 0.5, 0]), Atom('Pt', [0.5, 0, 0.5]), Atom('Pt', [0, 0.5, 0.5]) ]) uc = [[4.05, 0, 0], [0.0, 4.05, 0], [0.0, 0, 4.05]] atoms.SetUnitCell(uc) atoms.SetCalculator(v) import ASE.Utilities.GeometricTransforms as ASEgeotrans initvol = atoms.GetUnitCellVolume() vols, energies = [], [] #for f in [0.8, 0.85, 0.9, 0.95, 1.0, 1.05, 1.1, 1.15]: for f in [0.9, 0.95, 1.0, 1.05, 1.1]: ASEgeotrans.SetUnitCellVolume(atoms, f * initvol) #v.SetName('%1.2f_eos' % f) #print v.GetStress() vols.append(atoms.GetUnitCellVolume()) energies.append(atoms.GetPotentialEnergy()) import pylab as pl pl.plot(vols, energies, 'ko ') pl.show() import ASE.Utilities.EquationOfState as ASEeos eos = ASEeos.EquationOfState('Murnaghan', vols, energies) # print the minimum volume, energy, bulk modulus and pressure print eos g = eos.GetPlot() eos.SavePlot('murn.png') #save the figure as a png return
def test1(pw=300, kpts=(6, 6, 6), vaspcmd='mr vasp'): """Performs a test single-point energy calculation with vasp module for B2 FeAl.""" print "Test single-point energy calculation with vasp module for B2 FeAl." v = VASP(pw=pw, kpts=kpts, name='FeAl', vaspcmd=vaspcmd) from ASE import ListOfAtoms, Atom atoms = ListOfAtoms( [Atom('Fe', [0.0, 0.0, 0.0]), Atom('Al', [0.5, 0.5, 0.5])]) uc = [[2.87, 0.00, 0.00], [0.00, 2.87, 0.00], [0.00, 0.00, 2.87]] atoms.SetUnitCell(uc) atoms.SetCalculator(v) print "Potential energy: ", v.GetPotentialEnergy() return
class OldASECalculatorWrapper: def __init__(self, calc, atoms=None): self.calc = calc if atoms is None: try: self.atoms = calc.GetListOfAtoms() except AttributeError: self.atoms = None else: from ASE import Atom, ListOfAtoms numbers = atoms.get_atomic_numbers() positions = atoms.get_positions() magmoms = atoms.get_initial_magnetic_moments() self.atoms = ListOfAtoms( [Atom(Z=numbers[a], position=positions[a], magmom=magmoms[a]) for a in range(len(atoms))], cell=npy2num(atoms.get_cell()), periodic=tuple(atoms.get_pbc())) self.atoms.SetCalculator(calc) def get_atoms(self): return OldASEListOfAtomsWrapper(self.atoms) def get_potential_energy(self, atoms): self.atoms.SetCartesianPositions(npy2num(atoms.get_positions())) self.atoms.SetUnitCell(npy2num(atoms.get_cell()), fix=True) return self.calc.GetPotentialEnergy() def get_forces(self, atoms): self.atoms.SetCartesianPositions(npy2num(atoms.get_positions())) self.atoms.SetUnitCell(npy2num(atoms.get_cell()), fix=True) return np.array(self.calc.GetCartesianForces()) def get_stress(self, atoms): self.atoms.SetCartesianPositions(npy2num(atoms.get_positions())) self.atoms.SetUnitCell(npy2num(atoms.get_cell()), fix=True) return np.array(self.calc.GetStress()) def get_number_of_bands(self): return self.calc.GetNumberOfBands() def get_kpoint_weights(self): return np.array(self.calc.GetIBZKPointWeights()) def get_number_of_spins(self): return 1 + int(self.calc.GetSpinPolarized()) def get_eigenvalues(self, kpt=0, spin=0): return np.array(self.calc.GetEigenvalues(kpt, spin)) def get_fermi_level(self): return self.calc.GetFermiLevel() def get_number_of_grid_points(self): return np.array(self.get_pseudo_wave_function(0, 0, 0).shape) def get_pseudo_wave_function(self, n=0, k=0, s=0, pad=True): kpt = self.get_bz_k_points()[k] state = self.calc.GetElectronicStates().GetState(band=n, spin=s, kptindex=k) # Get wf, without bolch phase (Phase = True doesn't do anything!) wave = state.GetWavefunctionOnGrid(phase=False) # Add bloch phase if this is not the Gamma point if np.all(kpt == 0): return wave coord = state.GetCoordinates() phase = coord[0] * kpt[0] + coord[1] * kpt[1] + coord[2] * kpt[2] return np.array(wave) * np.exp(-2.j * np.pi * phase) # sign! XXX #return np.array(self.calc.GetWaveFunctionArray(n, k, s)) # No phase! def get_bz_k_points(self): return np.array(self.calc.GetBZKPoints()) def get_ibz_k_points(self): return np.array(self.calc.GetIBZKPoints()) def get_wannier_localization_matrix(self, nbands, dirG, kpoint, nextkpoint, G_I, spin): return np.array(self.calc.GetWannierLocalizationMatrix( G_I=G_I.tolist(), nbands=nbands, dirG=dirG.tolist(), kpoint=kpoint, nextkpoint=nextkpoint, spin=spin)) def initial_wannier(self, initialwannier, kpointgrid, fixedstates, edf, spin): # Use initial guess to determine U and C init = self.calc.InitialWannier(initialwannier, self.atoms, npy2num(kpointgrid, num.Int)) states = self.calc.GetElectronicStates() waves = [[state.GetWaveFunction() for state in states.GetStatesKPoint(k, spin)] for k in self.calc.GetIBZKPoints()] init.SetupMMatrix(waves, self.calc.GetBZKPoints()) c, U = init.GetListOfCoefficientsAndRotationMatrices( (self.calc.GetNumberOfBands(), fixedstates, edf)) U = np.array(U) for k in range(len(c)): c[k] = np.array(c[k]) return c, U
class Dacapo: def __init__(self, filename=None, stay_alive=False, stress=False, **kwargs): self.kwargs = kwargs self.stay_alive = stay_alive self.stress = stress if filename is not None: from Dacapo import Dacapo self.loa = Dacapo.ReadAtoms(filename, **kwargs) self.calc = self.loa.GetCalculator() else: self.loa = None self.calc = None self.pps = [] def set_pp(self, Z, path): self.pps.append((Z, path)) def set_txt(self, txt): if self.calc is None: self.kwargs['txtout'] = txt else: self.calc.SetTxtFile(txt) def set_nc(self, nc): if self.calc is None: self.kwargs['out'] = nc else: self.calc.SetNetCDFFile(nc) def update(self, atoms): from Dacapo import Dacapo if self.calc is None: if 'nbands' not in self.kwargs: n = sum([valence[atom.symbol] for atom in atoms]) self.kwargs['nbands'] = int(n * 0.65) + 4 magmoms = atoms.get_initial_magnetic_moments() if magmoms.any(): self.kwargs['spinpol'] = True self.calc = Dacapo(**self.kwargs) if self.stay_alive: self.calc.StayAliveOn() else: self.calc.StayAliveOff() if self.stress: self.calc.CalculateStress() for Z, path in self.pps: self.calc.SetPseudoPotential(Z, path) if self.loa is None: from ASE import Atom, ListOfAtoms numbers = atoms.get_atomic_numbers() positions = atoms.get_positions() magmoms = atoms.get_initial_magnetic_moments() self.loa = ListOfAtoms([ Atom(Z=numbers[a], position=positions[a], magmom=magmoms[a]) for a in range(len(atoms)) ], cell=np2num(atoms.get_cell()), periodic=tuple(atoms.get_pbc())) self.loa.SetCalculator(self.calc) else: self.loa.SetCartesianPositions(np2num(atoms.get_positions())) self.loa.SetUnitCell(np2num(atoms.get_cell()), fix=True) def get_atoms(self): atoms = OldASEListOfAtomsWrapper(self.loa).copy() atoms.set_calculator(self) return atoms def get_potential_energy(self, atoms): self.update(atoms) return self.calc.GetPotentialEnergy() def get_forces(self, atoms): self.update(atoms) return np.array(self.calc.GetCartesianForces()) def get_stress(self, atoms): self.update(atoms) stress = np.array(self.calc.GetStress()) if stress.ndim == 2: return stress.ravel()[[0, 4, 8, 5, 2, 1]] else: return stress def calculation_required(self, atoms, quantities): if self.calc is None: return True if atoms != self.get_atoms(): return True return False def get_number_of_bands(self): return self.calc.GetNumberOfBands() def get_k_point_weights(self): return np.array(self.calc.GetIBZKPointWeights()) def get_number_of_spins(self): return 1 + int(self.calc.GetSpinPolarized()) def get_eigenvalues(self, kpt=0, spin=0): return np.array(self.calc.GetEigenvalues(kpt, spin)) def get_fermi_level(self): return self.calc.GetFermiLevel() def get_number_of_grid_points(self): return np.array(self.get_pseudo_wave_function(0, 0, 0).shape) def get_pseudo_density(self, spin=0): return np.array(self.calc.GetDensityArray(s)) def get_pseudo_wave_function(self, band=0, kpt=0, spin=0, pad=True): kpt_c = self.get_bz_k_points()[kpt] state = self.calc.GetElectronicStates().GetState(band=band, spin=spin, kptindex=kpt) # Get wf, without bloch phase (Phase = True doesn't do anything!) wave = state.GetWavefunctionOnGrid(phase=False) # Add bloch phase if this is not the Gamma point if np.all(kpt_c == 0): return wave coord = state.GetCoordinates() phase = coord[0] * kpt_c[0] + coord[1] * kpt_c[1] + coord[2] * kpt_c[2] return np.array(wave) * np.exp(-2.j * np.pi * phase) # sign! XXX #return np.array(self.calc.GetWaveFunctionArray(n, k, s)) # No phase! def get_bz_k_points(self): return np.array(self.calc.GetBZKPoints()) def get_ibz_k_points(self): return np.array(self.calc.GetIBZKPoints()) def get_wannier_localization_matrix(self, nbands, dirG, kpoint, nextkpoint, G_I, spin): return np.array( self.calc.GetWannierLocalizationMatrix(G_I=G_I.tolist(), nbands=nbands, dirG=dirG.tolist(), kpoint=kpoint, nextkpoint=nextkpoint, spin=spin)) def initial_wannier(self, initialwannier, kpointgrid, fixedstates, edf, spin): # Use initial guess to determine U and C init = self.calc.InitialWannier(initialwannier, self.atoms, np2num(kpointgrid, num.Int)) states = self.calc.GetElectronicStates() waves = [[ state.GetWaveFunction() for state in states.GetStatesKPoint(k, spin) ] for k in self.calc.GetIBZKPoints()] init.SetupMMatrix(waves, self.calc.GetBZKPoints()) c, U = init.GetListOfCoefficientsAndRotationMatrices( (self.calc.GetNumberOfBands(), fixedstates, edf)) U = np.array(U) for k in range(len(c)): c[k] = np.array(c[k]) return c, U
def ReadAtoms(name='.'): """Static method to read in the atoms.""" f = open('POSCAR', 'r') lines = f.readlines() f.close() comment = lines[0] uc = [] uc.append([float(x) for x in lines[2].split()]) uc.append([float(x) for x in lines[3].split()]) uc.append([float(x) for x in lines[4].split()]) scalefactor = float(lines[1].strip()) if scalefactor < 0: #that means this is the volume of the cell #vol = determinant of the uc vol0 = abs(num.determinant(uc)) uc = abs(scalefactor) / vol0 * uc else: uc = scalefactor * num.array(uc) atomcounts = [int(x) for x in lines[5].split()] natoms = 0 for count in atomcounts: natoms += count if lines[6][0] in ['s', 'S']: #selective dynamics were chosen, and positions start on line 7 coordsys = lines[7][0] poscounter = 8 else: coordsys = lines[6][0] poscounter = 7 positions = [] for i in range(natoms): pos = num.array([float(x) for x in lines[poscounter + i].split()]) if coordsys[0] in ['C', 'c', 'K', 'k']: #cartesian coordinates, do nothing pass else: #direct coordinates. calculate cartesian coords pos = pos[0] * uc[0] + pos[1] * uc[1] + pos[2] * uc[2] positions.append(pos) positions = num.array(positions) #now get the identities from the POTCAR file. f = open('POTCAR', 'r') lines = f.readlines() f.close() #the start of each psp is either 'US symbol' 'PAW_GGA symbol #comment' or 'PAW_PBE symbol comment' tag, symbol = lines[0].split() regexp = re.compile('^\s+%s' % tag) psps = [] for line in lines: if regexp.search(line): psps.append(line) #print atomcounts, psps if len(atomcounts) != len(psps): raise Exception, 'number of atom counts in POSCAR does not equal # of psps in POTCAR' from ASE import Atom, ListOfAtoms atoms = ListOfAtoms([]) poscounter = 0 for i, count in enumerate(atomcounts): tag, symbol = psps[i].split() for j in range(count): atoms.append(Atom(symbol, position=positions[poscounter])) poscounter += 1 atoms.SetUnitCell(uc, fix=True) if os.path.exists('OUTCAR'): f = open('OUTCAR', 'r') regexp = re.compile('TOTAL-FORCE \(eV/Angst\)') lines = f.readlines() f.close() forcei = None for i, line in enumerate(lines): if regexp.search(line): forcei = i + 2 #linenumber that forces start on break if forcei is None: raise Exception, 'forcei is none, no forces found!' forces = [] for i in range(len(atoms)): posforce = [float(x) for x in lines[forcei + i].split()] forces.append(posforce[3:]) else: forces = [None for atom in atoms] for atom, force in zip(atoms, forces): #print force atom._SetCartesianForce(force) ### more code must be added to read in the calculator. calc = VASP() calc.incar = parser2.INPUT2('INCAR') return atoms