Skip to content

Commit 89fa13e

Browse files
committed
#476 Memory optimization using OVITO pipeline for lindemann index per frame
1 parent 5601d99 commit 89fa13e

File tree

2 files changed

+53
-2
lines changed

2 files changed

+53
-2
lines changed

lindemann/index/mem_use.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ def in_gb(nframes: int, natoms: int) -> str:
3131
f"\nFlag -t (per_trj) will use {np.round((trj+num_distances*2*float_size)/1024**3,4)} GB\n"
3232
)
3333
online_per_trj = (
34-
f"\nFlag -ot (per_trj) will use {np.round((num_distances*2*float_size)/1024**3,4)} GB\n"
34+
f"Flag -ot (per_trj) will use {np.round((num_distances*2*float_size)/1024**3,4)} GB\n"
3535
)
3636
per_frames = f"Flag -f (per_frames) will use {np.round((trj+(num_distances*2*float_size)+(nframes*float_size))/1024**3,4)} GB\n"
37+
online_per_frames = f"Flag -of (per_frames) will use {np.round(((num_distances*2*float_size)+(nframes*float_size))/1024**3,4)} GB\n"
3738
per_atoms = f"Flag -a (per_atoms) will use {np.round(sum_bytes/1024**3,4)} GB"
38-
return f"{per_trj}{online_per_trj}{per_frames}{per_atoms}"
39+
return f"{per_trj}{online_per_trj}{per_frames}{online_per_frames}{per_atoms}"

lindemann/index/online_frames.py

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
from typing import Optional
2+
3+
import numba as nb
4+
import numpy as np
5+
from ovito.data import DataCollection
6+
from ovito.pipeline import Pipeline
7+
8+
import lindemann
9+
from lindemann.trajectory import read
10+
11+
12+
@nb.njit(fastmath=True, parallel=False)
13+
def calculate_frame(positions, mean_distances, m2_distances, frame: int, num_atoms: int):
14+
15+
index = 0
16+
frame_count = frame + 1
17+
for i in range(num_atoms):
18+
for j in range(i + 1, num_atoms):
19+
dist = 0.0
20+
for k in range(3):
21+
dist += (positions[i, k] - positions[j, k]) ** 2
22+
23+
dist = np.sqrt(dist)
24+
delta = dist - mean_distances[index]
25+
mean_distances[index] += delta / frame_count
26+
delta2 = dist - mean_distances[index]
27+
m2_distances[index] += delta * delta2
28+
29+
index += 1
30+
return np.mean(np.sqrt(m2_distances / frame_count) / mean_distances)
31+
32+
33+
def calculate(pipeline: Pipeline, data: DataCollection, nframes: Optional[int] = None):
34+
num_particle = data.particles.count
35+
num_frame = pipeline.source.num_frames
36+
if nframes is None:
37+
nframes = num_frame
38+
elif nframes > num_frame:
39+
raise ValueError(f"Requested {nframes} frames, but only {num_frame} frames are available.")
40+
41+
num_distances = num_particle * (num_particle - 1) // 2
42+
mean_distances = np.zeros(num_distances, dtype=np.float32)
43+
m2_distances = np.zeros(num_distances, dtype=np.float32)
44+
lindemann_index_array = np.zeros(nframes, dtype=np.float32)
45+
for frame in range(nframes):
46+
data = pipeline.compute(frame)
47+
lindemann_index_array[frame] = calculate_frame(
48+
data.particles["Position"].array, mean_distances, m2_distances, frame, num_particle
49+
)
50+
return lindemann_index_array

0 commit comments

Comments
 (0)