def aucu_phonons(): N = 7 atoms = bulk("Au", crystalstructure="fcc", a=4.08) calc = EMT() atoms.set_calculator(calc) ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05) ph.run() ph.read(acoustic=True) ph.clean() omega_e_au, dos_e_au = ph.dos(kpts=(50, 50, 50), npts=1000, delta=5E-4) atoms = bulk("Cu", crystalstructure="fcc", a=3.62) atoms.set_calculator(calc) ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05) ph.run() ph.read(acoustic=True) ph.clean() omega_e_cu, dos_e_cu = ph.dos(kpts=(13, 13, 13), npts=100, delta=5E-4) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(omega_e_au * 1000.0, dos_e_au) ax.plot(omega_e_cu * 1000.0, dos_e_cu) ax.set_xlabel("Energy (meV)") logw_au = np.sum(np.log(omega_e_au[1:]) * dos_e_au[1:]) logw_cu = np.sum(np.log(omega_e_cu[1:]) * dos_e_cu[1:]) print(logw_au, logw_cu, logw_au - logw_cu) plt.show()
def getLJeigenvaluesB(X, S, epsilon, sigma, rc, getForceMatrix): from ase import Atoms from ase.build import bulk from ase.calculators.lj import LennardJones from ase.phonons import Phonons import numpy as np from scipy import linalg as LA calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc) # chemStr = 'H' + str(len(X)) # atoms = Atoms(chemStr, X, calculator=calc ) atoms = Atoms(getChemStr(S), X, calculator=calc) energy = atoms.get_potential_energy() eig = [] if getForceMatrix: ph = Phonons(atoms, calc) ph.run() ph.read(acoustic=True) ph.clean() f = ph.get_force_constant() (l, m, n) = f.shape if l == 1: ff = np.reshape(f, (m, n)) else: print("error") # eig = LA.eigvalsh(ff) # eig is a numpy array # return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
def ase_dynmat(args): from gpaw import GPAW from ase.phonons import Phonons from ase.dft.kpoints import BandPath calc = GPAW(args.GPW) phonon = Phonons(calc.get_atoms(), name=args.name, delta=args.displacement) phonon.read(acoustic=args.acoustic, symmetrize=args.symmetrize, method=args.method) return phonon.compute_dynamical_matrix([0, 0, 0], phonon.D_N)
def _calculate_finite_difference_hessian(self, atoms, calculator): """Calcualte the Hessian matrix using finite differences.""" ph = Phonons(atoms, calculator, supercell=(1, 1, 1), delta=1e-6) ph.clean() ph.run() ph.read(acoustic=False) ph.clean() H_numerical = ph.get_force_constant()[0, :, :] return H_numerical
def __init__(self, atoms, *args, **kwargs): RamanData.__init__(self, atoms, *args, **kwargs) for key in ['txt', 'exext', 'exname']: kwargs.pop(key, None) kwargs['name'] = kwargs.get('name', self.name) self.vibrations = Phonons(atoms, *args, **kwargs) self.delta = self.vibrations.delta self.indices = self.vibrations.indices self.kpts = (1, 1, 1)
def phonon_run(runID, save_to_db=False, plot_bands=False): print("Running ID %d" % (runID)) db = connect(db_name) atoms = db.get_atoms(id=runID) #view(atoms) #atoms = bulk("Al") #atoms = atoms*(2,1,1) #calc = EAM(potential="/home/davidkl/Documents/EAM/Al-LEA.eam.alloy") calc = EAM(potential="/home/davidkl/Documents/EAM/mg-al-set.eam.alloy") atoms.set_calculator(calc) #calc = gp.GPAW( mode=gp.PW(600), xc="PBE", kpts=(4,4,4), nbands="120%", symmetry="off" ) #atoms.set_calculator(calc) ph = Phonons(atoms, calc, supercell=(3, 3, 3), name=wrk + "/phonon_files/phonon%d" % (runID)) ph.run() #return ph.read(acoustic=True) omega_e, dos_e = ph.dos(kpts=(30, 30, 30), npts=1000, delta=5E-4) if (plot_bands): points = ibz_points['fcc'] G = points['Gamma'] X = points['X'] W = points['W'] K = points['K'] L = points['L'] U = points['U'] point_names = ['$\Gamma$', 'X', 'U', 'L', '$\Gamma$', 'K'] path = [G, X, U, L, G, K] path_kc, q, Q = bandpath(path, atoms.cell, 100) omega_kn = 1000.0 * ph.band_structure(path_kc) figb = plt.figure() axb = figb.add_subplot(1, 1, 1) for n in range(len(omega_kn[0])): omega_n = omega_kn[:, n] axb.plot(q, omega_n) plt.show() if (save_to_db): # Store the results in the database db.update(runID, has_dos=True) manager = cpd.PhononDOS_DB(db_name) # Extract relevant information from the atoms database row = db.get(id=runID) name = row.name atID = row.id manager.save(name=name, atID=atID, omega_e=omega_e, dos_e=dos_e)
def get_dos( model, posinp, device="cpu", supercell=(6, 6, 6), qpoints=[30, 30, 30], npts=1000, width=0.004, ): if isinstance(posinp, str): atoms = posinp_to_ase_atoms(Posinp.from_file(posinp)) elif isinstance(posinp, Posinp): atoms = posinp_to_ase_atoms(posinp) else: raise ValueError("The posinp variable is not recognized.") if isinstance(model, str): model = load_model(model, map_location=device) elif isinstance(model, torch.nn.Module): pass else: raise ValueError("The model variable is not recognized.") # Bugfix to make older models work with PyTorch 1.6 # Hopefully temporary for mod in model.modules(): if not hasattr(mod, "_non_persistent_buffers_set"): mod._non_persistent_buffers_set = set() assert len(supercell) == 3, "Supercell should be a length 3 object." assert len(qpoints) == 3, "Qpoints should be a length 3 object." supercell = tuple(supercell) cutoff = float(model.state_dict() ["representation.interactions.0.cutoff_network.cutoff"]) calculator = SpkCalculator( model, device=device, energy="energy", forces="forces", environment_provider=AseEnvironmentProvider(cutoff), ) ph = Phonons(atoms, calculator, supercell=supercell, delta=0.02) ph.run() ph.read(acoustic=True) dos = ph.get_dos(kpts=qpoints).sample_grid(npts=npts, width=width) ph.clean() return Dos(dos.energy * 8065.6, dos.weights[0])
def test_hessian(self): for calc in [{ (1, 1): LennardJonesQuadratic(1, 1, 3), (1, 2): LennardJonesQuadratic(1.5, 0.8, 2.4), (2, 2): LennardJonesQuadratic(0.5, 0.88, 2.64) }]: atoms = io.read("KA256_Min.xyz") atoms.center(vacuum=5.0) b = calculator.PairPotential(calc) H_analytical = b.calculate_hessian_matrix(atoms, "dense") # Numerical ph = Phonons(atoms, b, supercell=(1, 1, 1), delta=0.001) ph.run() ph.read(acoustic=False) ph.clean() H_numerical = ph.get_force_constant()[0, :, :] self.assertArrayAlmostEqual(H_analytical, H_numerical, tol=0.03)
def calculate_phonons(x): # Setup crystal and EMT calculator atoms = bulk('Al', 'fcc', a=x) #4.05) # Phonon calculator N = 7 ph = Phonons(atoms, EMT(), supercell=(N, N, N), delta=0.05) ph.run() # Read forces and assemble the dynamical matrix ph.read(acoustic=True) ph.clean() path = atoms.cell.bandpath('GXULGK', npoints=100) bs = ph.get_band_structure(path) dos = ph.get_dos(kpts=(20, 20, 20)).sample_grid(npts=100, width=1e-3) forces = ph.get_force_constant() print(forces) # Plot the band structure and DOS: import matplotlib.pyplot as plt fig = plt.figure(1, figsize=(8, 4), dpi=300) ax = fig.add_axes([.12, .07, .67, .85]) emax = 0.035 bs.plot(ax=ax, emin=-0.01, emax=emax) dosax = fig.add_axes([.8, .07, .17, .85]) dosax.fill_between(dos.weights[0], dos.energy, y2=0, color='grey', edgecolor='k', lw=1) dosax.set_ylim(-0.01, emax) dosax.set_yticks([]) dosax.set_xticks([]) dosax.set_xlabel("DOS", fontsize=18) fig.savefig('Al_phonon.png') return
def test_crystal_thermo(asap3, testdir): atoms = bulk('Al', 'fcc', a=4.05) calc = asap3.EMT() atoms.calc = calc energy = atoms.get_potential_energy() # Phonon calculator N = 7 ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05) ph.run() ph.read(acoustic=True) phonon_energies, phonon_DOS = ph.dos(kpts=(4, 4, 4), npts=30, delta=5e-4) thermo = CrystalThermo(phonon_energies=phonon_energies, phonon_DOS=phonon_DOS, potentialenergy=energy, formula_units=4) thermo.get_helmholtz_energy(temperature=298.15)
def getLJeigenvalues(listOfPositions, epsilon, sigma, rc, getForceMatrix): from ase import Atoms from ase.build import bulk from ase.calculators.lj import LennardJones from ase.phonons import Phonons import numpy as np from scipy import linalg as LA # from gpaw import GPAW, FermiDirac # calc = LennardJones() #a.set_calculator(calc) # atoms = bulk('Si', 'diamond', a=5.4) # atoms = bulk('H', 'fcc', a=1.1, cubic=True) #atoms = Atoms('N3', [(0, 0, 0), (0, 0, 1.1), (0, 0, 2.2)], calculator=LennardJones() ) # atoms = Atoms('H2', [(0, 0, 0), (0, 0, 1.12246)], calculator=LennardJones() ) # calc = GPAW(kpts=(5, 5, 5), h=0.2, occupations=FermiDirac(0.)) chemStr = 'H' + str(len(listOfPositions)) calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc) atoms = Atoms(chemStr, listOfPositions, calculator=calc) energy = atoms.get_potential_energy() eig = [] if getForceMatrix: ph = Phonons(atoms, calc) ph.run() ph.read(acoustic=True) ph.clean() f = ph.get_force_constant() # f # f.size (l, m, n) = f.shape if l == 1: ff = np.reshape(f, (m, n)) else: print("error") # # ff eig = LA.eigvalsh(ff) # eig is a numpy array # return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
def getEnergyAndEigen(self, aseStruct): aseStruct.set_calculator(self.calc) energy = aseStruct.get_potential_energy() eig = [] ph = Phonons(aseStruct, self.calc) ph.run() ph.read(acoustic=True) ph.clean() f = ph.get_force_constant() (l, m, n) = f.shape if l == 1: ff = np.reshape(f, (m, n)) else: print("error") # eig = LA.eigvalsh(ff) # eig is a numpy array # return energy, [ float("{0:.5f}".format(eig[i])) for i in range(len(eig)) ]
def getLJeigenvalues2B(X, S, epsilon, sigma, rc, getForceMatrix, aCell): from ase import Atoms from ase.build import bulk from ase.phonons import Phonons import numpy as np from scipy import linalg as LA from ase import Atom, Atoms from lammpslib import LAMMPSlib # chemStr = 'H' + str(len(X)) # struct = Atoms(chemStr, X, cell=(aCell, aCell, aCell), pbc=True) struct = Atoms(getChemStr(S), X, cell=(aCell, aCell, aCell), pbc=True) lammps_header = ["units metal"] cmds = [ "pair_style mlip /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_LJ.ini",\ "pair_coeff * * " ] mylammps = LAMMPSlib( lmpcmds=cmds, atom_types={1: 1}, keep_alive=True, log_file= '/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/log.txt') struct.set_calculator(mylammps) energy = struct.get_potential_energy() eig = [] if getForceMatrix: ph = Phonons(struct, mylammps) ph.run() ph.read(acoustic=True) ph.clean() f = ph.get_force_constant() (l, m, n) = f.shape if l == 1: ff = np.reshape(f, (m, n)) else: print("error") # eig = LA.eigvalsh(ff) # eig is a numpy array # return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
def get_phonons(self, kpts=(50, 50, 50), npts=5000): """Calculate the phonon spectrum and DOS. Parameters ---------- kpts : tuple Number of points in each directions of the k-space grid. npts : int Number of energy points to calculate the DOS at. """ self.phonons = Phonons(self.atoms, self.calc(), supercell=self.supercell_size, delta=0.05, name=self.name) self.phonons.run() # Read forces and assemble the dynamical matrix self.phonons.read(acoustic=True) self.phonon_kpts_mp = monkhorst_pack(kpts) self.phonon_energy_mp = self.phonons.band_structure( self.phonon_kpts_mp) self.phonon_energy, self.phonon_dos = \ self.phonons.dos(kpts=kpts, npts=npts, delta=5e-4)
def ase_phonon_calc( struct, calc=None, kpoints=[1, 1, 1], ftol=0.01, force_clean=False, name="asephonon", ): """Calculate phonon modes of a molecule using ASE and a given calculator. The system will be geometry optimized before calculating the modes. A report of the phonon modes will be written to a file and arrays of the eigenvectors and eigenvalues returned. | Args: | struct (ase.Atoms): Atoms object with to calculate modes for. | calc (ase.Calculator): Calculator for energies and forces (if not | present, use the one from struct) | kpoints (np.ndarray): Kpoint grid for phonon calculation. If None, just | do a Vibration modes calculation (default is [1,1,1]) | ftol (float): Tolerance for geometry optimisation (default | is 0.01 eV/Ang) | force_clean (bool): If True, force a deletion of all phonon files | and recalculate them | Returns: | evals (float[k-points][modes]): Eigenvalues of phonon modes | evecs (float[k-points][modes][ions][3]): Eigenvectors of phonon modes | struct (ase.Atoms): Optimised structure """ N = len(struct) if calc is None: calc = struct.calc struct = struct.copy() calc.atoms = struct struct.calc = calc dyn = BFGS(struct, trajectory="geom_opt.traj") dyn.run(fmax=ftol) # Calculate phonon modes vib_pbc = kpoints is not None if vib_pbc: vib = Phonons(struct, calc, name=name) else: vib = Vibrations(struct, name=name) if force_clean: vib.clean() vib.run() if vib_pbc: vib.read(acoustic=True) path = monkhorst_pack(kpoints) evals, evecs = vib.band_structure(path, True) else: vib.read() path = np.zeros((1, 3)) # One axis added since it's like the gamma point evals = np.real(vib.get_energies()[None]) evecs = np.array([vib.get_mode(i) for i in range(3 * N)])[None] # eV to cm^-1 evals *= ((cnst.electron_volt / cnst.h) / cnst.c) / 100.0 # Normalise eigenvectors evecs /= np.linalg.norm(evecs, axis=(2, 3))[:, :, None, None] return ASEPhononData(evals, evecs, path, struct)
def test_thermochemistry(): """Tests of the major methods (HarmonicThermo, IdealGasThermo, CrystalThermo) from the thermochemistry module.""" # Ideal gas thermo. atoms = Atoms('N2', positions=[(0, 0, 0), (0, 0, 1.1)], calculator=EMT()) QuasiNewton(atoms).run(fmax=0.01) energy = atoms.get_potential_energy() vib = Vibrations(atoms, name='idealgasthermo-vib') vib.run() vib_energies = vib.get_energies() thermo = IdealGasThermo(vib_energies=vib_energies, geometry='linear', atoms=atoms, symmetrynumber=2, spin=0, potentialenergy=energy) thermo.get_gibbs_energy(temperature=298.15, pressure=2 * 101325.) # Harmonic thermo. atoms = fcc100('Cu', (2, 2, 2), vacuum=10.) atoms.set_calculator(EMT()) add_adsorbate(atoms, 'Pt', 1.5, 'hollow') atoms.set_constraint( FixAtoms(indices=[atom.index for atom in atoms if atom.symbol == 'Cu'])) QuasiNewton(atoms).run(fmax=0.01) vib = Vibrations( atoms, name='harmonicthermo-vib', indices=[atom.index for atom in atoms if atom.symbol != 'Cu']) vib.run() vib.summary() vib_energies = vib.get_energies() thermo = HarmonicThermo(vib_energies=vib_energies, potentialenergy=atoms.get_potential_energy()) thermo.get_helmholtz_energy(temperature=298.15) # Crystal thermo. atoms = bulk('Al', 'fcc', a=4.05) calc = EMT() atoms.set_calculator(calc) energy = atoms.get_potential_energy() # Phonon calculator N = 7 ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05) ph.run() ph.read(acoustic=True) phonon_energies, phonon_DOS = ph.dos(kpts=(4, 4, 4), npts=30, delta=5e-4) thermo = CrystalThermo(phonon_energies=phonon_energies, phonon_DOS=phonon_DOS, potentialenergy=energy, formula_units=4) thermo.get_helmholtz_energy(temperature=298.15) # Hindered translator / rotor. # (Taken directly from the example given in the documentation.) vibs = np.array([ 3049.060670, 3040.796863, 3001.661338, 2997.961647, 2866.153162, 2750.855460, 1436.792655, 1431.413595, 1415.952186, 1395.726300, 1358.412432, 1335.922737, 1167.009954, 1142.126116, 1013.918680, 803.400098, 783.026031, 310.448278, 136.112935, 112.939853, 103.926392, 77.262869, 60.278004, 25.825447 ]) vib_energies = vibs / 8065.54429 # Convert to eV from cm^-1. trans_barrier_energy = 0.049313 # eV rot_barrier_energy = 0.017675 # eV sitedensity = 1.5e15 # cm^-2 rotationalminima = 6 symmetrynumber = 1 mass = 30.07 # amu inertia = 73.149 # amu Ang^-2 thermo = HinderedThermo(vib_energies=vib_energies, trans_barrier_energy=trans_barrier_energy, rot_barrier_energy=rot_barrier_energy, sitedensity=sitedensity, rotationalminima=rotationalminima, symmetrynumber=symmetrynumber, mass=mass, inertia=inertia) helmholtz = thermo.get_helmholtz_energy(temperature=298.15) target = 1.593 # Taken from documentation example. assert (helmholtz - target) < 0.001
# creates: Al_phonon.png from ase.build import bulk from ase.calculators.emt import EMT from ase.phonons import Phonons # Setup crystal and EMT calculator atoms = bulk('Al', 'fcc', a=4.05) # Phonon calculator N = 7 ph = Phonons(atoms, EMT(), supercell=(N, N, N), delta=0.05) ph.run() # Read forces and assemble the dynamical matrix ph.read(acoustic=True) ph.clean() path = atoms.cell.bandpath('GXULGK', npoints=100) bs = ph.get_band_structure(path) dos = ph.get_dos(kpts=(20, 20, 20)).sample_grid(npts=100, width=1e-3) # Plot the band structure and DOS: import matplotlib.pyplot as plt fig = plt.figure(1, figsize=(7, 4)) ax = fig.add_axes([.12, .07, .67, .85]) emax = 0.035 bs.plot(ax=ax, emin=0.0, emax=emax) dosax = fig.add_axes([.8, .07, .17, .85])
from ase.calculators.emt import EMT from ase.optimize import QuasiNewton from ase.phonons import Phonons from ase.thermochemistry import CrystalThermo # Set up gold bulk and attach EMT calculator a = 4.078 atoms = crystal('Au', (0., 0., 0.), spacegroup=225, cellpar=[a, a, a, 90, 90, 90], pbc=(1, 1, 1)) calc = EMT() atoms.set_calculator(calc) qn = QuasiNewton(atoms) qn.run(fmax=0.05) electronicenergy = atoms.get_potential_energy() # Phonon analysis N = 5 ph = Phonons(atoms, calc, supercell=(N, N, N), delta=0.05) ph.run() ph.read(acoustic=True) phonon_energies, phonon_DOS = ph.dos(kpts=(40, 40, 40), npts=3000, delta=5e-4) # Calculate the Helmholtz free energy thermo = CrystalThermo(phonon_energies=phonon_energies, phonon_DOS=phonon_DOS, electronicenergy=electronicenergy, formula_units=4) F = thermo.get_helmholtz_energy(temperature=298.15)
}, 'H': { 'L': -1, 'U': 0.0, 'J': 0.0 } }, ldauprint=2, lmaxmix=6, lorbit=11, ) #__| #| - Phonon Calculation from ase.phonons import Phonons ph = Phonons(new_atoms, calc, supercell=(1, 1, 1)) #ph.run() ph.read(method='frederiksen', acoustic=True) phonon_energies, phonon_DOS = ph.dos(kpts=(40, 40, 40), npts=3000, delta=5e-4) # Calculate the Helmholtz free energy potentialenergy = 0.0 from ase.thermochemistry import CrystalThermo thermo = CrystalThermo(phonon_energies=phonon_energies, phonon_DOS=phonon_DOS, potentialenergy=potentialenergy, formula_units=1) F = thermo.get_helmholtz_energy(temperature=298.15) #dyn = QuasiNewton(atoms, logfile=name+'.log', trajectory=name+'.traj')
'basis': 'dzp', 'symmetry': { 'point_group': False }, 'xc': 'PBE' } elph_calc = GPAW(**parameters) atoms.set_calculator(elph_calc) atoms.get_potential_energy() gamma_bands = elph_calc.wfs.kpt_u[0].C_nM elph = ElectronPhononCoupling(atoms, elph_calc, supercell=supercell, calculate_forces=True) elph.run() parameters['parallel'] = {'domain': 1} elph_calc = GPAW(**parameters) elph = ElectronPhononCoupling(atoms, calc=None, supercell=supercell) elph.set_lcao_calculator(elph_calc) elph.calculate_supercell_matrix(dump=1) ph = Phonons(atoms=atoms, name='phonons', supercell=supercell, calc=None) ph.read() kpts = [[0, 0, 0]] frequencies, modes = ph.band_structure(kpts, modes=True) c_kn = np.array([[gamma_bands[0]]]) g_qklnn = elph.bloch_matrix(c_kn=c_kn, kpts=kpts, qpts=kpts, u_ql=modes)
# creates: Al_phonon.png Al_mode.gif Al_mode.pdf from ase.lattice import bulk from ase.calculators.emt import EMT from ase.dft.kpoints import ibz_points, get_bandpath from ase.phonons import Phonons # Setup crystal and EMT calculator atoms = bulk('Al', a=4.05) calc = EMT() # Phonon calculator N = 6 ph = Phonons(atoms, calc, supercell=(N, N, N)) ph.run() # Read forces and assemble the dynamical matrix ph.read(acoustic=True) # High-symmetry points in the Brillouin zone points = ibz_points['fcc'] G = points['Gamma'] X = points['X'] W = points['W'] K = points['K'] L = points['L'] U = points['U'] point_names = ['$\Gamma$', 'X', 'U', 'L', '$\Gamma$', 'K'] path = [G, X, U, L, G, K] path_kc, q, Q = get_bandpath(path, atoms.cell, 100)
def main(): ''' Read in parameters for EAM calc ''' with open('HA4/results/fit_potential_output_full.txt', 'r') as textfile: line = next(textfile) line = line.split(',') A = float(line[0]) lmbd = float(line[1]) D = float(line[2]) mu2 = float(line[3]) # with open('HAlea') # ''' Optimization parameters ''' # A = 1000 # eV # lmbd = 3 # Å^(-1) # D = 5 # Å # mu2 = 1 # 2 # Å^(-1) # param_0 = [A, lmbd, D, mu2] ''' Strains and stuff ''' eV_to_J = 1.60217662 * 10**(-19) angstrom_to_meter = 1e-10 calc = get_calc((A, lmbd, D, mu2)) # calc = EMT() e1 = 0.01 e6 = 0.01 energies = [] C11_vec = [] C12_vec = [] B_vec = [] x = np.linspace(0, 0.5, 100) for i in x: e1 = i e6 = i # C11-C12 al_bulk = bulk('Al', 'fcc', a=4.032, cubic=True) al_bulk.set_calculator(calc) ep_mat_1 = np.array([[e1, 0, 0], [0, -e1, 0], [0, 0, e1**2 / (1 - e1**2)]]) energies.append(al_bulk.get_potential_energy()) cell_0 = al_bulk.get_cell() # al_bulk.set_cell(np.dot((np.eye(3) + ep_mat_1), np.transpose(cell_0))) al_bulk.set_cell(np.dot((np.eye(3) + ep_mat_1), cell_0)) # Yields same result energies.append(al_bulk.get_potential_energy()) # print(cell_0 / al_bulk.get_cell()) # print(cell_0) # print(al_bulk.get_cell()) V = al_bulk.get_volume() #4 * al_bulk.get_volume() delta_E = energies[-1] - energies[0] C11_minus_C12 = delta_E / (V * e1**2) # print('Hola', C11_minus_C12 * eV_to_J / (angstrom_to_meter**3 * 1e9)) # C11+C12 al_bulk = bulk('Al', 'fcc', a=4.032, cubic=True) al_bulk.set_calculator(calc) e2 = e1 ep_mat_12 = np.array([[e1, 0, 0], [0, e2, 0], [0, 0, 0]]) energies.append(al_bulk.get_potential_energy()) V = al_bulk.get_volume( ) #4 * al_bulk.get_volume() # Equilibrium cell volume cell_0 = al_bulk.get_cell() al_bulk.set_cell(np.dot((np.eye(3) + ep_mat_12), cell_0)) energies.append(al_bulk.get_potential_energy()) delta_E = energies[-1] - energies[0] C11_plus_C12 = delta_E / (V * e1**2) # print(C11_plus_C12) # C11 and C12 C11 = (C11_minus_C12 + C11_plus_C12) / 2 C12 = C11_plus_C12 - C11 C11_vec.append(C11 * eV_to_J / (angstrom_to_meter**3 * 1e9)) C12_vec.append(C12 * eV_to_J / (angstrom_to_meter**3 * 1e9)) B_vec.append( ((C11 + 2 * C12) / 3) * eV_to_J / (angstrom_to_meter**3 * 1e9)) plt.figure() plt.plot(x, C11_vec) plt.plot(x, C12_vec) plt.plot(x, B_vec) plt.set_xlabel( r'Displacement factor $\varepsilon_1 = \varepsilon_2 \varepsilon_6 $') plt.set_ylabel('Elastic constants/Bulk modulus [GPa]') plt.show() # C44 al_bulk = bulk('Al', 'fcc', a=4.032, cubic=True) al_bulk.set_calculator(calc) cell_0 = al_bulk.get_cell() ep_mat_6 = np.array([[0, 0.5 * e6, 0], [0.5 * e6, 0, 0], [0, 0, e6**2 / (4 - e6**2)]]) al_bulk.set_cell(np.dot((np.eye(3) + ep_mat_6), cell_0)) energies.append(al_bulk.get_potential_energy()) V = 4 * al_bulk.get_volume() delta_E = energies[-1] - energies[0] C44 = 2 * delta_E / (V * e6**2) # print(C44) B = (C11 + 2 * C12) / 3 # print('C11: ', C11 * eV_to_J / (angstrom_to_meter**3 * 1e9)) # print('C12: ', C12 * eV_to_J / (angstrom_to_meter**3 * 1e9)) B_SI = B * eV_to_J / (angstrom_to_meter)**3 B_GPa = B_SI / 1e9 # print('B', B_GPa) c_prim = (C11 * C12) / 2 ''' Phonon calculator ''' al_bulk = bulk('Al', 'fcc', a=4.032) N = 7 ph = Phonons(al_bulk, calc, supercell=(N, N, N), delta=0.05) ph.run() # Read forces and assemble the dynamical matrix ph.read(acoustic=True, banana=True) # High-symmetry points in the Brillouin zone points = ibz_points['fcc'] G = points['Gamma'] X = points['X'] W = points['W'] K = points['K'] L = points['L'] U = points['U'] point_names = ['$\Gamma$', 'X', 'U', 'L', '$\Gamma$', 'K'] path = [G, X, U, L, G, K] # Band structure in meV path_kc, q, Q = bandpath(path, al_bulk.cell, 100) omega_kn = 1000 * ph.band_structure(path_kc) # # Check band path # fig = plt.figure() # ax = fig.add_subplot(111, projection='3d') # ax.plot(path_kc[:,0], path_kc[:,1], path_kc[:,2]) # plt.show() # Calculate phonon DOS # omega_e, dos_e = ph.dos(kpts=(50, 50, 50), npts=5000, delta=5e-4) # omega_e *= 1000 # # # Plot the band structure and DOS # plt.figure(1, (8, 6)) # plt.axes([.1, .07, .67, .85]) # for n in range(len(omega_kn[0])): # omega_n = omega_kn[:, n] # plt.plot(q, omega_n, 'k-', lw=2) # # plt.xticks(Q, point_names, fontsize=18) # plt.yticks(fontsize=18) # plt.xlim(q[0], q[-1]) # plt.ylabel("Frequency ($\mathrm{meV}$)", fontsize=22) # plt.grid('on') # # plt.axes([.8, .07, .17, .85]) # plt.fill_between(dos_e, omega_e, y2=0, color='lightgrey', edgecolor='k', lw=1) # plt.ylim(0, 35) # plt.xticks([], []) # plt.yticks([], []) # plt.xlabel("DOS", fontsize=18) # plt.show() ''' Sound velocity ''' # point_names = ['$\Gamma$', 'X'] path_100 = [G, X] # Band structure in meV # Return list of k-points, list of x-coordinates and list of x-coordinates of special points. path_kc_100, q_100, Q_100 = bandpath(path_100, al_bulk.cell, 100) omega_kn_100 = 1000 * ph.band_structure(path_kc_100) # # Find the longitudinal curve (the one that is not initially overlapping) # print(omega_kn_100[0:10,0]) # print(omega_kn_100[0:10,1]) # print(omega_kn_100[0:10,2]) # <-- This one! k = np.sqrt(path_kc_100[:, 0]**2 + path_kc_100[:, 1]**2 + path_kc_100[:, 2]**2) # [Å^-1] convert_meV_to_1_over_s = (1 / 1000) * (1 / (6.582119514 * 10**(-16))) # print(omega_kn_100[1,2]) omega_long_at_q_to_0 = omega_kn_100[1, 2] * convert_meV_to_1_over_s # omega_long_at_q_to_1 = omega_kn_100[2,2] * convert_meV_to_1_over_s c_s = omega_long_at_q_to_0 * 10**(-10) / k[1] # Speed of sound, [m/s] # c_s = 10**(-10) * ((omega_long_at_q_to_1 - omega_long_at_q_to_0) / (k[2] - k[1])) # Speed of sound, [m/s] print(c_s) # # convert_u_to_kg = 1.66054 * 10**(-27) # convert_kg_to_eV_c2 = (2.99792 * 10**8)**2 # m_Al = al_bulk.get_masses()[0] * convert_u_to_kg * convert_kg_to_eV_c2 # [eV * (s^2/m^2)] # nbr_of_atoms_UC = 4 # Number of atoms per unit cell for fcc # V_Al = nbr_of_atoms_UC * al_bulk.get_volume() # [Å^3] # rho_Al = m_Al * nbr_of_atoms_UC / V_Al # [eV * (s^2/m^2) / Å^3] # young = c_s**2 * rho_Al # # print(C11) # print(young) plt.figure() plt.plot(q_100, omega_kn_100) plt.show()
import dill as pickle from ase.build import bulk from gpaw import GPAW, FermiDirac from ase.phonons import Phonons import ase import numpy as np atoms = ase.io.read("moo3_bulk.cif") calc = GPAW(symmetry={'point_group': False}, mode='lcao', basis='szp(dzp)', kpts=(6, 6, 3), convergence={'density': 1e-7}, xc='PBE', # No PBEsol :( occupations=FermiDirac(0.01)) ph = Phonons(atoms, calc, supercell=(3, 3, 2), delta=0.05) ph.run() ph.read(acoustic=True) force_constants = ph.get_force_constant() ph.acoustic(force_constants) force_constants = ph.symmetrize(force_constants) np.save("force_constant.npy", force_constants) with open('phonons.pkl', 'wb') as file: pickle.dump(ph, file)
def get_elph_elements(atoms, gpw_name, calc_fd, sc=(1, 1, 1), basename=None, phononname='phonon'): """ Evaluates the dipole transition matrix elements Input ---------- params_fd : Calculation parameters used for the phonon calculation sc (tuple): Supercell, default is (1,1,1) used for gamma phonons basename : If you want give a specific name (gqklnn_{}.pckl) Output ---------- gqklnn.pckl, the electron-phonon matrix elements """ from ase.phonons import Phonons from gpaw.elph.electronphonon import ElectronPhononCoupling calc_gs = GPAW(gpw_name) world = calc_gs.wfs.world #calc_fd = GPAW(**params_fd) calc_gs.initialize_positions(atoms) kpts = calc_gs.get_ibz_k_points() nk = len(kpts) gamma_kpt = [[0, 0, 0]] nbands = calc_gs.wfs.bd.nbands qpts = gamma_kpt # calc_fd.get_potential_energy() # XXX needed to initialize C_nM ?????? # Phonon calculation, We'll read the forces from the elph.run function # This only looks at gamma point phonons ph = Phonons(atoms=atoms, name=phononname, supercell=sc) ph.read() frequencies, modes = ph.band_structure(qpts, modes=True) if world.rank == 0: print("Phonon frequencies are loaded.") # Find el-ph matrix in the LCAO basis elph = ElectronPhononCoupling(atoms, calc=None, supercell=sc) elph.set_lcao_calculator(calc_fd) elph.load_supercell_matrix() if world.rank == 0: print("Supercell matrix is loaded") # Non-root processes on GD comm seem to be missing kpoint data. assert calc_gs.wfs.gd.comm.size == 1, "domain parallelism not supported" # not sure how to fix this, sorry gcomm = calc_gs.wfs.gd.comm kcomm = calc_gs.wfs.kd.comm if gcomm.rank == 0: # Find the bloch expansion coefficients c_kn = np.empty((nk, nbands, calc_gs.wfs.setups.nao), dtype=complex) for k in range(calc_gs.wfs.kd.nibzkpts): c_k = calc_gs.wfs.collect_array("C_nM", k, 0) if kcomm.rank == 0: c_kn[k] = c_k kcomm.broadcast(c_kn, 0) # And we finally find the electron-phonon coupling matrix elements! g_qklnn = elph.bloch_matrix(c_kn=c_kn, kpts=kpts, qpts=qpts, u_ql=modes) if world.rank == 0: print("Saving the elctron-phonon coupling matrix") np.save("gqklnn{}.npy".format(make_suffix(basename)), np.array(g_qklnn))
def getLJeigenvalues2(listOfPositions, epsilon, sigma, rc, getForceMatrix, aCell): from ase import Atoms from ase.build import bulk # from ase.calculators.lj import LennardJones from ase.phonons import Phonons import numpy as np from scipy import linalg as LA # from gpaw import GPAW, FermiDirac # calc = LennardJones() #a.set_calculator(calc) # atoms = bulk('Si', 'diamond', a=5.4) # atoms = bulk('H', 'fcc', a=1.1, cubic=True) #atoms = Atoms('N3', [(0, 0, 0), (0, 0, 1.1), (0, 0, 2.2)], calculator=LennardJones() ) # atoms = Atoms('H2', [(0, 0, 0), (0, 0, 1.12246)], calculator=LennardJones() ) # calc = GPAW(kpts=(5, 5, 5), h=0.2, occupations=FermiDirac(0.)) # d = 1.122 # = 2**(1/6) # a = 10.00 # struct = Atoms( 'H2', positions=[(0, 0, 0), (0, 0, d)] , cell=(a, a, a), pbc=True ) chemStr = 'H' + str(len(listOfPositions)) # struct = Atoms(chemStr, listOfPositions, cell=(aCell, aCell, aCell)) # <<< without pbc=True you would need a very large aCell value! struct = Atoms(chemStr, listOfPositions, cell=(aCell, aCell, aCell), pbc=True) # struct = Atoms(chemStr, positions=positions , cell=(aCell, aCell, aCell), pbc=True ) ############################################################################ # from ase.calculators.lj import LennardJones # calc = LennardJones(sigma=sigma, epsilon=epsilon, rc=rc) # struct = Atoms(chemStr, listOfPositions, calculator=calc ) ############################################################################ from ase import Atom, Atoms from lammpslib import LAMMPSlib # lammps_header=['units metal' ,\ # 'boundary p p p ' ,\ # "atom_style atomic" ,\ # "atom_modify map hash" ] lammps_header = ["units metal"] cmds = [ "pair_style mlip /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_LJ.ini",\ "pair_coeff * * " ] # cmds = ["pair_style mlip /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_LJ.ini",\ # "pair_coeff * * " ,\ # "neighbor 1.5 bin " ] # cmds = ["pair_style mlip /Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/mlip_test.ini",\ # "pair_coeff * * " ,\ # "neighbor 1.5 bin " ] mylammps = LAMMPSlib( lmpcmds=cmds, atom_types={1: 1}, keep_alive=True, log_file= '/Users/chinchay/Documents/9_Git/reverseEnergyPartitioning/log.txt') # struct = Atoms(chemStr, listOfPositions, calculator=mylammps ) struct.set_calculator(mylammps) ############################################################################ energy = struct.get_potential_energy() eig = [] if getForceMatrix: # ph = Phonons(struct, calc) ph = Phonons(struct, mylammps) ph.run() ph.read(acoustic=True) ph.clean() f = ph.get_force_constant() # f # f.size (l, m, n) = f.shape if l == 1: ff = np.reshape(f, (m, n)) else: print("error") # # ff eig = LA.eigvalsh(ff) # eig is a numpy array # return energy, [float("{0:.5f}".format(eig[i])) for i in range(len(eig))]
if world.rank == 0: print('Electronic structure calculation completed') #### Phononic band structure # if world.rank == 0: print('Phononic structure calculation started') atoms, calc = restart('Si_calc.gpw') # # kpts = {'size': (20,20,20)} calc.set( symmetry='off', ) # Set up the ASE phonon calculator N = 3 # Use a 2x2x2 supercell ph = Phonons(atoms, calc, supercell=(N, N, N-1), delta=0.05, name='./phonons/ph_Si') # Run the phonon calculation if world.rank == 0: print('******** Phonon calculation started *********') ph.run() if world.rank == 0: print('******** Phonon calculation completed *********') ph.read(acoustic=True) # Define BZ-path - use the same as for the electronic calculation path = atoms.cell.bandpath('GXWKL', npoints=100) # Fetch band structure and dos if world.rank == 0: print('******** Calculating phononic band structure *********')
# Tests the phonon-based perturbation and velocity distribution # for thermal equilibration in MD. rng = RandomState(17) atoms = bulk('Pd') atoms *= (3, 3, 3) avail = [atomic_numbers[sym] for sym in ['Ni', 'Cu', 'Pd', 'Ag', 'Pt', 'Au']] atoms.numbers[:] = rng.choice(avail, size=len(atoms)) atoms.calc = EMT() opt = FIRE(atoms, trajectory='relax.traj') opt.run(fmax=0.001) positions0 = atoms.positions.copy() phonons = Phonons(atoms, EMT(), supercell=(1, 1, 1), delta=0.05) try: phonons.run() phonons.read() # Why all this boilerplate? finally: phonons.clean() matrices = phonons.get_force_constant() K = matrices[0] T = 300 * units.kB atoms.calc = EMT() Epotref = atoms.get_potential_energy() temps = []
def test_phonon_md_init(asap3): # Tests the phonon-based perturbation and velocity distribution # for thermal equilibration in MD. EMT = asap3.EMT rng = RandomState(17) atoms = bulk('Pd') atoms *= (3, 3, 3) avail = [atomic_numbers[sym] for sym in ['Ni', 'Cu', 'Pd', 'Ag', 'Pt', 'Au']] atoms.numbers[:] = rng.choice(avail, size=len(atoms)) atoms.calc = EMT() opt = FIRE(atoms, trajectory='relax.traj') opt.run(fmax=0.001) positions0 = atoms.positions.copy() phonons = Phonons(atoms, EMT(), supercell=(1, 1, 1), delta=0.05) try: phonons.run() phonons.read() # Why all this boilerplate? finally: phonons.clean() matrices = phonons.get_force_constant() K = matrices[0] T = 300 * units.kB atoms.calc = EMT() Epotref = atoms.get_potential_energy() temps = [] Epots = [] Ekins = [] Etots = [] for i in range(24): PhononHarmonics(atoms, K, T, quantum=True, rng=np.random.RandomState(888 + i)) Epot = atoms.get_potential_energy() - Epotref Ekin = atoms.get_kinetic_energy() Ekins.append(Ekin) Epots.append(Epot) Etots.append(Ekin + Epot) temps.append(atoms.get_temperature()) atoms.positions[:] = positions0 # The commented code would produce displacements/velocities # resolved over phonon modes if we borrow some expressions # from the function. Each mode should contribute on average # equally to both Epot and Ekin/temperature # # atoms1.calc = EMT() # atoms1 = atoms.copy() # v_ac = np.zeros_like(positions0) # D_acs, V_acs = ... # for s in range(V_acs.shape[2]): # atoms1.positions += D_acs[:, :, s] # v_ac += V_acs[:, :, s] # atoms1.set_velocities(v_ac) # X1.append(atoms1.get_potential_energy() - Epotref) # X2.append(atoms1.get_kinetic_energy()) print('energies', Epot, Ekin, Epot + Ekin) Epotmean = np.mean(Epots) Ekinmean = np.mean(Ekins) Tmean = np.mean(temps) Terr = abs(Tmean - T / units.kB) relative_imbalance = abs(Epotmean - Ekinmean) / (Epotmean + Ekinmean) print('epotmean', Epotmean) print('ekinmean', Ekinmean) print('rel imbalance', relative_imbalance) print('Tmean', Tmean, 'Tref', T / units.kB, 'err', Terr) assert Terr < 0.1*T / units.kB, Terr # error in Kelvin for instantaneous velocity # Epot == Ekin give or take 2 %: assert relative_imbalance < 0.1, relative_imbalance if 0: import matplotlib.pyplot as plt I = np.arange(len(Epots)) plt.plot(I, Epots, 'o', label='pot') plt.plot(I, Ekins, 'o', label='kin') plt.plot(I, Etots, 'o', label='tot') plt.show()
# Get vibrational spectrum v = Vibrations(atoms, name='./vibs/vib_bulk') v.run() v.summary() # Get frequencies and DOS - i.e # of states per frequency (freq, counts) = np.unique(v.get_frequencies(), return_counts=True) freq = np.array(freq) dos = np.array(counts) # Save to db vibDB.write(atoms, data={'frequency': freq, 'DOS': dos}) #### Calculate band structure N = 7 # Use a supercell of size 7x7x7 ph = Phonons(atoms, mishin, name='./phonons/ph_bulk', supercell=(N, N, N), delta=0.05) ph.run() # Read the results from the run and obtain the bandpath and DOS ph.read(acoustic=True) # ph.clean() # lat.plot_bz(show=True) # Visualize Brillouin zone # Al has Space Group 225 [https://materialsproject.org/materials/mp-134/] # from which Bilbao Cryst gives us # Also here is given optimal vectors https://wiki.fysik.dtu.dk/ase/ase/dft/kpoints.html # Use default path for now # And here [https://wiki.fysik.dtu.dk/ase/ase/dft/kpoints.html#ase.dft.band_structure.BandStructure] path = atoms.cell.bandpath(path='GXWKGLUWLK,UX', density=100)