\(\newcommand{\AA}{\text{Å}}\)

Output file structure#

\(\mathrm{LModeA\text{-}}\vec{\mathbf{k}}\) writes all results to a single HDF5 output file, lmodea.h5. The file is organised into data groups corresponding to:

Each dataset is described in detail in the following sections. The overall structure of the output file is:

/
├── internal_coordinates/           Internal coordinate definitions
│   ├── type                        (n_ic,)                     str
│   ├── value                       (n_ic,)                     float
│   ├── sym_key                     (n_ic,)                     int
│   ├── n_atoms                     (n_ic,)                     int
│   ├── offsets                     (n_ic + 1,)                 int
│   ├── atom_indices                (n_tot,)                    int
│   ├── asymm_indices               (n_tot,)                    int
│   ├── cell_indices                (n_tot, 3)                  int
│   └── derivatives                 (n_tot, 3)                  float
│
 ├── kpoints/                        Wavevector information
 │   ├── wavevectors                 (n_kpts, 3)                 float
 │   ├── labels                      (n_kpts,)                   str
 │   └── indices_in_dynmat_h5        (n_kpts,)                   int
 │
 ├── normal_modes/ ¹                 Harmonic normal mode data ¹
 │   ├── frequencies                 (n_kpts, n_nm, n_at, 3)     float
 │   └── eigenvectors                (n_kpts, n_nm, n_at, 3)     float
 │
 ├── Wilson_matrices/ ²              Wilson matrices ²
 │   ├── G_diagonal                  (n_kpts, n_ic,)             float
 │   ├── B_matrix                    (n_kpts, n_ic, 3*n_at,)     float
 │   └── D_matrix                    (n_kpts, n_ic, n_nm,)       float
 │
 ├── local_modes/                    Local mode data (LMA)
 │   ├── frequencies                 (n_kpts, n_ic,)             float
 │   ├── force_constants_au          (n_kpts, n_ic,)             float
 │   ├── force_constants             (n_kpts, n_ic,)             float
 │   ├── effective_force_constants   (n_kpts, n_ic,)             float
 │   └── adiabatic_vectors ³         (n_kpts, n_ic, n_at, 3)     float
 │
 └── CNM/ ⁴                          Characterisation of normal modes (CNM) ⁴
     └── amplitudes                  (n_kpts, n_nm, n_ic,)       float


¹ Written only when ``--write-normal`` is specified.
² Written only when ``--write-wilson`` is specified.
³ Written only when ``--write-adiabatic`` is specified.
⁴ Written only when ``--cnm`` is specified.

Here:

  • n_at is the number of atoms.

  • n_ic is the number of internal coordinates/local modes.

  • n_nm is the number of normal modes.

  • n_tot = \(\sum_i N_{\mathrm{atoms}}(i)\) is the total number of atom entries across all internal coordinates.

  • n_kpts is the number of k-points sampled in the calculation.

Internal coordinate definitions are the same for analysis performed at all wavevectors. The remaining data is ordered according to the wavevectors (nkpts) included in the calculation along the first axis, and follows the ordering of the internal coordinates (n_ic) or the normal modes (n_nm) along the second axis.

The method used to construct the B matrix for local mode analysis (primitive or supercell) is stored in /attrs/b_method. The stored B_matrix always corresponds to the one generated using the primitive method (shape (n_ic, 3*n_atoms)) even if the supercell method was used for analysis. The supercell B matrix can be re-constructed directly from the derivatives data. The attribute can be read as:

import h5py

with h5py.File("lmodea.h5", "r") as f:
    b_method = f.attrs.get("b_method")
    print(b_method)  # e.g. b'primitive' or b'supercell'

Internal coordinate definitions#

The internal_coordinates group of the lmodea.h5 file defines the set of internal coordinates used for the reported analysis. These data define the topology and real-space character of each internal coordinate and are independent of wavevector, normal-mode, or local-mode calculations. This contains the scalar quantities: type, value, sym_key, n_atoms, and variable-length data: atom_indices, asymm_indices, cell_indices, derivatives, organised according to offsets.

The scalar datasets have length n_ic and contain one entry per internal coordinate. Because different internal coordinate types involve different numbers of atoms, variable-length data are stored using a flattened array with offsets scheme for memory-efficient storage. Offsets are stored in the offsets array of length n_ic + 1. This representation supports arbitrary internal coordinate definitions without imposing a fixed maximum size.

