pymdkit 1.7.0__tar.gz → 1.7.2__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 (74) hide show
  1. {pymdkit-1.7.0 → pymdkit-1.7.2}/PKG-INFO +149 -3
  2. {pymdkit-1.7.0 → pymdkit-1.7.2}/README.md +148 -2
  3. {pymdkit-1.7.0 → pymdkit-1.7.2}/pyproject.toml +48 -48
  4. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/__init__.py +1 -1
  5. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/compute_rmsd.py +868 -532
  6. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/convert.py +1189 -1135
  7. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/supercell.py +16 -11
  8. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit.egg-info/PKG-INFO +149 -3
  9. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit.egg-info/SOURCES.txt +4 -0
  10. pymdkit-1.7.2/tests/test_rmsd_gpu.py +298 -0
  11. pymdkit-1.7.2/tests/test_rmsd_max.py +367 -0
  12. pymdkit-1.7.2/tests/test_rmsd_two_folder.py +448 -0
  13. pymdkit-1.7.2/tests/test_v172_vasp_writing.py +233 -0
  14. {pymdkit-1.7.0 → pymdkit-1.7.2}/LICENSE +0 -0
  15. {pymdkit-1.7.0 → pymdkit-1.7.2}/setup.cfg +0 -0
  16. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/_config.py +0 -0
  17. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/_logging.py +0 -0
  18. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/__init__.py +0 -0
  19. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_cifio.py +0 -0
  20. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_extxyz.py +0 -0
  21. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_fileio.py +0 -0
  22. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_geometry.py +0 -0
  23. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_gpumd.py +0 -0
  24. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_gpumd_final_structure.py +0 -0
  25. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_gpumd_msd.py +0 -0
  26. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_gpumd_status.py +0 -0
  27. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_gpumd_thermo.py +0 -0
  28. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_lattice.py +0 -0
  29. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_oxidation.py +0 -0
  30. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_parallel.py +0 -0
  31. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_precision.py +0 -0
  32. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_reduction.py +0 -0
  33. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_submit.py +0 -0
  34. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_submit_vasp.py +0 -0
  35. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_supercell.py +0 -0
  36. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_symmetry.py +0 -0
  37. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_vasp_ehull.py +0 -0
  38. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_vasp_final_structure.py +0 -0
  39. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_vasp_nep.py +0 -0
  40. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_vasp_output.py +0 -0
  41. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/_vaspset.py +0 -0
  42. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/chemsys_entry.py +0 -0
  43. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/config.py +0 -0
  44. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/dope.py +0 -0
  45. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/ewald.py +0 -0
  46. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/gpumd_job.py +0 -0
  47. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/gpumd_out.py +0 -0
  48. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/nep_rmse.py +0 -0
  49. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/perturb.py +0 -0
  50. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/rd.py +0 -0
  51. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/realloc_occ.py +0 -0
  52. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/submit.py +0 -0
  53. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/trjconv.py +0 -0
  54. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/vasp_job.py +0 -0
  55. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/commands/vasp_out.py +0 -0
  56. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit/pymdkit_main.py +0 -0
  57. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit.egg-info/dependency_links.txt +0 -0
  58. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit.egg-info/entry_points.txt +0 -0
  59. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit.egg-info/requires.txt +0 -0
  60. {pymdkit-1.7.0 → pymdkit-1.7.2}/src/pymdkit.egg-info/top_level.txt +0 -0
  61. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_config_logging.py +0 -0
  62. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_convert.py +0 -0
  63. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_ehull.py +0 -0
  64. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_gpumd_out.py +0 -0
  65. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_lattice_symmetry.py +0 -0
  66. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_parallel.py +0 -0
  67. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_progress.py +0 -0
  68. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_realloc_occ.py +0 -0
  69. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_submit.py +0 -0
  70. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_v165.py +0 -0
  71. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_v170_job_infrastructure.py +0 -0
  72. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_v170_vasp_consolidation.py +0 -0
  73. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_vasp_out.py +0 -0
  74. {pymdkit-1.7.0 → pymdkit-1.7.2}/tests/test_vaspset.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymdkit
