Question about partial current correlations for 2D GaN monolayer in Dynasor

Dear Dynasor developers,

I’m using Dynasor to analyze LAMMPS MD trajectories of a 2D GaN monolayer and I’d appreciate your advice on whether I’m setting up the calculations correctly.

My setup is: (a) System: 2D GaN monolayer with vacuum in the out-of-plane direction, (b) T = 300 K, (c) Trajectory: 10000 frames from a NVE run, (d) Atoms: 12800 in total, 6400 Ga and 6400 N-atoms, and (e) Input to Dynasor: LAMMPS dump file with the full trajectory.

My goal is to obtain: (a) Phonon-like dispersions S(q,w) along a high-symmetry in-plane path (Gamma-M-K-Gamma) for the 2D Brillouin zone and (b) Partial current correlations and dynamical structure factors resolved into Ga-Ga, Ga-N, and N-N contributions.

I construct the q-path using the simulation cell, and I try to separate Ga and N using atomic_indices so that I can access the fields Sqw_Ga_Ga, Sqw_Ga_N, Sqw_N_N, Sqw_total, Clqw_Ga-Ga, Clqw_Ga-N, Clqw_N-N, Clqw_total, Ctqw_Ga-Ga, Ctqw_Ga-N, Ctqw_N-N, Ctqw_total, etc. I then generate the partial current correlations maps.

However, I’m unsure whether the resulting partial currents are physically meaningful.

I’m attaching: (a) The Python code used to compute the dynamical structure factors and current correlations and (b) The resulting plots are at 300 K, including the Ga-Ga, Ga-N, and N-N partial current correlations.

Could you please let me know: (a) Whether my general approach is correct for a 2D monolayer treated as a 3D cell with vacuum and (b) Any obvious issues you can spot in the attached code or plots that might explain suspicious features in the partial current correlations.

Any guidance or example scripts for a binary 2D system (similar to GaN) would be extremely helpful. I’d also be happy to provide the trajectory if that would assist in diagnosing the problem.

Thank you very much for your time and for developing Dynasor. Looking forward to hearing from you.

Best Regards
Bishwajit Debnath
Research Scholar
Dept. of Chemistry
School of Physical Sciences
Sikkim University, Gangtok
India-737102
Email- [email protected]

"import numpy as np
from ase.io import read
from matplotlib import pyplot as plt

from dynasor import compute_dynamic_structure_factors, Trajectory
from dynasor.units import radians_per_fs_to_meV

------------------ Load trajectory ------------------

traj = Trajectory(‘gan_dump.lammpstrj’,
trajectory_format=‘lammps_internal’,
length_unit=‘Angstrom’,
time_unit=‘fs’,
frame_step=1,
frame_stop=10000)
print(traj)

Just to see the real cell

structure = read(‘gan_dump.lammpstrj’, index=0, format=‘lammps-dump-text’)
print(“Real cell dimensions:”, structure.cell.diagonal())

------------------ Species mapping Ga / N ------------------

n_atoms = traj.n_atoms
n_ga = n_atoms // 2
atomic_indices = {
‘Ga’: list(range(n_ga)),
‘N’: list(range(n_ga, n_atoms))
}
print(“Ga atoms:”, len(atomic_indices[‘Ga’]))
print(“N atoms:”, len(atomic_indices[‘N’]))

Reload trajectory with species separation

traj = Trajectory(‘gan_dump.lammpstrj’,
trajectory_format=‘lammps_internal’,
atomic_indices=atomic_indices,
length_unit=‘Angstrom’,
time_unit=‘fs’,
frame_step=1,
frame_stop=10000)
print(traj)

------------------ q-path Γ–M–K–Γ in ABSOLUTE q (rad/Å) ------------------

Simulation cell (Å)

A = np.array(traj.cell) # shape (3,3)

Reciprocal lattice (rad/Å), columns are b1,b2,b3

B = 2.0 * np.pi * np.linalg.inv(A).T # dynasor expects 2π included

High-symmetry points in reduced (fractional) coordinates

Gamma_frac = np.array([0.0, 0.0, 0.0])
M_frac = np.array([0.5, 0.0, 0.0])
K_frac = np.array([1/3., 1/3., 0.0])

Convert to absolute Cartesian q: q_abs = B @ q_frac (rad/Å)

Gamma_q = B @ Gamma_frac
M_q = B @ M_frac
K_q = B @ K_frac

def segment(q_start, q_end, npts):
return np.linspace(q_start, q_end, npts, endpoint=False)

