Skip to content

Commit 2ded2f6

Browse files
committed
parallelised spin-wave calculation with a ProcessPoolExecutor
1 parent 3ecded8 commit 2ded2f6

File tree

1 file changed

+29
-15
lines changed

1 file changed

+29
-15
lines changed

pyspinw/calculations/spinwave.py

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
"""Spinwave Calculations"""
22

3+
from concurrent.futures import as_completed, ProcessPoolExecutor
34
from dataclasses import dataclass
45
from enum import Enum
56

@@ -58,8 +59,8 @@ def spinwave_calculation(rotations: np.ndarray,
5859
root_mags = np.sqrt(0.5*magnitudes) # S_i / sqrt(2)
5960
spin_coefficients = root_mags.reshape(-1, 1) * root_mags.reshape(1, -1)
6061

61-
energies = []
62-
methods = []
62+
energies = {}
63+
methods = {}
6364

6465
# calculate the C matrix for h(q), which is q-independent
6566
C = np.zeros((n_sites, n_sites), dtype=complex)
@@ -70,24 +71,37 @@ def spinwave_calculation(rotations: np.ndarray,
7071

7172
C *= 2
7273

73-
for q in q_vectors:
74-
eigenvalues, method = spinwave_calculation_single_q(q, C, n_sites, z, z_conj, spin_coefficients, couplings)
75-
energies.append(eigenvalues) # These are currently the square energies
76-
methods.append(method)
74+
# we index the single-q calculations so that we can create a dictionary of which order the energies are in
75+
# and can sort them later: we use q_index as the key because the q-vectors themselves are not hashable
76+
with ProcessPoolExecutor() as executor:
77+
q_calculations = {executor.submit(_calc_single_q, q, C, n_sites, z, z_conj, spin_coefficients, couplings)
78+
: q_index for q_index, q in enumerate(q_vectors)}
79+
for future in as_completed(q_calculations):
80+
q_index = q_calculations[future]
81+
try:
82+
eigenvalues, method = future.result()
83+
except Exception as err:
84+
raise err
85+
else:
86+
energies[q_index] = eigenvalues
87+
methods[q_index] = method
88+
89+
sorted_energies = [energies[i] for i in range(q_vectors.shape[0])]
90+
sorted_methods = [methods[i] for i in range(q_vectors.shape[0])]
7791

7892
return SpinwaveResult(
7993
q_vectors=q_vectors,
80-
raw_energies=energies,
81-
method=methods)
94+
raw_energies=sorted_energies,
95+
method=sorted_methods)
8296

8397

84-
def spinwave_calculation_single_q(q: float,
85-
C: np.ndarray,
86-
n_sites: int,
87-
z: np.ndarray,
88-
z_conj: np.ndarray,
89-
spin_coefficients: np.ndarray,
90-
couplings: list[Coupling]):
98+
def _calc_single_q(q: float,
99+
C: np.ndarray,
100+
n_sites: int,
101+
z: np.ndarray,
102+
z_conj: np.ndarray,
103+
spin_coefficients: np.ndarray,
104+
couplings: list[Coupling]):
91105
"""Calculate the energies for the 'Hamiltonian' h(q) for a single q-value."""
92106
A = np.zeros((n_sites, n_sites), dtype=complex)
93107
B = np.zeros((n_sites, n_sites), dtype=complex)

0 commit comments

Comments
 (0)