3
- Version: 1.7.0
3
+ Version: 1.7.2
4
4
  Summary: A Python command-line toolkit for high-throughput atomistic workflows in AI-driven materials design.
5
5
  Author-email: Yueda Wang <ydwang0608@ustc.edu.cn>
6
6
  License-Expression: GPL-3.0-or-later
@@ -53,6 +53,29 @@ h5py,
53
53
  dpdata, matplotlib, UMAP, and tqdm. Some packages also install transitive
54
54
  dependencies.
55
55
 
56
+ ### Optional CUDA 12 GPU support
57
+
58
+ The default installation is CPU-only. Optional support for the CUDA fingerprint
59
+ prefilter used by `pmk rmsd -gpu` is installed separately:
60
+
61
+ ```bash
62
+ python -m pip install "pymdkit[gpu-cuda12]"
63
+ ```
64
+
65
+ This extra installs `cupy-cuda12x`; CuPy is not a required dependency for normal
66
+ PMK use. The GPU path currently applies only to the batched fingerprint candidate
67
+ prefilter used during one-folder duplicate screening. Structure loading, fingerprint
68
+ construction, and exact pymatgen `StructureMatcher` RMSDs remain CPU operations.
69
+ `-ncore` can still parallelize those exact CPU RMSD tasks. GPU mode is not
70
+ guaranteed to outperform CPU mode for every workload.
71
+
72
+ CuPy must be able to see a working NVIDIA GPU/driver/CUDA environment. On an HPC
73
+ system, CUDA may be provided through environment modules, for example
74
+ `module load cuda/12.6`, but the exact module name and scheduler GPU-allocation
75
+ commands are site-specific. Follow the cluster documentation rather than assuming
76
+ that CUDA 12.6 is required everywhere.
77
+
78
+
56
79
  ### Complete offline installation
57
80
 
58
81
  For an HPC system or another network-isolated machine, prepare a complete local
@@ -63,7 +86,7 @@ installed.
63
86
  On a machine with Internet access, run:
64
87
 
65
88
  ```bash
66
- pip download pymdkit==1.7.0 -d pymdkit-offline
89
+ python -m pip download pymdkit==1.7.2 -d pymdkit-offline
67
90
  ```
68
91
 
69
92
  This downloads `pymdkit` and the dependencies resolved by pip into the
@@ -71,9 +94,28 @@ This downloads `pymdkit` and the dependencies resolved by pip into the
71
94
  system. Then, inside the target pymdkit Python or conda environment, run:
72
95
 
73
96
  ```bash
74
- pip install --no-index --find-links=pymdkit-offline pymdkit==1.7.0
97
+ python -m pip install --no-index --find-links=pymdkit-offline pymdkit==1.7.2
98
+ ```
99
+
100
+ For optional GPU use, prepare the bundle on a networked machine compatible with
101
+ the target HPC platform and Python environment:
102
+
103
+ ```bash
104
+ python -m pip download "pymdkit[gpu-cuda12]==1.7.2" -d pymdkit-offline
105
+ ```
106
+
107
+ Transfer the whole `pymdkit-offline` directory, then install from it on the
108
+ target system:
109
+
110
+ ```bash
111
+ python -m pip install --no-index --find-links=pymdkit-offline \
112
+ "pymdkit[gpu-cuda12]==1.7.2"
75
113
  ```
76
114
 
115
+ This GPU bundle includes the optional `cupy-cuda12x` package. Its wheels must also
116
+ be compatible with the target platform, Python version, and CUDA environment.
117
+
118
+
77
119
  - `--no-index` prevents pip from accessing PyPI.
78
120
  - `--find-links=pymdkit-offline` tells pip to install packages from the
79
121
  transferred local directory.
@@ -210,9 +252,87 @@ pmk vasp-out -save-fs -fs-name CONTCAR -of vasp-opted
210
252
  pmk dope -i Li3YCl6.cif -se Li -sn 1 -we Na -on 20 -seed 7