All variable-length datasets share the same offset structure, allowing an internal coordinate to be reconstructed unambiguously:

import h5py

with h5py.File("output.h5", "r") as f:
    ic_data = f["internal_coordinates"]
    offsets = ic_data["offsets"]

    i = 0  # internal coordinate index
    start, end = offsets[i], offsets[i+1]

    atom_indices = ic_data["atom_indices"][start:end]
    asymm_indices = ic_data["asymm_indices"][start:end]
    cell_indices = ic_data["cell_indices"][start:end]
    derivatives = ic_data["derivatives"][start:end]

type#

String identifying the coordinate type (e.g. "bond", "angle", "ring").

value#

The equilibrium value of the internal coordinate (e.g. bond length in \(\AA\), angle in degrees)

sym_key#

Integer label identifying symmetry-equivalent internal coordinates. Internal coordinates assigned the same sym_key are equivalent by space group symmetry of the studied system. Special system-wide rigid-body translational coordinates are assigned sym_key = 0.

n_atoms#

Number of atoms involved in the internal coordinate.

offsets#

Cumulative offsets into all flattened internal-coordinate arrays (atom_indices, asymm_indices, cell_indices, derivatives). For internal coordinate i, the relevant slice is:

start = offsets[i]
end   = offsets[i + 1]

atom_indices#

Atom indices involved in each internal coordinate in canonical representation. Indices refer to atoms in the reference unit cell.

asymm_indices#

Integer labels identifying symmetry-equivalent atoms involved in each internal coordinate.

The labels are computed using spglib and correspond to equivalence under the full space group symmetry. Atoms assigned the same value in asymm_indices belong to the same symmetry orbit. The value itself corresponds to the index of a representative atom in the reference unit cell.

These labels do not enumerate asymmetric-unit atoms sequentially, but instead reference representative atom indices as defined by spglib.

cell_indices#

Cell indices specify which periodic image of the unit cell each atom of the internal coordinate belongs to. They are stored as signed integer triples [nx, ny, nz], corresponding to integer translations along the lattice vectors relative to the reference cell at [0, 0, 0].

The j-th entry of cell_indices corresponds to the j-th atom in atom_indices.

derivatives#

Derivatives of each internal coordinate with respect to the Cartesian displacements of its constituent atoms.

Each entry is a vector of length three corresponding to the Cartesian components along the lattice axes:

\[\frac{\partial q}{\partial \mathbf{r}_\alpha} = \left[ \frac{\partial q}{\partial x_\alpha}, \frac{\partial q}{\partial y_\alpha}, \frac{\partial q}{\partial z_\alpha} \right]\]

The derivatives are stored in a flattened array in the same order as atom_indices and cell_indices. The j-th entry of derivatives corresponds to the representation of the j-th atom in atom_indices and in the unit cell defined by cell_indices.

These derivatives are used to construct the wavevector-dependent \(\mathbf{B}(\mathbf{k})\) matrix, which projects Cartesian displacements onto internal coordinates.

The returned array has shape (n_atoms(i), 3) and is ordered consistently with atom_indices and cell_indices.

Wavevector information#

kpoints#

Wavevectors sampled in the calculation, expressed in reduced (fractional) coordinates with respect to the reciprocal lattice vectors.

labels#

String labels associated with high-symmetry k-points. Entries corresponding to non-high-symmetry k-points are stored as empty strings.

indices_in_dynmat_h5#

Indices in the input dynmat.h5 file corresponding to each k-point analyzed in the calculation. This dataset records which dynamical matrix was used for each k-point in the lmodea.h5 output, allowing direct correspondence between the analyzed k-points and their source data in dynmat.h5.

This is distinct from the kpoints/indices dataset in dynmat.h5, which records the enumeration of the k-points in the output file that produced the phonon data. The indices_in_dynmat_h5 dataset specifically tracks the position of each analyzed k-point within the dynmat.h5 file’s own k-point list.

Harmonic normal mode data#

frequencies#

Harmonic normal mode frequencies in cm–1 at each sampled wavevector.

The dataset is ordered according to wavevector (kpoints) along the first axis, and in ascending order along the second axis.

eigenvectors#

Harmonic normal mode eigenvectors corresponding to the normal mode frequencies.

The dataset is odered according to wavevector (kpoints) along the first axis, normal mode along the second axis, atom index along the third axis, and the Cartesian component (x, y, z) along the fourth axis.

Wilson matrices#

G_diagonal#

Diagonal elements of the Wilson G matrix, storing the inertial weighting used in the calculation of local mode frequencies. These values should be the same for all wavevectors.

The dataset is ordered according to wavevector (kpoints) along the first axis, and according to internal coordinate ordering along the second axis.

B_matrix#

Wavevector-dependent \(\mathbf{B}(\mathbf{k})\) matrix at each wavevector, encoding the Cartesian-internal coordinate transformation obeying the wavevector-imposed phase relations and periodic boundary conditions.

The dataset is ordered according to wavevector (kpoints) along the first axis,according to internal coordinate ordering along the second axis, and follows the ordering of Cartesian atomic coordinates in the input structure along the third axis.

The stored B_matrix always corresponds to the one generated using the primitive method (shape (n_ic, 3*n_atoms)) even if the supercell method was used for analysis. The supercell B matrix can be re-constructed directly from the derivatives data.

D_matrix#

Wavevector-dependent \(\mathbf{D}(\mathbf{k})\) matrix, encoding the coefficients that express normal coordinates as linear combinations of internal coordinates at each wavevector.

The dataset is ordered according to wavevector (kpoints) along the first axis,according to internal coordinate ordering along the second axis, and follows the normal mode ordering along the third axis.

Local mode data (LMA)#

The local_modes group of the lmodea.h5 file stores the local mode properties computed foe each wavevector included in the calculation.

The datasets are ordered according to wavevector (kpoints) along the first axis, and follow the internal coordinate ordering along the second axis.

frequencies#

Local mode frequencies in cm–1 computed at each wavevector.

force_constants_au#

Local mode force constants in atomic units computed at each wavevector.

The local mode force constant corresponds to the second derivative of the energy with respect to the internal coordinate, i.e. \(k_n = \partial^2 E / \partial q_n^2\), evaluated along the adiabatically relaxed displacement path defined by the compliance matrix. Consequently, its unit depends on the dimensionality of the internal coordinate:

  • For bond-length coordinates (\(q_n\) in Bohr), the unit is Hartree / Bohr2.

  • For angular or torsional coordinates (\(q_n\) in radians, dimensionless), the unit is Hartree.

In general, the unit is Energy / (internal coordinate)2.

force_constants#

Local mode force constants in conventional units computed at each wavevector.

These are the same quantities as force_constants_au converted to conventional units. Their unit reflects the dimensionality of the internal coordinate:

  • For bond stretches, the unit is typically mdyn / \(\AA\) (or equivalently N/m).

  • For angular or torsional coordinates, the unit corresponds to an energy (e.g. mdyn \(\AA\) or an equivalent energy unit).

In general, the unit is Energy / (internal coordinate)2 expressed in conventional units.

effective_force_constants#

Effective local mode force constants in conventional units computed at each wavevector.

For bond-stretch coordinates, the effective force constant is identical to the local mode force constant and has units of mdyn / \(\AA\) (≡ N/m).

For angular and dihedral coordinates, the local mode force constant has units of energy because the internal coordinate (radians) is dimensionless. To allow direct comparison with bond-stretch force constants, an additional geometrical conversion factor is applied that introduces a length–2 scaling so that it can be expressed in mdyn / \(\AA\).

The effective force constants are therefore unit-normalized quantities intended for comparison across different types of internal coordinates.

adiabatic_vectors#

Adiabatic vectors describing the atomic displacement patterns as the system relaxes in response to internal coordinate distortions, computed at each wavevector.

This dataset is only written when the –write-adiabatic flag is specified.

Characterisation of normal modes (CNM)#

The CNM group of the lmodea.h5 file stores the local mode-normal mode similarity metric computed according to the Konkoli-Cremer Hessian-weighted amplitude.

This group is only written when the –cnm flag is specified.

The datasets are ordered according to wavevector (kpoints) along the first axis, and follow the normal mode ordering along the second axis and internal coordinate ordering along the third axis.

amplitudes#

Local mode amplitudes for each normal mode at each wavevector. The relative magnitude of these values quantifies the contribution of each internal coordinate to each normal mode, or, equivalently, the participation of each normal mode in the response of the system to the distortion of each internal coordinate.

These amplitudes are stored raw (unnormalised). If a row-normalised representation is required (e.g. for bar-chart visualisation), it can be computed by dividing each row by its sum or by using the --normalise-cnm option of the plotting utility.