diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index f59b082..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "python.testing.pytestArgs": [ - "tests" - ], - "python.testing.unittestEnabled": false, - "python.testing.pytestEnabled": true, - "pythonTestExplorer.testFramework": "pytest" -} \ No newline at end of file diff --git a/cp2kdata/cell.py b/cp2kdata/cell.py new file mode 100644 index 0000000..47de514 --- /dev/null +++ b/cp2kdata/cell.py @@ -0,0 +1,95 @@ +from ase.geometry.cell import cellpar_to_cell +from ase.geometry.cell import cell_to_cellpar +import numpy.typing as npt +import numpy as np +from copy import deepcopy + +class Cp2kCell: + def __init__( + self, + cell_param: npt.NDArray[np.float64], + grid_point: npt.NDArray[np.int_] = None, + grid_spacing_matrix: npt.NDArray[np.float64] = None + ): + """ + The documentation of Cell class used in cp2kdata + Parameters + ---------- + cell_param: np. array + The length of the cell in bohr + divi: np. array + The number of grid points in each direction + h: float + The grid spacing in bohr + + a b c alpha beta gamma + grid_point : array + grid_spacing_matrix : matrix 3x3 + """ + + + if len(cell_param) == 1 and isinstance(cell_param, float): + self.cell_matrix = np.array( + [ + [cell_param, 0, 0], + [0, cell_param, 0], + [0, 0, cell_param] + ] + ) + print("input cell_param is a float, the cell is assumed to be cubic") + elif cell_param.shape == 3: + self.cell_matrix = np.array( + [ + [cell_param[0], 0, 0], + [0, cell_param[1], 0], + [0, 0, cell_param[2]] + ] + ) + print("input cell_param is a list or array, the cell is assumed to be orthorhombic") + elif cell_param.shape == 6: + self.cell_matrix = cellpar_to_cell(cell_param) + print("input cell_param is in [a, b, c, alpha, beta, gamma] form, it is converted to cell matrix") + elif cell_param.shape == (3, 3): + self.cell_matrix = cell_param + print("input cell_param is a matrix, the cell is read as is") + else: + raise ValueError("The input cell_param is not supported") + + + if (grid_point is None) and (grid_spacing_matrix is None): + print("No grid point generated") + elif (grid_point is None) and (grid_spacing_matrix is not None): + self.grid_spacing_matrix = grid_spacing_matrix + self.grid_point = np.round(self.cell_matrix/self.grid_spacing_matrix) + elif (grid_point is not None) and (grid_spacing_matrix is None): + self.grid_point = np.array(grid_point) + self.grid_spacing_matrix = self.cell_matrix/self.grid_point[:, np.newaxis] + elif (grid_point is not None) and (grid_spacing_matrix is not None): + self.grid_point = np.array(grid_point) + self.grid_spacing_matrix = np.array(grid_spacing_matrix) + + self.grid_point = self.grid_point.astype(int) + self.volume = np.linalg.det(self.cell_matrix) + self.dv = np.linalg.det(self.grid_spacing_matrix) + + self.cell_param = cell_to_cellpar(self.cell_matrix) + + def copy(self): + return deepcopy(self) + + def get_volume(self): + return self.volume + + def get_dv(self): + return self.dv + + def get_cell_param(self): + return self.cell_param + + def get_cell_angles(self): + return self.cell_param[3:] + + def get_cell_lengths(self): + return self.cell_param[:3] + + \ No newline at end of file diff --git a/cp2kdata/cli/cmd.py b/cp2kdata/cli/cmd.py index 4f6acfb..36de772 100644 --- a/cp2kdata/cli/cmd.py +++ b/cp2kdata/cli/cmd.py @@ -1,5 +1,6 @@ from email.policy import default import click +from cp2kdata import Cp2kCube from .funcs import * @@ -19,6 +20,11 @@ def plot(): cli.add_command(plot) +@click.group("cube") +def cube(): + click.echo('Manipulate Cube Files') +cli.add_command(cube) + #-- for gen test --# #-- Cutoff --# @click.command() @@ -221,4 +227,60 @@ def hubbardU(target_dir, exp_yaml): def ti(fig_name): plot_ti(fig_name=fig_name) -plot.add_command(ti) \ No newline at end of file +plot.add_command(ti) + + +# -- for cube -- # +@click.command() +@click.option( + '--cube_file', + type=str, + default=".", + help='cube file' + ) +@click.option( + '--axis', + type=str, + default="z", + help='axis' + ) +@click.option( + '--mav', + type=bool, + default=False, + help='switch on macro average or not' + ) +@click.option( + '--l1', + type=float, + default=1, + help='l1' + ) +@click.option( + '--l2', + type=float, + default=1, + help='l2' + ) +@click.option( + '--ncov', + type=int, + default=1, + help='ncov' + ) +@click.option( + '--unit', + type=str, + default="eV", + help='unit' + ) +@click.option( + '--width', + type=int, + default=135, + help='width' + ) +def view(cube_file, axis, mav, l1, l2, ncov, unit, width): + cube = Cp2kCube(cube_file) + cube.view_cube_acsii(axis=axis, mav=mav, l1=l1, l2=l2, ncov=ncov, unit=unit, width=width) +cube.add_command(view) \ No newline at end of file diff --git a/cp2kdata/cli/funcs.py b/cp2kdata/cli/funcs.py index 77fad4f..3bdf7bd 100644 --- a/cp2kdata/cli/funcs.py +++ b/cp2kdata/cli/funcs.py @@ -2,4 +2,5 @@ from ..test_input import write_basis_test_inp from ..test_input import write_hubbard_U_test_inp from ..plots.test_plot import plot_U_test, get_exp_collect_from_yaml, plot_cutoff_test, plot_basis_test -from ..plots.fep_plot import plot_ti \ No newline at end of file +from ..plots.fep_plot import plot_ti + diff --git a/cp2kdata/cube/cube.py b/cp2kdata/cube/cube.py index 06b1b86..e34642f 100644 --- a/cp2kdata/cube/cube.py +++ b/cp2kdata/cube/cube.py @@ -1,5 +1,6 @@ from cp2kdata.utils import file_content, interpolate_spline from cp2kdata.utils import au2A, au2eV +from cp2kdata.cell import Cp2kCell import numpy as np import matplotlib.pyplot as plt import os @@ -7,6 +8,7 @@ from ase import Atom, Atoms from monty.json import MSONable from copy import deepcopy +import asciichartpy as acp def square_wave_filter(x, l, cell_z): @@ -138,17 +140,11 @@ def quick_plot(self, axis="z", interpolate=False, output_dir="./"): class Cp2kCube(MSONable): - # remove useless timestep argument # add MSONable use as_dict and from_dict - # add copy method - # add addition and subtraction method cube1 + cube2 - - #TODO: .write method to write a cube file - #TODO: complete parse the grid_spacing and num_grid - - - - def __init__(self, file=None, cube_vals=None, grid_size=None, grid_space=None): + """ + Documentation for the Cp2kCube class. + """ + def __init__(self, fname=None, cube_vals=None, cell=None, stc=None): print("Warning: This is New Cp2kCube Class, if you want to use old Cp2kCube") print("try, from cp2kdata.cube.cube import Cp2kCube") print("New Cp2kCube return raw values in cp2k cube file") @@ -156,47 +152,47 @@ def __init__(self, file=None, cube_vals=None, grid_size=None, grid_space=None): print("that is, length in bohr and density in e/bohr^3 for density file") print("to convert unit: try from cp2kdata.utils import au2A, au2eV") - self.file = file - self.cube_vals = self.read_cube_vals() - self.cell_x = self.grid_size[0]*self.grid_space[0] - self.cell_y = self.grid_size[1]*self.grid_space[1] - self.cell_z = self.grid_size[2]*self.grid_space[2] + self.file = fname + + + if cell is None: + self.cell = self.read_cell() + else: + self.cell = cell + if stc is None: + self.stc = self.get_stc() + else: + self.stc = stc + + if cube_vals is None: + self.cube_vals = self.read_cube_vals(self.file, + self.num_atoms, + self.cell.grid_point + ) + else: + self.cube_vals = cube_vals + + def read_cell(self): + grid_point = self.read_grid_point(self.file) + gs_matrix = self.read_gs_matrix(self.file) + cell_param = gs_matrix*grid_point[:, np.newaxis] + return Cp2kCell(cell_param, grid_point, gs_matrix) @property def num_atoms(self): line = file_content(self.file, 2) num_atoms = int(line.split()[0]) return num_atoms - - @property - def grid_size(self): - # read grid point and grid size, unit: angstrom - content_list = file_content(self.file, (3,6)) - content_list = content_list.split() - num_x = int(content_list[0]) - num_y = int(content_list[4]) - num_z = int(content_list[8]) - return num_x, num_y, num_z - - @property - def grid_space(self): - # read grid point and grid size, unit: angstrom - content_list = file_content(self.file, (3,6)) - content_list = content_list.split() - step_x = float(content_list[1]) - step_y = float(content_list[6]) - step_z = float(content_list[11]) - return step_x, step_y, step_z def as_dict(self): - """Returns data dict of System instance.""" + """Returns data dict of Cp2kCube instance.""" data_dict = { "@module": self.__class__.__module__, "@class": self.__class__.__name__, "file": self.file, "cube_vals": self.cube_vals, - "grid_size": self.grid_size, - "grid_space": self.grid_space, + "cell": self.cell, + "stc": self.stc, } return data_dict @@ -220,7 +216,6 @@ def __sub__(self, others): raise RuntimeError("Unspported Class") return self_copy - def get_stc(self): atom_list = [] for i in range(self.num_atoms): @@ -233,37 +228,37 @@ def get_stc(self): atom_list.append(atom) stc = Atoms(atom_list) - stc.set_cell([self.cell_x, self.cell_y, self.cell_z]) + stc.set_cell(self.cell.cell_matrix) return stc def copy(self): return deepcopy(self) - - def read_cube_vals(self): - # read the cube value from file - cube_vals = file_content(self.file, (6+self.num_atoms,)) - cube_vals = cube_vals.split() - cube_vals = np.array(cube_vals, dtype = float) - cube_vals = cube_vals.reshape(self.grid_size) - cube_vals = cube_vals*au2eV - return cube_vals - def get_pav(self, axis="z", interpolate=False): + def get_pav(self, axis='z', interpolate=False): + np.testing.assert_array_equal( + self.cell.get_cell_angles(), + np.array([90.0, 90.0, 90.0]), + err_msg="The cell is not orthorhombic, the pav can not be used!" + ) + # do the planar average along specific axis + lengths = self.cell.get_cell_lengths() + grid_point = self.cell.grid_point + gs_matrix = self.cell.grid_spacing_matrix if axis == 'x': vals = self.cube_vals.mean(axis=(1,2)) - points = np.arange(0, self.grid_size[0])*self.grid_space[0] - length = self.grid_size[0]*self.grid_space[0] + points = np.arange(0, grid_point[0])*gs_matrix[0][0] + length = lengths[0] elif axis == 'y': vals = self.cube_vals.mean(axis=(0,2)) - points = np.arange(0, self.grid_size[1])*self.grid_space[1] - length = self.grid_size[1]*self.grid_space[1] + points = np.arange(0, grid_point[1])*gs_matrix[1][1] + length = lengths[1] elif axis == 'z': vals = self.cube_vals.mean(axis=(0,1)) - points = np.arange(0, self.grid_size[2])*self.grid_space[2] - length = self.grid_size[2]*self.grid_space[2] + points = np.arange(0, grid_point[2])*gs_matrix[2][2] + length = lengths[2] else: - print("not such plane average style!") + print("not such plane average style, the avaialble options are 'x', 'y', 'z'") # interpolate or note if interpolate: @@ -278,9 +273,9 @@ def get_pav(self, axis="z", interpolate=False): def get_mav(self, l1, l2=0, ncov=1, interpolate=False, axis="z"): cell_length = { - "x": self.cell_x, - "y": self.cell_y, - "z": self.cell_z + "x": self.cell.get_cell_lengths()[0], + "y": self.cell.get_cell_lengths()[1], + "z": self.cell.get_cell_lengths()[2] } length = cell_length[axis] @@ -294,15 +289,106 @@ def get_mav(self, l1, l2=0, ncov=1, interpolate=False, axis="z"): mav = fft.ifft(mav_fft) return pav_x, np.real(mav) - - def quick_plot(self, axis="z", interpolate=False, output_dir="./"): + def quick_plot(self, axis="z", interpolate=False): + x, y = self.get_pav(axis=axis, interpolate=interpolate) - plt.figure(figsize=(9,9), dpi=100) - plt.plot(x, y, label=("PAV"+axis)) - plt.xlabel(axis + " [A]") - plt.ylabel("Hartree [eV]") - plt.legend() - plt.savefig(os.path.join(output_dir, "pav.png"), dpi=100) + plt.style.use('cp2kdata.matplotlibstyle.jcp') + row = 1 + col = 1 + fig = plt.figure(figsize=(3.37*col, 1.89*row), dpi=600, facecolor='white') + gs = fig.add_gridspec(row,col) + ax = fig.add_subplot(gs[0]) + ax.plot(x, y, label=(f"PAV along {axis}")) + #ax.set_xlabel(f'{axis} [A]') + #ax.set_ylabel('Hartree [eV]') + ax.legend() + return fig + + def view_cube_acsii(self, axis='z', mav=False, l1=None, l2=None, ncov=1, unit='au', width=135): + if mav: + x, y = self.get_mav(l1, l2, ncov, axis=axis) + else: + x, y = self.get_pav(axis=axis) + + if unit == 'au': + pass + elif unit == 'eV': + y = y*au2eV + else: + print("not such unit, the available options are 'au' and 'eV'") + step = int(len(y)/width) + print(acp.plot(y[::step], {'height': 20})) + + def write_cube(self, fname, comments='#'): + grid_point = self.cell.grid_point + gs_matrix = self.cell.grid_spacing_matrix + with open(fname, 'w') as fw: + # write header + fw.write('Cube file generated by CP2KData\n') + fw.write(comments+'\n') + # grid information + fw.write(f'{self.num_atoms:5d}{0:12.6f}{0:12.6f}{0:12.6f}\n') + fw.write(f'{grid_point[0]:5d}{gs_matrix[0][0]:12.6f}{gs_matrix[0][1]:12.6f}{gs_matrix[0][2]:12.6f}\n') + fw.write(f'{grid_point[1]:5d}{gs_matrix[1][0]:12.6f}{gs_matrix[1][1]:12.6f}{gs_matrix[1][2]:12.6f}\n') + fw.write(f'{grid_point[2]:5d}{gs_matrix[2][0]:12.6f}{gs_matrix[2][1]:12.6f}{gs_matrix[2][2]:12.6f}\n') + # structure information + for atom in self.stc: + fw.write(f'{atom.number:5d}{0:12.6f}{atom.position[0]/au2A:12.6f}{atom.position[1]/au2A:12.6f}{atom.position[2]/au2A:12.6f}\n') + # cube values + # cp2k write cube loop in z, y, x order + # https://github.com/cp2k/cp2k/blob/01090ebf0718ff6885d11f89fe10938d80eb0a02/src/pw/realspace_grid_cube.F#L99 + for i in range(grid_point[0]): + for j in range(grid_point[1]): + for k in range(grid_point[2]): + # notice that cp2k write scientific notion differntly + # cp2k: 0.20871E+00 + # python: 2.08710E-01 + fw.write(f'{self.cube_vals[i,j,k]:13.5E}') + if (k+1)%6 == 0: + fw.write('\n') + # write a blank line after each z value + if grid_point[2]%6 != 0: + fw.write('\n') + + def get_integration(self): + dv = self.cell.get_dv() + result = np.sum(self.cube_vals)*dv + return result + + def get_cell(self): + return self.cell.copy() + + @staticmethod + def read_gs_matrix(fname): + content_list = file_content(fname, (3,6)) + content_list = content_list.split() + + gs_matrix = [ + [float(content_list[1]), float(content_list[2]), float(content_list[3])], + [float(content_list[5]), float(content_list[6]), float(content_list[7])], + [float(content_list[9]), float(content_list[10]), float(content_list[11])] + ] + gs_matrix = np.array(gs_matrix) + return gs_matrix + + @staticmethod + def read_grid_point(fname): + # read grid point and grid size, unit: angstrom + content_list = file_content(fname, (3,6)) + content_list = content_list.split() + num_x = int(content_list[0]) + num_y = int(content_list[4]) + num_z = int(content_list[8]) + return np.array([num_x, num_y, num_z]) + + @staticmethod + def read_cube_vals(fname, num_atoms, grid_point): + # read the cube value from file + cube_vals = file_content(fname, (6+num_atoms,)) + cube_vals = cube_vals.split() + cube_vals = np.array(cube_vals, dtype = float) + cube_vals = cube_vals.reshape(grid_point) + return cube_vals class Cp2kCubeTraj: def __init__(cube_dir, prefix): diff --git a/cp2kdata/matplotlibstyle/__init__.py b/cp2kdata/matplotlibstyle/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/cp2kdata/matplotlibstyle/jcp.mplstyle b/cp2kdata/matplotlibstyle/jcp.mplstyle new file mode 100644 index 0000000..2ed6019 --- /dev/null +++ b/cp2kdata/matplotlibstyle/jcp.mplstyle @@ -0,0 +1,32 @@ +# the following settings are compliant with JCP standards +axes.titlesize : 8 +axes.labelsize : 7 # for x y labels +axes.linewidth : 0.8 +font.size: 6 + +patch.linewidth : 0.8 + +figure.dpi: 600 +figure.figsize: 3.37, 1.89 + +lines.linewidth : 0.8 +lines.markeredgewidth: 0.8 +lines.markersize : 4.0 + +xtick.direction: in +xtick.minor.visible: True +xtick.major.size: 5 +xtick.minor.size: 2.5 +xtick.major.width: 0.8 +xtick.minor.width: 0.8 +xtick.labelsize : 6 + +ytick.direction: in +ytick.minor.visible: True +ytick.major.size: 5 +ytick.minor.size: 2.5 +ytick.major.width: 0.8 +ytick.minor.width: 0.8 +ytick.labelsize : 6 + +grid.linewidth: 0.6 \ No newline at end of file diff --git a/cp2kdata/output.py b/cp2kdata/output.py index 3dd0316..10a1953 100644 --- a/cp2kdata/output.py +++ b/cp2kdata/output.py @@ -284,6 +284,7 @@ def parse_geo_opt(self): self.init_atomic_coordinates, self.atom_kind_list, self.chemical_symbols = parse_init_atomic_coordinates( self.output_file) self.geo_opt_info = parse_geo_opt_info(self.output_file) + self.energies_list = parse_energies_list(self.output_file) self.num_frames = len(self.geo_opt_info) self.atomic_forces_list = parse_atomic_forces_list(self.output_file) self.stress_tensor_list = parse_stress_tensor_list(self.output_file) diff --git a/cp2kdata/plots/fep_plot.py b/cp2kdata/plots/fep_plot.py index 0d4a107..1bafdee 100644 --- a/cp2kdata/plots/fep_plot.py +++ b/cp2kdata/plots/fep_plot.py @@ -2,7 +2,6 @@ import matplotlib.pyplot as plt import glob import os -from toolkit.utils.utils import get_cum_mean from cp2kdata.block_parser.fep import parse_vertical_gap from scipy import integrate from cycler import cycler @@ -10,6 +9,16 @@ au2eV = 2.72113838565563E+01 +def get_cum_mean(array): + tot = 0.0 + cum_mean_array = [] + for idx, i in enumerate(array): + tot += i + cum_mean_array.append(tot/(idx+1)) + cum_mean_array = np.array(cum_mean_array) + return cum_mean_array + + def plot_ti(fig_name): eta_sub_dir_list = glob.glob("[0-1].*") eta_sub_dir_list.sort() diff --git a/docs/cube/README.md b/docs/cube/README.md index 6a2511a..751a481 100644 --- a/docs/cube/README.md +++ b/docs/cube/README.md @@ -1,23 +1,50 @@ # Manipulate CP2K Cube Files -The `cp2kdata` Python package provides tools for working with cube files generated by the CP2K quantum chemistry software. One of the standout features of this package is its ability to handle CP2K cube files and perform various analyses. +The `CP2KData` Python package provides tools for working with cube files generated by the CP2K quantum chemistry software. One of the standout features of this package is its ability to handle CP2K cube files and perform various analyses. ## Getting Started Import the necessary modules and load a cube file: ```python from cp2kdata import Cp2kCube +cube_file_path = "slab-ELECTRON_DENSITY-1_0.cube" +mycube = Cp2kCube(cube_file_path) +``` -cube_file = "xxx.cube" -mycube = Cp2kCube(cube_file) +## Retrieving Cell Information +Users can easily obtain cell information from CP2K cube files by the following method +```python +cell = mycube.get() +type(cell) +``` +As a result, you will get new object `Cp2kCell` +```shell +# output +cp2kdata.cell.Cp2kCell ``` + ## Retrieving Structural Information CP2K cube files include structural information, making it easy to work with atomic structures. You can retrieve this information using the `get_stc()` method: ```python stc = mycube.get_stc() -print(stc) +``` +The stc is ASE `Atoms` object +```shell +#output +ase.atoms.Atoms ``` +## Integration over space +User can obtain the integration over space using the `get_integration()` method, for example, if you get integration using density cube, you will get the total number electrons in this cube +```python +mycube.get_integration() +``` +```shell +#output +1152.0007910850024 +``` +The result is not exactly an integer. User should round it to integer manually. + ## Planar Averaging You can calculate planar average data from the cube file, both with and without interpolation: ```python @@ -40,10 +67,10 @@ mav_x, mav = mycube.get_mav(l1=4.8, l2=4.8, ncov=2, interpolate=True) ``` -## Addition and Subtraction of Cp2kCubes -The Cp2kCubeNew class provides a convenient way to perform addition and subtraction operations on CP2K cube files, allowing you to manipulate the data contained within them. +## Addition and Subtraction of Cp2kCube +The Cp2kCube class provides a convenient way to perform addition and subtraction operations on CP2K cube files, allowing you to manipulate the data contained within them. This method is extremly useful, if you would like to obtain the charge difference ```python -from cp2kcube.cube.cube import Cp2kCubeNew as Cp2kCube +from cp2kcube import Cp2kCube # Load the first cube file cube1 = Cp2kCube("path/to/cube1.cube") @@ -59,13 +86,54 @@ result_cube = cube1 + cube2 result_cube = cube1 - cube2 ``` +The resulted object is a new Cp2kCube, with which, all above methods can be used. -## Quick Plotting -Easily create quick plots of your data with the quick_plot() method. You can specify the axis, interpolation, and output directory: +## Writing Cube +The Cp2kCube can write data into a cube file with cp2k format using the `write_cube()` method: +```python +mycube.write_cube("./test.cube") +``` +With this command, you will obtain a new cube file under the current folder. +## Quick Plotting +Easily create quick plots of your data with the quick_plot() method. The method returns matplotlib `figure` object, with which, users can further manupulate the figure or save it to a directory. ```python -mycube.quick_plot(axis="z", interpolate=False, output_dir="./") +fig = mycube.quick_plot(axis="z", interpolate=False) +fig.savefig("pav.png") +``` + +## View Planar and Macro average in Terminal +CP2K are often installed in HPC, which means no graphic interface but only the terminal for users. `CP2KData` uses command line tools to check Planar and Macro average in terminal + +In your terminal, type +```shell +cp2kdata cube view --cube_file slab-ELECTRON_DENSITY-1_0.cube ``` +You will get +![terminal_plot](./terminal.png) +The width of plot can be adjusted according to your terminal width +```shell +cp2kdata cube view --cube_file slab-ELECTRON_DENSITY-1_0.cube --width 80 +``` +For other option, see the help +``` +cp2kdata cube view --help +``` +```shell +Usage: cp2kdata cube view [OPTIONS] + +Options: + --cube_file TEXT cube file + --axis TEXT axis + --mav BOOLEAN switch on macro average or not + --l1 FLOAT l1 + --l2 FLOAT l2 + --ncov INTEGER ncov + --unit TEXT unit + --width INTEGER width + --help Show this message and exit. +``` + ## Benchmark Comparison The Planar Average and Macro Average results from cp2kdata are benchmarked against those from Siesta and Abinit, as shown in the following figures: diff --git a/docs/cube/terminal.png b/docs/cube/terminal.png new file mode 100644 index 0000000..256ca4c Binary files /dev/null and b/docs/cube/terminal.png differ diff --git a/pyproject.toml b/pyproject.toml index 4613bf2..a0127ea 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "setuptools.build_meta" [project] name = "Cp2kData" -version = "0.6.1" +version = "0.6.2" description = "A Small Package to Postprocess Cp2k Output" authors = [ {name = "Yongbin Zhuang", email = "robinzhuang@outlook.com"} @@ -28,7 +28,9 @@ dependencies = [ "dpdata", "click", "regex", - "monty" + "monty", + "pyyaml", + "asciichartpy" ] requires-python = ">=3.8" keywords = ["cp2k", "cp2kdata"] @@ -49,5 +51,8 @@ cp2kdata = "cp2kdata.cli.cmd:cli" [tool.setuptools.packages.find] include = ["cp2kdata*"] +[tool.setuptools.package-data] +cp2kdata = ["matplotlibstyle/*.mplstyle"] + diff --git a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/cube_vals.npy b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/cube_vals.npy index c14eb70..1ba0cb1 100644 Binary files a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/cube_vals.npy and b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/cube_vals.npy differ diff --git a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/grid_size.npy b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/grid_point.npy similarity index 100% rename from tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/grid_size.npy rename to tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/grid_point.npy diff --git a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/grid_space.npy b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/grid_space.npy deleted file mode 100644 index ea80b45..0000000 Binary files a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/grid_space.npy and /dev/null differ diff --git a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/gs_matrix.npy b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/gs_matrix.npy new file mode 100644 index 0000000..21995d7 Binary files /dev/null and b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/gs_matrix.npy differ diff --git a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/integral.npy b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/integral.npy new file mode 100644 index 0000000..28046f9 Binary files /dev/null and b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/integral.npy differ diff --git a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/mav.npy b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/mav.npy index 5c753d4..f87c666 100644 Binary files a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/mav.npy and b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/mav.npy differ diff --git a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/pav.npy b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/pav.npy index df19a90..79650f5 100644 Binary files a/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/pav.npy and b/tests/test_cube/answer_Si_bulk8-v_hartree-1_0.cube/pav.npy differ diff --git a/tests/test_cube/gen_test_answer.py b/tests/test_cube/gen_test_answer.py index 6c50415..5075334 100644 --- a/tests/test_cube/gen_test_answer.py +++ b/tests/test_cube/gen_test_answer.py @@ -10,8 +10,9 @@ dir_name = f"answer_{file}" os.makedirs(dir_name, exist_ok = True) np.save(os.path.join(dir_name, "cube_vals.npy"), cube.cube_vals) - np.save(os.path.join(dir_name, "grid_size.npy"), cube.grid_size) - np.save(os.path.join(dir_name, "grid_space.npy"), cube.grid_space) + np.save(os.path.join(dir_name, "grid_point.npy"), cube.cell.grid_point) + np.save(os.path.join(dir_name, "gs_matrix.npy"), cube.cell.grid_spacing_matrix) np.save(os.path.join(dir_name, "num_atoms.npy"), cube.num_atoms) + np.save(os.path.join(dir_name, "integral.npy"), cube.get_integration()) np.save(os.path.join(dir_name, "pav.npy"), cube.get_pav()) np.save(os.path.join(dir_name, "mav.npy"), cube.get_mav(l1=1, l2=1, ncov=2)) diff --git a/tests/test_cube/test_cube.py b/tests/test_cube/test_cube.py index 8b515aa..544bfd4 100644 --- a/tests/test_cube/test_cube.py +++ b/tests/test_cube/test_cube.py @@ -22,18 +22,18 @@ def test_num_atoms(self, cube_and_answer): num_atoms = cube.num_atoms num_atoms_answer = np.load(os.path.join(answer_dir, "num_atoms.npy")) assert num_atoms == num_atoms_answer - def test_grid_size(self, cube_and_answer): + def test_grid_point(self, cube_and_answer): cube = cube_and_answer[0] answer_dir = cube_and_answer[1] - grid_size = cube.grid_size - grid_size_answer = np.load(os.path.join(answer_dir, "grid_size.npy")) - assert np.all(grid_size == grid_size_answer) - def test_grid_space(self, cube_and_answer): + grid_point = cube.cell.grid_point + grid_point_answer = np.load(os.path.join(answer_dir, "grid_point.npy")) + assert np.all(grid_point == grid_point_answer) + def test_grid_spacing_matrix(self, cube_and_answer): cube = cube_and_answer[0] answer_dir = cube_and_answer[1] - grid_space = cube.grid_space - grid_space_answer = np.load(os.path.join(answer_dir, "grid_space.npy")) - assert np.all(grid_space == grid_space_answer) + gs_matrix = cube.cell.grid_spacing_matrix + gs_matrix_answer = np.load(os.path.join(answer_dir, "gs_matrix.npy")) + assert np.all(gs_matrix == gs_matrix_answer) def test_cube_vals(self, cube_and_answer): cube = cube_and_answer[0] answer_dir = cube_and_answer[1]