n_points_per_segment = 50
q_GM = segment(Gamma_q, M_q, n_points_per_segment)
q_MK = segment(M_q, K_q, n_points_per_segment)
q_KG = segment(K_q, Gamma_q, n_points_per_segment)

q_points = np.vstack([q_GM, q_MK, q_KG]) # (150, 3)

enforce in-plane qz = 0 (monolayer)

q_points[:, 2] = 0.0

print(f"Generated {len(q_points)} ABSOLUTE q-points along Γ–M–K–Γ path")

------------------ Dynamic structure factors ------------------

sample = compute_dynamic_structure_factors(traj, q_points,
dt=1.0,
window_size=2000,
window_step=100,
calculate_currents=True)
sample.omega *= radians_per_fs_to_meV
print(sample)

------------------ q-distance along path ------------------

cumulative distance along the ABSOLUTE q-points

dq = np.linalg.norm(np.diff(q_points, axis=0), axis=1)
q_distances = np.concatenate([[0.0], np.cumsum(dq)]) # len = len(q_points)

idx_G = 0
idx_M = n_points_per_segment
idx_K = 2 * n_points_per_segment
idx_G2 = len(q_points) - 1

q_labels_pos = [idx_G, idx_M, idx_K, idx_G2]
q_labels = [‘Γ’, ‘M’, ‘K’, ‘Γ’]

------------------ Plot 1: S(q,ω) and C_L - C_T ------------------

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True, dpi=150)

S(q,ω)

im1 = ax1.pcolormesh(q_distances, sample.omega, sample.Sqw_coh.T,
cmap=‘Reds’, vmin=0, vmax=8)
ax1.text(0.02, 0.98, r’S(\mathbf{q}, \omega) - GaN 300K’,
transform=ax1.transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
ax1.set_ylabel(‘Energy (meV)’)
ax1.set_ylim(0, 60)

C_L - C_T

m_lt = 0.1 * np.max(np.abs(sample.Clqw.T - sample.Ctqw.T))
im2 = ax2.pcolormesh(q_distances, sample.omega,
sample.Clqw.T - sample.Ctqw.T,
cmap=‘seismic’, vmin=-m_lt, vmax=m_lt)
ax2.text(0.02, 0.98, r’C_L - C_T(\mathbf{q}, \omega)‘,
transform=ax2.transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
ax2.set_ylabel(‘Energy (meV)’)
ax2.set_xlabel(r’q-path Γ–M–K–Γ’)
ax2.set_ylim(0, 60)

for ax in [ax1, ax2]:
for pos in q_labels_pos:
ax.axvline(q_distances[pos], c=‘white’, lw=2, alpha=0.8)

ax2.set_xticks([q_distances[i] for i in q_labels_pos])
ax2.set_xticklabels(q_labels)

plt.tight_layout()
plt.savefig(‘GaN_Sqw_Clt.png’, dpi=300, bbox_inches=‘tight’)
plt.show()

------------------ Plot 2: Ga–Ga, Ga–N, N–N currents ------------------

fig, axes = plt.subplots(3, 1, figsize=(12, 12), sharex=True, dpi=150)

Ga–Ga

m_gg = 0.1 * np.max(np.abs(sample.Clqw_Ga_Ga.T + sample.Ctqw_Ga_Ga.T))
axes[0].pcolormesh(q_distances, sample.omega,
sample.Clqw_Ga_Ga.T + sample.Ctqw_Ga_Ga.T,
cmap=‘seismic’, vmin=-m_gg, vmax=m_gg)
axes[0].text(0.02, 0.98, r’C_{GaGa}^{tot}(\mathbf{q}, \omega)',
transform=axes[0].transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
axes[0].set_ylabel(‘Energy (meV)’)
axes[0].set_ylim(0, 60)

Ga–N

m_gn = 0.1 * np.max(np.abs(sample.Clqw_Ga_N.T + sample.Ctqw_Ga_N.T))
axes[1].pcolormesh(q_distances, sample.omega,
sample.Clqw_Ga_N.T + sample.Ctqw_Ga_N.T,
cmap=‘seismic’, vmin=-m_gn, vmax=m_gn)
axes[1].text(0.02, 0.98, r’C_{GaN}^{cross}(\mathbf{q}, \omega)',
transform=axes[1].transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
axes[1].set_ylabel(‘Energy (meV)’)
axes[1].set_ylim(0, 60)

N–N

m_nn = 0.1 * np.max(np.abs(sample.Clqw_N_N.T + sample.Ctqw_N_N.T))
axes[2].pcolormesh(q_distances, sample.omega,
sample.Clqw_N_N.T + sample.Ctqw_N_N.T,
cmap=‘seismic’, vmin=-m_nn, vmax=m_nn)
axes[2].text(0.02, 0.98, r’C_{NN}^{tot}(\mathbf{q}, \omega)‘,
transform=axes[2].transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
axes[2].set_ylabel(‘Energy (meV)’)
axes[2].set_xlabel(r’q-path Γ–M–K–Γ’)
axes[2].set_ylim(0, 60)

for ax in axes:
for pos in q_labels_pos:
ax.axvline(q_distances[pos], c=‘white’, lw=2, alpha=0.8)

axes[2].set_xticks([q_distances[i] for i in q_labels_pos])
axes[2].set_xticklabels(q_labels)

plt.tight_layout()
plt.savefig(‘GaN_partial_currents.png’, dpi=300, bbox_inches=‘tight’)
plt.show()

print(“GaN phonon dispersion ALONG Γ–M–K–Γ PATH COMPLETE!”)
print(f"Supercell: {traj.cell.diagonal()}“)
print(f"Ga: {len(atomic_indices[‘Ga’])} atoms, N: {len(atomic_indices[‘N’])} atoms”)"

I dont see the plots of ur correlation functions so its hard to tell if they are reasonable or not.

You are generating qpts yourself along the high symmetry path with 50 points in between.
This will lead to your qpts not being commensurate with your supercell and means the results will be quite strange/odd unphysical and or useless.
Instead generate your qpts with this function dynasor.qpoints.get_supercell_qpoints_along_path

Else I think code should work fine.

Addtionally, if you are interested in phonon dispersions from MD, I would recommend using SED over current correlations and Sqw as its a bit simpler and faster to compute, but either works.

Dear erikfransson,
Thank you for your attention and response.



These are the plots, I got using the python code I uploaded.
Then, I tried what you suggested about letting dynasor generate the qpts through the function dynasor.qpoints.get_supercell_qpoints_along_path, but it gave me the followig error and didn’t produce any plots:
“INFO 2025-12-05 15:26:14: Trajectory file: gan_dump.lammpstrj
INFO 2025-12-05 15:26:14: Total number of particles: 12800
INFO 2025-12-05 15:26:14: Number of atom types: 1
INFO 2025-12-05 15:26:14: Number of atoms of type X: 12800
INFO 2025-12-05 15:26:14: Simulation cell (in Angstrom):
[[127.90653126 0. 0. ]
[ 0. 221.40111885 0. ]
[ 0. 0. 200. ]]
Trajectory
filename : gan_dump.lammpstrj
natoms : 12800
frame_start : 0
frame_stop : 10000
frame_step : 1
frame_index : 0
cell : [[127.90653126 0. 0. ]
[ 0. 221.40111885 0. ]
[ 0. 0. 200.]]
Real cell dimensions: [127.90653126 221.40111885 200. ]
Ga atoms: 6400
N atoms: 6400
INFO 2025-12-05 15:39:11: Trajectory file: gan_dump.lammpstrj
INFO 2025-12-05 15:39:11: Total number of particles: 12800
INFO 2025-12-05 15:39:11: Number of atom types: 2
INFO 2025-12-05 15:39:11: Number of atoms of type Ga: 6400
INFO 2025-12-05 15:39:11: Number of atoms of type N: 6400
INFO 2025-12-05 15:39:11: Simulation cell (in Angstrom):
[[127.90653126 0. 0. ]
[ 0. 221.40111885 0. ]
[ 0. 0. 200. ]]
Trajectory
filename : gan_dump.lammpstrj
natoms : 12800
frame_start : 0
frame_stop : 10000
frame_step : 1
frame_index : 0
cell : [[127.90653126 0. 0. ]
[ 0. 221.40111885 0. ]
[ 0. 0. 200.]]
/home/laser_lab/.local/lib/python3.10/site-packages/dynasor/qpoints/lattice.py:133: UserWarning: No q-points along path!
warnings.warn(‘No q-points along path!’)
Generated 2 commensurate q‑points along Γ–M–K–Γ path
INFO 2025-12-05 15:39:11: Spacing between samples (frame_step): 1
INFO 2025-12-05 15:39:11: Time between consecutive frames in input trajectory (dt): 1.0 fs
INFO 2025-12-05 15:39:11: Time between consecutive frames used (dt * frame_step): 1.0 fs
INFO 2025-12-05 15:39:11: Time window size (dt * frame_step * window_size): 2000.0 fs
INFO 2025-12-05 15:39:11: Angular frequency resolution: dw = 0.001571 rad/fs = 1.034 meV
INFO 2025-12-05 15:39:11: Maximum angular frequency (dw * window_size): 3.141593 rad/fs = 2067.834 meV
INFO 2025-12-05 15:39:11: Nyquist angular frequency (2pi / frame_step / dt / 2): 3.141593 rad/fs = 2067.834 meV
INFO 2025-12-05 15:39:11: Calculating current (velocity) correlations
INFO 2025-12-05 15:39:11: Number of q-points: 2
INFO 2025-12-05 15:43:43: Processing window 0 to 2000
INFO 2025-12-05 15:46:00: Processing window 1000 to 3000
INFO 2025-12-05 15:48:18: Processing window 2000 to 4000
INFO 2025-12-05 15:50:34: Processing window 3000 to 5000
INFO 2025-12-05 15:52:50: Processing window 4000 to 6000
INFO 2025-12-05 15:54:39: Processing window 5000 to 7000
INFO 2025-12-05 15:56:04: Processing window 6000 to 8000
INFO 2025-12-05 15:57:25: Processing window 7000 to 9000
INFO 2025-12-05 15:58:39: Processing window 8000 to 9999
INFO 2025-12-05 15:58:41: Processing window 9000 to 9999
DynamicSample
Angular frequency resolution: 0.0015707963267948967
Atom types: [‘Ga’, ‘N’]
Cell: [[127.90653126 0. 0. ]
[ 0. 221.40111885 0. ]
[ 0. 0. 200. ]]
maximum_angular_frequency: 3.141592653589793
Maximum time lag: 2000.0
Number of frames: 10000
pairs: [(‘Ga’, ‘Ga’), (‘Ga’, ‘N’), (‘N’, ‘N’)]
Particle counts: {‘Ga’: 6400, ‘N’: 6400}
Time between frames: 1.0
omega with shape: (2001,)
q_points with shape: (2, 3)
time with shape: (2001,)
Clqt with shape: (2, 2001)
Clqt_Ga_Ga with shape: (2, 2001)
Clqt_Ga_N with shape: (2, 2001)
Clqt_N_N with shape: (2, 2001)
Clqw with shape: (2, 2001)
Clqw_Ga_Ga with shape: (2, 2001)
Clqw_Ga_N with shape: (2, 2001)
Clqw_N_N with shape: (2, 2001)
Ctqt with shape: (2, 2001)
Ctqt_Ga_Ga with shape: (2, 2001)
Ctqt_Ga_N with shape: (2, 2001)
Ctqt_N_N with shape: (2, 2001)
Ctqw with shape: (2, 2001)
Ctqw_Ga_Ga with shape: (2, 2001)
Ctqw_Ga_N with shape: (2, 2001)
Ctqw_N_N with shape: (2, 2001)
Fqt_coh with shape: (2, 2001)
Fqt_coh_Ga_Ga with shape: (2, 2001)
Fqt_coh_Ga_N with shape: (2, 2001)
Fqt_coh_N_N with shape: (2, 2001)
Sqw_coh with shape: (2, 2001)
Sqw_coh_Ga_Ga with shape: (2, 2001)
Sqw_coh_Ga_N with shape: (2, 2001)
Sqw_coh_N_N with shape: (2, 2001)
Traceback (most recent call last):
File “/media/laser_lab/com-lab1/gan-melting/10Kps-1-inter/dynamic_sf/test-bishwa/500K/test-dynamic-1.py”, line 119, in
ax1.pcolormesh(q_distances, sample.omega, sample.Sqw_coh.T,
File “/home/laser_lab/.local/lib/python3.10/site-packages/matplotlib/init.py”, line 1524, in inner
return func(
File “/home/laser_lab/.local/lib/python3.10/site-packages/matplotlib/axes/_axes.py”, line 6528, in pcolormesh
X, Y, C, shading = self._pcolorargs(‘pcolormesh’, *args,
File “/home/laser_lab/.local/lib/python3.10/site-packages/matplotlib/axes/_axes.py”, line 6060, in _pcolorargs
raise TypeError(f"Dimensions of C {C.shape} should”
TypeError: Dimensions of C (2001, 2) should be one smaller than X(3) and Y(2001) while using shading=‘flat’ see help(pcolormesh)
".
Following is the modified python code as per your suggestion:
"import numpy as np
from ase.io import read
from matplotlib import pyplot as plt

from dynasor import compute_dynamic_structure_factors, Trajectory
from dynasor.qpoints import get_supercell_qpoints_along_path
from dynasor.units import radians_per_fs_to_meV

------------------ Load trajectory ------------------

traj = Trajectory(
‘gan_dump.lammpstrj’,
trajectory_format=‘lammps_internal’,
length_unit=‘Angstrom’,
time_unit=‘fs’,
frame_step=1,
frame_stop=10000)
print(traj)

Just to see the real cell

structure = read(‘gan_dump.lammpstrj’, index=0, format=‘lammps-dump-text’)
print(“Real cell dimensions:”, structure.cell.diagonal())

------------------ Species mapping Ga / N ------------------

n_atoms = traj.n_atoms
n_ga = n_atoms // 2
atomic_indices = {
‘Ga’: list(range(n_ga)),
‘N’: list(range(n_ga, n_atoms))
}
print(“Ga atoms:”, len(atomic_indices[‘Ga’]))
print(“N atoms:”, len(atomic_indices[‘N’]))

Reload trajectory with species separation

traj = Trajectory(
‘gan_dump.lammpstrj’,
trajectory_format=‘lammps_internal’,
atomic_indices=atomic_indices,
length_unit=‘Angstrom’,
time_unit=‘fs’,
frame_step=1,
frame_stop=10000)
print(traj)

------------------ Define 2D hexagonal path ------------------

Fractional coordinates of high‑symmetry points in primitive cell

point_coordinates = {
‘GAMMA’: np.array([0.0, 0.0, 0.0]),
‘M’: np.array([0.5, 0.0, 0.0]),
‘K’: np.array([1/3., 1/3., 0.0]),
}

Path as list of tuples of labels

path = [(‘GAMMA’, ‘M’),
(‘M’, ‘K’),
(‘K’, ‘GAMMA’)]

Primitive cell of 2D GaN.

If your MD cell is an n×m supercell of a primitive hexagonal cell,

set prim_cell to that primitive cell (here: approximate from traj.cell).

For a simple n×n in‑plane repetition, you can do:

repeats_x = 1
repeats_y = 1
repeats_z = 1
prim_cell = np.array(traj.cell) / [repeats_x, repeats_y, repeats_z]

------------------ Commensurate q‑points from Dynasor ------------------

q_segments = get_supercell_qpoints_along_path(
path,
point_coordinates,
prim_cell,
traj.cell)

Stack all segments

q_points = np.vstack(q_segments) # shape (Nq, 3)

Enforce 2D: project to in‑plane qz = 0

q_points[:, 2] = 0.0

print(f"Generated {len(q_points)} commensurate q‑points along Γ–M–K–Γ path")

------------------ Dynamic structure factors ------------------

sample = compute_dynamic_structure_factors(
traj,
q_points,
dt=1.0,
window_size=2000,
window_step=100,
calculate_currents=True)
sample.omega *= radians_per_fs_to_meV
print(sample)

------------------ q‑distance along path ------------------

q_distances =
q_label_positions = {}
qr = 0.0

for iseg, q_seg in enumerate(q_segments):
# starting point of segment
q_distances.append(qr)
start_label = path[iseg][0]
q_label_positions[qr] = start_label

# accumulate along the segment
for qi, qj in zip(q_seg[1:], q_seg[:-1]):
    qr += np.linalg.norm(qi - qj)
    q_distances.append(qr)

ensure final point label (last of last segment)

end_label = path[-1][1]
q_label_positions[qr] = end_label

q_distances = np.array(q_distances)
q_labels_pos = sorted(q_label_positions.keys())
q_labels = [q_label_positions for x in q_labels_pos]

------------------ Plot 1: S(q,ω) and C_L − C_T ------------------

fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8), sharex=True, dpi=150)

S(q,ω)

ax1.pcolormesh(q_distances, sample.omega, sample.Sqw_coh.T,
cmap=‘Reds’, vmin=0, vmax=8)
ax1.text(0.02, 0.98, r’S(\mathbf{q}, \omega) - GaN 500 K’,
transform=ax1.transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
ax1.set_ylabel(‘Energy (meV)’)
ax1.set_ylim(0, 60)

C_L − C_T

m_lt = 0.1 * np.max(np.abs(sample.Clqw.T - sample.Ctqw.T))
ax2.pcolormesh(q_distances, sample.omega,
sample.Clqw.T - sample.Ctqw.T,
cmap=‘seismic’, vmin=-m_lt, vmax=m_lt)
ax2.text(0.02, 0.98, r’C_L - C_T(\mathbf{q}, \omega)‘,
transform=ax2.transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
ax2.set_ylabel(‘Energy (meV)’)
ax2.set_xlabel(r’q-path Γ–M–K–Γ’)
ax2.set_ylim(0, 60)

for ax in [ax1, ax2]:
for xpos in q_labels_pos:
ax.axvline(xpos, c=‘white’, lw=2, alpha=0.8)

ax2.set_xticks(q_labels_pos)
ax2.set_xticklabels([r’\Gamma’ if lab == ‘GAMMA’ else lab for lab in q_labels])

plt.tight_layout()
plt.savefig(‘GaN_Sqw_Clt.png’, dpi=300, bbox_inches=‘tight’)
plt.show()

------------------ Plot 2: Ga–Ga, Ga–N, N–N currents ------------------

fig, axes = plt.subplots(3, 1, figsize=(12, 12), sharex=True, dpi=150)

Ga–Ga

m_gg = 0.1 * np.max(np.abs(sample.Clqw_Ga_Ga.T + sample.Ctqw_Ga_Ga.T))
axes[0].pcolormesh(q_distances, sample.omega,
sample.Clqw_Ga_Ga.T + sample.Ctqw_Ga_Ga.T,
cmap=‘seismic’, vmin=-m_gg, vmax=m_gg)
axes[0].text(0.02, 0.98, r’C_{GaGa}^{tot}(\mathbf{q}, \omega)',
transform=axes[0].transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
axes[0].set_ylabel(‘Energy (meV)’)
axes[0].set_ylim(0, 60)

Ga–N

m_gn = 0.1 * np.max(np.abs(sample.Clqw_Ga_N.T + sample.Ctqw_Ga_N.T))
axes[1].pcolormesh(q_distances, sample.omega,
sample.Clqw_Ga_N.T + sample.Ctqw_Ga_N.T,
cmap=‘seismic’, vmin=-m_gn, vmax=m_gn)
axes[1].text(0.02, 0.98, r’C_{GaN}^{cross}(\mathbf{q}, \omega)',
transform=axes[1].transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
axes[1].set_ylabel(‘Energy (meV)’)
axes[1].set_ylim(0, 60)

N–N

m_nn = 0.1 * np.max(np.abs(sample.Clqw_N_N.T + sample.Ctqw_N_N.T))
axes[2].pcolormesh(q_distances, sample.omega,
sample.Clqw_N_N.T + sample.Ctqw_N_N.T,
cmap=‘seismic’, vmin=-m_nn, vmax=m_nn)
axes[2].text(0.02, 0.98, r’C_{NN}^{tot}(\mathbf{q}, \omega)‘,
transform=axes[2].transAxes, va=‘top’, fontsize=14,
bbox=dict(boxstyle=“round,pad=0.3”, facecolor=“white”, alpha=0.9))
axes[2].set_ylabel(‘Energy (meV)’)
axes[2].set_xlabel(r’q-path Γ–M–K–Γ’)
axes[2].set_ylim(0, 60)

for ax in axes:
for xpos in q_labels_pos:
ax.axvline(xpos, c=‘white’, lw=2, alpha=0.8)

axes[2].set_xticks(q_labels_pos)
axes[2].set_xticklabels([r’\Gamma’ if lab == ‘GAMMA’ else lab for lab in q_labels])

plt.tight_layout()
plt.savefig(‘GaN_partial_currents.png’, dpi=300, bbox_inches=‘tight’)
plt.show()

print(“GaN phonon dispersion ALONG Γ–M–K–Γ PATH COMPLETE!”)
print(f"Supercell: {traj.cell.diagonal()}“)
print(f"Ga: {len(atomic_indices[‘Ga’])} atoms, N: {len(atomic_indices[‘N’])} atoms”)
"

Maybe you can write your code in a more readable format, use code formatting or something.
Also no need to attach all the code again.

You are setting your primitive cell to that of the supercell, hence you only get one or two qpts generated. You need to use the real primitive cell.

I would recommend first just take your primitive cell and your supercell and run the generate_qpts function, make sure the outputted qpts segments array contains reasonable qpts and reasonable number of qpts.
And only then move on to running the full Sqw/Cqw calculations