diff --git a/macrodensity/density.py b/macrodensity/density.py index d647a7d..e5207d5 100755 --- a/macrodensity/density.py +++ b/macrodensity/density.py @@ -12,9 +12,8 @@ from macrodensity.utils import matrix_2_abc -def gradient_magnitude(gx: np.ndarray, - gy: np.ndarray, - gz: np.ndarray +def gradient_magnitude( + gx: np.ndarray, gy: np.ndarray, gz: np.ndarray ) -> np.ndarray: """ Calculate the magnitude of the gradient at each point in a 3D field. @@ -42,18 +41,14 @@ def gradient_magnitude(gx: np.ndarray, for i in range(gx.shape[0]): for j in range(gy.shape[1]): for k in range(gz.shape[2]): - grad_mag[i,j,k] = np.sqrt(gx[i,j,k]**2 + - gy[i,j,k]**2 + - gz[i,j,k]**2) + grad_mag[i, j, k] = np.sqrt( + gx[i, j, k] ** 2 + gy[i, j, k] ** 2 + gz[i, j, k] ** 2 + ) return grad_mag -def element_vol(vol: float, - nx: int, - ny: int, - nz: int -) -> float: +def element_vol(vol: float, nx: int, ny: int, nz: int) -> float: """ Calculate the volume of each element in a 3D grid. @@ -83,9 +78,7 @@ def element_vol(vol: float, def macroscopic_average( - potential: np.ndarray, - periodicity: float, - resolution: float + potential: np.ndarray, periodicity: float, resolution: float ) -> np.ndarray: """ Calculate the macroscopic average of a 1D potential field with periodicity. @@ -109,7 +102,7 @@ def macroscopic_average( >>> print(macro_avg_result) """ macro_average = np.zeros(shape=(len(potential))) - period_points = int((periodicity/resolution)) + period_points = int((periodicity / resolution)) # Period points must be even if period_points % 2 != 0: period_points = period_points + 1 @@ -120,14 +113,24 @@ def macroscopic_average( end = i + int(period_points / 2) if start < 0: start = start + length - macro_average[i] = macro_average[i] + sum(potential[0:end]) + sum(potential[start:length]) + macro_average[i] = ( + macro_average[i] + + sum(potential[0:end]) + + sum(potential[start:length]) + ) macro_average[i] = macro_average[i] / period_points elif end >= length: end = end - length - macro_average[i] = macro_average[i] + sum(potential[start:length]) + sum(potential[0:end]) + macro_average[i] = ( + macro_average[i] + + sum(potential[start:length]) + + sum(potential[0:end]) + ) macro_average[i] = macro_average[i] / period_points else: - macro_average[i] = macro_average[i] + sum(potential[start:end]) / period_points + macro_average[i] = ( + macro_average[i] + sum(potential[start:end]) / period_points + ) print("Average of the average = ", np.average(macro_average)) @@ -135,13 +138,13 @@ def macroscopic_average( def volume_average( - origin: tuple, - cube: tuple, - grid: np.ndarray, - nx: int, - ny: int, - nz: int, - travelled: list=[0, 0, 0], + origin: tuple, + cube: tuple, + grid: np.ndarray, + nx: int, + ny: int, + nz: int, + travelled: list = [0, 0, 0], ) -> tuple: """ Calculate the volume average and variance of a cube in a 3D grid. @@ -159,7 +162,7 @@ def volume_average( nz (int): Number of points along the z-axis in the grid. - travelled (list, optional): Distance travelled from the origin in each + travelled (list, optional): Distance travelled from the origin in each direction (x, y, z). Default is [0, 0, 0]. Returns: @@ -178,22 +181,22 @@ def volume_average( """ # Recalc the origin as grid point coordinates n_origin = np.zeros(shape=(3)) - n_origin[0] = int(origin[0]*nx) - n_origin[1] = int(origin[1]*ny) - n_origin[2] = int(origin[2]*nz) - potential_cube = np.zeros(shape=(cube[0],cube[1],cube[2])) - for x in range(0,cube[0]): - for y in range(0,cube[1]): - for z in range(0,cube[2]): + n_origin[0] = int(origin[0] * nx) + n_origin[1] = int(origin[1] * ny) + n_origin[2] = int(origin[2] * nz) + potential_cube = np.zeros(shape=(cube[0], cube[1], cube[2])) + for x in range(0, cube[0]): + for y in range(0, cube[1]): + for z in range(0, cube[2]): # Assign the values of coordinates in the original grid - xv = int(n_origin[0]+travelled[0]+x) - yv = int(n_origin[1]+travelled[1]+y) - zv = int(n_origin[2]+travelled[2]+z) + xv = int(n_origin[0] + travelled[0] + x) + yv = int(n_origin[1] + travelled[1] + y) + zv = int(n_origin[2] + travelled[2] + z) # Minimum image convention - zv = int(zv - nz*round(zv/nz)) - yv = int(yv - ny*round(yv/ny)) - xv = int(xv - nx*round(xv/nx)) - potential_cube[x,y,z] = grid[int(xv),int(yv),int(zv)] + zv = int(zv - nz * round(zv / nz)) + yv = int(yv - ny * round(yv / ny)) + xv = int(xv - nx * round(xv / nx)) + potential_cube[x, y, z] = grid[int(xv), int(yv), int(zv)] return potential_cube.mean(), np.var(potential_cube) @@ -201,75 +204,88 @@ def volume_average( def spherical_average( cube_size: list, cube_origin: list, - input_file: str='LOCPOT', - print_output: bool=True + input_file: str = "LOCPOT", + print_output: bool = True, ) -> (float, float): - ''' + """ Calculate the volume average of the electronic potential within a spherical region. - This function calculates the volume average of the electronic potential within a - spherical region defined by a specific size and origin. + This function calculates the volume average of the electronic potential within a + spherical region defined by a specific size and origin. The size of the spherical region is specified by the cube_size - parameter, which determines the number of mesh points along each direction (NGX/Y/Z). - The origin of the sphere is given by the cube_origin parameter, - specified in fractional coordinates. The function reads the electronic potential data + parameter, which determines the number of mesh points along each direction (NGX/Y/Z). + The origin of the sphere is given by the cube_origin parameter, + specified in fractional coordinates. The function reads the electronic potential data from the specified input file (e.g., LOCPOT) and calculates the potential and variance within the spherical region. Parameters: - cube_size (:obj:`list`): The size of the spherical region + cube_size (:obj:`list`): The size of the spherical region in units of mesh points (NGX/Y/Z). - cube_origin (:obj:`list`): The origin of the spherical region + cube_origin (:obj:`list`): The origin of the spherical region in fractional coordinates. - input_file (:obj:`str`, optional): The filename of the file containing + input_file (:obj:`str`, optional): The filename of the file containing the electronic potential (e.g., LOCPOT). Default is 'LOCPOT'. - print_output (:obj:`bool`, optional): If True, the function prints + print_output (:obj:`bool`, optional): If True, the function prints the calculated potential and variance. Default is True. Returns: - :obj:`tuple`: A tuple containing the volume-averaged potential and + :obj:`tuple`: A tuple containing the volume-averaged potential and the variance within the spherical region. Outputs: cube_potential, cube_variance - ''' - ## GETTING POTENTIAL - if 'cube' in input_file: + """ + ## GETTING POTENTIAL + if "cube" in input_file: cube_pot, NGX, NGY, NGZ, lattice = cube.read_cube_data(input_file) - vector_a,vector_b,vector_c,av,bv,cv = matrix_2_abc(lattice) - resolution_x = vector_a/NGX - resolution_y = vector_b/NGY - resolution_z = vector_c/NGZ - grid_pot, electrons = density_2_grid(cube_pot, NGX, NGY, NGZ, config="CUBE") - elif 'vasp' in input_file or 'LOCPOT' in input_file or 'CHGCAR' in input_file: + vector_a, vector_b, vector_c, av, bv, cv = matrix_2_abc(lattice) + resolution_x = vector_a / NGX + resolution_y = vector_b / NGY + resolution_z = vector_c / NGZ + grid_pot, electrons = density_2_grid( + cube_pot, NGX, NGY, NGZ, config="CUBE" + ) + elif ( + "vasp" in input_file + or "LOCPOT" in input_file + or "CHGCAR" in input_file + ): vasp_pot, NGX, NGY, NGZ, lattice = read_vasp_density(input_file) - vector_a,vector_b,vector_c,av,bv,cv = matrix_2_abc(lattice) - resolution_x = vector_a/NGX - resolution_y = vector_b/NGY - resolution_z = vector_c/NGZ - grid_pot, electrons = density_2_grid(vasp_pot, NGX, NGY, NGZ, config="VASP") - elif 'gulp' in input_file or '.out' in input_file: + vector_a, vector_b, vector_c, av, bv, cv = matrix_2_abc(lattice) + resolution_x = vector_a / NGX + resolution_y = vector_b / NGY + resolution_z = vector_c / NGZ + grid_pot, electrons = density_2_grid( + vasp_pot, NGX, NGY, NGZ, config="VASP" + ) + elif "gulp" in input_file or ".out" in input_file: gulp_pot, NGX, NGY, NGZ, lattice = read_gulp_density(input_file) - vector_a,vector_b,vector_c,av,bv,cv = matrix_2_abc(lattice) - resolution_x = vector_a/NGX - resolution_y = vector_b/NGY - resolution_z = vector_c/NGZ - grid_pot, electrons = density_2_grid(gulp_pot, NGX, NGY, NGZ, config="GULP") + vector_a, vector_b, vector_c, av, bv, cv = matrix_2_abc(lattice) + resolution_x = vector_a / NGX + resolution_y = vector_b / NGY + resolution_z = vector_c / NGZ + grid_pot, electrons = density_2_grid( + gulp_pot, NGX, NGY, NGZ, config="GULP" + ) else: - raise ValueError("Invalid input file. File must be in VASP, GULP, or CUBE configuration.") + raise ValueError( + "Invalid input file. File must be in VASP, GULP, or CUBE configuration." + ) cube = cube_size origin = cube_origin - travelled = [0,0,0] + travelled = [0, 0, 0] cube_pot, cube_var = volume_average( origin=cube_origin, cube=cube_size, grid=grid_pot, - nx=NGX,ny=NGY, + nx=NGX, + ny=NGY, nz=NGZ, - travelled=[0,0,0] + travelled=[0, 0, 0], ) ## PRINTING @@ -281,16 +297,16 @@ def spherical_average( def travelling_volume_average( - grid: np.ndarray, - cube: tuple, - origin: tuple, - vector: list, - nx: int, - ny: int, - nz: int, - magnitude: int + grid: np.ndarray, + cube: tuple, + origin: tuple, + vector: list, + nx: int, + ny: int, + nz: int, + magnitude: int, ) -> np.ndarray: - """ + """ Calculate the volume average at multiple positions along a given vector. Parameters: @@ -311,34 +327,31 @@ def travelling_volume_average( magnitude (int): Number of positions to travel along the vector. Returns: - np.ndarray: 1D array containing the volume averages at each position + np.ndarray: 1D array containing the volume averages at each position along the vector. Example: >>> vector = (0.1, 0.2, 0.3) >>> magnitude = 5 - >>> travelling_avg = travelling_volume_average(grid, cube, origin, vector, + >>> travelling_avg = travelling_volume_average(grid, cube, origin, vector, nx, ny, nz, magnitude) >>> print("Travelling volume Average:") >>> print(travelling_avg) """ - plotting_average = np.zeros(shape=(magnitude)) - i = 0 - while i < magnitude: - travelled = np.multiply(i, vector) - plotting_average[i], varience = volume_average( - origin, cube, grid, nx, ny, nz, travelled + plotting_average = np.zeros(shape=(magnitude)) + i = 0 + while i < magnitude: + travelled = np.multiply(i, vector) + plotting_average[i], varience = volume_average( + origin, cube, grid, nx, ny, nz, travelled ) - i = i + 1 + i = i + 1 - return plotting_average + return plotting_average -def planar_average(grid: np.ndarray, - nx: int, - ny: int, - nz: int, - axis: str='z' +def planar_average( + grid: np.ndarray, nx: int, ny: int, nz: int, axis: str = "z" ) -> np.ndarray: """ Calculate the planar average of a 3D grid along a specified axis. @@ -352,7 +365,7 @@ def planar_average(grid: np.ndarray, nz (int): Number of points along the z-axis in the grid. - axis (str, optional): Axis along which to calculate the average + axis (str, optional): Axis along which to calculate the average ('x', 'y', or 'z'). Default is 'z'. Returns: @@ -364,36 +377,36 @@ def planar_average(grid: np.ndarray, >>> print("Planar Average along axis", axis) >>> print(planar_avg) """ - if axis == 'x': + if axis == "x": x_plane = np.zeros(shape=(ny, nz)) average = np.zeros(shape=(nx)) for x_value in range(nx): - x_plane[:,:] = grid[x_value,:,:] + x_plane[:, :] = grid[x_value, :, :] average[x_value] = x_plane.mean() - if axis == 'y': + if axis == "y": average = np.zeros(shape=(ny)) - y_plane = np.zeros(shape=(nx,nz)) + y_plane = np.zeros(shape=(nx, nz)) for y_value in range(ny): - y_plane[:,:] = grid[:,y_value,:] + y_plane[:, :] = grid[:, y_value, :] average[y_value] = y_plane.mean() - if axis == 'z': + if axis == "z": average = np.zeros(shape=(nz)) - z_plane = np.zeros(shape=(nx,ny)) + z_plane = np.zeros(shape=(nx, ny)) for z_value in range(nz): - z_plane[:,:] = grid[:,:,z_value] + z_plane[:, :] = grid[:, :, z_value] average[z_value] = z_plane.mean() return average def density_2_grid( - density: np.ndarray, - nx: int, - ny: int, - nz: int, - charge: bool=False, - volume: float=1, - config: str = 'VASP' + density: np.ndarray, + nx: int, + ny: int, + nz: int, + charge: bool = False, + volume: float = 1, + config: str = "VASP", ) -> tuple: """ Convert density data to a 3D grid. @@ -407,13 +420,13 @@ def density_2_grid( nz (int): Number of grid points along the z-axis. - charge (bool, optional): If True, convert charge density to the number of + charge (bool, optional): If True, convert charge density to the number of electrons. Default is False. - volume (float, optional): volume of the grid cell. + volume (float, optional): volume of the grid cell. Used to convert charge density to electrons. Default is 1. - config (str, optional): config of the density data (e.g., 'VASP', 'GULP'). + config (str, optional): config of the density data (e.g., 'VASP', 'GULP'). Default is 'VASP'. Returns: @@ -436,35 +449,34 @@ def density_2_grid( """ l = 0 Potential_grid = np.zeros(shape=(nx, ny, nz)) - + if config.lower() == "gulp": for k in range(nx): for j in range(ny): for i in range(nz): - Potential_grid[k,j,i] = density[l] + Potential_grid[k, j, i] = density[l] l = l + 1 return Potential_grid - + elif config.lower() == "vasp": total_electrons = 0 for k in range(nz): for j in range(ny): for i in range(nx): - Potential_grid[i,j,k] = density[l]/volume + Potential_grid[i, j, k] = density[l] / volume if charge == True: # Convert the charge density to a number of electrons - point_volume = volume / (nx*ny*nz) - Potential_grid[i,j,k] = ( - Potential_grid[i,j,k] * point_volume + point_volume = volume / (nx * ny * nz) + Potential_grid[i, j, k] = ( + Potential_grid[i, j, k] * point_volume ) total_electrons = total_electrons + density[l] l = l + 1 - + total_electrons = total_electrons / (nx * ny * nz) if charge == True: - print("Total electrons: ", total_electrons) + print("Total electrons: ", total_electrons) return Potential_grid, total_electrons - + else: raise ValueError("Invalid config. config must be 'VASP' or 'GULP'.") - diff --git a/macrodensity/io.py b/macrodensity/io.py index 4f9d909..cc732e6 100644 --- a/macrodensity/io.py +++ b/macrodensity/io.py @@ -14,7 +14,7 @@ def read_gulp_potential(gulpfile: str = "gulp.out") -> tuple: Read electrostatic potential data from a GULP output file. Parameters: - gulpfile (str, optional): Path to the GULP output file (gulp.out). + gulpfile (str, optional): Path to the GULP output file (gulp.out). Default is 'gulp.out'. Returns: @@ -101,14 +101,14 @@ def _read_partial_density( spin: int = 0, ) -> np.ndarray: """ - This function is used internally within the read_casp_parchg, + This function is used internally within the read_casp_parchg, reading partial density data from a VASP-PARCHG file. Parameters: FILE (str): Path to the CHGCAR-like file. - use_pandas (bool or None, optional): If True, use Pandas to read 3D data - (recommended for large files). If False, use np. + use_pandas (bool or None, optional): If True, use Pandas to read 3D data + (recommended for large files). If False, use np. If None, automatically use Pandas if available. Default is None. num_atoms (int): Total number of atoms in the system. @@ -119,7 +119,7 @@ def _read_partial_density( NGZ (int): Number of grid points along the z-axis. - spin (int, optional): If 0, read the first spin channel (total density). + spin (int, optional): If 0, read the first spin channel (total density). If 1, read the second spin channel (spin-up or spin-down). Default is 0. Returns: @@ -190,8 +190,8 @@ def _read_partial_density( def _read_vasp_density_fromlines(lines: list) -> tuple: """ - Read density data from a list of lines (classic VASP-style format). - This function is used internally within the read_vasp_density_classic function + Read density data from a list of lines (classic VASP-style format). + This function is used internally within the read_vasp_density_classic function Parameters: lines (list): List of lines from the density file. @@ -293,20 +293,20 @@ def read_vasp_parchg( Parameters: FILE (str): Path to the PARCHG-like file. - use_pandas (bool or None, optional): If True, use Pandas to read 3D data - (recommended for large files). - If False, use np. If None, automatically use Pandas if available. + use_pandas (bool or None, optional): If True, use Pandas to read 3D data + (recommended for large files). + If False, use np. If None, automatically use Pandas if available. Default is None. - quiet (bool, optional): If True, suppress print statements during reading. + quiet (bool, optional): If True, suppress print statements during reading. Default is False. - spin (bool, optional): If True, read spin-polarized partial densities. + spin (bool, optional): If True, read spin-polarized partial densities. Default is False. Returns: tuple: A tuple containing: - - list or np.ndarray: List containing arrays representing the density data + - list or np.ndarray: List containing arrays representing the density data for each spin channel, or np.ndarray for the total density if spin is False. - int: Number of grid points along the x-axis (NGX). - int: Number of grid points along the y-axis (NGY). @@ -384,11 +384,11 @@ def read_vasp_density( Parameters: FILE (str): Path to the CHGCAR-like file. - use_pandas (bool or None, optional): If True, use Pandas to read 3D data - (recommended for large files). If False, use np. + use_pandas (bool or None, optional): If True, use Pandas to read 3D data + (recommended for large files). If False, use np. If None, automatically use Pandas if available. Default is None. - quiet (bool, optional): If True, suppress print statements during reading. + quiet (bool, optional): If True, suppress print statements during reading. Default is False. Returns: diff --git a/macrodensity/plotting.py b/macrodensity/plotting.py index 3be9416..d73308e 100644 --- a/macrodensity/plotting.py +++ b/macrodensity/plotting.py @@ -88,8 +88,7 @@ def energy_band_alignment_diagram( cols=['#74356C', '#efce19'], textsize=18, arrowhead=0.5, outfile='BandAlignment', references={'Reference 1': 3.0, 'Reference 1', 'Reference 2': 4.0}, - edge='black') -""" + edge='black')""" energies_list = list(energies.values()) materials = list(energies.keys()) @@ -210,36 +209,36 @@ def plot_active_space( """Plot the active space (vacuum and non-vacuum regions) based on potential variations. - This function analyzes the potential variations within the specified - cubes of the given size and determines whether each cube belongs to + This function analyzes the potential variations within the specified + cubes of the given size and determines whether each cube belongs to the vacuum or non-vacuum region based on the provided tolerance. - This function also plots the cube potentials of vacuum and + This function also plots the cube potentials of vacuum and non vacuum cubes. Parameters: cube_size (list of int): The size of the cubes in units of mesh points (NGX/Y/Z) for analysis. - cube_origin (list of float): The starting point (origin) of the + cube_origin (list of float): The starting point (origin) of the cubes in fractional coordinates (range [0, 1]). - tolerance (float, optional): The cutoff variance value to + tolerance (float, optional): The cutoff variance value to distinguish vacuum from non-vacuum cubes. Default is 1E-4. - input_file (str, optional): The file with VASP output for potential. + input_file (str, optional): The file with VASP output for potential. Default is 'LOCPOT'. - print_output (bool, optional): Whether to print the analysis results. + print_output (bool, optional): Whether to print the analysis results. Default is True. Returns: - tuple: A tuple containing the number of cubes identified as + tuple: A tuple containing the number of cubes identified as vacuum and non-vacuum regions. Note: - The function calculates the potential variation within each - cube and compares it to the tolerance value. Cubes with potential - variations below the tolerance are considered vacuum regions, + The function calculates the potential variation within each + cube and compares it to the tolerance value. Cubes with potential + variations below the tolerance are considered vacuum regions, while others are non-vacuum regions. Example: @@ -333,30 +332,30 @@ def plot_on_site_potential( ) -> tuple: """Plot on-site electrostatic potential for a specific species. - This function reads the electronic potential from the specified VASP - output file (LOCPOT) and the atomic coordinates from the POSCAR file. - It then calculates the on-site electrostatic potential for the - specified species and generates a histogram to visualize + This function reads the electronic potential from the specified VASP + output file (LOCPOT) and the atomic coordinates from the POSCAR file. + It then calculates the on-site electrostatic potential for the + specified species and generates a histogram to visualize its distribution across the sample cube. Parameters: - species (str): The chemical symbol of the species whose on-site + species (str): The chemical symbol of the species whose on-site potential is of interest. - sample_cube (list of int): The size of the sampling cube + sample_cube (list of int): The size of the sampling cube in units of mesh points (NGX/Y/Z). - potential_file (str, optional): The filename of the VASP output file + potential_file (str, optional): The filename of the VASP output file containing the electronic potential (LOCPOT). Default is 'LOCPOT'. - coordinate_file (str, optional): The filename of the POSCAR file + coordinate_file (str, optional): The filename of the POSCAR file containing atomic coordinates. Default is 'POSCAR'. - output_file (str, optional): Name of the output data file - to store the on-site potential values. + output_file (str, optional): Name of the output data file + to store the on-site potential values. Default is 'OnSitePotential.csv'. - img_file (str, optional): Name of the output image file + img_file (str, optional): Name of the output image file for the histogram plot. Default is 'OnSitePotential.png'. Returns: @@ -476,7 +475,7 @@ def plot_planar_average( new_resolution (int): New resolution for interpolation. Returns: - tuple: A tuple containing a dataframe with the planar average + tuple: A tuple containing a dataframe with the planar average and macroscopic average and a figure object. """ @@ -619,12 +618,12 @@ def plot_field_at_point( ) -> plt.figure: """Plot the electric field magnitude and direction on a user-defined plane. - This function plots the electric field magnitude and direction on a user-defined plane - defined by three points: a_point, b_point, and c_point. - The function reads the electronic potential data from the specified + This function plots the electric field magnitude and direction on a user-defined plane + defined by three points: a_point, b_point, and c_point. + The function reads the electronic potential data from the specified input file (e.g., LOCPOT) and calculates the electric field (gradient of the potential). - The electric field is then visualized by plotting contours of the - electric field magnitude and arrows indicating the direction of the + The electric field is then visualized by plotting contours of the + electric field magnitude and arrows indicating the direction of the electric field on the defined plane. Parameters: @@ -634,10 +633,10 @@ def plot_field_at_point( c_point (list): The fractional coordinates of the third point defining the plane. - input_file (str, optional): The filename of the file containing the + input_file (str, optional): The filename of the file containing the electronic potential (e.g., LOCPOT). Default is 'LOCPOT'. - grad_calc (bool): if True , calculates the gradient of the field. + grad_calc (bool): if True , calculates the gradient of the field. Default is False due to computational expense Returns: @@ -749,7 +748,7 @@ def plot_plane_field( c_point (list): Fractional coordinates of the third point that defines the plane. - input_file (str, optional): The filename of the VASP LOCPOT file containing the + input_file (str, optional): The filename of the VASP LOCPOT file containing the electrostatic potential. Default is 'LOCPOT'. Returns: @@ -818,24 +817,24 @@ def plot_active_plane( cube_origin (list): The origin point of the cube in fractional coordinates. - tolerance (float, optional): The cutoff variance for identifying active and + tolerance (float, optional): The cutoff variance for identifying active and non-active cubes. Default is 1E-4. - input_file (str, optional): The filename of the VASP LOCPOT file containing + input_file (str, optional): The filename of the VASP LOCPOT file containing the electrostatic potential. Default is 'LOCPOT'. - grad_calc (bool): if True , calculates the gradient of the field. + grad_calc (bool): if True , calculates the gradient of the field. Default is False due to computational expense Returns: Figure: A matplotlib figure object containing the electric field contours and planar average. Note: - - The function reads the electrostatic potential from the specified VASP LOCPOT + - The function reads the electrostatic potential from the specified VASP LOCPOT file. - The active plane is determined by sampling the potential in a cube around the cube_origin point. - - The cutoff_varience parameter sets the threshold for distinguishing active and + - The cutoff_varience parameter sets the threshold for distinguishing active and non-active cubes based on their variance in potential. - The function creates a contour plot of the electric field on the active plane. - It also plots the planar average of the electric field and potential throughout the material. diff --git a/macrodensity/tools.py b/macrodensity/tools.py index a98f917..cd107e6 100644 --- a/macrodensity/tools.py +++ b/macrodensity/tools.py @@ -34,27 +34,27 @@ def bulk_interstitial_alignment( by considering the effect of interstitial sites on the electronic structure of the bulk material. Parameters: - interstices (:obj:`list` of tuples): A list of tuples representing the - coordinates of the interstitial sites for which the aligned band energies + interstices (:obj:`list` of tuples): A list of tuples representing the + coordinates of the interstitial sites for which the aligned band energies will be calculated. - outcar (:obj:`str`, optional): The filename of the OUTCAR file containing + outcar (:obj:`str`, optional): The filename of the OUTCAR file containing electronic band structure information. Default is "OUTCAR". - locpot (:obj:`str`, optional): The filename of the LOCPOT file containing the + locpot (:obj:`str`, optional): The filename of the LOCPOT file containing the electronic density information. Default is "LOCPOT". - cube_size (:obj:`list` of int, optional): The size of the cube (in grid points) - around each interstitial site used to calculate the local potential. + cube_size (:obj:`list` of int, optional): The size of the cube (in grid points) + around each interstitial site used to calculate the local potential. Default is [2, 2, 2]. - print_output (:obj:`bool`, optional): Whether to print the intermediate and final results. + print_output (:obj:`bool`, optional): Whether to print the intermediate and final results. Default is True. Returns: - :obj:`tuple`: A tuple containing the aligned VB energy, aligned CB energy, - and a list of interstitial variances. - The variances represent the deviation of the potential from the + :obj:`tuple`: A tuple containing the aligned VB energy, aligned CB energy, + and a list of interstitial variances. + The variances represent the deviation of the potential from the reference state at each interstitial site. Output: @@ -121,33 +121,33 @@ def _find_active_space( """ Plot the active space (vacuum and non-vacuum regions) based on potential variations. - This function analyzes the potential variations within the specified cubes of the - given size and determines whether each cube belongs to the vacuum or non-vacuum + This function analyzes the potential variations within the specified cubes of the + given size and determines whether each cube belongs to the vacuum or non-vacuum region based on the provided tolerance. This function also plots the cube potentials of vacuum and non vacuum cubes. Parameters: - cube_size (list of int): The size of the cubes in units of mesh points (NGX/Y/Z) + cube_size (list of int): The size of the cubes in units of mesh points (NGX/Y/Z) for analysis. - cube_origin (list of float): The starting point (origin) of the cubes in + cube_origin (list of float): The starting point (origin) of the cubes in fractional coordinates (range [0, 1]). - tolerance (float, optional): The cutoff variance value to + tolerance (float, optional): The cutoff variance value to distinguish vacuum from non-vacuum cubes. Default is 1E-4. - input_file (str, optional): The file with VASP output for potential. + input_file (str, optional): The file with VASP output for potential. Default is 'LOCPOT'. - print_output (bool, optional): Whether to print the analysis results. + print_output (bool, optional): Whether to print the analysis results. Default is True. Returns: dict: A dictionary containing the potentials for the vacuum and non-vacuum regions. Note: - The function calculates the potential variation within each cube and - compares it to the tolerance value. Cubes with potential variations below the + The function calculates the potential variation within each cube and + compares it to the tolerance value. Cubes with potential variations below the tolerance are considered vacuum regions, while others are non-vacuum regions. Example: @@ -540,16 +540,16 @@ def subs_potentials(A: np.ndarray, B: np.ndarray, tol: float) -> np.ndarray: Subtract potentials between two datasets based on a tolerance value. Parameters: - A (:obj:`numpy.ndarray`): The first dataset containing potential + A (:obj:`numpy.ndarray`): The first dataset containing potential values in the format (x, potential). - B (:obj:`numpy.ndarray`): The second dataset containing potential + B (:obj:`numpy.ndarray`): The second dataset containing potential values in the format (x, potential). tol (:obj:`float`): The tolerance value for potential subtraction. Returns: - C (:obj:`numpy.ndarray`): The resulting dataset containing the subtracted + C (:obj:`numpy.ndarray`): The resulting dataset containing the subtracted potentials in the format (x, potential). Example: @@ -578,23 +578,23 @@ def translate_grid( boundary_shift: float = 0.0, ) -> np.ndarray: """ - Translates the grid points of a given potential by a specified translation + Translates the grid points of a given potential by a specified translation along the vector direction. Parameters: - potential (numpy.ndarray): Array containing potential data with shape (N, 2), + potential (numpy.ndarray): Array containing potential data with shape (N, 2), where N is the number of grid points. - translation (float): The amount of translation to apply to the grid points + translation (float): The amount of translation to apply to the grid points along the specified vector direction. - periodic (bool, optional): Whether to apply periodic boundary conditions. + periodic (bool, optional): Whether to apply periodic boundary conditions. Default is False. - vector (list, optional): The direction vector for translation. + vector (list, optional): The direction vector for translation. Default is [0, 0, 0]. - boundary_shift (float, optional): The amount of shift to consider when + boundary_shift (float, optional): The amount of shift to consider when applying periodic boundary conditions. Default is 0.0. Returns: @@ -647,7 +647,7 @@ def create_plotting_mesh( grad (numpy.ndarray): Array containing gradient data with shape (NGX, NGY, NGZ). Returns: - numpy.ndarray: A 2D array representing the plotting mesh with shape (a, b), + numpy.ndarray: A 2D array representing the plotting mesh with shape (a, b), where 'a' and 'b' depend on the plane direction. Example: diff --git a/macrodensity/utils.py b/macrodensity/utils.py index 6cda3b7..240ce45 100644 --- a/macrodensity/utils.py +++ b/macrodensity/utils.py @@ -9,14 +9,14 @@ def matrix_2_abc( lattice: np.ndarray, ) -> (float, float, float, float, float, float): """ - Extract lattice parameters and vectors from a 3x3 matrix + Extract lattice parameters and vectors from a 3x3 matrix representing a lattice. Parameters: lattice (np.ndarray): 3x3 matrix representing the lattice. Returns: - tuple: A tuple containing the lattice parameters a, b, c and + tuple: A tuple containing the lattice parameters a, b, c and lattice vectors a_vec, b_vec, c_vec. Example: @@ -78,7 +78,7 @@ def one_2_2d( array: np.ndarray, resolution: float, vector: np.ndarray ) -> np.ndarray: """ - Transform a 1D array to a 2D array with abscissa values based on the + Transform a 1D array to a 2D array with abscissa values based on the given resolution and vector. Parameters: