1b_BNE_plot.py — Plot BNE Growth Rate

Reads the HDF5 entropy files written by 1a_BNE_workflow.py, obtains BNE as a function of LAE size, and computes the growth-rate normalisation within the window [config.N_START, config.N_STOP]. Produces plots of BNE vs LAE size and the normalised growth rate.

Run after 1a_BNE_workflow.py.

cd workflows
python 1b_BNE_plot.py
 1import sys
 2import pathlib
 3sys.path.insert(0, str(pathlib.Path(__file__).parent))
 4
 5import h5py
 6import numpy as np
 7import matplotlib
 8import matplotlib.pyplot as plt
 9from ase.io import read
10from scipy.interpolate import interp1d
11
12from tqdm import tqdm
13
14from smooth_disorder.vis.interactive import *
15
16from config import BNE_WORK_DIR, BNE_FOLDER, STRUCTURE_IDX, LOCAL_ENVIRONMENT_NAT, N_START, N_STOP
17
18
19BNE_data_directory = f"{BNE_WORK_DIR}/{BNE_FOLDER}"
20
21
22BNE_data = {}
23
24structure_idx = STRUCTURE_IDX
25
26temp_BNE = []
27temp_nat = []
28for LE_nat in LOCAL_ENVIRONMENT_NAT:
29    with h5py.File(f"{BNE_data_directory}/structure_{structure_idx}/entropy_number_{LE_nat}.hdf5", "r") as f:
30        temp_BNE.append(np.asarray(f['entropy'])[0])
31        temp_nat.append(np.asarray(f['number_of_atoms'])[0])
32
33temp_BNE, temp_nat = np.array(temp_BNE), np.array(temp_nat)
34
35BNE_data[f"{structure_idx}_BNE"] = temp_BNE
36BNE_data[f"{structure_idx}_nat"] = temp_nat
37
38
39
40
41n_start, n_stop = N_START, N_STOP
42
43def normalised_BNE(n_atoms, entropy, n_start=n_start, n_stop=n_stop):
44    """
45    Estimate the BNE growth rate by averaging BNE(n)/n over [n_start, n_stop].
46
47    Returns
48    -------
49    BNE_mean : float
50        Mean BNE(n)/n in nats per atom — the growth rate estimate.
51    BNE_std : float
52        Standard deviation of BNE(n)/n over the window.
53    """
54    idx_start = np.arange(0, len(n_atoms), 1)[n_atoms == n_start][-1]
55    idx_stop  = np.arange(0, len(n_atoms), 1)[n_atoms == n_stop][0]
56
57    local_n_atoms  = n_atoms[idx_start:idx_stop+1]
58    local_quotient = entropy[idx_start:idx_stop+1] / local_n_atoms
59
60    BNE_mean = np.mean(local_quotient)
61    BNE_std  = np.std(local_quotient, ddof=1)
62
63    return BNE_mean, BNE_std
64
65
66
67structure_idx = 0
68nat  = BNE_data[f"{structure_idx}_nat"]
69bne  = BNE_data[f"{structure_idx}_BNE"]
70
71
72bne_mean, bne_std = normalised_BNE(nat, bne)
73print(f"Growth rate (BNE/n averaged over n={n_start}{n_stop}): {bne_mean:.4f} ± {bne_std:.4f} nats/atom")
74
75
76plt.figure(figsize=(16, 8))
77plt.plot(nat, bne, color=Colors[0], label="BNE (disordered system)")
78plt.ylabel("BNE (nats)")
79plt.xlabel("LAE size $n$ (number of atoms)")
80
81plt.text(15, 2.3, f"Growth rate: {bne_mean:.4f} ± {bne_std:.4f}", fontsize=14)
82
83plt.xlim([0, 40])
84plt.legend()
85plt.title("BNE vs local environment size")
86plt.savefig(f"{BNE_data_directory}/structure_{structure_idx}/bne_growth.png", dpi=300)
87