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
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 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 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 SortAtomListBySpecies(self): """Returns a dictionary with atoms sorted according to species The dictionary will have the atomtypes of the different atomic species found in the list of atoms as keys. The corresponding values will be a list of atoms containing the atoms of the given type. """ dictofspecies = {} for atom in self.GetListOfAtoms(): if dictofspecies.has_key(atom.GetChemicalSymbol()): dictofspecies[atom.GetChemicalSymbol()].append(atom.Copy()) else: atomlist = self.GetListOfAtoms().Copy() atomlist.data = ListOfAtoms([atom.Copy()]) unitcell = copy.copy(atomlist.GetUnitCell()) atomlist.data.SetUnitCell(unitcell, fix=True) dictofspecies[atom.GetChemicalSymbol()] = atomlist.data return dictofspecies
def afunc(var, data=None): rcs, rcp = var[0], var[1] f = open("base.fdf", "w") f.write("%block PAO.Basis\n Ga 2\n") f.write(" 0 1\n") f.write("%10.5f\n1.0\n" % (rcs, )) f.write("1 1\n") f.write("%10.5f\n1.0\n" % (rcp, )) f.write("%endblock PAO.Basis\n") f.close() atoms = ListOfAtoms([ Atom('Ga', (0.0, 0.0, 0.0), magmom=0), Atom('Ga', (2.0, 0.0, 0.0), magmom=0) ]) a = Siesta(executable="/Users/ag/bin/siesta-xlf") a.SetOption("%include", "base.fdf") energy = a.run(atoms) print rcs, rcp, energy return -energy
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
1.00000 1.00000 n=6 1 2 E 2.50435 0.86601 6.12615 5.62330 1.00000 1.00000 n=6 2 1 E 135.64896 4.82387 5.14075 1.00000 %EndBlock PAO.Basis """) URLbase = "http://fisica.ehu.es/ag/siesta-psffiles/" urllib.urlretrieve(URLbase + "Pb.psf", "Pb.psf") cell = Num.array([ [0.5,0.5,0.0], [0.5,0.0,0.5], [0.0,0.5,0.5]]) cell = 4.89*cell atoms = ListOfAtoms([Atom('Pb', (0.0,0.0,0.0))], cell=cell, periodic=1) for i in range(len(cutoffs)): cutoff = cutoffs[i] print i, cutoff a = Siesta(executable="$HOME/bin/siesta-2.6.9") # Initialize object ### a.SetOption("FilterCutoff"," 100.0 Ry") # Optional Filtering a.SetOption("Meshcutoff", str(cutoff)+" Ry") a.SetOption("%include"," basis.fdf") energy[i], dum, dum2 = a.run(atoms) # Run Siesta and get the (free)energy # # Plot # p.add(biggles.Curve(cutoffs[:],energy[:])) p.show()
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
# create a work subdirectory orig_dir = os.getcwd() dir = "bond_work" if os.path.isdir(dir): # does dir exist? shutil.rmtree(dir) # yes, remove old directory os.mkdir(dir) # make dir directory os.chdir(dir) # move to dir URLbase = "http://fisica.ehu.es/ag/siesta-psffiles/" urllib.urlretrieve(URLbase + "H.psf", "H.psf") urllib.urlretrieve(URLbase + "O.psf", "O.psf") for i in range(len(bonds)): d = bonds[i] print i, d atoms = ListOfAtoms([ Atom('H', (d * math.cos(theta), d * math.sin(theta), 0.0), magmom=1), Atom('H', (-d * math.cos(theta), d * math.sin(theta), 0.0), magmom=1), Atom('O', (0, 0, 0), magmom=1) ]) # cell=(4, 4, 4), periodic=1) energy[i] = a.run(atoms) # Run Siesta and get the (free)energy # # Plot # p.add(biggles.Curve(bonds[:], energy[:])) p.show() os.chdir(orig_dir)
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