structuretoolkit 0.0.29__tar.gz → 0.0.32__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.
- {structuretoolkit-0.0.29/structuretoolkit.egg-info → structuretoolkit-0.0.32}/PKG-INFO +17 -16
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/README.md +2 -2
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/pyproject.toml +59 -12
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/__init__.py +58 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/_version.py +3 -3
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/__init__.py +36 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/dscribe.py +3 -1
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/neighbors.py +37 -37
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/phonopy.py +1 -3
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/pyscal.py +3 -4
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/snap.py +17 -19
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/spatial.py +6 -3
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/strain.py +2 -2
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/symmetry.py +0 -2
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/__init__.py +15 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/aimsgb.py +1 -2
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/mesh.py +5 -8
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/random.py +12 -9
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/sqs.py +38 -47
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/__init__.py +17 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/helper.py +1 -5
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/visualize.py +36 -31
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32/structuretoolkit.egg-info}/PKG-INFO +17 -16
- structuretoolkit-0.0.32/structuretoolkit.egg-info/requires.txt +39 -0
- structuretoolkit-0.0.29/structuretoolkit.egg-info/requires.txt +0 -39
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/LICENSE +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/MANIFEST.in +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/setup.cfg +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/setup.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/analyse/distance.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/compound.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/build/surface.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/error.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/phonopy.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/pymatgen.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit/common/pyscal.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit.egg-info/SOURCES.txt +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit.egg-info/dependency_links.txt +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/structuretoolkit.egg-info/top_level.txt +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_aimsgb.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse_distance.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse_phonopy.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_analyse_symmetry.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_compound.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_dscribe.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_helpers.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_high_index_surface.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_mesh.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_neighbors.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_pymatgen.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_pyscal.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_pyxtal.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_snap.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_sqs.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_strain.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_symmetry.py +0 -0
- {structuretoolkit-0.0.29 → structuretoolkit-0.0.32}/tests/test_visualize.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: structuretoolkit
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.32
|
|
4
4
|
Summary: build, analyse and visualise atomistic structures for materials science
|
|
5
5
|
Author-email: Jan Janssen <janssen@mpie.de>
|
|
6
6
|
License: BSD 3-Clause License
|
|
@@ -49,39 +49,40 @@ Classifier: Programming Language :: Python :: 3.12
|
|
|
49
49
|
Requires-Python: <3.13,>=3.9
|
|
50
50
|
Description-Content-Type: text/markdown
|
|
51
51
|
License-File: LICENSE
|
|
52
|
-
Requires-Dist: ase<=3.
|
|
52
|
+
Requires-Dist: ase<=3.25.0,>=3.20.1
|
|
53
53
|
Requires-Dist: numpy<=1.26.4,>=1.23.5
|
|
54
|
-
Requires-Dist: scipy<=1.15.
|
|
54
|
+
Requires-Dist: scipy<=1.15.2,>=1.9.3
|
|
55
55
|
Provides-Extra: dscribe
|
|
56
56
|
Requires-Dist: dscribe==2.1.1; extra == "dscribe"
|
|
57
57
|
Provides-Extra: grainboundary
|
|
58
58
|
Requires-Dist: aimsgb<=1.1.1,>=1.0.2; extra == "grainboundary"
|
|
59
|
-
Requires-Dist: pymatgen<=
|
|
59
|
+
Requires-Dist: pymatgen<=2025.3.10,>=2022.2.1; extra == "grainboundary"
|
|
60
60
|
Provides-Extra: pyscal
|
|
61
61
|
Requires-Dist: pyscal3<=3.2.7,>=3.2.5; extra == "pyscal"
|
|
62
62
|
Provides-Extra: nglview
|
|
63
63
|
Requires-Dist: nglview<=3.1.4,>=2.7.7; extra == "nglview"
|
|
64
64
|
Provides-Extra: matplotlib
|
|
65
|
-
Requires-Dist: matplotlib==3.10.
|
|
65
|
+
Requires-Dist: matplotlib==3.10.1; extra == "matplotlib"
|
|
66
66
|
Provides-Extra: plotly
|
|
67
|
-
Requires-Dist: plotly<=
|
|
67
|
+
Requires-Dist: plotly<=6.0.1,>=4.14.3; extra == "plotly"
|
|
68
68
|
Provides-Extra: clusters
|
|
69
|
-
Requires-Dist: scikit-learn==1.6.
|
|
69
|
+
Requires-Dist: scikit-learn==1.6.1; extra == "clusters"
|
|
70
70
|
Provides-Extra: symmetry
|
|
71
|
-
Requires-Dist: spglib<=2.
|
|
71
|
+
Requires-Dist: spglib<=2.6.0,>=1.16.5; extra == "symmetry"
|
|
72
72
|
Provides-Extra: surface
|
|
73
|
-
Requires-Dist: spglib<=2.
|
|
74
|
-
Requires-Dist: pymatgen<=
|
|
73
|
+
Requires-Dist: spglib<=2.6.0,>=1.16.5; extra == "surface"
|
|
74
|
+
Requires-Dist: pymatgen<=2025.3.10,>=2022.2.1; extra == "surface"
|
|
75
75
|
Provides-Extra: phonopy
|
|
76
|
-
Requires-Dist: phonopy<=2.
|
|
77
|
-
Requires-Dist: spglib<=2.
|
|
76
|
+
Requires-Dist: phonopy<=2.38.0,>=2.16.2; extra == "phonopy"
|
|
77
|
+
Requires-Dist: spglib<=2.6.0,>=1.16.5; extra == "phonopy"
|
|
78
78
|
Provides-Extra: pyxtal
|
|
79
|
-
Requires-Dist: pyxtal<=1.0.
|
|
79
|
+
Requires-Dist: pyxtal<=1.0.7,>=0.5.5; extra == "pyxtal"
|
|
80
|
+
Dynamic: license-file
|
|
80
81
|
|
|
81
82
|
# structuretoolkit
|
|
82
83
|
|
|
83
|
-
[](https://github.com/pyiron/structuretoolkit/actions/workflows/pipeline.yml)
|
|
85
|
+
[](https://codecov.io/gh/pyiron/structuretoolkit)
|
|
85
86
|
|
|
86
87
|
Originally developed as part of the `pyiron_atomistics` module the `structuretoolkit` was release as standalone library
|
|
87
88
|
for analysing, building and visualising atomistic structures. Internally it uses the `ase.atoms.Atoms` class to
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# structuretoolkit
|
|
2
2
|
|
|
3
|
-
[](https://github.com/pyiron/structuretoolkit/actions/workflows/pipeline.yml)
|
|
4
|
+
[](https://codecov.io/gh/pyiron/structuretoolkit)
|
|
5
5
|
|
|
6
6
|
Originally developed as part of the `pyiron_atomistics` module the `structuretoolkit` was release as standalone library
|
|
7
7
|
for analysing, building and visualising atomistic structures. Internally it uses the `ase.atoms.Atoms` class to
|
|
@@ -24,9 +24,9 @@ classifiers = [
|
|
|
24
24
|
"Programming Language :: Python :: 3.12",
|
|
25
25
|
]
|
|
26
26
|
dependencies = [
|
|
27
|
-
"ase>=3.20.1,<=3.
|
|
27
|
+
"ase>=3.20.1,<=3.25.0",
|
|
28
28
|
"numpy>=1.23.5,<=1.26.4",
|
|
29
|
-
"scipy>=1.9.3,<=1.15.
|
|
29
|
+
"scipy>=1.9.3,<=1.15.2",
|
|
30
30
|
]
|
|
31
31
|
dynamic = ["version"]
|
|
32
32
|
|
|
@@ -39,23 +39,23 @@ Repository = "https://github.com/pyiron/structuretoolkit"
|
|
|
39
39
|
dscribe = ["dscribe==2.1.1"]
|
|
40
40
|
grainboundary = [
|
|
41
41
|
"aimsgb>=1.0.2,<=1.1.1",
|
|
42
|
-
"pymatgen>=2022.2.1,<=
|
|
42
|
+
"pymatgen>=2022.2.1,<=2025.3.10",
|
|
43
43
|
]
|
|
44
44
|
pyscal = ["pyscal3>=3.2.5,<=3.2.7"]
|
|
45
45
|
nglview = ["nglview>=2.7.7,<=3.1.4"]
|
|
46
|
-
matplotlib = ["matplotlib==3.10.
|
|
47
|
-
plotly = ["plotly>=4.14.3,<=
|
|
48
|
-
clusters = ["scikit-learn==1.6.
|
|
49
|
-
symmetry = ["spglib>=1.16.5,<=2.
|
|
46
|
+
matplotlib = ["matplotlib==3.10.1"]
|
|
47
|
+
plotly = ["plotly>=4.14.3,<=6.0.1"]
|
|
48
|
+
clusters = ["scikit-learn==1.6.1"]
|
|
49
|
+
symmetry = ["spglib>=1.16.5,<=2.6.0"]
|
|
50
50
|
surface = [
|
|
51
|
-
"spglib>=1.16.5,<=2.
|
|
52
|
-
"pymatgen>=2022.2.1,<=
|
|
51
|
+
"spglib>=1.16.5,<=2.6.0",
|
|
52
|
+
"pymatgen>=2022.2.1,<=2025.3.10",
|
|
53
53
|
]
|
|
54
54
|
phonopy = [
|
|
55
|
-
"phonopy>=2.16.2,<=2.
|
|
56
|
-
"spglib>=1.16.5,<=2.
|
|
55
|
+
"phonopy>=2.16.2,<=2.38.0",
|
|
56
|
+
"spglib>=1.16.5,<=2.6.0",
|
|
57
57
|
]
|
|
58
|
-
pyxtal = ["pyxtal>=0.5.5,<=1.0.
|
|
58
|
+
pyxtal = ["pyxtal>=0.5.5,<=1.0.7"]
|
|
59
59
|
|
|
60
60
|
[tool.setuptools.packages.find]
|
|
61
61
|
include = ["structuretoolkit*"]
|
|
@@ -63,6 +63,53 @@ include = ["structuretoolkit*"]
|
|
|
63
63
|
[tool.setuptools.dynamic]
|
|
64
64
|
version = {attr = "structuretoolkit.__version__"}
|
|
65
65
|
|
|
66
|
+
[tool.ruff]
|
|
67
|
+
exclude = [".ci_support", "tests", "setup.py", "_version.py"]
|
|
68
|
+
|
|
69
|
+
[tool.ruff.lint]
|
|
70
|
+
select = [
|
|
71
|
+
# pycodestyle
|
|
72
|
+
"E",
|
|
73
|
+
# Pyflakes
|
|
74
|
+
"F",
|
|
75
|
+
# pyupgrade
|
|
76
|
+
"UP",
|
|
77
|
+
# flake8-bugbear
|
|
78
|
+
"B",
|
|
79
|
+
# flake8-simplify
|
|
80
|
+
"SIM",
|
|
81
|
+
# isort
|
|
82
|
+
"I",
|
|
83
|
+
# flake8-comprehensions
|
|
84
|
+
"C4",
|
|
85
|
+
# eradicate
|
|
86
|
+
"ERA",
|
|
87
|
+
# pylint
|
|
88
|
+
"PL",
|
|
89
|
+
]
|
|
90
|
+
ignore = [
|
|
91
|
+
# ignore functions in argument defaults
|
|
92
|
+
"B008",
|
|
93
|
+
# ignore exception naming
|
|
94
|
+
"B904",
|
|
95
|
+
# ignore line-length violations
|
|
96
|
+
"E501",
|
|
97
|
+
# ignore equality comparisons for numpy arrays
|
|
98
|
+
"E712",
|
|
99
|
+
# ignore bare except
|
|
100
|
+
"E722",
|
|
101
|
+
# ignore ambiguous variable name
|
|
102
|
+
"E741",
|
|
103
|
+
# Too many arguments in function definition
|
|
104
|
+
"PLR0913",
|
|
105
|
+
# Magic value used in comparison
|
|
106
|
+
"PLR2004",
|
|
107
|
+
# Too many branches
|
|
108
|
+
"PLR0912",
|
|
109
|
+
# Too many statements
|
|
110
|
+
"PLR0915",
|
|
111
|
+
]
|
|
112
|
+
|
|
66
113
|
[tool.versioneer]
|
|
67
114
|
VCS = "git"
|
|
68
115
|
style = "pep440-pre"
|
|
@@ -98,4 +98,62 @@ from structuretoolkit.visualize import plot3d
|
|
|
98
98
|
|
|
99
99
|
from . import _version
|
|
100
100
|
|
|
101
|
+
__all__ = [
|
|
102
|
+
"find_mic",
|
|
103
|
+
"find_solids",
|
|
104
|
+
"get_adaptive_cna_descriptors",
|
|
105
|
+
"get_average_of_unique_labels",
|
|
106
|
+
"get_centro_symmetry_descriptors",
|
|
107
|
+
"get_cluster_positions",
|
|
108
|
+
"get_delaunay_neighbors",
|
|
109
|
+
"get_diamond_structure_descriptors",
|
|
110
|
+
"get_distances_array",
|
|
111
|
+
"get_equivalent_atoms",
|
|
112
|
+
"get_interstitials",
|
|
113
|
+
"get_layers",
|
|
114
|
+
"get_mean_positions",
|
|
115
|
+
"get_neighborhood",
|
|
116
|
+
"get_neighbors",
|
|
117
|
+
"get_steinhardt_parameters",
|
|
118
|
+
"get_strain",
|
|
119
|
+
"get_symmetry",
|
|
120
|
+
"get_voronoi_neighbors",
|
|
121
|
+
"get_voronoi_vertices",
|
|
122
|
+
"get_voronoi_volumes",
|
|
123
|
+
"analyse_find_solids",
|
|
124
|
+
"analyse_cna_adaptive",
|
|
125
|
+
"analyse_centro_symmetry",
|
|
126
|
+
"cluster_positions",
|
|
127
|
+
"analyse_diamond_structure",
|
|
128
|
+
"analyse_phonopy_equivalent_atoms",
|
|
129
|
+
"get_steinhardt_parameter_structure",
|
|
130
|
+
"analyse_voronoi_volume",
|
|
131
|
+
"B2",
|
|
132
|
+
"C14",
|
|
133
|
+
"C15",
|
|
134
|
+
"C36",
|
|
135
|
+
"D03",
|
|
136
|
+
"create_mesh",
|
|
137
|
+
"get_grainboundary_info",
|
|
138
|
+
"get_high_index_surface_info",
|
|
139
|
+
"grainboundary",
|
|
140
|
+
"high_index_surface",
|
|
141
|
+
"sqs_structures",
|
|
142
|
+
"grainboundary_info",
|
|
143
|
+
"high_index_surface_info",
|
|
144
|
+
"grainboundary_build",
|
|
145
|
+
"get_sqs_structures",
|
|
146
|
+
"SymmetryError",
|
|
147
|
+
"apply_strain",
|
|
148
|
+
"ase_to_pymatgen",
|
|
149
|
+
"ase_to_pyscal",
|
|
150
|
+
"center_coordinates_in_unit_cell",
|
|
151
|
+
"get_cell",
|
|
152
|
+
"get_extended_positions",
|
|
153
|
+
"get_vertical_length",
|
|
154
|
+
"get_wrapped_coordinates",
|
|
155
|
+
"pymatgen_to_ase",
|
|
156
|
+
"select_index",
|
|
157
|
+
"plot3d",
|
|
158
|
+
]
|
|
101
159
|
__version__ = _version.get_versions()["version"]
|
|
@@ -8,11 +8,11 @@ import json
|
|
|
8
8
|
|
|
9
9
|
version_json = '''
|
|
10
10
|
{
|
|
11
|
-
"date": "2025-
|
|
11
|
+
"date": "2025-04-13T08:36:36+0200",
|
|
12
12
|
"dirty": true,
|
|
13
13
|
"error": null,
|
|
14
|
-
"full-revisionid": "
|
|
15
|
-
"version": "0.0.
|
|
14
|
+
"full-revisionid": "6a0b89e67ab34d999e56a93afceaa1fbedf249bc",
|
|
15
|
+
"version": "0.0.32"
|
|
16
16
|
}
|
|
17
17
|
''' # END VERSION_JSON
|
|
18
18
|
|
|
@@ -254,3 +254,39 @@ def get_ir_reciprocal_mesh(
|
|
|
254
254
|
is_shift=is_shift,
|
|
255
255
|
is_time_reversal=is_time_reversal,
|
|
256
256
|
)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
__all__ = [
|
|
260
|
+
"find_mic",
|
|
261
|
+
"get_distances_array",
|
|
262
|
+
"soap_descriptor_per_atom",
|
|
263
|
+
"get_neighborhood",
|
|
264
|
+
"get_neighbors",
|
|
265
|
+
"get_equivalent_atoms",
|
|
266
|
+
"find_solids",
|
|
267
|
+
"get_adaptive_cna_descriptors",
|
|
268
|
+
"get_centro_symmetry_descriptors",
|
|
269
|
+
"get_diamond_structure_descriptors",
|
|
270
|
+
"get_steinhardt_parameters",
|
|
271
|
+
"get_voronoi_volumes",
|
|
272
|
+
"get_snap_descriptor_derivatives",
|
|
273
|
+
"get_snap_descriptor_names",
|
|
274
|
+
"get_snap_descriptors_per_atom",
|
|
275
|
+
"get_average_of_unique_labels",
|
|
276
|
+
"get_cluster_positions",
|
|
277
|
+
"get_delaunay_neighbors",
|
|
278
|
+
"get_interstitials",
|
|
279
|
+
"get_layers",
|
|
280
|
+
"get_mean_positions",
|
|
281
|
+
"get_voronoi_neighbors",
|
|
282
|
+
"get_voronoi_vertices",
|
|
283
|
+
"get_strain",
|
|
284
|
+
"get_ir_reciprocal_mesh",
|
|
285
|
+
"get_symmetry",
|
|
286
|
+
"symmetrize_vectors",
|
|
287
|
+
"group_points_by_symmetry",
|
|
288
|
+
"get_primitive_cell",
|
|
289
|
+
"get_spacegroup",
|
|
290
|
+
"get_symmetry_dataset",
|
|
291
|
+
"get_equivalent_points",
|
|
292
|
+
]
|
|
@@ -13,7 +13,7 @@ def soap_descriptor_per_atom(
|
|
|
13
13
|
rbf: str = "gto",
|
|
14
14
|
weighting: Optional[np.ndarray] = None,
|
|
15
15
|
average: str = "off",
|
|
16
|
-
compression: dict =
|
|
16
|
+
compression: dict = None,
|
|
17
17
|
species: Optional[list] = None,
|
|
18
18
|
periodic: bool = True,
|
|
19
19
|
sparse: bool = False,
|
|
@@ -50,6 +50,8 @@ def soap_descriptor_per_atom(
|
|
|
50
50
|
"""
|
|
51
51
|
from dscribe.descriptors import SOAP
|
|
52
52
|
|
|
53
|
+
if compression is None:
|
|
54
|
+
compression = {"mode": "off", "species_weighting": None}
|
|
53
55
|
if species is None:
|
|
54
56
|
species = list(set(structure.get_chemical_symbols()))
|
|
55
57
|
periodic_soap = SOAP(
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
|
|
3
2
|
# Distributed under the terms of "New BSD License", see the LICENSE file.
|
|
4
3
|
|
|
5
4
|
import itertools
|
|
6
5
|
import warnings
|
|
7
|
-
from typing import
|
|
6
|
+
from typing import Optional, Union
|
|
8
7
|
|
|
9
8
|
import numpy as np
|
|
10
9
|
from ase.atoms import Atoms
|
|
@@ -104,11 +103,11 @@ class Tree:
|
|
|
104
103
|
Raises:
|
|
105
104
|
KeyError: If the new mode is not found in the available modes.
|
|
106
105
|
"""
|
|
107
|
-
if new_mode not in self._mode
|
|
106
|
+
if new_mode not in self._mode:
|
|
108
107
|
raise KeyError(
|
|
109
108
|
f"{new_mode} not found. Available modes: {', '.join(self._mode.keys())}"
|
|
110
109
|
)
|
|
111
|
-
self._mode =
|
|
110
|
+
self._mode = dict.fromkeys(self._mode, False)
|
|
112
111
|
self._mode[new_mode] = True
|
|
113
112
|
|
|
114
113
|
def __repr__(self) -> str:
|
|
@@ -366,7 +365,7 @@ class Tree:
|
|
|
366
365
|
num_neighbors: Optional[int] = None,
|
|
367
366
|
cutoff_radius: float = np.inf,
|
|
368
367
|
width_buffer: float = 1.2,
|
|
369
|
-
) ->
|
|
368
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
370
369
|
"""
|
|
371
370
|
Get the distances and indices of the neighbors for the given positions.
|
|
372
371
|
|
|
@@ -406,7 +405,8 @@ class Tree:
|
|
|
406
405
|
warnings.warn(
|
|
407
406
|
"Number of neighbors found within the cutoff_radius is equal to (estimated) "
|
|
408
407
|
+ "num_neighbors. Increase num_neighbors (or set it to None) or "
|
|
409
|
-
+ "width_buffer to find all neighbors within cutoff_radius."
|
|
408
|
+
+ "width_buffer to find all neighbors within cutoff_radius.",
|
|
409
|
+
stacklevel=2,
|
|
410
410
|
)
|
|
411
411
|
self._extended_indices = indices.copy()
|
|
412
412
|
indices[distances < np.inf] = self._get_wrapped_indices()[
|
|
@@ -508,7 +508,8 @@ class Tree:
|
|
|
508
508
|
if num_neighbors > self.num_neighbors:
|
|
509
509
|
warnings.warn(
|
|
510
510
|
"Taking a larger search area after initialization has the risk of "
|
|
511
|
-
+ "missing neighborhood atoms"
|
|
511
|
+
+ "missing neighborhood atoms",
|
|
512
|
+
stacklevel=2,
|
|
512
513
|
)
|
|
513
514
|
return num_neighbors
|
|
514
515
|
|
|
@@ -632,15 +633,14 @@ class Tree:
|
|
|
632
633
|
bool: True if the width exceeds the specified value, False otherwise.
|
|
633
634
|
|
|
634
635
|
"""
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
return False
|
|
636
|
+
return bool(
|
|
637
|
+
any(pbc)
|
|
638
|
+
and np.prod(self.filled.distances.shape) > 0
|
|
639
|
+
and np.linalg.norm(
|
|
640
|
+
self.flattened.vecs[..., pbc], axis=-1, ord=self.norm_order
|
|
641
|
+
).max()
|
|
642
|
+
> width
|
|
643
|
+
)
|
|
644
644
|
|
|
645
645
|
def get_spherical_harmonics(
|
|
646
646
|
self,
|
|
@@ -811,9 +811,9 @@ class Mode:
|
|
|
811
811
|
def __dir__(self):
|
|
812
812
|
"""Show value names which are available for different filling modes."""
|
|
813
813
|
return list(
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
)
|
|
814
|
+
{"distances", "vecs", "indices", "shells", "atom_numbers"}.intersection(
|
|
815
|
+
self.ref_neigh.__dir__()
|
|
816
|
+
)
|
|
817
817
|
)
|
|
818
818
|
|
|
819
819
|
|
|
@@ -1008,7 +1008,7 @@ class Neighbors(Tree):
|
|
|
1008
1008
|
|
|
1009
1009
|
def get_shell_matrix(
|
|
1010
1010
|
self,
|
|
1011
|
-
chemical_pair: Optional[
|
|
1011
|
+
chemical_pair: Optional[list[str]] = None,
|
|
1012
1012
|
cluster_by_distances: bool = False,
|
|
1013
1013
|
cluster_by_vecs: bool = False,
|
|
1014
1014
|
):
|
|
@@ -1225,7 +1225,7 @@ class Neighbors(Tree):
|
|
|
1225
1225
|
|
|
1226
1226
|
def cluster_analysis(
|
|
1227
1227
|
self, id_list: list, return_cluster_sizes: bool = False
|
|
1228
|
-
) -> Union[
|
|
1228
|
+
) -> Union[dict[int, list[int]], tuple[dict[int, list[int]], list[int]]]:
|
|
1229
1229
|
"""
|
|
1230
1230
|
Perform cluster analysis on a list of atom IDs.
|
|
1231
1231
|
|
|
@@ -1240,11 +1240,8 @@ class Neighbors(Tree):
|
|
|
1240
1240
|
"""
|
|
1241
1241
|
self._cluster = [0] * len(self._ref_structure)
|
|
1242
1242
|
c_count = 1
|
|
1243
|
-
# element_list = self.get_atomic_numbers()
|
|
1244
1243
|
for ia in id_list:
|
|
1245
|
-
# el0 = element_list[ia]
|
|
1246
1244
|
nbrs = self.ragged.indices[ia]
|
|
1247
|
-
# print ("nbrs: ", ia, nbrs)
|
|
1248
1245
|
if self._cluster[ia] == 0:
|
|
1249
1246
|
self._cluster[ia] = c_count
|
|
1250
1247
|
self.__probe_cluster(c_count, nbrs, id_list)
|
|
@@ -1261,7 +1258,7 @@ class Neighbors(Tree):
|
|
|
1261
1258
|
return cluster_dict # sizes
|
|
1262
1259
|
|
|
1263
1260
|
def __probe_cluster(
|
|
1264
|
-
self, c_count: int, neighbors:
|
|
1261
|
+
self, c_count: int, neighbors: list[int], id_list: list[int]
|
|
1265
1262
|
) -> None:
|
|
1266
1263
|
"""
|
|
1267
1264
|
Recursively probe the cluster and assign cluster IDs to neighbors.
|
|
@@ -1275,11 +1272,12 @@ class Neighbors(Tree):
|
|
|
1275
1272
|
None
|
|
1276
1273
|
"""
|
|
1277
1274
|
for nbr_id in neighbors:
|
|
1278
|
-
if
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1275
|
+
if (
|
|
1276
|
+
self._cluster[nbr_id] == 0 and nbr_id in id_list
|
|
1277
|
+
): # TODO: check also for ordered structures
|
|
1278
|
+
self._cluster[nbr_id] = c_count
|
|
1279
|
+
nbrs = self.ragged.indices[nbr_id]
|
|
1280
|
+
self.__probe_cluster(c_count, nbrs, id_list)
|
|
1283
1281
|
|
|
1284
1282
|
# TODO: combine with corresponding routine in plot3d
|
|
1285
1283
|
def get_bonds(
|
|
@@ -1287,7 +1285,7 @@ class Neighbors(Tree):
|
|
|
1287
1285
|
radius: float = np.inf,
|
|
1288
1286
|
max_shells: Optional[int] = None,
|
|
1289
1287
|
prec: float = 0.1,
|
|
1290
|
-
) ->
|
|
1288
|
+
) -> list[dict[str, list[list[int]]]]:
|
|
1291
1289
|
"""
|
|
1292
1290
|
Get the bonds in the structure.
|
|
1293
1291
|
|
|
@@ -1303,7 +1301,7 @@ class Neighbors(Tree):
|
|
|
1303
1301
|
|
|
1304
1302
|
def get_cluster(
|
|
1305
1303
|
dist_vec: np.ndarray, ind_vec: np.ndarray, prec: float = prec
|
|
1306
|
-
) ->
|
|
1304
|
+
) -> list[np.ndarray]:
|
|
1307
1305
|
"""
|
|
1308
1306
|
Get clusters from a distance vector and index vector.
|
|
1309
1307
|
|
|
@@ -1326,7 +1324,6 @@ class Neighbors(Tree):
|
|
|
1326
1324
|
ind_shell = []
|
|
1327
1325
|
for d, i in zip(dist, ind):
|
|
1328
1326
|
id_list = get_cluster(d[d < radius], i[d < radius])
|
|
1329
|
-
# print ("id: ", d[d<radius], id_list, dist_lst)
|
|
1330
1327
|
ia_shells_dict = {}
|
|
1331
1328
|
for i_shell_list in id_list:
|
|
1332
1329
|
ia_shell_dict = {}
|
|
@@ -1338,9 +1335,11 @@ class Neighbors(Tree):
|
|
|
1338
1335
|
for el, ia_lst in ia_shell_dict.items():
|
|
1339
1336
|
if el not in ia_shells_dict:
|
|
1340
1337
|
ia_shells_dict[el] = []
|
|
1341
|
-
if
|
|
1342
|
-
|
|
1343
|
-
|
|
1338
|
+
if (
|
|
1339
|
+
max_shells is not None
|
|
1340
|
+
and len(ia_shells_dict[el]) + 1 > max_shells
|
|
1341
|
+
):
|
|
1342
|
+
continue
|
|
1344
1343
|
ia_shells_dict[el].append(ia_lst)
|
|
1345
1344
|
ind_shell.append(ia_shells_dict)
|
|
1346
1345
|
return ind_shell
|
|
@@ -1457,7 +1456,8 @@ def _get_neighbors(
|
|
|
1457
1456
|
if neigh._check_width(width=width, pbc=structure.pbc):
|
|
1458
1457
|
warnings.warn(
|
|
1459
1458
|
"width_buffer may have been too small - "
|
|
1460
|
-
"most likely not all neighbors properly assigned"
|
|
1459
|
+
"most likely not all neighbors properly assigned",
|
|
1460
|
+
stacklevel=2,
|
|
1461
1461
|
)
|
|
1462
1462
|
return neigh
|
|
1463
1463
|
|
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
|
|
3
2
|
# Distributed under the terms of "New BSD License", see the LICENSE file.
|
|
4
3
|
|
|
5
|
-
from typing import List
|
|
6
4
|
|
|
7
5
|
import numpy as np
|
|
8
6
|
from ase.atoms import Atoms
|
|
@@ -21,7 +19,7 @@ __date__ = "Sep 1, 2018"
|
|
|
21
19
|
|
|
22
20
|
def get_equivalent_atoms(
|
|
23
21
|
structure: Atoms, symprec: float = 1e-5, angle_tolerance: float = -1.0
|
|
24
|
-
) ->
|
|
22
|
+
) -> list[int]:
|
|
25
23
|
"""
|
|
26
24
|
Get the indices of atoms that are equivalent under symmetry operations.
|
|
27
25
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
# coding: utf-8
|
|
2
1
|
# Copyright (c) Max-Planck-Institut für Eisenforschung GmbH - Computational Materials Design (CM) Department
|
|
3
2
|
# Distributed under the terms of "New BSD License", see the LICENSE file.
|
|
4
3
|
|
|
5
|
-
from typing import Any,
|
|
4
|
+
from typing import Any, Optional, Union
|
|
6
5
|
|
|
7
6
|
import numpy as np
|
|
8
7
|
from ase.atoms import Atoms
|
|
@@ -28,7 +27,7 @@ def get_steinhardt_parameters(
|
|
|
28
27
|
n_clusters: Optional[int] = 2,
|
|
29
28
|
q: Optional[tuple] = None,
|
|
30
29
|
averaged: bool = False,
|
|
31
|
-
) -> Union[
|
|
30
|
+
) -> Union[tuple[np.ndarray], tuple[np.ndarray, np.ndarray]]:
|
|
32
31
|
"""
|
|
33
32
|
Calculate Steinhardts parameters
|
|
34
33
|
|
|
@@ -81,7 +80,7 @@ def get_centro_symmetry_descriptors(
|
|
|
81
80
|
|
|
82
81
|
def get_diamond_structure_descriptors(
|
|
83
82
|
structure: Atoms, mode: str = "total", ovito_compatibility: bool = False
|
|
84
|
-
) -> Union[
|
|
83
|
+
) -> Union[dict[str, int], np.ndarray]:
|
|
85
84
|
"""
|
|
86
85
|
Analyse diamond structure
|
|
87
86
|
|
|
@@ -64,7 +64,7 @@ def get_snap_descriptors_per_atom(
|
|
|
64
64
|
structure: Atoms,
|
|
65
65
|
atom_types: list[str],
|
|
66
66
|
twojmax: int = 6,
|
|
67
|
-
element_radius: list[int] =
|
|
67
|
+
element_radius: list[int] = None,
|
|
68
68
|
rcutfac: float = 1.0,
|
|
69
69
|
rfac0: float = 0.99363,
|
|
70
70
|
rmin0: float = 0.0,
|
|
@@ -92,6 +92,8 @@ def get_snap_descriptors_per_atom(
|
|
|
92
92
|
Returns:
|
|
93
93
|
np.ndarray: Numpy array with the calculated descriptor derivatives
|
|
94
94
|
"""
|
|
95
|
+
if element_radius is None:
|
|
96
|
+
element_radius = [4.0]
|
|
95
97
|
lmp, bispec_options, cutoff = _get_default_parameters(
|
|
96
98
|
atom_types=atom_types,
|
|
97
99
|
twojmax=twojmax,
|
|
@@ -113,7 +115,7 @@ def get_snap_descriptor_derivatives(
|
|
|
113
115
|
structure: Atoms,
|
|
114
116
|
atom_types: list[str],
|
|
115
117
|
twojmax: int = 6,
|
|
116
|
-
element_radius: list[int] =
|
|
118
|
+
element_radius: list[int] = None,
|
|
117
119
|
rcutfac: float = 1.0,
|
|
118
120
|
rfac0: float = 0.99363,
|
|
119
121
|
rmin0: float = 0.0,
|
|
@@ -141,6 +143,8 @@ def get_snap_descriptor_derivatives(
|
|
|
141
143
|
Returns:
|
|
142
144
|
np.ndarray: Numpy array with the calculated descriptor derivatives
|
|
143
145
|
"""
|
|
146
|
+
if element_radius is None:
|
|
147
|
+
element_radius = [4.0]
|
|
144
148
|
lmp, bispec_options, cutoff = _get_default_parameters(
|
|
145
149
|
atom_types=atom_types,
|
|
146
150
|
twojmax=twojmax,
|
|
@@ -420,7 +424,7 @@ def _calc_snap_per_atom(
|
|
|
420
424
|
return np.array([])
|
|
421
425
|
else:
|
|
422
426
|
if (
|
|
423
|
-
"quadraticflag" in bispec_options
|
|
427
|
+
"quadraticflag" in bispec_options
|
|
424
428
|
and int(bispec_options["quadraticflag"]) == 1
|
|
425
429
|
):
|
|
426
430
|
return _extract_compute_np(
|
|
@@ -521,7 +525,7 @@ def _set_computes_snap(lmp, bispec_options: dict):
|
|
|
521
525
|
kw_substrings = [f"{k} {v}" for k, v in kw_options.items()]
|
|
522
526
|
kwargs = " ".join(kw_substrings)
|
|
523
527
|
|
|
524
|
-
for
|
|
528
|
+
for _op, base in zip(("b", "db", "vb"), (base_b, base_db, base_vb)):
|
|
525
529
|
command = f"{base} {radelem} {wj} {kwargs}"
|
|
526
530
|
lmp.command(command)
|
|
527
531
|
|
|
@@ -545,16 +549,15 @@ def _extract_computes_snap(
|
|
|
545
549
|
np.ndarray: Output of the LAMMPS compute command
|
|
546
550
|
"""
|
|
547
551
|
lmp_atom_ids = lmp.numpy.extract_atom_iarray("id", num_atoms).flatten()
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
), "LAMMPS seems to have lost atoms"
|
|
552
|
+
cond = np.all(lmp_atom_ids == 1 + np.arange(num_atoms))
|
|
553
|
+
assert cond, "LAMMPS seems to have lost atoms"
|
|
551
554
|
|
|
552
555
|
# Extract types
|
|
553
556
|
lmp_types = lmp.numpy.extract_atom_iarray(name="type", nelem=num_atoms).flatten()
|
|
554
557
|
lmp_volume = lmp.get_thermo("vol")
|
|
555
558
|
|
|
556
559
|
# Extract Bsum
|
|
557
|
-
|
|
560
|
+
_extract_compute_np(lmp, "b_sum", 0, 1, (n_coeff))
|
|
558
561
|
|
|
559
562
|
# Extract B
|
|
560
563
|
lmp_barr = _extract_compute_np(lmp, "b", 1, 2, (num_atoms, n_coeff))
|
|
@@ -569,16 +572,14 @@ def _extract_computes_snap(
|
|
|
569
572
|
|
|
570
573
|
lmp_dbarr = _extract_compute_np(lmp, "db", 1, 2, (num_atoms, num_types, 3, n_coeff))
|
|
571
574
|
lmp_dbsum = _extract_compute_np(lmp, "db_sum", 0, 1, (num_types, 3, n_coeff))
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
), "db_sum doesn't match sum of db"
|
|
575
|
+
cond = np.allclose(lmp_dbsum, lmp_dbarr.sum(axis=0), rtol=1e-12, atol=1e-12)
|
|
576
|
+
assert cond, "db_sum doesn't match sum of db"
|
|
575
577
|
db_atom = np.transpose(lmp_dbarr, (0, 2, 1, 3))
|
|
576
578
|
|
|
577
579
|
lmp_vbarr = _extract_compute_np(lmp, "vb", 1, 2, (num_atoms, num_types, 6, n_coeff))
|
|
578
580
|
lmp_vbsum = _extract_compute_np(lmp, "vb_sum", 0, 1, (num_types, 6, n_coeff))
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
), "vb_sum doesn't match sum of vb"
|
|
581
|
+
cond = np.allclose(lmp_vbsum, lmp_vbarr.sum(axis=0), rtol=1e-12, atol=1e-12)
|
|
582
|
+
assert cond, "vb_sum doesn't match sum of vb"
|
|
582
583
|
vb_sum = np.transpose(lmp_vbsum, (1, 0, 2)) / lmp_volume * eV_div_A3_to_bar
|
|
583
584
|
|
|
584
585
|
dbatom_shape = db_atom.shape
|
|
@@ -631,7 +632,7 @@ def _calc_snap_derivatives(
|
|
|
631
632
|
return np.array([])
|
|
632
633
|
else:
|
|
633
634
|
if (
|
|
634
|
-
"quadraticflag" in bispec_options
|
|
635
|
+
"quadraticflag" in bispec_options
|
|
635
636
|
and int(bispec_options["quadraticflag"]) == 1
|
|
636
637
|
):
|
|
637
638
|
return _extract_computes_snap(
|
|
@@ -681,10 +682,7 @@ def _get_default_parameters(
|
|
|
681
682
|
"""
|
|
682
683
|
from lammps import lammps
|
|
683
684
|
|
|
684
|
-
if weights is None
|
|
685
|
-
wj = [1.0] * len(atom_types)
|
|
686
|
-
else:
|
|
687
|
-
wj = weights
|
|
685
|
+
wj = [1.0] * len(atom_types) if weights is None else weights
|
|
688
686
|
if isinstance(element_radius, float):
|
|
689
687
|
radelem = [element_radius] * len(atom_types)
|
|
690
688
|
else:
|