211
253
  pmk ewald -if cifs -ncore 64
212
254
  pmk realloc-occ -if cifs -of disorder -formula Li3YCl6 -occ 0.25 0.5 0.75 1 -ncore 64
255
+ pmk rmsd -if Li3YCl6-gpumd Li3YCl6-vasp -max-rmsd 0.5 -of Li3YCl6-gpumd-stable -ncore 32
213
256
  pmk rmsd -if vasp-opted -rm-duplicate -of unique -gpu -ncore 64
214
257
  ```
215
258
 
259
+ ### RMSD folder comparisons
260
+
261
+ Use one folder to calculate every unordered compatible structure pair found
262
+ recursively:
263
+
264
+ ```bash
265
+ pmk rmsd -if FOLDER
266
+ ```
267
+
268
+ One-folder duplicate removal uses a default maximum RMSD of `0.1`:
269
+
270
+ ```bash
271
+ pmk rmsd -if FOLDER -rm-duplicate -of UNIQUE_FOLDER
272
+ ```
273
+
274
+ Set a custom inclusive threshold with `-max-rmsd`:
275
+
276
+ ```bash
277
+ pmk rmsd -if FOLDER \
278
+ -rm-duplicate \
279
+ -max-rmsd 0.5 \
280
+ -of UNIQUE_FOLDER
281
+ ```
282
+
283
+ **Optional GPU fingerprint prefilter.** The valid GPU mode is one-folder duplicate
284
+ screening:
285
+
286
+ ```bash
287
+ pmk rmsd -if FOLDER \
288
+ -rm-duplicate \
289
+ -of UNIQUE_FOLDER \
290
+ -gpu \
291
+ -ncore 64
292
+ ```
293
+
294
+ `-gpu` does not move the exact RMSD calculation to CUDA. Its execution model is:
295
+
296
+ - **CPU:** structure loading and fingerprint construction.
297
+ - **GPU:** batched fingerprint candidate prefilter, which rejects clearly
298
+ dissimilar pairs.
299
+ - **CPU:** exact pymatgen `StructureMatcher` RMSDs for remaining candidates,
300
+ optionally multiprocessing via `-ncore`.
301
+
302
+ GPU duplicate screening supports the default maximum RMSD `0.1`; explicitly using
303
+ `-max-rmsd 0.1 -gpu` is equivalent and valid. For a non-default custom threshold,
304
+ omit `-gpu` and use the exact CPU path. This restriction avoids scientifically
305
+ unsafe filtering because the fingerprint cutoff has not been validated as a
306
+ general mapping to arbitrary exact RMSD thresholds.
307
+
308
+
309
+ Use two folders to calculate only cross-folder pairs with the same exact
310
+ filename, including the extension and case:
311
+
312
+ ```bash
313
+ pmk rmsd -if FOLDER_A FOLDER_B
314
+ ```
315
+
316
+ Add `-max-rmsd` and `-of` together for directional filtering:
317
+
318
+ ```bash
319
+ pmk rmsd \
320
+ -if Li3YCl6-gpumd Li3YCl6-vasp \
321
+ -max-rmsd 0.5 \
322
+ -of Li3YCl6-gpumd-stable
323
+ ```
324
+
325
+ Here `Li3YCl6-gpumd` (Folder A) is the source/candidate folder and
326
+ `Li3YCl6-vasp` (Folder B) is the reference folder. PMK compares exact
327
+ same-filename pairs and copies only Folder-A structures with RMSD less than or
328
+ equal to the threshold into `Li3YCl6-gpumd-stable`. It never copies reference
329
+ structures from Folder B.
330
+
331
+ Two-folder modes perform no within-folder comparisons. Unmatched files are
332
+ skipped and reported. If recursive discovery finds a basename more than once
333
+ under either root, that ambiguous basename and its conflicting relative paths
334
+ are reported and skipped rather than copied.
335
+
216
336
  ### File I/O and XYZ
217
337
 
218
338
  `convert` uses ASE `read`, `iread`/multi-frame indexing, format detection, and
@@ -438,6 +558,32 @@ standalone `substitute` command is removed.
438
558
  - Standalone `gpumd-group` tagging and `gpumd-trjcat` are removed without
439
559
  replacement. `gpumd-job -group` remains available during job creation.
440
560
 
561
+ ### Generated VASP structures
562
+
563
+ New `.vasp` files written by `convert`, standalone `supercell`, and
564
+ `dope -output-format vasp` automatically group atoms by species using
565
+ pymatgen's POSCAR ordering. For example, a 64-atom LiI supercell has a single
566
+ `Li I` species line and a `32 32` count line. Site order changes to group
567
+ species; the lattice, species-resolved positions, and selective-dynamics
568
+ flags remain associated with their sites.
569
+
570
+ Direct (fractional) coordinates are the default. Both `convert` and
571
+ `supercell` accept mutually exclusive `-direct` and `-cartesian` flags for
572
+ `.vasp` output. These flags also apply in folder mode and when `convert`
573
+ creates a supercell. They have no effect on CIF, XYZ, extxyz, or other output
574
+ formats. VASP job input sets and collected CONTCAR files retain their existing
575
+ behavior.
576
+
577
+ ```bash
578
+ pmk convert -i LiI.cif -o LiI.vasp -direct
579
+ pmk convert -i LiI.cif -o LiI-cart.vasp -cartesian
580
+ pmk convert -if structures -of vasp-direct -oe vasp
581
+ pmk convert -i LiI.cif -o LiI-222.vasp -supercell-matrix 2x2x2 -cartesian
582
+ pmk supercell -i LiI.vasp -o LiI-222.vasp -matrix 2x2x2 -direct
583
+ pmk supercell -i LiI.vasp -o LiI-222-cart.vasp -matrix 2x2x2 -cartesian
584
+ pmk supercell -if vasp-direct -of vasp-cart -matrix 2x2x2 -cartesian
585
+ ```
586
+
441
587
  ### Other behavior
442
588
 
443
589
  `convert -d2o` first symmetrizes the disordered structure so each distinct
@@ -24,6 +24,29 @@ h5py,
24
24
  dpdata, matplotlib, UMAP, and tqdm. Some packages also install transitive
25
25
  dependencies.
26
26
 
27
+ ### Optional CUDA 12 GPU support
28
+
29
+ The default installation is CPU-only. Optional support for the CUDA fingerprint
30
+ prefilter used by `pmk rmsd -gpu` is installed separately:
31
+
32
+ ```bash
33
+ python -m pip install "pymdkit[gpu-cuda12]"
34
+ ```
35
+
36
+ This extra installs `cupy-cuda12x`; CuPy is not a required dependency for normal
37
+ PMK use. The GPU path currently applies only to the batched fingerprint candidate
38
+ prefilter used during one-folder duplicate screening. Structure loading, fingerprint
39
+ construction, and exact pymatgen `StructureMatcher` RMSDs remain CPU operations.
40
+ `-ncore` can still parallelize those exact CPU RMSD tasks. GPU mode is not
41
+ guaranteed to outperform CPU mode for every workload.
42
+
43
+ CuPy must be able to see a working NVIDIA GPU/driver/CUDA environment. On an HPC
44
+ system, CUDA may be provided through environment modules, for example
45
+ `module load cuda/12.6`, but the exact module name and scheduler GPU-allocation
46
+ commands are site-specific. Follow the cluster documentation rather than assuming
47
+ that CUDA 12.6 is required everywhere.
48
+
49
+
27
50
  ### Complete offline installation
28
51
 
29
52
  For an HPC system or another network-isolated machine, prepare a complete local
@@ -34,7 +57,7 @@ installed.
34
57
  On a machine with Internet access, run:
35
58
 
36
59
  ```bash
37
- pip download pymdkit==1.7.0 -d pymdkit-offline
60
+ python -m pip download pymdkit==1.7.2 -d pymdkit-offline
38
61
  ```
39
62
 
40
63
  This downloads `pymdkit` and the dependencies resolved by pip into the
@@ -42,9 +65,28 @@ This downloads `pymdkit` and the dependencies resolved by pip into the
42
65
  system. Then, inside the target pymdkit Python or conda environment, run:
43
66
 
44
67
  ```bash
45
- pip install --no-index --find-links=pymdkit-offline pymdkit==1.7.0
68
+ python -m pip install --no-index --find-links=pymdkit-offline pymdkit==1.7.2
69
+ ```
70
+
71
+ For optional GPU use, prepare the bundle on a networked machine compatible with
72
+ the target HPC platform and Python environment:
73
+
74
+ ```bash
75
+ python -m pip download "pymdkit[gpu-cuda12]==1.7.2" -d pymdkit-offline
76
+ ```
77
+
78
+ Transfer the whole `pymdkit-offline` directory, then install from it on the
79
+ target system:
80
+
81
+ ```bash
82
+ python -m pip install --no-index --find-links=pymdkit-offline \
83
+ "pymdkit[gpu-cuda12]==1.7.2"
46
84
  ```
47
85
 
86
+ This GPU bundle includes the optional `cupy-cuda12x` package. Its wheels must also
87
+ be compatible with the target platform, Python version, and CUDA environment.
88
+
89
+
48
90
  - `--no-index` prevents pip from accessing PyPI.
49
91
  - `--find-links=pymdkit-offline` tells pip to install packages from the
50
92
  transferred local directory.
@@ -181,9 +223,87 @@ pmk vasp-out -save-fs -fs-name CONTCAR -of vasp-opted
181
223
  pmk dope -i Li3YCl6.cif -se Li -sn 1 -we Na -on 20 -seed 7
182
224
  pmk ewald -if cifs -ncore 64
183
225
  pmk realloc-occ -if cifs -of disorder -formula Li3YCl6 -occ 0.25 0.5 0.75 1 -ncore 64
226
+ pmk rmsd -if Li3YCl6-gpumd Li3YCl6-vasp -max-rmsd 0.5 -of Li3YCl6-gpumd-stable -ncore 32
184
227
  pmk rmsd -if vasp-opted -rm-duplicate -of unique -gpu -ncore 64
185
228
  ```
