pymdkit 1.4.7__tar.gz → 1.4.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. {pymdkit-1.4.7 → pymdkit-1.4.9}/PKG-INFO +66 -11
  2. {pymdkit-1.4.7 → pymdkit-1.4.9}/README.md +288 -232
  3. {pymdkit-1.4.7 → pymdkit-1.4.9}/pyproject.toml +1 -2
  4. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/__init__.py +1 -1
  5. pymdkit-1.4.9/src/pymdkit/commands/_cifio.py +192 -0
  6. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/chemsys_entry.py +6 -6
  7. pymdkit-1.4.9/src/pymdkit/commands/compute_rmsd.py +280 -0
  8. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/convert.py +10 -2
  9. pymdkit-1.4.9/src/pymdkit/commands/gather_fs.py +216 -0
  10. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/gpumd_group.py +7 -2
  11. pymdkit-1.4.9/src/pymdkit/commands/gpumd_relax.py +127 -0
  12. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/substitute.py +3 -3
  13. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/supercell.py +13 -7
  14. pymdkit-1.4.9/src/pymdkit/commands/symmetrize.py +289 -0
  15. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit.egg-info/PKG-INFO +66 -11
  16. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit.egg-info/SOURCES.txt +3 -1
  17. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit.egg-info/requires.txt +0 -1
  18. pymdkit-1.4.7/src/pymdkit/commands/compute_rmsd.py +0 -139
  19. pymdkit-1.4.7/src/pymdkit/commands/gather_contcar.py +0 -106
  20. pymdkit-1.4.7/src/pymdkit/commands/symmetrize.py +0 -446
  21. {pymdkit-1.4.7 → pymdkit-1.4.9}/LICENSE +0 -0
  22. {pymdkit-1.4.7 → pymdkit-1.4.9}/setup.cfg +0 -0
  23. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/__init__.py +0 -0
  24. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/_extxyz.py +0 -0
  25. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/_fileio.py +0 -0
  26. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/_geometry.py +0 -0
  27. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/_gpumd.py +0 -0
  28. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/_reduction.py +0 -0
  29. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/_vasp_output.py +0 -0
  30. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/_vaspset.py +0 -0
  31. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/add_config_type.py +0 -0
  32. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/compute_ehull.py +0 -0
  33. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/compute_msd_all_groups.py +0 -0
  34. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/ewald.py +0 -0
  35. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/gpumd_thermo.py +0 -0
  36. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/gpumd_trjcat.py +0 -0
  37. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/nep_rmse.py +0 -0
  38. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/pca.py +0 -0
  39. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/perturb.py +0 -0
  40. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/submit_vasp.py +0 -0
  41. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/trj_extract.py +0 -0
  42. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/trj_sparse.py +0 -0
  43. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/umap.py +0 -0
  44. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/vasp2xyz.py +0 -0
  45. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/vasp_fe.py +0 -0
  46. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/vasp_relax.py +0 -0
  47. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/commands/vasp_static.py +0 -0
  48. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit/pymdkit_main.py +0 -0
  49. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit.egg-info/dependency_links.txt +0 -0
  50. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit.egg-info/entry_points.txt +0 -0
  51. {pymdkit-1.4.7 → pymdkit-1.4.9}/src/pymdkit.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymdkit
3
- Version: 1.4.7
3
+ Version: 1.4.9
4
4
  Summary: A unified command-line toolkit for atomistic / MD structure workflows.
5
5
  Author-email: Yueda Wang <ydwang0608@ustc.edu.cn>
6
6
  License-Expression: GPL-3.0-or-later
@@ -18,7 +18,6 @@ Requires-Dist: ase
18
18
  Requires-Dist: pymatgen
19
19
  Requires-Dist: mp-api
20
20
  Requires-Dist: py4vasp-core
21
- Requires-Dist: pyxtal
22
21
  Requires-Dist: dpdata
23
22
  Requires-Dist: matplotlib
24
23
  Requires-Dist: umap-learn
@@ -65,10 +64,11 @@ directory for job sub-folders automatically.
65
64
  |---|---|
66
65
  | `add-config-type` | Add Config_type to one XYZ structure or every trajectory frame |
67
66
  | `gpumd-group` | Tag atoms with a GPUMD group index by element order |
67
+ | `gpumd-relax` | Write GPUMD energy-minimization jobs for a file, folder, or trajectory |
68
68
  | `ewald` | Compute CIF electrostatic energy with pymatgen EwaldSummation |
