amorphouspy 0.5.2__py3-none-any.whl
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.
- amorphouspy/__init__.py +95 -0
- amorphouspy/analysis/__init__.py +6 -0
- amorphouspy/analysis/bond_angle_distribution.py +119 -0
- amorphouspy/analysis/cavities.py +704 -0
- amorphouspy/analysis/cte.py +181 -0
- amorphouspy/analysis/qn_network_connectivity.py +192 -0
- amorphouspy/analysis/radial_distribution_functions.py +344 -0
- amorphouspy/analysis/rings.py +549 -0
- amorphouspy/analysis/structure_factor.py +356 -0
- amorphouspy/io_utils.py +239 -0
- amorphouspy/mass.py +23 -0
- amorphouspy/neighbors.py +900 -0
- amorphouspy/potentials/__init__.py +4 -0
- amorphouspy/potentials/bjp_potential.py +114 -0
- amorphouspy/potentials/pmmcs_potential.py +134 -0
- amorphouspy/potentials/potential.py +99 -0
- amorphouspy/potentials/shik_potential.py +265 -0
- amorphouspy/shared.py +95 -0
- amorphouspy/structure/__init__.py +57 -0
- amorphouspy/structure/composition.py +221 -0
- amorphouspy/structure/density.py +225 -0
- amorphouspy/structure/geometry.py +362 -0
- amorphouspy/structure/planner.py +274 -0
- amorphouspy/workflows/__init__.py +1 -0
- amorphouspy/workflows/cte.py +559 -0
- amorphouspy/workflows/cte_helpers.py +445 -0
- amorphouspy/workflows/elastic_mod.py +279 -0
- amorphouspy/workflows/md.py +94 -0
- amorphouspy/workflows/meltquench.py +216 -0
- amorphouspy/workflows/meltquench_protocols.py +336 -0
- amorphouspy/workflows/shared.py +190 -0
- amorphouspy/workflows/structural_analysis.py +683 -0
- amorphouspy/workflows/viscosity.py +1142 -0
- amorphouspy-0.5.2.dist-info/METADATA +147 -0
- amorphouspy-0.5.2.dist-info/RECORD +62 -0
- amorphouspy-0.5.2.dist-info/WHEEL +4 -0
- amorphouspy-0.5.2.dist-info/licenses/LICENSE +28 -0
- amorphouspy_api/__init__.py +7 -0
- amorphouspy_api/app.py +100 -0
- amorphouspy_api/auth.py +33 -0
- amorphouspy_api/config.py +52 -0
- amorphouspy_api/database.py +261 -0
- amorphouspy_api/executor.py +134 -0
- amorphouspy_api/mcp_server.py +91 -0
- amorphouspy_api/models.py +576 -0
- amorphouspy_api/routers/__init__.py +6 -0
- amorphouspy_api/routers/glasses.py +103 -0
- amorphouspy_api/routers/jobs.py +539 -0
- amorphouspy_api/routers/jobs_helpers.py +688 -0
- amorphouspy_api/static/css/results.css +320 -0
- amorphouspy_api/static/js/results.js +653 -0
- amorphouspy_api/static/js/vendor/3dmol.min.js +2 -0
- amorphouspy_api/static/js/vendor/plotly.min.js +3882 -0
- amorphouspy_api/templates/results.html +397 -0
- amorphouspy_api/workflows/__init__.py +136 -0
- amorphouspy_api/workflows/analyses/__init__.py +8 -0
- amorphouspy_api/workflows/analyses/cte.py +378 -0
- amorphouspy_api/workflows/analyses/elastic.py +131 -0
- amorphouspy_api/workflows/analyses/meltquench_viz.py +218 -0
- amorphouspy_api/workflows/analyses/structure.py +150 -0
- amorphouspy_api/workflows/analyses/viscosity.py +527 -0
- amorphouspy_api/workflows/meltquench.py +106 -0
amorphouspy/__init__.py
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"""amorphouspy - workflows for atomistic modeling of oxide glasses."""
|
|
2
|
+
|
|
3
|
+
from amorphouspy.analysis.bond_angle_distribution import compute_angles
|
|
4
|
+
from amorphouspy.analysis.cavities import compute_cavities
|
|
5
|
+
from amorphouspy.analysis.cte import (
|
|
6
|
+
cte_from_npt_fluctuations,
|
|
7
|
+
cte_from_volume_temperature_data,
|
|
8
|
+
)
|
|
9
|
+
from amorphouspy.analysis.qn_network_connectivity import (
|
|
10
|
+
classify_oxygens,
|
|
11
|
+
compute_network_connectivity,
|
|
12
|
+
compute_qn,
|
|
13
|
+
compute_qn_and_classify,
|
|
14
|
+
)
|
|
15
|
+
from amorphouspy.analysis.radial_distribution_functions import compute_coordination, compute_rdf
|
|
16
|
+
from amorphouspy.analysis.rings import compute_guttmann_rings, generate_bond_length_dict
|
|
17
|
+
from amorphouspy.analysis.structure_factor import compute_structure_factor
|
|
18
|
+
from amorphouspy.io_utils import (
|
|
19
|
+
load_lammps_dump,
|
|
20
|
+
structure_from_parsed_output,
|
|
21
|
+
write_angle_distribution,
|
|
22
|
+
write_distribution_to_file,
|
|
23
|
+
write_xyz,
|
|
24
|
+
)
|
|
25
|
+
from amorphouspy.mass import get_atomic_mass
|
|
26
|
+
from amorphouspy.neighbors import get_neighbors
|
|
27
|
+
from amorphouspy.potentials.potential import generate_potential
|
|
28
|
+
from amorphouspy.shared import count_distribution, running_mean, type_to_dict
|
|
29
|
+
from amorphouspy.structure import (
|
|
30
|
+
check_neutral_oxide,
|
|
31
|
+
create_random_atoms,
|
|
32
|
+
extract_composition,
|
|
33
|
+
formula_mass_g_per_mol,
|
|
34
|
+
get_ase_structure,
|
|
35
|
+
get_composition,
|
|
36
|
+
get_glass_density_from_model,
|
|
37
|
+
get_structure_dict,
|
|
38
|
+
parse_formula,
|
|
39
|
+
plan_system,
|
|
40
|
+
)
|
|
41
|
+
from amorphouspy.workflows.cte import cte_from_fluctuations_simulation, temperature_scan_simulation
|
|
42
|
+
from amorphouspy.workflows.elastic_mod import elastic_simulation
|
|
43
|
+
from amorphouspy.workflows.md import md_simulation
|
|
44
|
+
from amorphouspy.workflows.meltquench import melt_quench_simulation
|
|
45
|
+
from amorphouspy.workflows.structural_analysis import analyze_structure, find_rdf_minimum, plot_analysis_results_plotly
|
|
46
|
+
from amorphouspy.workflows.viscosity import fit_vft, get_viscosity, viscosity_ensemble, viscosity_simulation
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
"analyze_structure",
|
|
50
|
+
"check_neutral_oxide",
|
|
51
|
+
"classify_oxygens",
|
|
52
|
+
"compute_angles",
|
|
53
|
+
"compute_cavities",
|
|
54
|
+
"compute_coordination",
|
|
55
|
+
"compute_guttmann_rings",
|
|
56
|
+
"compute_network_connectivity",
|
|
57
|
+
"compute_qn",
|
|
58
|
+
"compute_qn_and_classify",
|
|
59
|
+
"compute_rdf",
|
|
60
|
+
"compute_structure_factor",
|
|
61
|
+
"count_distribution",
|
|
62
|
+
"create_random_atoms",
|
|
63
|
+
"cte_from_fluctuations_simulation",
|
|
64
|
+
"cte_from_npt_fluctuations",
|
|
65
|
+
"cte_from_volume_temperature_data",
|
|
66
|
+
"elastic_simulation",
|
|
67
|
+
"extract_composition",
|
|
68
|
+
"find_rdf_minimum",
|
|
69
|
+
"fit_vft",
|
|
70
|
+
"formula_mass_g_per_mol",
|
|
71
|
+
"generate_bond_length_dict",
|
|
72
|
+
"generate_potential",
|
|
73
|
+
"get_ase_structure",
|
|
74
|
+
"get_atomic_mass",
|
|
75
|
+
"get_composition",
|
|
76
|
+
"get_glass_density_from_model",
|
|
77
|
+
"get_neighbors",
|
|
78
|
+
"get_structure_dict",
|
|
79
|
+
"get_viscosity",
|
|
80
|
+
"load_lammps_dump",
|
|
81
|
+
"md_simulation",
|
|
82
|
+
"melt_quench_simulation",
|
|
83
|
+
"parse_formula",
|
|
84
|
+
"plan_system",
|
|
85
|
+
"plot_analysis_results_plotly",
|
|
86
|
+
"running_mean",
|
|
87
|
+
"structure_from_parsed_output",
|
|
88
|
+
"temperature_scan_simulation",
|
|
89
|
+
"type_to_dict",
|
|
90
|
+
"viscosity_ensemble",
|
|
91
|
+
"viscosity_simulation",
|
|
92
|
+
"write_angle_distribution",
|
|
93
|
+
"write_distribution_to_file",
|
|
94
|
+
"write_xyz",
|
|
95
|
+
]
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Structural analysis functions for multicomponent glass systems.
|
|
2
|
+
|
|
3
|
+
Author: Achraf Atila (achraf.atila@bam.de)
|
|
4
|
+
|
|
5
|
+
This module provides tools to compute local structural descriptors
|
|
6
|
+
in amorphous materials, focusing on bond angle distributions around
|
|
7
|
+
selected atoms. It supports type-specific neighbor searches
|
|
8
|
+
using periodic boundary conditions and customizable cutoffs.
|
|
9
|
+
|
|
10
|
+
Currently implemented:
|
|
11
|
+
|
|
12
|
+
- compute_angles: Calculates bond angle distributions for atom
|
|
13
|
+
triplets of the form neighbor-center-neighbor, filtered by atomic
|
|
14
|
+
types and distance cutoff.
|
|
15
|
+
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
import numpy as np
|
|
19
|
+
from ase import Atoms
|
|
20
|
+
|
|
21
|
+
from amorphouspy.neighbors import get_neighbors
|
|
22
|
+
|
|
23
|
+
MIN_NEIGHBORS_FOR_ANGLE = 2
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def compute_angles(
|
|
27
|
+
structure: Atoms,
|
|
28
|
+
center_type: int,
|
|
29
|
+
neighbor_type: int,
|
|
30
|
+
cutoff: float,
|
|
31
|
+
bins: int = 180,
|
|
32
|
+
) -> tuple[np.ndarray, np.ndarray]:
|
|
33
|
+
"""Compute bond angle distribution between triplets of neighbor_type-center-neighbor_type.
|
|
34
|
+
|
|
35
|
+
Args:
|
|
36
|
+
structure: Atomic structure.
|
|
37
|
+
center_type: Atom type at the angle center.
|
|
38
|
+
neighbor_type: Atom type forming the angle with center.
|
|
39
|
+
cutoff: Neighbor search cutoff.
|
|
40
|
+
bins: Number of histogram bins. Defaults to 180.
|
|
41
|
+
|
|
42
|
+
Returns:
|
|
43
|
+
A tuple containing:
|
|
44
|
+
bin_centers: Bin centers (degrees).
|
|
45
|
+
angle_hist: Normalized angle histogram.
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
>>> bins, hist = compute_angles(structure, center_type=1, neighbor_type=2, cutoff=3.0)
|
|
49
|
+
|
|
50
|
+
"""
|
|
51
|
+
# Wrap and extract positions/cell once — needed for minimum-image vectors
|
|
52
|
+
structure_wrapped = structure.copy()
|
|
53
|
+
structure_wrapped.wrap()
|
|
54
|
+
coords = structure_wrapped.get_positions()
|
|
55
|
+
cell = structure_wrapped.get_cell().array
|
|
56
|
+
is_orthogonal = np.allclose(cell - np.diag(np.diag(cell)), 0.0, atol=1e-10)
|
|
57
|
+
|
|
58
|
+
# Build ID → array index map to look up coordinates by real atom ID
|
|
59
|
+
if "id" in structure_wrapped.arrays:
|
|
60
|
+
raw_ids = structure_wrapped.arrays["id"]
|
|
61
|
+
else:
|
|
62
|
+
raw_ids = np.arange(1, len(structure_wrapped) + 1)
|
|
63
|
+
id_to_idx = {int(aid): i for i, aid in enumerate(raw_ids)}
|
|
64
|
+
|
|
65
|
+
# get_neighbors returns List[Tuple[central_id, List[neighbor_ids]]]
|
|
66
|
+
neighbors = get_neighbors(
|
|
67
|
+
structure,
|
|
68
|
+
cutoff=cutoff,
|
|
69
|
+
target_types=[center_type],
|
|
70
|
+
neighbor_types=[neighbor_type],
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
angles = []
|
|
74
|
+
|
|
75
|
+
for central_id, nn_ids in neighbors:
|
|
76
|
+
if len(nn_ids) < MIN_NEIGHBORS_FOR_ANGLE:
|
|
77
|
+
continue
|
|
78
|
+
|
|
79
|
+
ci = id_to_idx[central_id]
|
|
80
|
+
center_coord = coords[ci]
|
|
81
|
+
|
|
82
|
+
# Resolve neighbor coordinates by real ID — shape (k, 3)
|
|
83
|
+
nn_indices = np.array([id_to_idx[nid] for nid in nn_ids], dtype=np.int32)
|
|
84
|
+
vecs = coords[nn_indices] - center_coord # (k, 3)
|
|
85
|
+
|
|
86
|
+
# Minimum-image correction — vectorized for all neighbor vectors at once
|
|
87
|
+
if is_orthogonal:
|
|
88
|
+
box = np.diag(cell)
|
|
89
|
+
vecs -= box * np.round(vecs / box)
|
|
90
|
+
else:
|
|
91
|
+
inv_cell = np.linalg.inv(cell)
|
|
92
|
+
delta_frac = (inv_cell @ vecs.T).T
|
|
93
|
+
delta_frac -= np.round(delta_frac)
|
|
94
|
+
vecs = (cell.T @ delta_frac.T).T
|
|
95
|
+
|
|
96
|
+
# Normalise all vectors at once
|
|
97
|
+
norms = np.linalg.norm(vecs, axis=1) # (k,)
|
|
98
|
+
valid = norms > 0
|
|
99
|
+
if valid.sum() < MIN_NEIGHBORS_FOR_ANGLE:
|
|
100
|
+
continue
|
|
101
|
+
vecs = vecs[valid]
|
|
102
|
+
norms = norms[valid]
|
|
103
|
+
unit_vecs = vecs / norms[:, np.newaxis] # (k, 3)
|
|
104
|
+
|
|
105
|
+
# Compute all unique pair cosines via matrix multiply: (k, k)
|
|
106
|
+
# Upper triangle gives each unique i<j pair
|
|
107
|
+
cos_mat = np.clip(unit_vecs @ unit_vecs.T, -1.0, 1.0)
|
|
108
|
+
i_idx, j_idx = np.triu_indices(len(unit_vecs), k=1)
|
|
109
|
+
cos_angles = cos_mat[i_idx, j_idx]
|
|
110
|
+
angles.extend(np.degrees(np.arccos(cos_angles)).tolist())
|
|
111
|
+
|
|
112
|
+
angle_hist, bin_edges = np.histogram(
|
|
113
|
+
angles,
|
|
114
|
+
bins=bins,
|
|
115
|
+
range=(0, 180),
|
|
116
|
+
density=True,
|
|
117
|
+
)
|
|
118
|
+
bin_centers = (bin_edges[:-1] + bin_edges[1:]) / 2
|
|
119
|
+
return bin_centers, angle_hist
|