186
229
 
230
+ ### RMSD folder comparisons
231
+
232
+ Use one folder to calculate every unordered compatible structure pair found
233
+ recursively:
234
+
235
+ ```bash
236
+ pmk rmsd -if FOLDER
237
+ ```
238
+
239
+ One-folder duplicate removal uses a default maximum RMSD of `0.1`:
240
+
241
+ ```bash
242
+ pmk rmsd -if FOLDER -rm-duplicate -of UNIQUE_FOLDER
243
+ ```
244
+
245
+ Set a custom inclusive threshold with `-max-rmsd`:
246
+
247
+ ```bash
248
+ pmk rmsd -if FOLDER \
249
+ -rm-duplicate \
250
+ -max-rmsd 0.5 \
251
+ -of UNIQUE_FOLDER
252
+ ```
253
+
254
+ **Optional GPU fingerprint prefilter.** The valid GPU mode is one-folder duplicate
255
+ screening:
256
+
257
+ ```bash
258
+ pmk rmsd -if FOLDER \
259
+ -rm-duplicate \
260
+ -of UNIQUE_FOLDER \
261
+ -gpu \
262
+ -ncore 64
263
+ ```
264
+
265
+ `-gpu` does not move the exact RMSD calculation to CUDA. Its execution model is:
266
+
267
+ - **CPU:** structure loading and fingerprint construction.
268
+ - **GPU:** batched fingerprint candidate prefilter, which rejects clearly
269
+ dissimilar pairs.
270
+ - **CPU:** exact pymatgen `StructureMatcher` RMSDs for remaining candidates,
271
+ optionally multiprocessing via `-ncore`.
272
+
273
+ GPU duplicate screening supports the default maximum RMSD `0.1`; explicitly using
274
+ `-max-rmsd 0.1 -gpu` is equivalent and valid. For a non-default custom threshold,
275
+ omit `-gpu` and use the exact CPU path. This restriction avoids scientifically
276
+ unsafe filtering because the fingerprint cutoff has not been validated as a
277
+ general mapping to arbitrary exact RMSD thresholds.
278
+
279
+
280
+ Use two folders to calculate only cross-folder pairs with the same exact
281
+ filename, including the extension and case:
282
+
283
+ ```bash
284
+ pmk rmsd -if FOLDER_A FOLDER_B
285
+ ```
286
+
287
+ Add `-max-rmsd` and `-of` together for directional filtering:
288
+
289
+ ```bash
290
+ pmk rmsd \
291
+ -if Li3YCl6-gpumd Li3YCl6-vasp \
292
+ -max-rmsd 0.5 \
293
+ -of Li3YCl6-gpumd-stable
294
+ ```
295
+
296
+ Here `Li3YCl6-gpumd` (Folder A) is the source/candidate folder and
297
+ `Li3YCl6-vasp` (Folder B) is the reference folder. PMK compares exact
298
+ same-filename pairs and copies only Folder-A structures with RMSD less than or
299
+ equal to the threshold into `Li3YCl6-gpumd-stable`. It never copies reference
300
+ structures from Folder B.
301
+
302
+ Two-folder modes perform no within-folder comparisons. Unmatched files are
303
+ skipped and reported. If recursive discovery finds a basename more than once
304
+ under either root, that ambiguous basename and its conflicting relative paths
305
+ are reported and skipped rather than copied.
306
+
187
307
  ### File I/O and XYZ
