Skip to content

phonopy.load() on a phono3py_params.yaml silently ignores phonon_supercell_matrix and the phonon dataset #592

Description

@VariableYT

Calling phonopy.load() on a phono3py_params.yaml file that contains a
separate phonon_supercell_matrix returns a Phonopy object without error, but
that object carries the fc3 supercell matrix and has neither force constants
nor a displacement dataset. The failure only surfaces later, with an error that
does not point at the cause.

I hit this while building an evaluation harness over phonopy/phono3py, and it
cost me a while to diagnose because nothing fails at load time. Filing in case
a warning would be worth adding.

Versions

phonopy  4.4.0
phono3py 4.4.0
Python   3.12.3

Data

phono3py_params.yaml for zincblende BAs from the 103-compound set on NIMS MDR
(https://github.com/atztogo/phonondb, mdr/phono3py_103compounds_fd_PBE).
It has supercell_matrix 2x2x2 (64 atoms) and phonon_supercell_matrix 4x4x4
(512 atoms).

Reproduce

import numpy as np, phonopy, phono3py

b = phonopy.load("phono3py_params.yaml", log_level=0)
print(np.array(b.supercell_matrix).diagonal(), len(b.supercell))  # [2 2 2] 64
print(b.force_constants)                                          # None
print(b.dataset)                                                  # None

p3 = phono3py.load("phono3py_params.yaml", produce_fc=False, log_level=0)
print(np.array(p3.supercell_matrix).diagonal(), len(p3.supercell))                # [2 2 2] 64
print(np.array(p3.phonon_supercell_matrix).diagonal(), len(p3.phonon_supercell))  # [4 4 4] 512
print(p3.phonon_dataset is not None)                                             # True
print(len(p3.phonon_supercells_with_displacements))                              # 2

What happens

phonopy.load() succeeds and returns a Phonopy object built on the 2x2x2 fc3
supercell. The 4x4x4 phonon_supercell_matrix and the phonon_displacements
block are both ignored. Because no force constants or dataset are attached, the
first thing you try fails:

b.run_qpoints(q)
# RuntimeError: Dynamical matrix has not yet built.

b.produce_force_constants()
# RuntimeError: Displacement dataset is not set.

Neither message hints that the file contained a phonon supercell and dataset
that were dropped at load time.

Why it matters

For this dataset the two supercells give materially different harmonic results,
so quietly using the smaller one is not a cosmetic difference. Using the 4x4x4
fc2 via phono3py.load(...).fc2, BAs acoustic sound velocities land within
about 2 to 3 percent of values derived from published elastic constants. In a
separate check on silicon, going from a 16-atom to a 64-atom supercell moved
transverse acoustic group velocities from about 42 percent low to about 15
percent low, so group velocities converge much more slowly with supercell size
than zone-boundary frequencies do. Anyone reaching for phonopy.load() on one
of these files because they only want harmonic properties is the exact user
most likely to be affected.

Possibly related

#62 (phonopy and phono3py find different numbers of phonon displacements) looks
adjacent but is about displacement generation rather than data being dropped at
load time. #231 touches phonon_supercell_matrix handling but from the internal
data-structure side. I did not find an existing report of this specific
behaviour.

Suggestion

Either of these would have saved the diagnosis:

  1. Emit a warning from phonopy.load() when the file contains
    phonon_supercell_matrix or phonon_displacements, noting that those are
    ignored and pointing at phono3py.load().
  2. Or have phonopy.load() use phonon_supercell_matrix and
    phonon_displacements when present, since for a phonopy-level object those
    are the harmonic data the file carries.

Option 1 is the conservative one and would be enough.

Workaround, for anyone who finds this

import phono3py
from phonopy import Phonopy

p3 = phono3py.load("phono3py_params.yaml", produce_fc=True, log_level=0)
ph = Phonopy(p3.unitcell,
             supercell_matrix=p3.phonon_supercell_matrix,
             primitive_matrix=p3.primitive_matrix)
ph.force_constants = p3.fc2
ph.nac_params = p3.nac_params

Thanks for phonopy and phono3py, and for publishing the datasets. Happy to test
a patch if that would help.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions