dynasor 2.2__tar.gz → 2.4__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.
- {dynasor-2.2 → dynasor-2.4}/PKG-INFO +28 -8
- {dynasor-2.2 → dynasor-2.4}/README.rst +14 -7
- {dynasor-2.2 → dynasor-2.4}/dynasor/__init__.py +5 -1
- {dynasor-2.2 → dynasor-2.4}/dynasor/cli/main.py +17 -6
- {dynasor-2.2 → dynasor-2.4}/dynasor/core/reciprocal.py +1 -1
- {dynasor-2.2 → dynasor-2.4}/dynasor/core/rho_j_q_numba.py +18 -19
- dynasor-2.4/dynasor/core/time_averager.py +103 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/correlation_functions.py +129 -74
- {dynasor-2.2 → dynasor-2.4}/dynasor/logging_tools.py +11 -17
- dynasor-2.4/dynasor/modes/__init__.py +16 -0
- dynasor-2.4/dynasor/modes/atoms.py +178 -0
- dynasor-2.4/dynasor/modes/band.py +107 -0
- dynasor-2.4/dynasor/modes/complex_coordinate.py +130 -0
- dynasor-2.4/dynasor/modes/mode_projector.py +525 -0
- dynasor-2.4/dynasor/modes/project_modes.py +90 -0
- dynasor-2.4/dynasor/modes/qpoint.py +112 -0
- dynasor-2.4/dynasor/modes/tools.py +231 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/__init__.py +0 -2
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/atomic_weighting.py +37 -17
- dynasor-2.4/dynasor/post_processing/average_runs.py +90 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/electron_scattering_factors.py +33 -24
- dynasor-2.4/dynasor/post_processing/form-factors/neutron_scattering_lengths.json +1 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/neutron_scattering_lengths.py +21 -6
- dynasor-2.4/dynasor/post_processing/spherical_average.py +309 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/weights.py +30 -11
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/x_ray_form_factors.py +16 -9
- {dynasor-2.2 → dynasor-2.4}/dynasor/qpoints/lattice.py +28 -26
- {dynasor-2.2 → dynasor-2.4}/dynasor/qpoints/spherical_qpoints.py +56 -33
- dynasor-2.4/dynasor/qpoints/tools.py +165 -0
- dynasor-2.4/dynasor/sample.py +425 -0
- dynasor-2.4/dynasor/tools/acfs.py +277 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/tools/damped_harmonic_oscillator.py +38 -15
- dynasor-2.4/dynasor/tools/structures.py +308 -0
- dynasor-2.4/dynasor/trajectory/abstract_trajectory_reader.py +59 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/ase_trajectory_reader.py +5 -12
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/atomic_indices.py +5 -3
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/extxyz_trajectory_reader.py +52 -40
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/lammps_trajectory_reader.py +5 -12
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/mdanalysis_trajectory_reader.py +15 -16
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/trajectory.py +47 -35
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/trajectory_frame.py +32 -32
- dynasor-2.4/dynasor/units.py +42 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor.egg-info/PKG-INFO +28 -8
- {dynasor-2.2 → dynasor-2.4}/dynasor.egg-info/SOURCES.txt +11 -1
- dynasor-2.4/dynasor.egg-info/requires.txt +20 -0
- {dynasor-2.2 → dynasor-2.4}/pyproject.toml +25 -2
- dynasor-2.4/tests/test_SED.py +185 -0
- dynasor-2.4/tests/test_average_independent_samples.py +144 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_cli.py +33 -1
- dynasor-2.4/tests/test_compute_Sqw_with_too_long_window.py +26 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_dho.py +13 -0
- dynasor-2.4/tests/test_dynasor_API.py +317 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_integration.py +21 -19
- {dynasor-2.2 → dynasor-2.4}/tests/test_logging.py +2 -2
- {dynasor-2.2 → dynasor-2.4}/tests/test_normalization.py +11 -2
- dynasor-2.4/tests/test_numba.py +256 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_qpoints.py +90 -0
- dynasor-2.4/tests/test_sample_class.py +303 -0
- dynasor-2.4/tests/test_scattering_factors.py +295 -0
- dynasor-2.4/tests/test_spherical_average.py +263 -0
- dynasor-2.4/tests/test_structures.py +112 -0
- dynasor-2.4/tests/test_time_averager.py +190 -0
- dynasor-2.4/tests/test_tools.py +222 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_trajectory_and_window_iterator.py +35 -2
- dynasor-2.4/tests/test_utils.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_weighting.py +113 -44
- {dynasor-2.2 → dynasor-2.4}/tests/test_weights.py +21 -1
- dynasor-2.2/dynasor/core/time_averager.py +0 -44
- dynasor-2.2/dynasor/post_processing/average_runs.py +0 -61
- dynasor-2.2/dynasor/post_processing/filon.py +0 -148
- dynasor-2.2/dynasor/post_processing/form-factors/neutron_scattering_lengths.json +0 -1
- dynasor-2.2/dynasor/post_processing/spherical_average.py +0 -225
- dynasor-2.2/dynasor/qpoints/tools.py +0 -247
- dynasor-2.2/dynasor/sample.py +0 -204
- dynasor-2.2/dynasor/tools/acfs.py +0 -117
- dynasor-2.2/dynasor/tools/structures.py +0 -102
- dynasor-2.2/dynasor/trajectory/abstract_trajectory_reader.py +0 -38
- dynasor-2.2/dynasor/units.py +0 -42
- dynasor-2.2/dynasor.egg-info/requires.txt +0 -5
- dynasor-2.2/tests/test_SED.py +0 -98
- dynasor-2.2/tests/test_average_independent_samples.py +0 -86
- dynasor-2.2/tests/test_dynasor_API.py +0 -154
- dynasor-2.2/tests/test_numba.py +0 -40
- dynasor-2.2/tests/test_sample_class.py +0 -196
- dynasor-2.2/tests/test_spherical_average.py +0 -139
- dynasor-2.2/tests/test_time_averager.py +0 -33
- dynasor-2.2/tests/test_tools.py +0 -91
- dynasor-2.2/tests/test_utils.py +0 -23
- {dynasor-2.2 → dynasor-2.4}/LICENSE +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/cli/__init__.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/core/__init__.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/form-factors/compton-parameters-waasmaier-kirfel-1995.json +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/form-factors/electron-parameters-ions-peng-1998.json +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/form-factors/electron-parameters-kmax2-peng-1996.json +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/form-factors/electron-parameters-kmax6-peng-1996.json +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/form-factors/x-ray-parameters-itcc-2006.json +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/post_processing/form-factors/x-ray-parameters-waasmaier-kirfel-1995.json +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/qpoints/__init__.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/tools/__init__.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor/trajectory/__init__.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor.egg-info/dependency_links.txt +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor.egg-info/entry_points.txt +0 -0
- {dynasor-2.2 → dynasor-2.4}/dynasor.egg-info/top_level.txt +0 -0
- {dynasor-2.2 → dynasor-2.4}/setup.cfg +0 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_lattice.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_parse_gromacs_index_file.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_regression_vs_old_cmdline_results.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_trajectory_frame.py +0 -0
- {dynasor-2.2 → dynasor-2.4}/tests/test_units.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dynasor
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.4
|
|
4
4
|
Summary: Dynamical structure factors and correlation functions from molecular dynamics trajectories
|
|
5
5
|
Author: The dynasor developer team
|
|
6
6
|
Maintainer: The dynasor developer team
|
|
@@ -30,6 +30,19 @@ Requires-Dist: mdanalysis
|
|
|
30
30
|
Requires-Dist: numba>=0.55
|
|
31
31
|
Requires-Dist: numpy>=1.18
|
|
32
32
|
Requires-Dist: pandas>=2.2
|
|
33
|
+
Requires-Dist: scipy
|
|
34
|
+
Provides-Extra: test
|
|
35
|
+
Requires-Dist: coverage; extra == "test"
|
|
36
|
+
Requires-Dist: flake8; extra == "test"
|
|
37
|
+
Requires-Dist: phonopy; extra == "test"
|
|
38
|
+
Requires-Dist: pytest; extra == "test"
|
|
39
|
+
Requires-Dist: xdoctest; extra == "test"
|
|
40
|
+
Provides-Extra: documentation
|
|
41
|
+
Requires-Dist: pydata-sphinx-theme; extra == "documentation"
|
|
42
|
+
Requires-Dist: nbsphinx; extra == "documentation"
|
|
43
|
+
Requires-Dist: sphinx-autodoc-typehints; extra == "documentation"
|
|
44
|
+
Requires-Dist: sphinx-design; extra == "documentation"
|
|
45
|
+
Requires-Dist: sphinx-sitemap; extra == "documentation"
|
|
33
46
|
Dynamic: license-file
|
|
34
47
|
|
|
35
48
|
dynasor
|
|
@@ -38,27 +51,34 @@ dynasor
|
|
|
38
51
|
**dynasor** is a tool for calculating total and partial dynamic structure factors as well as related correlation functions from molecular dynamics (MD) simulations.
|
|
39
52
|
By analyzing these functions one can access the dynamics of a system without resorting to perturbative approaches.
|
|
40
53
|
Moreover by combining in particular the structure factor with the cross sections (or form factors) of, e.g., neutrons, X-rays or electrons, one can predict experimental spectra.
|
|
41
|
-
The main input consists of a trajectory from
|
|
54
|
+
The main input consists of a trajectory from an MD simulation, i.e., a file containing snapshots of the particle coordinates and optionally velocities that correspond to consecutive, equally spaced points in simulation time.
|
|
42
55
|
|
|
43
|
-
**dynasor** provides both
|
|
56
|
+
**dynasor** provides both a Python interface and a command-line interface.
|
|
44
57
|
The following snippet illustrates how one can calculate dynamic structure factors using the former.
|
|
45
58
|
|
|
46
59
|
.. code-block:: python
|
|
47
60
|
|
|
61
|
+
from dynasor import Trajectory, compute_dynamic_structure_factors
|
|
62
|
+
from dynasor.qpoints import get_spherical_qpoints
|
|
63
|
+
|
|
48
64
|
traj = Trajectory('dump.xyz', trajectory_format='extxyz')
|
|
49
|
-
q_points =
|
|
65
|
+
q_points = get_spherical_qpoints(traj.cell, q_max=20)
|
|
50
66
|
sample = compute_dynamic_structure_factors(traj, q_points=q_points, dt=5, window_size=100)
|
|
51
|
-
sample.
|
|
67
|
+
sample.write_to_npz('test.npz')
|
|
52
68
|
|
|
53
69
|
**dynasor** can be installed via `pip <https://pypi.org/project/dynasor/>`_ or `conda <https://anaconda.org/conda-forge/dynasor>`_.
|
|
54
|
-
Please consult the `installation section of the user guide <https://dynasor.materialsmodeling.org/installation.html>`_ for details.
|
|
70
|
+
Please consult the `installation section of the user guide <https://dynasor.materialsmodeling.org/get_started/installation.html>`_ for details.
|
|
55
71
|
|
|
56
|
-
The full documentation can be found in the `user guide <
|
|
72
|
+
The full documentation can be found in the `user guide <https://dynasor.materialsmodeling.org/>`_.
|
|
57
73
|
For questions and help please use the `dynasor discussion forum on matsci.org <https://matsci.org/dynasor>`_.
|
|
58
74
|
**dynasor** and its development are hosted on `gitlab <https://gitlab.com/materials-modeling/dynasor>`_.
|
|
59
75
|
|
|
60
|
-
When using **dynasor** in your research please cite the following
|
|
76
|
+
When using **dynasor** in your research please cite the following papers:
|
|
61
77
|
|
|
62
78
|
| *Dynasor – A tool for extracting dynamical structure factors and current correlation functions from molecular dynamics simulations*
|
|
63
79
|
| Erik Fransson, Mattias Slabanja, Paul Erhart, and Göran Wahnström
|
|
64
80
|
| Advanced Theory and Simulations **4**, 2000240 (2021); DOI:`10.1002/adts.202000240 <https://doi.org/10.1002/adts.202000240>`_
|
|
81
|
+
|
|
82
|
+
| *Dynasor 2: From simulation to experiment through correlation functions*
|
|
83
|
+
| Esmée Berger, Erik Fransson, Fredrik Eriksson, Eric Lindgren, Göran Wahnström, Thomas Holm Rod, and Paul Erhart
|
|
84
|
+
| Computer Physics Communications **316**, 109759 (2025); DOI: `10.1016/j.cpc.2025.109759 <https://doi.org/10.1016/j.cpc.2025.109759>`_
|
|
@@ -4,27 +4,34 @@ dynasor
|
|
|
4
4
|
**dynasor** is a tool for calculating total and partial dynamic structure factors as well as related correlation functions from molecular dynamics (MD) simulations.
|
|
5
5
|
By analyzing these functions one can access the dynamics of a system without resorting to perturbative approaches.
|
|
6
6
|
Moreover by combining in particular the structure factor with the cross sections (or form factors) of, e.g., neutrons, X-rays or electrons, one can predict experimental spectra.
|
|
7
|
-
The main input consists of a trajectory from
|
|
7
|
+
The main input consists of a trajectory from an MD simulation, i.e., a file containing snapshots of the particle coordinates and optionally velocities that correspond to consecutive, equally spaced points in simulation time.
|
|
8
8
|
|
|
9
|
-
**dynasor** provides both
|
|
9
|
+
**dynasor** provides both a Python interface and a command-line interface.
|
|
10
10
|
The following snippet illustrates how one can calculate dynamic structure factors using the former.
|
|
11
11
|
|
|
12
12
|
.. code-block:: python
|
|
13
13
|
|
|
14
|
+
from dynasor import Trajectory, compute_dynamic_structure_factors
|
|
15
|
+
from dynasor.qpoints import get_spherical_qpoints
|
|
16
|
+
|
|
14
17
|
traj = Trajectory('dump.xyz', trajectory_format='extxyz')
|
|
15
|
-
q_points =
|
|
18
|
+
q_points = get_spherical_qpoints(traj.cell, q_max=20)
|
|
16
19
|
sample = compute_dynamic_structure_factors(traj, q_points=q_points, dt=5, window_size=100)
|
|
17
|
-
sample.
|
|
20
|
+
sample.write_to_npz('test.npz')
|
|
18
21
|
|
|
19
22
|
**dynasor** can be installed via `pip <https://pypi.org/project/dynasor/>`_ or `conda <https://anaconda.org/conda-forge/dynasor>`_.
|
|
20
|
-
Please consult the `installation section of the user guide <https://dynasor.materialsmodeling.org/installation.html>`_ for details.
|
|
23
|
+
Please consult the `installation section of the user guide <https://dynasor.materialsmodeling.org/get_started/installation.html>`_ for details.
|
|
21
24
|
|
|
22
|
-
The full documentation can be found in the `user guide <
|
|
25
|
+
The full documentation can be found in the `user guide <https://dynasor.materialsmodeling.org/>`_.
|
|
23
26
|
For questions and help please use the `dynasor discussion forum on matsci.org <https://matsci.org/dynasor>`_.
|
|
24
27
|
**dynasor** and its development are hosted on `gitlab <https://gitlab.com/materials-modeling/dynasor>`_.
|
|
25
28
|
|
|
26
|
-
When using **dynasor** in your research please cite the following
|
|
29
|
+
When using **dynasor** in your research please cite the following papers:
|
|
27
30
|
|
|
28
31
|
| *Dynasor – A tool for extracting dynamical structure factors and current correlation functions from molecular dynamics simulations*
|
|
29
32
|
| Erik Fransson, Mattias Slabanja, Paul Erhart, and Göran Wahnström
|
|
30
33
|
| Advanced Theory and Simulations **4**, 2000240 (2021); DOI:`10.1002/adts.202000240 <https://doi.org/10.1002/adts.202000240>`_
|
|
34
|
+
|
|
35
|
+
| *Dynasor 2: From simulation to experiment through correlation functions*
|
|
36
|
+
| Esmée Berger, Erik Fransson, Fredrik Eriksson, Eric Lindgren, Göran Wahnström, Thomas Holm Rod, and Paul Erhart
|
|
37
|
+
| Computer Physics Communications **316**, 109759 (2025); DOI: `10.1016/j.cpc.2025.109759 <https://doi.org/10.1016/j.cpc.2025.109759>`_
|
|
@@ -15,8 +15,10 @@ from .qpoints import (
|
|
|
15
15
|
)
|
|
16
16
|
from .sample import read_sample_from_npz
|
|
17
17
|
from .trajectory import Trajectory
|
|
18
|
+
from .modes.mode_projector import ModeProjector
|
|
19
|
+
from .modes.project_modes import project_modes
|
|
18
20
|
|
|
19
|
-
__version__ = '2.
|
|
21
|
+
__version__ = '2.4'
|
|
20
22
|
__all__ = [
|
|
21
23
|
'compute_dynamic_structure_factors',
|
|
22
24
|
'compute_spectral_energy_density',
|
|
@@ -25,4 +27,6 @@ __all__ = [
|
|
|
25
27
|
'get_supercell_qpoints_along_path',
|
|
26
28
|
'read_sample_from_npz',
|
|
27
29
|
'Trajectory',
|
|
30
|
+
'ModeProjector',
|
|
31
|
+
'project_modes',
|
|
28
32
|
]
|
|
@@ -11,24 +11,35 @@ from dynasor.correlation_functions import compute_dynamic_structure_factors
|
|
|
11
11
|
from dynasor.post_processing import get_spherically_averaged_sample_binned
|
|
12
12
|
|
|
13
13
|
|
|
14
|
+
def _parse_q_direction(value):
|
|
15
|
+
message = 'q-direction must contain three comma-separated numbers'
|
|
16
|
+
try:
|
|
17
|
+
direction = np.asarray(value.split(','), dtype=float)
|
|
18
|
+
except ValueError as error:
|
|
19
|
+
raise argparse.ArgumentTypeError(message) from error
|
|
20
|
+
if direction.size != 3:
|
|
21
|
+
raise argparse.ArgumentTypeError(message)
|
|
22
|
+
return direction
|
|
23
|
+
|
|
24
|
+
|
|
14
25
|
def main():
|
|
15
26
|
|
|
16
27
|
parser = argparse.ArgumentParser(
|
|
17
28
|
description='dynasor is a simple tool for calculating total and partial dynamic structure'
|
|
18
29
|
' factors as well as current correlation functions from molecular dynamics simulations.'
|
|
19
|
-
' The main input consists of
|
|
30
|
+
' The main input consists of trajectory output from an MD simulation, i.e., a file'
|
|
20
31
|
' containing snapshots of the particle coordinates and optionally velocities that'
|
|
21
32
|
' correspond to consecutive, equally spaced points in (simulation) time.'
|
|
22
33
|
'\n'
|
|
23
34
|
' Dynasor has recently been updated. Some of the old options have new names and'
|
|
24
35
|
' some new options have been added. If your script has stopped working, check the'
|
|
25
36
|
' options with "dynasor --help". In addition, we would like to let you know that'
|
|
26
|
-
' dynasor now has a Python interface, which gives you
|
|
37
|
+
' dynasor now has a Python interface, which gives you access to more'
|
|
27
38
|
' functionality and options.')
|
|
28
39
|
|
|
29
40
|
iogroup = parser.add_argument_group(
|
|
30
41
|
'Input/output options',
|
|
31
|
-
'Options controlling input and output, files and
|
|
42
|
+
'Options controlling input and output, files and file formats.')
|
|
32
43
|
iogroup.add_argument(
|
|
33
44
|
'-f', '--trajectory', type=str, metavar='TRAJECTORY_FILE',
|
|
34
45
|
help='Molecular dynamics trajectory file to be analyzed.'
|
|
@@ -88,7 +99,7 @@ def main():
|
|
|
88
99
|
|
|
89
100
|
qline = parser.add_argument_group('Line-style q-space sampling')
|
|
90
101
|
qline.add_argument(
|
|
91
|
-
'--q-direction', metavar='QDIRECTION',
|
|
102
|
+
'--q-direction', metavar='QDIRECTION', type=_parse_q_direction,
|
|
92
103
|
help='Direction along which to sample. QPOINTS points will be evenly placed between'
|
|
93
104
|
' 0,0,0 and QDIRECTION. Given as three comma separated values.')
|
|
94
105
|
defval = 100
|
|
@@ -184,11 +195,11 @@ def main():
|
|
|
184
195
|
|
|
185
196
|
# setup q-points
|
|
186
197
|
if args.q_sampling == 'line':
|
|
187
|
-
q_dir =
|
|
198
|
+
q_dir = args.q_direction
|
|
188
199
|
n_qpoints = args.q_points
|
|
189
200
|
q_points = np.array([i * q_dir for i in np.linspace(0, 1, n_qpoints)])
|
|
190
201
|
elif args.q_sampling == 'isotropic':
|
|
191
|
-
q_points = get_spherical_qpoints(traj.cell, args.q_max, args.max_q_points)
|
|
202
|
+
q_points = get_spherical_qpoints(traj.cell, q_max=args.q_max, max_points=args.max_q_points)
|
|
192
203
|
|
|
193
204
|
# run dynasor calculation
|
|
194
205
|
sample = compute_dynamic_structure_factors(
|
|
@@ -20,29 +20,28 @@ import numba
|
|
|
20
20
|
# Calling this instead of manually inlining it actually incurs a small
|
|
21
21
|
# performance hit (<10%) with current numba (2023). It increases readability
|
|
22
22
|
# though and will probably sort itself out with later numba versions
|
|
23
|
-
@numba.njit(fastmath=True, nogil=True)
|
|
23
|
+
@numba.njit(fastmath=True, nogil=True) # pragma: no cover
|
|
24
24
|
def dot(a, b):
|
|
25
25
|
return a[0]*b[0] + a[1]*b[1] + a[2]*b[2]
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
# fastmath True makes the summation fast and also speeds up exponentiation
|
|
29
|
-
# nogil releases the
|
|
30
|
-
@numba.njit(fastmath=True, nogil=True)
|
|
29
|
+
# nogil releases the Python GIL, although it is probably not necessary here
|
|
30
|
+
@numba.njit(fastmath=True, nogil=True) # pragma: no cover
|
|
31
31
|
def rho_q_single(x: np.ndarray,
|
|
32
32
|
q: np.ndarray) -> complex:
|
|
33
|
-
"""Calculates the density at a single q-point
|
|
33
|
+
"""Calculates the density at a single q-point.
|
|
34
34
|
|
|
35
35
|
Parameters
|
|
36
36
|
----------
|
|
37
37
|
x
|
|
38
|
-
|
|
38
|
+
Positions as a `(N, 3)` array.
|
|
39
39
|
q
|
|
40
|
-
|
|
40
|
+
Single q point as a with shape `(3,)`.
|
|
41
41
|
|
|
42
42
|
Returns
|
|
43
43
|
-------
|
|
44
|
-
|
|
45
|
-
complex density at the specified q-point
|
|
44
|
+
Complex density at the specified q-point.
|
|
46
45
|
"""
|
|
47
46
|
Nx = len(x)
|
|
48
47
|
|
|
@@ -57,20 +56,20 @@ def rho_q_single(x: np.ndarray,
|
|
|
57
56
|
|
|
58
57
|
|
|
59
58
|
# parallel enables the numba.prange directive
|
|
60
|
-
@numba.njit(fastmath=True, nogil=True, parallel=True)
|
|
59
|
+
@numba.njit(fastmath=True, nogil=True, parallel=True) # pragma: no cover
|
|
61
60
|
def rho_q(x: np.ndarray, q: np.ndarray, rho: np.ndarray):
|
|
62
|
-
"""Calculates the fourier transformed density
|
|
61
|
+
"""Calculates the fourier transformed density.
|
|
63
62
|
|
|
64
63
|
The parallelization is over q-points. The density is calculated in-place.
|
|
65
64
|
|
|
66
65
|
Parameters
|
|
67
66
|
----------
|
|
68
67
|
x
|
|
69
|
-
|
|
68
|
+
The positions as a float array with shape `(Nx, 3)`.
|
|
70
69
|
q
|
|
71
|
-
|
|
70
|
+
The q-points as a float array with shape `(Nq, 3)`.
|
|
72
71
|
rho
|
|
73
|
-
|
|
72
|
+
Density as a complex array of length `Nq`.
|
|
74
73
|
"""
|
|
75
74
|
|
|
76
75
|
Nx = len(x)
|
|
@@ -85,7 +84,7 @@ def rho_q(x: np.ndarray, q: np.ndarray, rho: np.ndarray):
|
|
|
85
84
|
rho[i] = rho_q_single(x, q[i])
|
|
86
85
|
|
|
87
86
|
|
|
88
|
-
@numba.njit(fastmath=True, parallel=True, nogil=True)
|
|
87
|
+
@numba.njit(fastmath=True, parallel=True, nogil=True) # pragma: no cover
|
|
89
88
|
def rho_j_q(x: np.ndarray, v: np.ndarray, q: np.ndarray,
|
|
90
89
|
rho: np.ndarray, j_q: np.ndarray):
|
|
91
90
|
"""Calculates the fourier transformed density and current.
|
|
@@ -95,15 +94,15 @@ def rho_j_q(x: np.ndarray, v: np.ndarray, q: np.ndarray,
|
|
|
95
94
|
Parameters
|
|
96
95
|
----------
|
|
97
96
|
x
|
|
98
|
-
|
|
97
|
+
The positions as a float array with shape `(Nx, 3)`.
|
|
99
98
|
v
|
|
100
|
-
|
|
99
|
+
The velocities as a float array with shape `(Nx, 3)`.
|
|
101
100
|
q
|
|
102
|
-
|
|
101
|
+
The q-points as a float array with shape `(Nq, 3)`.
|
|
103
102
|
rho
|
|
104
|
-
|
|
103
|
+
Density as a complex array of length `Nq`.
|
|
105
104
|
j_q
|
|
106
|
-
|
|
105
|
+
Current as a complex array with shape `(Nq, 3)`.
|
|
107
106
|
"""
|
|
108
107
|
|
|
109
108
|
Nx = len(x)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
from numpy.typing import NDArray
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def truncate_nans(data):
|
|
6
|
+
"""
|
|
7
|
+
Truncate trailing time columns that contain NaN values.
|
|
8
|
+
|
|
9
|
+
The function assumes that the last axis of the array corresponds to
|
|
10
|
+
time and removes all columns from the first occurrence of a NaN
|
|
11
|
+
(in any row) to the end of the array.
|
|
12
|
+
|
|
13
|
+
This guarantees that the returned array contains **no NaN values**,
|
|
14
|
+
even if this means discarding some valid data points that appear
|
|
15
|
+
after a NaN in another row.
|
|
16
|
+
|
|
17
|
+
Parameters
|
|
18
|
+
----------
|
|
19
|
+
data : array_like, shape (N, T)
|
|
20
|
+
Input array where rows represent independent signals (e.g. q-points)
|
|
21
|
+
and the last axis represents time.
|
|
22
|
+
|
|
23
|
+
Returns
|
|
24
|
+
-------
|
|
25
|
+
ndarray
|
|
26
|
+
Array truncated along the time axis such that no NaN values remain.
|
|
27
|
+
The returned array has the same number of rows as the input but may
|
|
28
|
+
have fewer time columns.
|
|
29
|
+
|
|
30
|
+
Notes
|
|
31
|
+
-----
|
|
32
|
+
Example::
|
|
33
|
+
|
|
34
|
+
[[1.0, 0.8, 0.7, 0.6, 0.5, 0.3, nan],
|
|
35
|
+
[1.0, 0.8, 0.7, 0.6, 0.5, nan, nan]]
|
|
36
|
+
|
|
37
|
+
becomes::
|
|
38
|
+
|
|
39
|
+
[[1.0, 0.8, 0.7, 0.6, 0.5],
|
|
40
|
+
[1.0, 0.8, 0.7, 0.6, 0.5]]
|
|
41
|
+
|
|
42
|
+
because the first NaN appears in column 5.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
arr = np.asarray(data)
|
|
46
|
+
assert arr.ndim == 2
|
|
47
|
+
|
|
48
|
+
# Determine which time columns contain any NaN values
|
|
49
|
+
column_has_nan = np.any(np.isnan(arr), axis=0)
|
|
50
|
+
|
|
51
|
+
# Find the first column containing a NaN
|
|
52
|
+
nan_indices = np.where(column_has_nan)[0]
|
|
53
|
+
|
|
54
|
+
# No NaNs present, return array unchanged
|
|
55
|
+
if len(nan_indices) == 0:
|
|
56
|
+
return arr
|
|
57
|
+
|
|
58
|
+
# NaNs were found, Keep only the column without NaNs
|
|
59
|
+
first_nan_column = nan_indices[0]
|
|
60
|
+
return arr[:, :first_nan_column]
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
class TimeAverager:
|
|
64
|
+
"""Naive special purpose averager class used in dynasor to collect and time-average arrays
|
|
65
|
+
obtained from sliding time-window averaging.
|
|
66
|
+
|
|
67
|
+
It assists with keeping track of how many data samples have been added to each slot.
|
|
68
|
+
|
|
69
|
+
It will time-average arrays of shape ``(Nq, time_window)`` where ``Ǹq`` is the
|
|
70
|
+
number of q-points and ``time_window`` is the size of the time window.
|
|
71
|
+
|
|
72
|
+
Parameters
|
|
73
|
+
----------
|
|
74
|
+
time_window
|
|
75
|
+
Size of the time window in which the time-average happens.
|
|
76
|
+
array_length
|
|
77
|
+
Length of the array to be averaged for each time-lag, i.e., number of q-points.
|
|
78
|
+
"""
|
|
79
|
+
|
|
80
|
+
def __init__(self, time_window: int, array_length: int):
|
|
81
|
+
assert time_window >= 1
|
|
82
|
+
self._time_window = time_window
|
|
83
|
+
self._array_length = array_length
|
|
84
|
+
|
|
85
|
+
self._counts = np.zeros(time_window, dtype=int)
|
|
86
|
+
self._arrays = [np.zeros(array_length) for _ in range(time_window)]
|
|
87
|
+
|
|
88
|
+
def add_sample(self, time_lag: int, sample: np.ndarray):
|
|
89
|
+
assert len(sample) == self._array_length
|
|
90
|
+
self._counts[time_lag] += 1
|
|
91
|
+
self._arrays[time_lag] += sample
|
|
92
|
+
|
|
93
|
+
def get_average_at_timelag(self, time_lag: int):
|
|
94
|
+
if self._counts[time_lag] == 0:
|
|
95
|
+
array = np.full((self._array_length, ), np.nan)
|
|
96
|
+
return array
|
|
97
|
+
return self._arrays[time_lag] / self._counts[time_lag]
|
|
98
|
+
|
|
99
|
+
def get_average_all(self) -> NDArray[float]:
|
|
100
|
+
"""
|
|
101
|
+
Returns an averaged array of shape ``(array_length, time_window)``.
|
|
102
|
+
"""
|
|
103
|
+
return np.array([self.get_average_at_timelag(t) for t in range(self._time_window)]).T
|