188
308
 
189
309
  `convert` uses ASE `read`, `iread`/multi-frame indexing, format detection, and
@@ -409,6 +529,32 @@ standalone `substitute` command is removed.
409
529
  - Standalone `gpumd-group` tagging and `gpumd-trjcat` are removed without
410
530
  replacement. `gpumd-job -group` remains available during job creation.
411
531
 
532
+ ### Generated VASP structures
533
+
534
+ New `.vasp` files written by `convert`, standalone `supercell`, and
535
+ `dope -output-format vasp` automatically group atoms by species using
536
+ pymatgen's POSCAR ordering. For example, a 64-atom LiI supercell has a single
537
+ `Li I` species line and a `32 32` count line. Site order changes to group
538
+ species; the lattice, species-resolved positions, and selective-dynamics
539
+ flags remain associated with their sites.
540
+
541
+ Direct (fractional) coordinates are the default. Both `convert` and
542
+ `supercell` accept mutually exclusive `-direct` and `-cartesian` flags for
543
+ `.vasp` output. These flags also apply in folder mode and when `convert`
544
+ creates a supercell. They have no effect on CIF, XYZ, extxyz, or other output
545
+ formats. VASP job input sets and collected CONTCAR files retain their existing
546
+ behavior.
547
+
548
+ ```bash
549
+ pmk convert -i LiI.cif -o LiI.vasp -direct
550
+ pmk convert -i LiI.cif -o LiI-cart.vasp -cartesian
551
+ pmk convert -if structures -of vasp-direct -oe vasp
552
+ pmk convert -i LiI.cif -o LiI-222.vasp -supercell-matrix 2x2x2 -cartesian
553
+ pmk supercell -i LiI.vasp -o LiI-222.vasp -matrix 2x2x2 -direct
554
+ pmk supercell -i LiI.vasp -o LiI-222-cart.vasp -matrix 2x2x2 -cartesian
555
+ pmk supercell -if vasp-direct -of vasp-cart -matrix 2x2x2 -cartesian
556
+ ```
557
+
412
558
  ### Other behavior
413
559
 
414
560
  `convert -d2o` first symmetrizes the disordered structure so each distinct
