def getEamValues(p): mol = read('res_POSCAR_1.0.traj') calc = get_calc(p) mol.set_calculator(calc) forces = mol.get_forces() energy = [mol.get_potential_energy()] eps = 0.02 energies = [] lattice = [] initialLattice = mol.get_cell()[0, 0] for scale in np.linspace(1 - eps, 1 + eps, 3): mol.set_cell(3 * [initialLattice * scale], scale_atoms=True) energies = energies + [mol.get_potential_energy()] lattice = lattice + [[initialLattice * scale / 3.0]] lattice = np.array(lattice) energies = np.array(energies) functions = np.array([lattice**0, lattice, lattice**2]) polyfit = np.linalg.lstsq(functions.T[0], energies)[0] derivative = [polyfit[1], 2 * polyfit[2]] a0 = np.linalg.solve([derivative[1]], [-derivative[0]]) forces = forces.reshape(1, forces.size) print(a0) print(energy) ret = np.concatenate((a0, energy, forces), 1) return (ret)
def calc_lattice_parameter_al(al_bulk, A, lmbd, D, mu2): q = 0.03 n_points = 14 calc = get_calc((A, lmbd, D, mu2)) # # # Find lattice constant with lowest energy # # # cell_0 = al_bulk.cell # Unit cell object of the Al bulk al_bulk.set_calculator(calc) energies = [] volumes = [] for eps in np.linspace(-q, q, n_points): al_bulk.cell = (1 + eps) * cell_0 # Adjust lattice constant of unit cell # Calculate the potential energy for the Al bulk energies.append(al_bulk.get_potential_energy()) volumes.append(al_bulk.get_volume()) # Plot energies as a function of unit cell volume (directly related to latt. const.) eos = EquationOfState(volumes, energies) v0, E, B = eos.fit() # Latt. const. acc. to ASE doc., but why is this correct? a_calc = (4 * v0)**(1 / 3.0) al_bulk.cell = cell_0 print('Lattice_parameter:', a_calc) return a_calc
def calc_lattice_parameter(al_bulk_ASE, A, lmbd, D, mu2): q = 0.2 n_points = 15 calc = get_calc((A, lmbd, D, mu2)) # # # Find lattice constant with lowest energy # # # cell_0 = al_bulk_ASE.get_cell() # Unit cell object of the Al bulk al_bulk_ASE.set_calculator(calc) energies = [] volumes = [] for eps in np.linspace(-q, q, n_points): al_bulk_ASE.set_cell( (1 + eps) * cell_0) # Adjust lattice constant of unit cell # Calculate the potential energy for the Al bulk energies.append(al_bulk_ASE.get_potential_energy()) volumes.append(al_bulk_ASE.get_volume()) #plt.plot(np.asarray(volumes)**(1 / 3), energies) # plt.show() # Plot energies as a function of unit cell volume (directly related to latt. const.) eos = EquationOfState(volumes, energies) v0, E, B = eos.fit() # Latt. const. acc. to ASE doc., but why is this correct? a_calc = v0**(1 / 3.0) print('a=' + str(a_calc)) al_bulk_ASE.set_cell(cell_0) return a_calc
def calc_lattice_parameter_al(atom_set, A, lmbd, D, mu2): global n_sets, cells q = 0.2 n_points = 10 lattice_param_set = np.zeros(n_sets) calc = get_calc((A, lmbd, D, mu2)) for index, atoms in enumerate(atom_set): # # # Find lattice constant with lowest energy # # # cell_0 = atoms.cells[index] # Unit cell object of the Al bulk atoms.set_calculator(calc) energies = [] volumes = [] inval = np.linspace(-q, q, n_points) for eps in inval: atoms.cell = (1 + eps) * cell_0 # Adjust lattice constant of unit cell # Calculate the potential energy for the Al bulk energies.append(atoms.get_potential_energy()) volumes.append(atoms.get_volume()) # Plot energies as a function of unit cell volume (directly related to latt. const.) eos = EquationOfState(volumes, energies) v0, E, B = eos.fit() # Latt. const. acc. to ASE doc., but why is this correct? a_calc = v0**(1 / 3.0) n_min = np.argmin(energies) atoms.cell = (1 + inval[n_min]) * cell_0 lattice_param_set[index] = a_calc return lattice_param_set
def calc_forces_al(atoms_set, A, lmbd, D, mu2): forces = [] calc = get_calc((A, lmbd, D, mu2)) for atoms in atoms_set: atoms.set_calculator(calc) forces_tmp = atoms.get_forces() forces = np.hstack([forces, forces_tmp[:, 0], forces_tmp[:, 1], forces_tmp[:, 2]]) return forces
def calc_cohesive_energy_al(atom_set, A, lmbd, D, mu2): global n_sets energy_set = np.zeros(n_sets) calc = get_calc((A, lmbd, D, mu2)) for index, atoms in enumerate(atom_set): atoms.set_calculator(calc) energy_set[index] = atoms.get_potential_energy() return energy_set
def calc_forces(data_input_forces, A, lmbd, D, mu2): calc = get_calc((A, lmbd, D, mu2)) forces = [] for atoms in data_input_forces: atoms.set_calculator(calc) forces_mat = atoms.get_forces() forces = np.hstack( [forces, forces_mat[:, 0], forces_mat[:, 1], forces_mat[:, 2]]) return forces
def calc_lattice_parameter(al_bulk_ASE, A, lmbd, D, mu2): calc = get_calc((A, lmbd, D, mu2)) eps = 0.001 energies = [] volumes = [] al_bulk_ASE.set_calculator(calc) # # # Find lattice constant with lowest energy # # # cell_0 = al_bulk_ASE.get_cell() # Unit cell object of the Al bulk # DIRECTION cell_orig = cell_0 E1 = al_bulk_ASE.get_potential_energy() al_bulk_ASE.set_cell((1 + eps) * cell_0) E2 = al_bulk_ASE.get_potential_energy() direction = (E2 - E1) / abs((E2 - E1)) print('Direction', direction) # Go one step in the right al_bulk_ASE.set_cell(cell_orig) energies.append(al_bulk_ASE.get_potential_energy()) volumes.append(al_bulk_ASE.get_volume()) cell_0 = al_bulk_ASE.get_cell() al_bulk_ASE.set_cell( (1 - direction * eps) * cell_0) # Adjust lattice constant of unit cell energies.append(al_bulk_ASE.get_potential_energy()) volumes.append(al_bulk_ASE.get_volume()) # Go two steps back while (energies[-1] - energies[-2]) < 0: cell_0 = al_bulk_ASE.get_cell() # Adjust lattice constant of unit cell al_bulk_ASE.set_cell((1 - direction * eps) * cell_0) # Calculate the potential energy for the Al bulk energies.append(al_bulk_ASE.get_potential_energy()) volumes.append(al_bulk_ASE.get_volume()) cell_0 = al_bulk_ASE.get_cell() al_bulk_ASE.set_cell( (1 - direction * eps) * cell_0) # Adjust lattice constant of unit cell # Calculate the potential energy for the Al bulk energies.append(al_bulk_ASE.get_potential_energy()) volumes.append(al_bulk_ASE.get_volume()) # plt.plot((4 * np.asarray(volumes))**(1 / 3), energies) # plt.show() # Plot energies as a function of unit cell volume (directly related to latt. const.) eos = EquationOfState(volumes, energies) v0, E, B = eos.fit() # Latt. const. acc. to ASE doc., but why is this correct? print('asdasdasdasdasd: ', E) a_calc = (4 * v0)**(1 / 3.0) # a_calc = v0**(1 / 3.0) print('a=' + str(a_calc)) al_bulk_ASE.set_cell(cell_0) return a_calc
def calc_cohesive_energy(al_bulk_ASE, A, lmbd, D, mu2): calc = get_calc((A, lmbd, D, mu2)) al_bulk_ASE.set_calculator(calc) energy = al_bulk_ASE.get_potential_energy() print('Cohesive energy: ', energy) return energy
def calc_cohesive_energy_al(al_bulk, A, lmbd, D, mu2): calc = get_calc((A, lmbd, D, mu2)) al_bulk.set_calculator(calc) energy = al_bulk.get_potential_energy() return energy
A = 2011 lmbda = 3.21 D = 5.29 mu = 0.93/2 p = (A, lmbda, D, 2*mu) dE1m2 = [] dE4 = [] dE1p2 = [] e = [] for deformation in (0.2,0.1,0.001): mol = read('res_POSCAR_1.0.traj') # mol = bulk('Al','fcc',a = latticeParam) calc = get_calc(p) mol.set_calculator(calc) preEnergy = mol.get_potential_energy() preVolume = mol.get_volume() strain_change1m2 = np.array(((deformation, 0, 0),(0,-deformation, 0),(0,0,deformation**2/(1-deformation**2)))) strain_change4 = np.array(((0,0.5*deformation, 0),(0.5*deformation,0, 0),(0,0,deformation**2/(4-deformation**2)))) strain_change1p2 = np.array(((deformation, 0, 0),(0,deformation, 0),(0,0,0))) strain1m2 = np.identity(3) + strain_change1m2 strain4 = np.identity(3) + strain_change4 strain1p2 = np.identity(3) + strain_change1p2 preCell = mol.get_cell()
def calc_cohesive_energy(al_bulk_ASE, A, lmbd, D, mu2): calc = get_calc((A, lmbd, D, mu2)) al_bulk_ASE.set_calculator(calc) return al_bulk_ASE.get_potential_energy()
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]) path_BCC = 'HA4/downloads/Al-EV-curves/BCC.dat' a0_BCC, V_BCC, E_BCC, scale_factors = read_data(path_BCC) path_DI = 'HA4/downloads/Al-EV-curves/DIAMOND.dat' a0_DI, V_DI, E_DI, scale_factors = read_data(path_DI) path_FCC = 'HA4/downloads/Al-EV-curves/FCC.dat' a0_FCC, V_FCC, E_FCC, scale_factors = read_data(path_FCC) a0_FCC_experimental = 4.032 E0_FCC_experimental = -3.36 path_SC = 'HA4/downloads/Al-EV-curves/SC.dat' a0_SC, V_SC, E_SC, scale_factors = read_data(path_SC) al_bulk_BCC = bulk('Al', 'bcc', a=a0_BCC) al_bulk_DI = bulk('Al', 'diamond', a=a0_DI) al_bulk_FCC = bulk('Al', 'fcc', a=a0_FCC) al_bulk_SC = bulk('Al', 'sc', a=a0_SC) calc = get_calc((A, lmbd, D, mu2)) al_bulk_BCC.set_calculator(calc) al_bulk_DI.set_calculator(calc) al_bulk_FCC.set_calculator(calc) al_bulk_SC.set_calculator(calc) V_BCC_sim, V_DI_sim, V_FCC_sim, V_SC_sim = [], [], [], [] E_BCC_sim, E_DI_sim, E_FCC_sim, E_SC_sim = [], [], [], [] for scale_factor in scale_factors: cell_0 = al_bulk_BCC.get_cell() al_bulk_BCC.set_cell(cell_0 * scale_factor) E_BCC_sim.append(al_bulk_BCC.get_potential_energy()) V_BCC_sim.append(2 * al_bulk_BCC.get_volume()) al_bulk_BCC.set_cell(cell_0) cell_0 = al_bulk_DI.get_cell() al_bulk_DI.set_cell(cell_0 * scale_factor) E_DI_sim.append(al_bulk_DI.get_potential_energy()) V_DI_sim.append(4 * al_bulk_DI.get_volume()) al_bulk_DI.set_cell(cell_0) cell_0 = al_bulk_FCC.get_cell() al_bulk_FCC.set_cell(cell_0 * scale_factor) E_FCC_sim.append(al_bulk_FCC.get_potential_energy()) V_FCC_sim.append(4 * al_bulk_FCC.get_volume()) al_bulk_FCC.set_cell(cell_0) cell_0 = al_bulk_SC.get_cell() al_bulk_SC.set_cell(cell_0 * scale_factor) E_SC_sim.append(al_bulk_SC.get_potential_energy()) V_SC_sim.append(1 * al_bulk_SC.get_volume()) al_bulk_SC.set_cell(cell_0) fig = plt.figure(1, figsize=(7.1, 7.1)) ax_BCC = fig.add_subplot(221) ax_BCC.plot(V_BCC, E_BCC, label='DFT', color='blue') ax_BCC.plot(V_BCC_sim, E_BCC_sim, label='EAM', color='red') ax_BCC.set_title('BCC unit cell') ax_BCC.minorticks_on() ax_BCC.grid(True, which='minor', linestyle='--') ax_BCC.grid(True, which='major', linestyle='-') ax_BCC.set_xlim(V_BCC[0], V_BCC[-1]) ax_BCC.legend() ax_DI = fig.add_subplot(222) ax_DI.plot(V_DI, E_DI, label='DFT', color='blue') ax_DI.plot(V_DI_sim, E_DI_sim, label='EAM', color='red') ax_DI.set_title('Diamond unit cell') ax_DI.minorticks_on() ax_DI.grid(True, which='minor', linestyle='--') ax_DI.grid(True, which='major', linestyle='-') ax_DI.set_xlim(V_DI[0], V_DI[-1]) ax_DI.legend() ax_FCC = fig.add_subplot(223) ax_FCC.plot(V_FCC, E_FCC, label='DFT', color='blue') ax_FCC.plot(V_FCC_sim, E_FCC_sim, label='EAM', color='red') ax_FCC.plot(a0_FCC_experimental**3, E0_FCC_experimental, marker='*', color='black') ax_FCC.set_title('FCC unit cell') ax_FCC.minorticks_on() ax_FCC.grid(True, which='minor', linestyle='--') ax_FCC.grid(True, which='major', linestyle='-') ax_FCC.set_xlim(V_FCC[0], V_FCC[-1]) ax_FCC.legend() ax_SC = fig.add_subplot(224) ax_SC.plot(V_SC, E_SC, label='DFT', color='blue') ax_SC.plot(V_SC_sim, E_SC_sim, label='EAM', color='red') ax_SC.set_title('SC unit cell') ax_SC.minorticks_on() ax_SC.grid(True, which='minor', linestyle='--') ax_SC.grid(True, which='major', linestyle='-') ax_SC.set_xlim(V_SC[0], V_SC[-1]) ax_SC.legend() fig.subplots_adjust(left=None, bottom=None, right=None, top=None, wspace=None, hspace=0.25) fig.text(0.5, 0.03, 'Volume [Å^3]', ha='center', fontsize=16) fig.text(0.03, 0.5, 'Energy [eV]', va='center', rotation='vertical', fontsize=16) fig.savefig("HA4/results/EV_curves.png", bbox_inches='tight') with open('HA4/results/EV_FCC.txt', 'w') as textfile: text = 'Volume, Enegy DFT, Energy EAM ' + '\n' for i in range(len(V_FCC)): text = text + str(V_FCC[i]) + ',' + str(E_FCC[i]) + ',' + str( E_FCC_sim[i]) + '\n' text = text[:-1] textfile.write(text) plt.show()
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()