69
69
  | `ehull` | Auto-detect VASP job folders and compute E_hull vs Materials Project |
70
70
  | `vasp-fe` | List VASP job final energies from lowest to highest |
71
- | `gather-contcar` | Collect CONTCARs from VASP job folders into one folder, renamed `<folder>.vasp` |
71
+ | `gather-fs` | Recursively gather final structures from converged VASP or GPUMD jobs |
72
72
  | `gpumd-thermo` | Export and plot GPUMD thermo data and detect sustained equilibrium changes |
73
73
  | `gpumd-trjcat` | Merge normal or all GPUMD trajectories and extract the first abnormal region |
74
74
  | `pca` | Reduce descriptor data to two dimensions; optional FPS sampling |
@@ -80,12 +80,12 @@ directory for job sub-folders automatically.
80
80
  | `perturb` | Generate perturbed structures with dpdata |
81
81
  | `vasp2xyz` | Collect SCF-converged VASP job folders (any name) into one extxyz file |
82
82
  | `submit-vasp` | Submit/resubmit VASP job folders while limiting active queue jobs |
83
- | `rmsd` | Compute RMSD between two structure files, or all pairs in a folder |
83
+ | `rmsd` | Compare structures by RMSD and optionally remove higher-energy duplicates |
84
84
  | `chemsys-entry` | Download stable Materials Project structures for a chemical system |
85
85
  | `convert` | Convert structures, trajectories, or folders between ASE/pymatgen formats |
86
86
  | `substitute` | Randomly substitute or remove selected atoms/sites from a structure |
87
87
  | `supercell` | Build a supercell with cell lengths capped at a maximum (Angstrom); optional per-temperature GPUMD setup |
88
- | `symmetrize` | Import space-group symmetry into a structure file (or folder) -> CIF |
88
+ | `symmetrize` | Detect/refine symmetry for structure files, folders, or CSV rows -> CIF |
89
89
  | `vasp-relax` | Write VASP relaxation inputs for a structure (or folder); INCAR tags overridable |
90
90
  | `vasp-static` | Write VASP static / single-point inputs for a structure (or folder) |
91
91
 
@@ -106,6 +106,8 @@ pmk supercell -if extxyz-opted -max-abc 24 -individual -temp 500 600 -md-if inpu
106
106
  # GPUMD: ./<name>/model.xyz (grouped) + ./<name>/<T>/ jobs
107
107
  pmk vasp-relax -i opted.vasp # relax inputs in current dir
108
108
  pmk vasp-relax -if optimal_occupancy # one ./<name>/ job folder per structure
109
+ pmk gpumd-relax -if example -nep nep89_20250409.txt # model.xyz + run.in + NEP per job folder
110
+ pmk gpumd-relax -it train.xyz -nep nep.txt -in run.in # one ./frame_N/ GPUMD job per frame
109
111
  pmk vasp-static -if cifs/ -custom-setting my_incar.txt # static inputs, custom INCAR
110
112
  pmk vasp-static -it traj.xyz # one ./frame_N/ job per trajectory frame
111
113
  pmk msd # scans <structure>/<temp>/ -> per-job msd/ + msd_summary.txt
@@ -114,8 +116,9 @@ pmk chemsys-entry -s Li La Ta Cl # MP stable entries -> Li-La-Ta
114
116
  pmk ehull -mp-api-key $MP_API_KEY # scans ./ for VASP jobs -> ehull.txt
115
117
  pmk ehull -local Li-La-Ta-Cl-stable-entries-opted
116
118
  pmk vasp-fe # scans ./ for VASP jobs -> final-energy.txt with convergence status
117
- pmk gather-contcar -of vasp-opted # CONTCARs -> vasp-opted/<folder>.vasp
118
- pmk gather-contcar -of vasp-opted -ehull 0.028 # only structures with E_hull < 0.028 eV/atom
119
+ pmk gather-fs -job vasp -fs-name CONTCAR -of vasp-opted
120
+ pmk gather-fs -job vasp -fs-name CONTCAR -of vasp-opted -ehull 0.028
121
+ pmk gather-fs -job gpumd -fs-name relaxed.xyz -of gpumd-opted
119
122
  pmk vasp2xyz # scans ./ for VASP output folders -> scf-converged.xyz
120
123
  pmk vasp2xyz -position-only # write positions only, without energy/forces/stress
121
124
  pmk submit-vasp -subscript sub_vasp -queue slurm -max-job-num 30
