rsspolymlp 0.4.1__tar.gz → 0.4.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.
- {rsspolymlp-0.4.1/src/rsspolymlp.egg-info → rsspolymlp-0.4.2}/PKG-INFO +39 -37
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/README.md +38 -36
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/pyproject.toml +1 -1
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/analysis/rss_summarize.py +20 -18
- rsspolymlp-0.4.2/src/rsspolymlp/analysis/struct_matcher/assignment_algo.py +112 -0
- rsspolymlp-0.4.1/src/rsspolymlp/analysis/struct_matcher/gen_redrep.py → rsspolymlp-0.4.2/src/rsspolymlp/analysis/struct_matcher/gen_struct_rep.py +144 -157
- rsspolymlp-0.4.2/src/rsspolymlp/analysis/struct_matcher/identify_uniqstr.py +193 -0
- rsspolymlp-0.4.1/src/rsspolymlp/analysis/struct_matcher/invert_and_swap.py → rsspolymlp-0.4.2/src/rsspolymlp/analysis/struct_matcher/redrep_lattice.py +84 -0
- rsspolymlp-0.4.1/src/rsspolymlp/analysis/struct_matcher/reduced_position.py → rsspolymlp-0.4.2/src/rsspolymlp/analysis/struct_matcher/redrep_position.py +61 -115
- rsspolymlp-0.4.2/src/rsspolymlp/analysis/struct_matcher/struct_match.py +275 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/cli_rsspolymlp_utils.py +25 -19
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/rsspolymlp.py +2 -1
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/rsspolymlp_utils.py +77 -45
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/rss/eliminate_duplicates.py +6 -4
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/rss/random_struct.py +32 -7
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2/src/rsspolymlp.egg-info}/PKG-INFO +39 -37
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp.egg-info/SOURCES.txt +5 -3
- rsspolymlp-0.4.1/src/rsspolymlp/analysis/struct_matcher/struct_match.py +0 -331
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/LICENSE +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/setup.cfg +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/analysis/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/analysis/eos.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/analysis/ghost_minima.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/analysis/phase_analysis.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/analysis/struct_matcher/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/analysis/struct_matcher/chiral_spg.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/cli_rsspolymlp.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/cli_rsspolymlp_devkit.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/cli_rsspolymlp_plot.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/rsspolymlp_devkit.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/api/rsspolymlp_plot.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/common/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/common/atomic_energy.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/common/composition.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/common/convert_dict.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/common/interface_vasp.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/common/property.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/dataset/compress_vasprun.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/dataset/gen_mlp_dataset.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/dataset/split_dataset.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/estimate_cost.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/model_selection/binary/gen_single_model.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/model_selection/elemental/gen_hybrid_model.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/model_selection/elemental/gen_single_model.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/model_selection/n_feature.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/model_selection/pypolymlp_gridsearch.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/model_selection/reduce_grid.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/pareto_opt_mlp.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/mlp_dev/polymlp_dev.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/rss/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/rss/load_logfile.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/rss/optimization_mlp.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/lammps_utils.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/matplot_util/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/matplot_util/custom_plt.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/matplot_util/examples/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/matplot_util/examples/example.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/matplot_util/examples/template.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/matplot_util/make_plot.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/opt_sscha/opt_geometry_sscha.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/opt_sscha/opt_position_sscha.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/opt_sscha/run_opt_sscha.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/opt_sscha/sscha_property.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/pymatgen_utils.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/spglib_utils.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/vasp_util/__init__.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/vasp_util/api.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/vasp_util/gen_incar.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/vasp_util/gen_script.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp/utils/vasp_util/write_poscar.py +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp.egg-info/dependency_links.txt +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp.egg-info/entry_points.txt +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp.egg-info/requires.txt +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/src/rsspolymlp.egg-info/top_level.txt +0 -0
- {rsspolymlp-0.4.1 → rsspolymlp-0.4.2}/tests/test_cli_help.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rsspolymlp
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.2
|
|
4
4
|
Summary: A framework for random structure search using polynomial MLPs
|
|
5
5
|
Author-email: Hayato Wakai <wakai@cms.mtl.kyoto-u.ac.jp>
|
|
6
6
|
Maintainer-email: Hayato Wakai <wakai@cms.mtl.kyoto-u.ac.jp>
|
|
@@ -31,27 +31,25 @@ Dynamic: license-file
|
|
|
31
31
|
|
|
32
32
|
# Framework for random structure search using polynomial machine learning potentials
|
|
33
33
|
|
|
34
|
-
##
|
|
34
|
+
## How to use rsspolymlp
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
- [Workflow of RSS with polynomial MLPs](docs/rsspolymlp.md)
|
|
37
|
+
- Initial structure generation
|
|
38
|
+
- Global RSS with polynomial MLPs
|
|
39
|
+
- Unique structure identification and RSS result summarization
|
|
40
|
+
- Phase stability analysis
|
|
41
|
+
- [Development kit for polynomial MLPs](docs/rsspolymlp_dev.md)
|
|
42
|
+
- MLP dataset generation
|
|
43
|
+
- DFT dataset division
|
|
44
|
+
- Polynomial MLP development
|
|
45
|
+
- Pareto-optimal MLP selection
|
|
46
|
+
- Python API
|
|
47
|
+
- [RSS workflow](docs/api_rsspolymlp.md)
|
|
48
|
+
- [VASP calculation utilities](src/rsspolymlp/utils/vasp_util/readme.md)
|
|
49
|
+
- Single-point calculation
|
|
50
|
+
- Local geometry optimization
|
|
51
|
+
- [Matplotlib utilities](src/rsspolymlp/utils/matplot_util/readme.md)
|
|
37
52
|
|
|
38
|
-
“Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials”, [Phys. Rev. Materials 10, 093801 (2026)](https://doi.org/10.1103/k9sg-v7hl)
|
|
39
|
-
```
|
|
40
|
-
@article{Phys.Rev.Mater.10.093801,
|
|
41
|
-
title = {Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials},
|
|
42
|
-
author = {Wakai, Hayato and Ishiwata, Shintaro and Seko, Atsuto},
|
|
43
|
-
journal = {Phys. Rev. Mater.},
|
|
44
|
-
volume = {10},
|
|
45
|
-
issue = {9},
|
|
46
|
-
pages = {093801},
|
|
47
|
-
numpages = {28},
|
|
48
|
-
year = {2026},
|
|
49
|
-
month = {Sep},
|
|
50
|
-
publisher = {American Physical Society},
|
|
51
|
-
doi = {10.1103/k9sg-v7hl},
|
|
52
|
-
url = {https://link.aps.org/doi/10.1103/k9sg-v7hl}
|
|
53
|
-
}
|
|
54
|
-
```
|
|
55
53
|
|
|
56
54
|
## Installation
|
|
57
55
|
|
|
@@ -89,21 +87,25 @@ conda install -c conda-forge scikit-learn joblib pypolymlp spglib symfc
|
|
|
89
87
|
pip install rsspolymlp
|
|
90
88
|
```
|
|
91
89
|
|
|
92
|
-
## How to use rsspolymlp
|
|
93
90
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
91
|
+
## Citation of rsspolymlp
|
|
92
|
+
|
|
93
|
+
If you use `rsspolymlp` in your study, please cite the following articles.
|
|
94
|
+
|
|
95
|
+
“Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials”, [Phys. Rev. Materials 10, 093801 (2026)](https://doi.org/10.1103/k9sg-v7hl)
|
|
96
|
+
```
|
|
97
|
+
@article{Phys.Rev.Mater.10.093801,
|
|
98
|
+
title = {Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials},
|
|
99
|
+
author = {Wakai, Hayato and Ishiwata, Shintaro and Seko, Atsuto},
|
|
100
|
+
journal = {Phys. Rev. Mater.},
|
|
101
|
+
volume = {10},
|
|
102
|
+
issue = {9},
|
|
103
|
+
pages = {093801},
|
|
104
|
+
numpages = {28},
|
|
105
|
+
year = {2026},
|
|
106
|
+
month = {Sep},
|
|
107
|
+
publisher = {American Physical Society},
|
|
108
|
+
doi = {10.1103/k9sg-v7hl},
|
|
109
|
+
url = {https://link.aps.org/doi/10.1103/k9sg-v7hl}
|
|
110
|
+
}
|
|
111
|
+
```
|
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
# Framework for random structure search using polynomial machine learning potentials
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## How to use rsspolymlp
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- [Workflow of RSS with polynomial MLPs](docs/rsspolymlp.md)
|
|
6
|
+
- Initial structure generation
|
|
7
|
+
- Global RSS with polynomial MLPs
|
|
8
|
+
- Unique structure identification and RSS result summarization
|
|
9
|
+
- Phase stability analysis
|
|
10
|
+
- [Development kit for polynomial MLPs](docs/rsspolymlp_dev.md)
|
|
11
|
+
- MLP dataset generation
|
|
12
|
+
- DFT dataset division
|
|
13
|
+
- Polynomial MLP development
|
|
14
|
+
- Pareto-optimal MLP selection
|
|
15
|
+
- Python API
|
|
16
|
+
- [RSS workflow](docs/api_rsspolymlp.md)
|
|
17
|
+
- [VASP calculation utilities](src/rsspolymlp/utils/vasp_util/readme.md)
|
|
18
|
+
- Single-point calculation
|
|
19
|
+
- Local geometry optimization
|
|
20
|
+
- [Matplotlib utilities](src/rsspolymlp/utils/matplot_util/readme.md)
|
|
6
21
|
|
|
7
|
-
“Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials”, [Phys. Rev. Materials 10, 093801 (2026)](https://doi.org/10.1103/k9sg-v7hl)
|
|
8
|
-
```
|
|
9
|
-
@article{Phys.Rev.Mater.10.093801,
|
|
10
|
-
title = {Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials},
|
|
11
|
-
author = {Wakai, Hayato and Ishiwata, Shintaro and Seko, Atsuto},
|
|
12
|
-
journal = {Phys. Rev. Mater.},
|
|
13
|
-
volume = {10},
|
|
14
|
-
issue = {9},
|
|
15
|
-
pages = {093801},
|
|
16
|
-
numpages = {28},
|
|
17
|
-
year = {2026},
|
|
18
|
-
month = {Sep},
|
|
19
|
-
publisher = {American Physical Society},
|
|
20
|
-
doi = {10.1103/k9sg-v7hl},
|
|
21
|
-
url = {https://link.aps.org/doi/10.1103/k9sg-v7hl}
|
|
22
|
-
}
|
|
23
|
-
```
|
|
24
22
|
|
|
25
23
|
## Installation
|
|
26
24
|
|
|
@@ -58,21 +56,25 @@ conda install -c conda-forge scikit-learn joblib pypolymlp spglib symfc
|
|
|
58
56
|
pip install rsspolymlp
|
|
59
57
|
```
|
|
60
58
|
|
|
61
|
-
## How to use rsspolymlp
|
|
62
59
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
60
|
+
## Citation of rsspolymlp
|
|
61
|
+
|
|
62
|
+
If you use `rsspolymlp` in your study, please cite the following articles.
|
|
63
|
+
|
|
64
|
+
“Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials”, [Phys. Rev. Materials 10, 093801 (2026)](https://doi.org/10.1103/k9sg-v7hl)
|
|
65
|
+
```
|
|
66
|
+
@article{Phys.Rev.Mater.10.093801,
|
|
67
|
+
title = {Systematic global structure search of bismuth-based binary systems under pressure using machine learning potentials},
|
|
68
|
+
author = {Wakai, Hayato and Ishiwata, Shintaro and Seko, Atsuto},
|
|
69
|
+
journal = {Phys. Rev. Mater.},
|
|
70
|
+
volume = {10},
|
|
71
|
+
issue = {9},
|
|
72
|
+
pages = {093801},
|
|
73
|
+
numpages = {28},
|
|
74
|
+
year = {2026},
|
|
75
|
+
month = {Sep},
|
|
76
|
+
publisher = {American Physical Society},
|
|
77
|
+
doi = {10.1103/k9sg-v7hl},
|
|
78
|
+
url = {https://link.aps.org/doi/10.1103/k9sg-v7hl}
|
|
79
|
+
}
|
|
80
|
+
```
|
|
@@ -12,11 +12,11 @@ import numpy as np
|
|
|
12
12
|
|
|
13
13
|
from pypolymlp.utils.vasp_utils import write_poscar_file
|
|
14
14
|
from rsspolymlp.analysis.ghost_minima import detect_ghost_minima
|
|
15
|
-
from rsspolymlp.analysis.struct_matcher.
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
from rsspolymlp.analysis.struct_matcher.gen_struct_rep import (
|
|
16
|
+
StructReps,
|
|
17
|
+
generate_struct_reps_parallel,
|
|
18
18
|
)
|
|
19
|
-
from rsspolymlp.analysis.struct_matcher.
|
|
19
|
+
from rsspolymlp.analysis.struct_matcher.identify_uniqstr import (
|
|
20
20
|
UniqueStructIdentifier,
|
|
21
21
|
identify_unique_structure,
|
|
22
22
|
)
|
|
@@ -264,7 +264,7 @@ class RSSResultSummarizer:
|
|
|
264
264
|
r["dupstr_paths"] = set(r["dupstr_paths"])
|
|
265
265
|
|
|
266
266
|
print(" - Converting reduced crystal structure representation...")
|
|
267
|
-
|
|
267
|
+
struct_reps_list = generate_struct_reps_parallel(
|
|
268
268
|
rss_results,
|
|
269
269
|
num_process=self.num_process,
|
|
270
270
|
backend=self.backend,
|
|
@@ -272,7 +272,7 @@ class RSSResultSummarizer:
|
|
|
272
272
|
)
|
|
273
273
|
if self.update_parent:
|
|
274
274
|
print(" - Eliminating duplicate structures...")
|
|
275
|
-
for idx, redreps in enumerate(
|
|
275
|
+
for idx, redreps in enumerate(struct_reps_list):
|
|
276
276
|
self.analyzer.identify_duplicate_struct(
|
|
277
277
|
unique_struct=redreps,
|
|
278
278
|
other_properties=rss_results[idx],
|
|
@@ -280,7 +280,7 @@ class RSSResultSummarizer:
|
|
|
280
280
|
pos_tol=0.03,
|
|
281
281
|
)
|
|
282
282
|
else:
|
|
283
|
-
self.analyzer._initialize_unique_structs(
|
|
283
|
+
self.analyzer._initialize_unique_structs(struct_reps_list, rss_results)
|
|
284
284
|
|
|
285
285
|
return set(processed_paths)
|
|
286
286
|
|
|
@@ -461,21 +461,22 @@ class RSSResultSummarizer:
|
|
|
461
461
|
|
|
462
462
|
def dump_json_rss_results(
|
|
463
463
|
file_name: str,
|
|
464
|
-
|
|
464
|
+
struct_reps_list: list[StructReps],
|
|
465
465
|
enthalpy_lists: list[float],
|
|
466
466
|
is_ghost_minima=None,
|
|
467
467
|
pressure=None,
|
|
468
468
|
):
|
|
469
469
|
if is_ghost_minima is None:
|
|
470
|
-
is_ghost_minima = np.full_like(
|
|
470
|
+
is_ghost_minima = np.full_like(struct_reps_list, False, dtype=bool)
|
|
471
471
|
|
|
472
472
|
rss_results = []
|
|
473
|
-
for idx, _str in enumerate(
|
|
473
|
+
for idx, _str in enumerate(struct_reps_list):
|
|
474
474
|
polymlp_st = _str.original_polymlp_st
|
|
475
475
|
objprop = PropUtil(polymlp_st.axis.T, polymlp_st.positions.T)
|
|
476
476
|
rss_results.append(
|
|
477
477
|
{
|
|
478
478
|
"struct_path": _str.struct_path,
|
|
479
|
+
"poscar_path": _str.struct_path,
|
|
479
480
|
"structure": polymlp_struct_to_dict(polymlp_st),
|
|
480
481
|
"energy": enthalpy_lists[idx],
|
|
481
482
|
"axis_abc": objprop.abc,
|
|
@@ -487,8 +488,8 @@ def dump_json_rss_results(
|
|
|
487
488
|
"is_ghost_minima": bool(is_ghost_minima[idx]),
|
|
488
489
|
}
|
|
489
490
|
)
|
|
490
|
-
if len(
|
|
491
|
-
comp_res = compute_composition(
|
|
491
|
+
if len(struct_reps_list) > 0:
|
|
492
|
+
comp_res = compute_composition(struct_reps_list[0].original_polymlp_st.elements)
|
|
492
493
|
rss_result_all = {
|
|
493
494
|
"elements": comp_res.unique_elements.tolist(),
|
|
494
495
|
"comp_ratio": comp_res.comp_ratio,
|
|
@@ -507,13 +508,13 @@ def dump_json_rss_results(
|
|
|
507
508
|
|
|
508
509
|
def log_unique_structures(
|
|
509
510
|
file_name: str,
|
|
510
|
-
|
|
511
|
+
struct_reps_list: list[StructReps],
|
|
511
512
|
enthalpy_lists: Optional[list[float]] = None,
|
|
512
513
|
is_ghost_minima=None,
|
|
513
514
|
unique_struct_iters=None,
|
|
514
515
|
):
|
|
515
516
|
if is_ghost_minima is None:
|
|
516
|
-
is_ghost_minima = np.full_like(
|
|
517
|
+
is_ghost_minima = np.full_like(struct_reps_list, False, dtype=bool)
|
|
517
518
|
energy_min = None
|
|
518
519
|
if enthalpy_lists is not None:
|
|
519
520
|
for i in range(len(enthalpy_lists)):
|
|
@@ -522,9 +523,10 @@ def log_unique_structures(
|
|
|
522
523
|
break
|
|
523
524
|
|
|
524
525
|
struct_num_max = max(
|
|
525
|
-
(_s.struct_tag for _s in
|
|
526
|
+
(_s.struct_tag for _s in struct_reps_list if _s.struct_tag is not None),
|
|
527
|
+
default=0,
|
|
526
528
|
)
|
|
527
|
-
for _s in
|
|
529
|
+
for _s in struct_reps_list:
|
|
528
530
|
if _s.struct_tag is None:
|
|
529
531
|
struct_num_max += 1
|
|
530
532
|
_s.struct_tag = struct_num_max
|
|
@@ -532,7 +534,7 @@ def log_unique_structures(
|
|
|
532
534
|
with open(file_name, "a") as f:
|
|
533
535
|
print("unique_structures:", file=f)
|
|
534
536
|
for is_ghost in [False, True]:
|
|
535
|
-
for idx, _str in enumerate(
|
|
537
|
+
for idx, _str in enumerate(struct_reps_list):
|
|
536
538
|
if energy_min is not None:
|
|
537
539
|
e_diff = round((enthalpy_lists[idx] - energy_min) * 1000, 2)
|
|
538
540
|
if (not is_ghost and e_diff < -300) or (
|
|
@@ -579,7 +581,7 @@ def log_unique_structures(
|
|
|
579
581
|
|
|
580
582
|
def log_all_unique_structures(
|
|
581
583
|
file_name,
|
|
582
|
-
unique_structs: list[list[
|
|
584
|
+
unique_structs: list[list[StructReps]],
|
|
583
585
|
unique_str_prop: Optional[list[list[dict]]] = None,
|
|
584
586
|
unique_other_prop=None,
|
|
585
587
|
):
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from scipy.sparse import csr_array
|
|
3
|
+
from scipy.sparse.csgraph import maximum_bipartite_matching
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
def sort_match_screen(
|
|
7
|
+
pos_reps1: np.ndarray,
|
|
8
|
+
pos_reps2: np.ndarray,
|
|
9
|
+
elements1: np.ndarray,
|
|
10
|
+
elements2: np.ndarray,
|
|
11
|
+
pos_tol: float,
|
|
12
|
+
):
|
|
13
|
+
# pos1: (N1, n_atoms, 3)
|
|
14
|
+
# pos2: (N2, n_atoms, 3)
|
|
15
|
+
if len(elements1) != len(elements2):
|
|
16
|
+
return np.zeros((len(pos_reps1), len(pos_reps2)), dtype=bool)
|
|
17
|
+
unique_elements = np.unique(elements1)
|
|
18
|
+
|
|
19
|
+
def sort_positions(pos_reps, elements):
|
|
20
|
+
sorted_reps = []
|
|
21
|
+
for pos in pos_reps:
|
|
22
|
+
pos_sorted = []
|
|
23
|
+
for el in unique_elements:
|
|
24
|
+
pos_el = pos[elements == el]
|
|
25
|
+
pos_el = np.sort(pos_el, axis=0)
|
|
26
|
+
pos_sorted.append(pos_el)
|
|
27
|
+
sorted_reps.append(np.concatenate(pos_sorted, axis=0))
|
|
28
|
+
return np.asarray(sorted_reps)
|
|
29
|
+
|
|
30
|
+
pos1_sorted = sort_positions(pos_reps1, elements1)
|
|
31
|
+
pos2_sorted = sort_positions(pos_reps2, elements2)
|
|
32
|
+
|
|
33
|
+
diff = pos1_sorted[:, None, :, :] - pos2_sorted[None, :, :, :]
|
|
34
|
+
diff -= np.round(diff)
|
|
35
|
+
return np.all(np.abs(diff) <= pos_tol, axis=(2, 3))
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def greedy_match(
|
|
39
|
+
pos1: np.ndarray,
|
|
40
|
+
pos2: np.ndarray,
|
|
41
|
+
elements1: np.ndarray,
|
|
42
|
+
elements2: np.ndarray,
|
|
43
|
+
pos_tol: float,
|
|
44
|
+
):
|
|
45
|
+
for el in np.unique(elements1):
|
|
46
|
+
targets1 = np.where(elements1 == el)[0]
|
|
47
|
+
targets2 = np.where(elements2 == el)[0]
|
|
48
|
+
used = np.zeros(len(targets1), dtype=bool)
|
|
49
|
+
for i in targets1:
|
|
50
|
+
diff = np.max(np.abs(pos2[targets2] - pos1[i]), axis=1)
|
|
51
|
+
diff -= np.round(diff)
|
|
52
|
+
diff[used] = np.inf
|
|
53
|
+
j = np.argmin(np.abs(diff))
|
|
54
|
+
if diff[j] >= pos_tol:
|
|
55
|
+
return False
|
|
56
|
+
used[j] = True
|
|
57
|
+
return True
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def bottleneck_assignment(
|
|
61
|
+
pos1: np.ndarray,
|
|
62
|
+
pos2: np.ndarray,
|
|
63
|
+
elements1: np.ndarray,
|
|
64
|
+
elements2: np.ndarray,
|
|
65
|
+
pos_tol: float,
|
|
66
|
+
):
|
|
67
|
+
pos_max_diffs = []
|
|
68
|
+
for el in np.unique(elements1):
|
|
69
|
+
targets1 = np.where(elements1 == el)[0]
|
|
70
|
+
targets2 = np.where(elements2 == el)[0]
|
|
71
|
+
pos1_sub = pos1[targets1]
|
|
72
|
+
pos2_sub = pos2[targets2]
|
|
73
|
+
|
|
74
|
+
diff = pos1_sub[:, None, :] - pos2_sub[None, :, :]
|
|
75
|
+
diff -= np.round(diff)
|
|
76
|
+
pos_d = np.max(np.abs(diff), axis=2)
|
|
77
|
+
n = pos_d.shape[0]
|
|
78
|
+
|
|
79
|
+
# Sort distinct candidate distances
|
|
80
|
+
values = np.unique(pos_d)
|
|
81
|
+
left, right = 0, len(values) - 1
|
|
82
|
+
while left < right:
|
|
83
|
+
mid = (left + right) // 2
|
|
84
|
+
rows, cols = np.where(pos_d <= values[mid])
|
|
85
|
+
graph = csr_array(
|
|
86
|
+
(
|
|
87
|
+
np.ones(len(rows), dtype=np.int8),
|
|
88
|
+
(rows, cols),
|
|
89
|
+
),
|
|
90
|
+
shape=pos_d.shape,
|
|
91
|
+
)
|
|
92
|
+
matching = maximum_bipartite_matching(graph, perm_type="column")
|
|
93
|
+
if np.all(matching >= 0):
|
|
94
|
+
right = mid
|
|
95
|
+
else:
|
|
96
|
+
left = mid + 1
|
|
97
|
+
|
|
98
|
+
threshold = values[left]
|
|
99
|
+
rows, cols = np.where(pos_d <= threshold)
|
|
100
|
+
graph = csr_array(
|
|
101
|
+
(
|
|
102
|
+
np.ones(len(rows), dtype=np.int8),
|
|
103
|
+
(rows, cols),
|
|
104
|
+
),
|
|
105
|
+
shape=pos_d.shape,
|
|
106
|
+
)
|
|
107
|
+
matching = maximum_bipartite_matching(graph, perm_type="column")
|
|
108
|
+
pos_max_diffs.extend(pos_d[np.arange(n), matching].tolist())
|
|
109
|
+
|
|
110
|
+
if max(pos_max_diffs) < pos_tol:
|
|
111
|
+
judge = True
|
|
112
|
+
return judge
|