def main(): #Read in the file filename = 'dft_chargedensity1.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) #Create data in initial coordinates a = np.linspace(0, lattice[0, 0], grid[0]) b = np.linspace(0, lattice[1, 1], grid[1]) c = np.linspace(0, lattice[2, 2], grid[2]) #Create the interpolated data spline_data = spline(x=a, y=b, z=c, f=rho, dims=3) #Calculate the interpolation for the new coordinates r0 = np.array([0.1, 0.1, 2.8528]) #Given in the exercise r1 = np.array([4.45, 4.45, 2.8528]) t = np.linspace(0, 1, 500) result = [] for i in range(500): r = r0 + t[i] * (r1 - r0 ) #This is the new interpolation vector at index i inter = spline_data.eval3d(r[0], r[1], r[2])[0][0][0] result.append(inter) #Store the values in a list length = np.linalg.norm(r1 - r0) #Length of the interpoaltion line #Plot the electron density as a function of t plt.figure() plt.plot(t * length, result) plt.title('Electron density interpolation') plt.xlabel('Distance [Angstrom]') plt.xlim([0, 1 * length]) plt.ylabel('Electron density') plt.grid() plt.show()
def main(): """ All the necessary calculations perfomed in main() """ ###reading of the first XSF-file### filename = 'dft_chargedensity1.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) print("Lattice matrix 1: ", lattice) B = recip_vec(lattice) print(part_num(rho, lattice)) ###end for the first file### ###reading of the second XSF-file### filename = 'dft_chargedensity2.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) print("Lattice matrix 2: ", lattice) B = recip_vec(lattice) print(part_num(rho, lattice))
def main(): #Read in the file filename = 'dft_chargedensity2.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) A_inv = np.linalg.inv(np.transpose(lattice)) #The inverse of our matrix A #Create data in initial coordinates in orthonormal basis a = np.linspace(0, 1, grid[0]) b = np.linspace(0, 1, grid[1]) c = np.linspace(0, 1, grid[2]) spline_data = spline(x=a, y=b, z=c, f=rho, dims=3) #Input the values of the lines from starting to end point, along which the interpolation should be performed. vec = np.array([ [-1.4466, 1.3073, 3.2115], #start line 1 [1.4361, 3.1883, 1.3542], #end line 1 [2.9996, 2.1733, 2.1462], #start line 2 [8.7516, 2.1733, 2.1462] ]) #end line 2 t = np.linspace(0, 1, 500) counter = 0 for j in range( 0, 3, 2 ): #This gives the value 0 in the first iteration and 2 in the second. #(This loop is included because the spline in line 30 takes forever and I don't want to run that part twice) #Choose the vectors start and end points, so that we can construct the interpolation line r0+t[i]*(r1-r0): r0 = vec[j] r1 = vec[j + 1] result = [] #Calculate the interpolation for i in range(500): r = np.mod( A_inv.dot(r0 + t[i] * (r1 - r0)), 1 ) #This maps our vector according to r=A*alpha (r is our vector, A the transpose(lattice) and alpha our new coordinates) #The modulo is needed in case our interpolation vector is not in the unit cell anymore (see lecture slides week 4 p.3) inter = spline_data.eval3d(r[0], r[1], r[2])[0][0][0] result.append(inter) #Plot the figures counter += 1 length = np.linalg.norm(r1 - r0) #Length of the interpolation line plt.figure() plt.plot(t * length, result) plt.title('Interpolation along line {}'.format(counter)) plt.xlabel('Distance [Angstrom]') plt.xlim([0, 1 * length]) plt.ylabel('Electron density') plt.grid() plt.show()
def reciprocal_lattice_vectors(filename): # A function that calculates and returns the reciprocal lattice vectors. # Read the file. rho, lattice, grid, shift = read_example_xsf_density(filename) # Solve the matrix equation. mat = np.linalg.solve( (10**-10) * lattice, [[2 * np.pi, 0, 0], [0, 2 * np.pi, 0], [0, 0, 2 * np.pi]]) return np.transpose(mat)
def main(): #First example print('File 1:') filename = 'dft_chargedensity1.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) #read in the file N1=number_of_electrons(rho,lattice,grid) print(' Electrons in unit cell: ',int(np.round(N1))) #Reciprocal lattice vector according to lecture slides p.5: B^t*A=2*pi*Identity #A=transpose(lattice) B1=np.transpose(2*np.pi*np.dot(np.identity(3), np.linalg.inv(np.transpose(lattice)))) print(' Reciprocal lattice vectors:\n',B1,'\n') #Second example print('File 2:') filename = 'dft_chargedensity2.xsf' rho2, lattice2, grid2, shift = read_example_xsf_density(filename) N2=number_of_electrons2(rho2,lattice2,grid2) print(' Electrons in unit cell: ',int(np.round(N2))) B2=np.transpose(2*np.pi*np.dot(np.identity(3), np.linalg.inv(np.transpose(lattice2)))) print(' Reciprocal lattice vectors:\n', B2)
def lattice_analysis(filename): """ Calculate the number of electrons in cell, and display the number of electrons and the reciprocal lattice vector :param: filename: given filename to read data from """ rho, lattice, grid, shift = rxsf.read_example_xsf_density(filename) # Unit volume of block is V = (a x b) dot c, normalized with grid size volume = np.dot(np.cross(lattice[0,:]/grid[0], lattice[1,:]/grid[1]), lattice[2,:]/grid[2]) # Each block has electron density time volume electrons in it, so total electron amount is the # sum of all the electrons in blocks. Ne = np.sum(rho)*volume # reciprocal lattice is defined by B^T = 2pi*inv(A) reciLattice = np.transpose(2*np.pi*np.linalg.inv(lattice)) print(f"Total electrons in {filename}: {Ne}") print("Reciprocal lattice vectors", reciLattice[0, :], reciLattice[1, :], reciLattice[2, :])
def calc_nelectron(filename): """ Calculates the number of electrons in the simulated lattice cell :param: filename : filename for the lattice cell (.xsf - file) :return: Number of electrons in the simulated cell """ # rho: electron density in unit volume (one for each point) # lattice: lattice vectors (3 by 3) # grid: grid size in lattice vector diection (3 by 1) # shift: unknown rho, lattice, grid, shift = r_xsf.read_example_xsf_density(filename) # solve the unit volume of lattice unit_vol = calc_vol(lattice, grid) # Sum over all rho*unit volume return np.sum(rho) * unit_vol, lattice
def count_electrons(filename): # Function that integrates electron density over an area to get the number # of electrons, and returns it. # Read the file. rho, lattice, grid, shift = read_example_xsf_density(filename) # Define the axis points. x = np.linspace(0, lattice[0, 0], grid[0]) y = np.linspace(0, lattice[1, 1], grid[1]) z = np.linspace(0, lattice[2, 2], grid[2]) # Arrays for storing the intermediate integral values. ints1d = np.zeros(grid[0]) ints2d = np.zeros([grid[0], grid[1]]) # Integarte the electron density. for i in range(grid[0]): for j in range(grid[1]): ints2d[i, j] = simps(rho[i, j, :], z) ints1d[i] = simps(ints2d[i, :], y) return simps(ints1d, x)
def main(): filename1 = 'dft_chargedensity1.xsf' rho1, lattice1, grid1, shift1 = read_example_xsf_density(filename1) # Creates a spline-object x1 = linspace(0, lattice1[0][0], grid1[0]) y1 = linspace(0, lattice1[1][1], grid1[1]) z1 = linspace(0, lattice1[2][2], grid1[2]) electron_spline = spline(x=x1, y=y1, z=z1, f=rho1, dims=3) # t must be from 0 to 1, so we are on the line. # I took only 50 points, because it took so long with 500. t = linspace(0, 1, 50) j = 0 x = [] y = [] z = [] while j < 50: x.append(r(t[j])[0]) y.append(r(t[j])[1]) z.append(r(t[j])[2]) j = j + 1 # Evaluate the electrn density in the line evaluated = electron_spline.eval3d(x, y, z) # Let's draw some picture X, Y = meshgrid(x, y) pcolor(X, Y, evaluated[..., int(len(z) / 2)]) title('Interpolated') show()
def electron_density(filename, r0, r1, N=500): """ Calculate the electron density at a given line in the lattice :param: filename: given filename to read data from :param: r0: line starting point :param: r1: line end point :param: N: Number of points along line """ # Get the lattice values rho, lattice, grid, shift = r_xsf.read_example_xsf_density(filename) # define the lattice vectors a1 = lattice[:, 0] a2 = lattice[:, 1] a3 = lattice[:, 2] # start and end points as vectors in the lattice grid a_i = array([[r0.dot(a1)/(linalg.norm(a1)**2)*grid[0]], \ [r0.dot(a2)/(linalg.norm(a2)**2)*grid[1]], \ [r0.dot(a3)/(linalg.norm(a3)**2)*grid[2]]]) a_f = array([[r1.dot(a1)/(linalg.norm(a1)**2)*grid[0]], \ [r1.dot(a2)/(linalg.norm(a2)**2)*grid[1]], \ [r1.dot(a3)/(linalg.norm(a3)**2)*grid[2]]]) # check if the line goes outside the simulation cell, and create # more if needed nx = math.ceil(max(abs(a_i[0]) / grid[0], abs(a_f[0]) / grid[0], [1])[0]) ny = math.ceil(max(abs(a_i[1]) / grid[1], abs(a_f[1]) / grid[1], [1])[0]) nz = math.ceil(max(abs(a_i[2]) / grid[2], abs(a_f[2]) / grid[2], [1])[0]) # Interpolate values in the negative side, if we have to # calculate values there if any(r0 < 0) or any(r1 < 0): # Create more cells, if there is negative directions rho = concatenate((rho, rho), axis=0) rho = concatenate((rho, rho), axis=1) rho = concatenate((rho, rho), axis=2) # if line goes over the cell, create more if nx > 1: for i in range(2 * (nx - 1)): rho = concatenate((rho, rho), axis=0) if ny > 1: for i in range(2 * (ny - 1)): rho = concatenate((rho, rho), axis=1) if nz > 1: for i in range(2 * (nz - 1)): rho = concatenate((rho, rho), axis=2) spl3d = spline(x=nx*linspace(-grid[0]+1,grid[0]-1,2*nx*grid[0]),\ y=ny*linspace(-grid[1]+1,grid[1]-1,2*ny*grid[1]),\ z=nz*linspace(-grid[2]+1,grid[2]-1,2*nz*grid[2]),\ f=rho, dims = 3) else: # if lines go over simulation cell, create more if nx > 1: for i in range(nx - 1): rho = concatenate((rho, rho), axis=0) if ny > 1: for i in range(ny - 1): rho = concatenate((rho, rho), axis=1) if nz > 1: for i in range(nz - 1): rho = concatenate((rho, rho), axis=2) # create spline class for interpolation spl3d = spline(x=nx*linspace(0,grid[0]-1,nx*grid[0]),\ y=ny*linspace(0,grid[1]-1,ny*grid[1]),\ z=nz*linspace(0,grid[2]-1,nz*grid[2]),\ f=rho, dims = 3) # create line along which to interpolate x = linspace(a_i[0], a_f[0], N) y = linspace(a_i[1], a_f[1], N) z = linspace(a_i[2], a_f[2], N) # Interpolate values F = zeros((N, 1)) for i in range(N): F[i] = spl3d.eval3d(x[i], y[i], z[i]) return F
""" Calculating and plotting the electron density along two lines. Not working correctly. """ from read_xsf_example import read_example_xsf_density import numpy as np from scipy.interpolate import RegularGridInterpolator as rgi import matplotlib.pyplot as plt rho, lattice, grid, shift = read_example_xsf_density("dft_chargedensity2.xsf") # define the points on the first line. x = np.linspace(-1.4466, 1.1461, 500) # fix x so that it does not go uotside the unit cell using periodicity. for i in range(len(x)): if x[i] < 0: x[i] = x[i] + 5.75200 y = np.linspace(1.3073, 3.1883, 500) z = np.linspace(3.2115, 1.3542, 500) # Points for interpolation. xi = np.linspace(0, lattice[0, 0], grid[0]) yi = np.linspace(0, lattice[1, 1], grid[1]) zi = np.linspace(0, lattice[2, 2], grid[2]) # Interpolate the density. interp = rgi((xi, yi, zi), rho) # Get the interpolated density in the points on the line. points_density = np.zeros(500)
def electron_dens(filename, r0, r1, N): """ Calculates the electron density on an interpolated spline line :param: filename: file from which the data is read :param: r0 : starting point of the line :param: r1 : ending point of the line :param: N : number of points on the interpolated line :return: : electron density values on the line """ # rho: electron density in unit volume (one for each point) # lattice: lattice vectors (3 by 3) # grid: grid size in lattice vector diection (3 by 1) # shift: unknown rho, lattice, grid, shift = r_xsf.read_example_xsf_density(filename) # separate the lattice vectors a1 = lattice[:, 0] a2 = lattice[:, 1] a3 = lattice[:, 2] # starting and ending points as vectors in the simulation lattice grid a_i = np.array([[r0.dot(a1)/(np.linalg.norm(a1)**2)*grid[0]], \ [r0.dot(a2)/(np.linalg.norm(a2)**2)*grid[1]], \ [r0.dot(a3)/(np.linalg.norm(a3)**2)*grid[2]]]) a_f = np.array([[r1.dot(a1)/(np.linalg.norm(a1)**2)*grid[0]], \ [r1.dot(a2)/(np.linalg.norm(a2)**2)*grid[1]], \ [r1.dot(a3)/(np.linalg.norm(a3)**2)*grid[2]]]) # check if the line goes over the simulation cell # i.e. if we need to produce another cell n1 = math.ceil(max(abs(a_i[0]) / grid[0], abs(a_f[0]) / grid[0], [1])[0]) n2 = math.ceil(max(abs(a_i[1]) / grid[1], abs(a_f[1]) / grid[1], [1])[0]) n3 = math.ceil(max(abs(a_i[2]) / grid[2], abs(a_f[2]) / grid[2], [1])[0]) # spline interpolation, if some of the observed points are # on the negative side if any(r0 < 0) or any(r1 < 0): # if there is negative directions create more cells rho = np.concatenate((rho, rho), axis=0) rho = np.concatenate((rho, rho), axis=1) rho = np.concatenate((rho, rho), axis=2) # if lines go over simulation cell, create more if n1 > 1: for i in range(2 * (n1 - 1)): rho = np.concatenate((rho, rho), axis=0) if n2 > 1: for i in range(2 * (n2 - 1)): rho = np.concatenate((rho, rho), axis=1) if n3 > 1: for i in range(2 * (n3 - 1)): rho = np.concatenate((rho, rho), axis=2) # create spline class for interpolation spl = spline(x=n1*np.linspace(-grid[0]+1,grid[0]-1,2*n1*grid[0]),\ y=n2*np.linspace(-grid[1]+1,grid[1]-1,2*n2*grid[1]),\ z=n3*np.linspace(-grid[2]+1,grid[2]-1,2*n3*grid[2]),\ f=rho, dims = 3) else: # if lines go over simulation cell, create more if n1 > 1: for i in range(n1 - 1): rho = np.concatenate((rho, rho), axis=0) if n2 > 1: for i in range(n2 - 1): rho = np.concatenate((rho, rho), axis=1) if n3 > 1: for i in range(n3 - 1): rho = np.concatenate((rho, rho), axis=2) # create spline class for interpolation spl = spline(x=n1*np.linspace(0,grid[0]-1,n1*grid[0]),\ y=n2*np.linspace(0,grid[1]-1,n2*grid[1]),\ z=n3*np.linspace(0,grid[2]-1,n3*grid[2]),\ f=rho, dims = 3) # create line along which to interpolate x = np.linspace(a_i[0], a_f[0], N) y = np.linspace(a_i[1], a_f[1], N) z = np.linspace(a_i[2], a_f[2], N) F = np.zeros((N, 1)) # interpolation for i in range(N): F[i] = spl.eval3d(x[i], y[i], z[i]) return F
def main(): """ All the necessary calculations perfomed in main() """ filename = 'dft_chargedensity1.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) n = 500 # number of points in between """ Defining grid with shape of electorn density matrix in range of norm of lattice vectors """ x = linspace(0, lattice[0, 0], rho.shape[0]) y = linspace(0, lattice[1, 1], rho.shape[1]) z = linspace(0, lattice[2, 2], rho.shape[2]) """ Line points from assignment Line function in parametric form: r(t) = r_0 + t*(r_1-r_0) """ r0 = array([0.10000, 0.10000, 2.85280]) r1 = array([4.45000, 4.45000, 2.85280]) t = linspace(0, 1, n) """Interpolation along a line""" rho_spline = spline(x=x, y=y, z=z, f=rho, dims=3) rho_line = zeros((n, )) for i in range(n): xx = r0 + t[i] * (r1 - r0) rho_line[i] = rho_spline.eval3d(xx[0], xx[1], xx[2]) """ Plotting. Here the calculated values ploted as a function of electron density along the line \rho(x) It can be compared with the Line Profile perfomed by VESTA """ ###plotting of calculated results### fig = figure() ax = fig.add_subplot(111) ax.plot(t * linalg.norm(r1 - r0), rho_line, label=r"Electron density along a line") ax.legend(loc=0) ax.set_xlabel(r'$x$') ax.set_ylabel(r'$\rho$') # end of plotting ###ploting of VESTA results### print("XCrySDen XSF file (fractional points)") print("Point 1: 0.02196 0.02196 0.50000") print("Point 2: 0.97703 0.97703 0.50000") print("Number of points: 500") fig1 = figure() ax1 = fig1.add_subplot(111) X, Y = [], [] for line in open('problem3.txt', 'r'): values = [float(s) for s in line.split()] X.append(values[0]) Y.append(values[1]) ax1.plot(X, Y, label=r"Electron density along a line (VESTA)") ax1.legend(loc=0) ax1.set_xlabel(r'$x$') ax1.set_ylabel(r'$\rho$') # end of plotting show()
def main(): """ All the necessary calculations perfomed in main() """ filename = 'dft_chargedensity2.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) n = 500 # number of points in between """ Line points from assignment Line function in parametric form: r(t) = r_0 + t*(r_1-r_0) """ r0 = array([-1.44660, 1.30730, 3.21150]) r1 = array([1.43610, 3.18830, 1.35420]) r00 = array([2.99960, 2.17330, 2.14620]) r11 = array([8.75160, 2.17330, 2.14620]) t = linspace(0, 1, n) """ Since the lattice matrix is not a diagonal, we use fractional distances (for details see Week 4 FYS-4096 Computational Physics lecture slides) """ new_lat = linalg.inv(transpose(lattice)) # A⁻¹ """fractional vectors""" x = linspace(0, 1, rho.shape[0]) y = linspace(0, 1, rho.shape[1]) z = linspace(0, 1, rho.shape[2]) """Interpolation along a line""" rho_spline = spline(x=x, y=y, z=z, f=rho, dims=3) rho_line1 = zeros((n, )) for i in range(n): xx = new_lat.dot(r0) + t[i] * new_lat.dot((r1 - r0)) rho_line1[i] = rho_spline.eval3d(xx[0], xx[1], xx[2]) rho_line2 = zeros((n, )) """ Here we have to redefine one of the given point-vectors by taking modulus (periodic movement) (for details see Week 4 FYS-4096 Computational Physics lecture slides) """ unit = ones(3) for i in range(n): xx = mod(new_lat.dot(r00) + t[i] * new_lat.dot((r11 - r00)), unit) rho_line2[i] = rho_spline.eval3d(xx[0], xx[1], xx[2]) """ Plotting. Here the calculated values ploted as a function of electron density along the line \rho(x) It can be compared with the Line Profile perfomed by VESTA """ ###plotting of calculated results (1/2)### fig0 = figure() ax0 = fig0.add_subplot(111) ax0.plot(t * linalg.norm(r1 - r0), rho_line1, label=r"Electron density along the first line") ax0.legend(loc='upper right') ax0.set_xlabel(r'$x$') ax0.set_ylabel(r'$\rho$') # end of plotting ###plotting of calculated results (2/2)### fig00 = figure() ax00 = fig00.add_subplot(111) ax00.plot(t * linalg.norm(r11 - r00), rho_line2, label=r"Electron density along the second line") ax00.legend(loc='upper right') ax00.set_xlabel(r'$x$') ax00.set_ylabel(r'$\rho$') # end of plotting ###ploting of VESTA results (1/2)### fig = figure() ax = fig.add_subplot(111) print("XCrySDen XSF file 1 (fractional points)") print("Point 1: 0.10620 0.28809 0.70860") print("Point 2: 0.40050 0.70261 0.29880") print("Number of points: 500") X, Y = [], [] for line in open('problem4_1.txt', 'r'): values = [float(s) for s in line.split()] X.append(values[0]) Y.append(values[1]) ax.plot(X, Y, label=r"Electron density along the first line (VESTA)") ax.legend(loc='upper right') ax.set_xlabel(r'$x$') ax.set_ylabel(r'$\rho$') # end of plotting ###ploting of VESTA results (2/2)### fig1 = figure() ax1 = fig1.add_subplot(111) print("XCrySDen XSF file 2 (fractional points)") print("Point 1: 0.76053 0.47893 0.47355") print("Point 2: 1.76053 0.47893 0.47355") print("Number of points: 500") XX, YY = [], [] for line in open('problem4_2.txt', 'r'): values = [float(s) for s in line.split()] XX.append(values[0]) YY.append(values[1]) ax1.plot(XX, YY, label=r"Electron density along the second line (VESTA)") ax1.legend(loc='upper right') ax1.set_xlabel(r'$x$') ax1.set_ylabel(r'$\rho$') # end of plotting show()
def main(): filename = 'dft_chargedensity1.xsf' rho, lattice, grid, shift = read_example_xsf_density(filename) # runs too slowly to use 500 points for some reason i couldn't figure out interpolation_to_line(rho, grid, lattice, 0.1, 0.1, 2.8528, 4.45, 4.45, 2.8528, 50)