@@ -1,48 +1,48 @@
1
- [build-system]
2
- requires = ["setuptools>=77.0"]
3
- build-backend = "setuptools.build_meta"
4
-
5
- [project]
6
- name = "pymdkit"
7
- version = "1.7.0"
8
- description = "A Python command-line toolkit for high-throughput atomistic workflows in AI-driven materials design."
9
- readme = "README.md"
10
- requires-python = ">=3.9"
11
- authors = [{ name = "Yueda Wang", email = "ydwang0608@ustc.edu.cn" }]
12
- license = "GPL-3.0-or-later"
13
- license-files = ["LICENSE"]
14
- keywords = ["materials-science", "molecular-dynamics", "vasp", "gpumd", "ase", "pymatgen"]
15
- classifiers = [
16
- "Programming Language :: Python :: 3",
17
- "Operating System :: OS Independent",
18
- "Intended Audience :: Science/Research",
19
- "Topic :: Scientific/Engineering :: Chemistry",
20
- "Topic :: Scientific/Engineering :: Physics",
21
- ]
22
-
23
- # All dependencies are installed up front so a plain `pip install pymdkit`
24
- # gives a fully working CLI. Heavy libraries are still imported lazily inside
25
- # individual commands, so the dispatcher and pmk -help stay fast.
26
- dependencies = [
27
- "numpy",
28
- "ase",
29
- "pymatgen",
30
- "mp-api",
31
- "py4vasp-core",
32
- "h5py",
33
- "dpdata",
34
- "matplotlib",
35
- "umap-learn",
36
- "tqdm",
37
- ]
38
-
39
- [project.optional-dependencies]
40
- # CuPy wheels are CUDA-major-specific, so GPU support stays optional.
41
- gpu-cuda12 = ["cupy-cuda12x"]
42
-
43
- [project.scripts]
44
- # The distribution remains pymdkit; the concise public executable is `pmk`.
45
- pmk = "pymdkit.pymdkit_main:main"
46
-
47
- [tool.setuptools.packages.find]
48
- where = ["src"]
1
+ [build-system]
2
+ requires = ["setuptools>=77.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pymdkit"
7
+ version = "1.7.2"
8
+ description = "A Python command-line toolkit for high-throughput atomistic workflows in AI-driven materials design."
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ authors = [{ name = "Yueda Wang", email = "ydwang0608@ustc.edu.cn" }]
12
+ license = "GPL-3.0-or-later"
13
+ license-files = ["LICENSE"]
14
+ keywords = ["materials-science", "molecular-dynamics", "vasp", "gpumd", "ase", "pymatgen"]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Operating System :: OS Independent",
18
+ "Intended Audience :: Science/Research",
19
+ "Topic :: Scientific/Engineering :: Chemistry",
20
+ "Topic :: Scientific/Engineering :: Physics",
21
+ ]
22
+
23
+ # All dependencies are installed up front so a plain `pip install pymdkit`
24
+ # gives a fully working CLI. Heavy libraries are still imported lazily inside
25
+ # individual commands, so the dispatcher and pmk -help stay fast.
26
+ dependencies = [
27
+ "numpy",
28
+ "ase",
29
+ "pymatgen",
30
+ "mp-api",
31
+ "py4vasp-core",
32
+ "h5py",
33
+ "dpdata",
34
+ "matplotlib",
35
+ "umap-learn",
36
+ "tqdm",
37
+ ]
38
+
39
+ [project.optional-dependencies]
40
+ # CuPy wheels are CUDA-major-specific, so GPU support stays optional.
41
+ gpu-cuda12 = ["cupy-cuda12x"]
42
+
43
+ [project.scripts]
44
+ # The distribution remains pymdkit; the concise public executable is `pmk`.
45
+ pmk = "pymdkit.pymdkit_main:main"
46
+
47
+ [tool.setuptools.packages.find]
48
+ where = ["src"]
@@ -1,3 +1,3 @@
1
1
  """A Python command-line toolkit for high-throughput atomistic workflows in AI-driven materials design."""
2
2
 
3
- __version__ = "1.7.0"
3
+ __version__ = "1.7.2"