@@ -141,10 +144,12 @@ pmk gpumd-trjcat -all # merge every readable trajectory in
141
144
  pmk trj-extract -it traj.xyz -in run.in -b 100 -e 200 -o traj-100ps-200ps.xyz
142
145
  pmk trj-sparse -it example.xyz -r 0.5 -o sparse-example.xyz
143
146
 
144
- pmk rmsd a.cif b.cif # RMSD of two files -> rmsd.txt
145
- pmk rmsd vasp-opted/ # all pairs in a folder -> rmsd.txt
146
- pmk symmetrize -i opted.cif -symprec 0.01 -add_oxidation yes -o opted-symm.cif
147
- pmk symmetrize -if my_cifs/ -symprec 0.01 -add_oxidation no -of my_cifs-symm
147
+ pmk rmsd -i structure-1.vasp structure-2.vasp # one pair -> rmsd.txt
148
+ pmk rmsd -if vasp-opted # every pair -> rmsd.txt
149
+ pmk rmsd -if example -rm-duplicate -of unique-example # RMSD <= 0.1: keep lowest energy
150
+ pmk symmetrize -i opted.cif -add_oxidation yes -o opted-symm.cif
151
+ pmk symmetrize -if my_cifs/ -symprec 0.02 -add_oxidation no -of my_cifs-symm
152
+ pmk symmetrize -csv output_Li2YCl3_struct.csv -of Li2YCl3
148
153
  ```
149
154
 
150
155
  VASP input commands (`vasp-relax`, `vasp-static`) always produce **individual**
@@ -169,6 +174,53 @@ multi-structure trajectory and writes one job sub-folder per frame
169
174
  (`frame_1/`, `frame_2/`, ..., prefix configurable via `-frame-prefix`). Each
170
175
  folder also keeps a `frame_N.xyz`, so `Config_type` survives for a later
171
176
  `vasp2xyz`.
177
+ `gpumd-relax` accepts the same `-i`, `-if`, and `-it` structure modes. `-nep`
178
+ is required and the selected potential is copied into every job folder together
179
+ with `model.xyz` and `run.in`. `-in FILE` supplies a custom GPUMD input; its
180
+ first `potential` filename is synchronized to the copied NEP. Without `-in`,
181
+ the generated job-local input is:
182
+
183
+ ```text
184
+ potential <NEP filename>
185
+
186
+ minimize fire 2.0e-2 1000000
187
+
188
+ ensemble nve
189
+ dump_xyz -1 0 1 relaxed.xyz force
190
+ run 1
191
+ ```
192
+
193
+ `gather-fs` recursively scans all job folders below the current directory. For
194
+ VASP it follows the global `vaspout.h5 > vasprun.xml > OUTCAR` priority and
195
+ requires full convergence before copying the selected `-fs-name` as `.vasp`. The gathered VASP file's first line is replaced with `energy=<final_energy> eV` for later screening.
196
+ For GPUMD it requires `gpumd.out` to report a force tolerance and a final
197
+ `f_max` no greater than that tolerance before copying the final structure.
198
+ `-fs-name` defaults to `CONTCAR` for VASP and `relaxed.xyz` for GPUMD. The
199
+ `-ehull` and `-ehull-file` filters are available only with `-job vasp`.
200
+ `rmsd -i STRUCTURE_1 STRUCTURE_2` compares one pair, while `rmsd -if FOLDER`
201
+ records every unique pair in `rmsd.txt`. With `-rm-duplicate -of OUTPUT`, files
202
+ are processed from lowest to highest energy; a structure is removed only when
203
+ its RMSD to an already retained lower-energy representative is no greater than `0.1`. Duplicate removal supports `.vasp`,
204
+ `.xyz`, and `.extxyz`: VASP energy is read from the first line, and extended-XYZ
205
+ energy from the second-line `energy=` tag. The report records every RMSD,
206
+ duplicate decision, energy, group, and retained representative.
207
+
208
+ `symmetrize` uses pymatgen's spglib-backed `SpacegroupAnalyzer` for authoritative
209
+ space-group detection and conventional-cell refinement. Its default Cartesian
210
+ symmetry tolerance is `0.02 Angstrom` (`-symprec`), with a `5 degree` angle
211
+ tolerance (`-angle-tolerance`). CIF occupancies are retained by the pymatgen
212
+ structure and written directly rather than reconstructed after symmetry finding.
213
+ CSV mode reads serialized pymatgen `Structure` dictionaries from a required `cif`
214
+ column. `-csv INPUT.csv -of NAME` writes `INDEX-NAME-SPACEGROUP.cif`, for
215
+ example `1-Li2YCl3-66.cif`.
216
+
217
+ Every CIF exported by `symmetrize`, `convert`, `substitute`, `chemsys-entry`,
218
+ `supercell`, or `gpumd-group` is written through the same symmetry-aware helper.
219
+ The atom-site loop contains both `_atom_site_symmetry_multiplicity` and
220
+ `_atom_site_Wyckoff_symbol`. Multiplicity-letter assignments use the conventional
221
+ International Tables setting from pymatgen/spglib and correspond to the
222
+ [Bilbao Crystallographic Server WYCKPOS tables](https://cryst.ehu.es/cryst/get_wp.html);
223
+ the provenance URL is also recorded inside each generated CIF.
172
224
 
173
225
  `add-config-type` updates its input atomically in place. With `-i`, the file must contain exactly one XYZ structure; use `-it` for a trajectory. Existing `Config_type` values are replaced, missing values are added, and all other extended-XYZ bytes remain unchanged.
174
226
 
@@ -177,6 +229,7 @@ folder also keeps a `frame_N.xyz`, so `Config_type` survives for a later
177
229
  When `pca` or `umap` receives `-it train.xyz`, it reads `Config_type` from every frame and writes one additional descriptor table per value, such as `pca-descriptor-P-3m1.txt` and `pca-descriptor-Pnma.txt`. With `-fps`, it also writes matching files such as `fps-0.01-pca-descriptor-P-3m1.txt` and `fps-0.01-train-P-3m1.xyz`. These files partition the single global FPS selection; FPS is not rerun independently for each `Config_type`. Frames without `Config_type` remain in the main outputs but do not receive a type-specific file.
178
230
 
179
231
  For folder conversion, `convert -if INPUT -of OUTPUT` writes `.xyz` by default. Set another target extension with `-oe`, for example `-oe cif` or `-oe vasp`. Single-file and trajectory modes infer the target format from `-o` and `-ot`.
232
+ Because Wyckoff metadata describes one crystal structure, each `.cif` output file accepts exactly one frame.
180
233
 
181
234
  `gpumd-thermo` writes `temperature.txt`, `potential-energy.txt`, `pressure.txt`, `lattice-parameters.txt`, `volume.txt`, `lattice-angles.txt`, and a headless `thermo.png` in every detected GPUMD job folder. For an abnormal run it also writes `abnormal-time.txt`, with one `BEGIN ps to END ps` interval per line; a normal rerun removes a stale file. Potential energy is the primary equilibrium signal. Detection requires a persistent change with a meaningful magnitude relative to the robust natural energy fluctuations, so ordinary correlated thermal noise and isolated spikes are not classified as abnormal. An abnormal classification always requires a mapped potential-energy change. When at least two lattice-parameter or volume signals show the same mapped transition, they may enable a more sensitive noise-relative energy test; this avoids a fixed eV or percentage-of-total-energy threshold that would depend on system size. Cell signals can corroborate and refine the energy interval, but can never classify a run by themselves. Temperature and all six pressure components remain diagnostics only and cannot classify an otherwise stationary run as abnormal by themselves. A lone cell-axis drift, an isolated spike, or an empty anomaly mask never triggers a whole-run fallback. Thermo plots use Arial when available and Matplotlib's built-in qualitative `Dark2` color cycle. They plot all six pressure components, use frameless upper-right legends with added vertical headroom, preserve correct Å units, and show abnormal regions as shaded legend entries on potential energy, lattice parameters, and volume. Potential energy and volume are divided by 1000 and labeled ×10³ only when their absolute plotted values reach 1000. The analysis uses the last `run` segment, or the last 80% when `run.in` has no `run` record; inspect the plot before making a final scientific judgment.
182
235
 
@@ -231,6 +284,7 @@ pymdkit/
231
284
  |-- _geometry.py # shared minimum-image geometry helper
232
285
  |-- _vaspset.py # shared VASP input-set helper (not a command)
233
286
  |-- gpumd_group.py
287
+ |-- gpumd_relax.py
234
288
  |-- gpumd_thermo.py
235
289
  |-- gpumd_trjcat.py
236
290
  |-- compute_ehull.py
@@ -240,6 +294,7 @@ pymdkit/
240
294
  |-- perturb.py
241
295
  |-- nep_rmse.py
242
296
  |-- add_config_type.py
297
+ |-- _cifio.py
243
298
  |-- chemsys_entry.py
244
299
  |-- submit_vasp.py
245
300
  |-- convert.py