PAOFLOW.phonon.io#

I/O for the PAOFLOW finite-displacement phonon workflow.

Responsibilities (Stage 1):

  • write complete, ready-to-run Quantum ESPRESSO pw.x SCF inputs for the phonopy-generated displaced supercells (phonopy naming supercell-NNN.in);

  • harvest atomic forces from the corresponding pw.x outputs;

  • ingest externally produced FORCE_SETS files;

  • persist a FORCE_SETS for provenance.

All structural quantities follow the phonopy QE convention (Bohr lengths, Ry/au forces), matching Phonopy(..., calculator='qe') set up in PAOFLOW.phonon.do_phonopy.

Functions#

resolve_phonon_dir(data_controller[, phonon_dir])

Return (and create) the directory holding the displaced supercells.

read_hubbard_card(path[, include_v])

Extract the new-style HUBBARD card from a Quantum ESPRESSO input.

write_displaced_supercells(data_controller[, ...])

Write QE SCF inputs for every phonopy-generated displaced supercell.

write_raman_displaced_inputs(data_controller, delta[, ...])

Write QE SCF inputs for the +/- displaced primitive cells of Raman.

raman_cell_dirs(data_controller[, raman_dir, optical, ...])

Return (optical, [(v, '+'/'-', dir, save)]) for the displaced cells.

read_static_epsilon(eps_dir[, nspin])

Read the static dielectric tensor from epsr_<ab>*.dat files.

read_epsilon_at(eps_dir[, energy, nspin])

Read the (complex) dielectric tensor at a target photon energy.

harvest_qe_forces(data_controller[, phonon_dir])

Parse forces from supercell-NNN.out files and set them on phonopy.

parse_qe_total_energy(out_path)

Return the final total energy (Ry) from a pw.x SCF output.

ingest_force_sets(data_controller, force_sets_path)

Load an external FORCE_SETS onto the stored phonopy object.

write_force_sets(data_controller[, phonon_dir, filename])

Write the current displacement/forces dataset to FORCE_SETS.

write_born_file(data_controller, born, epsilon[, ...])

Write a phonopy BORN file (dielectric tensor + Born charges).

read_born_file(data_controller, born_path)

Parse a phonopy BORN file into NAC parameters.

write_field_inputs(data_controller[, field_strength, ...])

Write primitive-cell lelfield SCF inputs for Born charges + epsilon.

harvest_field_results(data_controller[, phonon_dir])

Assemble Born charges and epsilon_inf from the field-* runs.

write_ph_epsil_input(data_controller[, phonon_dir, ...])

Write a ph.x input for the Gamma-point dielectric + Born charges.

harvest_ph_results(data_controller[, phonon_dir, filename])

Parse the dielectric tensor and Born charges from a ph.x output.

Module Contents#

PAOFLOW.phonon.io.resolve_phonon_dir(data_controller, phonon_dir='phonon')[source]#

Return (and create) the directory holding the displaced supercells.

phonon_dir is resolved relative to the PAOFLOW output directory (attr['opath']) unless an absolute path is given.

PAOFLOW.phonon.io.read_hubbard_card(path, include_v=False)[source]#

Extract the new-style HUBBARD card from a Quantum ESPRESSO input.

Parameters:
  • path (str) – Path to a pw.x input file containing a HUBBARD (...) card.

  • include_v (bool) – Keep the intersite V lines. Default False drops them (their explicit atom indices are not valid for a supercell); the on-site U (and J-type) manifold lines are always kept.

Returns:

The card text (header + kept parameter lines), or None when the file contains no HUBBARD card.

Return type:

str or None

PAOFLOW.phonon.io.write_displaced_supercells(data_controller, phonon_dir='phonon', pp_dir=None, prefix=None, kgrid=None, hubbard_card=None)[source]#

Write QE SCF inputs for every phonopy-generated displaced supercell.

Requires that displacements have already been generated on the stored phonopy.Phonopy object (arry['phonopy']).

Parameters:

hubbard_card (str, optional) – New-style HUBBARD card text appended to every input (e.g. from read_hubbard_card()). On-site U parameters transfer verbatim to the supercell, so the forces reflect the DFT+U electronic structure.

Returns:

Absolute paths of the written supercell-NNN.in files (perfect supercell supercell.in excluded).

Return type:

list[str]

PAOFLOW.phonon.io.write_raman_displaced_inputs(data_controller, delta, raman_dir='raman', pp_dir=None, prefix=None, kgrid=None, nbnd=None, freq_tol=0.001, hubbard_card=None)[source]#

Write QE SCF inputs for the +/- displaced primitive cells of Raman.

For every optical zone-centre mode the primitive cell is displaced along the (mass-weighted) eigenvector by +delta and -delta and a complete pw.x SCF input is written under <raman_dir>/mode-NNN-{plus,minus}/<prefix>.scf.in. A subsequent PAOFLOW do_epsilon run on each SCF save yields the static dielectric tensor used to finite-difference the Raman tensor.

Parameters:
  • delta (float) – Normal-coordinate displacement amplitude (same value must be used when harvesting; persisted to <raman_dir>/raman_meta.npz).

  • nbnd (int, optional) – Number of bands (empty states are required for the optical response).

  • freq_tol (float) – Modes with |frequency| <= freq_tol THz (acoustic / imaginary) are skipped: a rigid translation leaves the dielectric tensor invariant.

Returns:

Absolute paths of the written *.scf.in files.

Return type:

list[str]

PAOFLOW.phonon.io.raman_cell_dirs(data_controller, raman_dir='raman', optical=None, width=None, prefix=None)[source]#

Return (optical, [(v, '+'/'-', dir, save)]) for the displaced cells.

Mirrors the directory layout produced by write_raman_displaced_inputs().

PAOFLOW.phonon.io.read_static_epsilon(eps_dir, nspin=1)[source]#

Read the static dielectric tensor from epsr_<ab>*.dat files.

Parameters:
  • eps_dir (str) – Directory containing the epsr_xx.dat … files written by PAOFLOW.response.do_epsilon.do_dielectric_tensor(). The first (lowest-energy) row of each file is the static \(\varepsilon_1\).

  • nspin (int) – Number of spin channels (files carry a _0/_1 suffix when nspin == 2; the channels are summed).

Returns:

Symmetric static dielectric tensor (3, 3).

Return type:

numpy.ndarray

PAOFLOW.phonon.io.read_epsilon_at(eps_dir, energy=None, nspin=1)[source]#

Read the (complex) dielectric tensor at a target photon energy.

The real part is read from epsr_<ab>*.dat and, when available, the imaginary part from epsi_<ab>*.dat (both written by PAOFLOW.response.do_epsilon.do_dielectric_tensor() on a shared energy grid given in the first column). Used by the resonance-Raman harvester to evaluate \(\varepsilon(\omega_L)\) at the laser energy; with energy=None it returns the static (omega -> 0) tensor.

Parameters:
  • eps_dir (str) – Directory containing the eps{r,i}_<ab>*.dat files.

  • energy (float, optional) – Photon energy (eV) at which to evaluate the dielectric tensor (linear interpolation on the file grid). None selects the static limit and the imaginary part is taken to be zero.

  • nspin (int) – Number of spin channels (_0/_1 suffixes summed when nspin == 2).

Returns:

Complex symmetric dielectric tensor (3, 3) (real when energy is None).

Return type:

numpy.ndarray

PAOFLOW.phonon.io.harvest_qe_forces(data_controller, phonon_dir='phonon')[source]#

Parse forces from supercell-NNN.out files and set them on phonopy.

Returns:

Force sets of shape (num_displacements, natoms_supercell, 3) in Ry/au.

Return type:

numpy.ndarray

PAOFLOW.phonon.io.parse_qe_total_energy(out_path)[source]#

Return the final total energy (Ry) from a pw.x SCF output.

Scans for Quantum ESPRESSO’s converged total-energy line (!    total energy   =  ... Ry) and returns the last occurrence, so a restarted or multi-step run yields the final self-consistent value.

Parameters:

out_path (str) – Path to the pw.x standard output.

Returns:

Total energy in Rydberg.

Return type:

float

PAOFLOW.phonon.io.ingest_force_sets(data_controller, force_sets_path)[source]#

Load an external FORCE_SETS onto the stored phonopy object.

The displacement/forces dataset fully replaces the current dataset, so the supercell matrix used to build the phonopy object must match the one that produced the FORCE_SETS.

PAOFLOW.phonon.io.write_force_sets(data_controller, phonon_dir='phonon', filename='FORCE_SETS')[source]#

Write the current displacement/forces dataset to FORCE_SETS.

PAOFLOW.phonon.io.write_born_file(data_controller, born, epsilon, phonon_dir='phonon', filename='BORN')[source]#

Write a phonopy BORN file (dielectric tensor + Born charges).

Parameters:
  • born (array_like) – Born effective charges of shape (natom_prim, 3, 3) in units of the elementary charge, ordered to match the phonopy primitive cell.

  • epsilon (array_like) – (3, 3) high-frequency dielectric tensor.

  • line (The file follows the phonopy format (a unit-conversion factor)

  • the

  • tensor (dielectric)

  • atom) (then one Born tensor per symmetry-inequivalent)

:param : :param written via phonopy.file_IO.write_BORN() using the stored phonopy: :param primitive cell for the atom ordering and symmetry reduction.:

PAOFLOW.phonon.io.read_born_file(data_controller, born_path)[source]#

Parse a phonopy BORN file into NAC parameters.

Returns:

{'born', 'dielectric', 'factor'} suitable for assignment to phonopy.Phonopy.nac_params. Symmetry is used to expand the reduced tensors onto every primitive atom, matching the stored phonopy primitive cell.

Return type:

dict

PAOFLOW.phonon.io.write_field_inputs(data_controller, field_strength=0.001, phonon_dir='phonon', pp_dir=None, prefix=None, kgrid=None, nberrycyc=3, hubbard_card=None)[source]#

Write primitive-cell lelfield SCF inputs for Born charges + epsilon.

Seven inputs are produced: a zero-field reference plus +/- field runs along each Cartesian axis. The finite differences of the per-atom forces give the Born effective charges, and the finite differences of the macroscopic polarization give the high-frequency dielectric tensor.

Parameters:
  • field_strength (float) – Magnitude of efield_cart in Quantum ESPRESSO atomic units (1 a.u. = 36.3609e10 V/m). Keep small (linear response).

  • nberrycyc (int) – Number of Berry-phase self-consistency cycles per SCF step.

  • hubbard_card (str, optional) – New-style HUBBARD card text appended to every input (e.g. from read_hubbard_card()). The on-site U parameters transfer verbatim to the primitive cell.

Returns:

Absolute paths of the written field-*.in files.

Return type:

list[str]

PAOFLOW.phonon.io.harvest_field_results(data_controller, phonon_dir='phonon')[source]#

Assemble Born charges and epsilon_inf from the field-* runs.

Parses the per-atom forces and macroscopic polarization from the seven field-*.out files and forms the central differences along each Cartesian axis.

Returns:

{'born', 'dielectric', 'forces', 'polarization'}.

Return type:

dict

PAOFLOW.phonon.io.write_ph_epsil_input(data_controller, phonon_dir='phonon', prefix=None, outdir=None, fildyn=None, tr2_ph=1e-16, filename='ph_epsil.in')[source]#

Write a ph.x input for the Gamma-point dielectric + Born charges.

The run uses epsil=.true., trans=.false. (electric-field perturbation only), which computes the high-frequency dielectric tensor and the Born effective charges (d Force / dE) without the full phonon dynamical matrix.

Returns:

Absolute path of the written ph.x input file.

Return type:

str

PAOFLOW.phonon.io.harvest_ph_results(data_controller, phonon_dir='phonon', filename='ph_epsil.out')[source]#

Parse the dielectric tensor and Born charges from a ph.x output.

Returns:

{'born', 'dielectric'} with Born charges of shape (natom_prim, 3, 3) (units of e) ordered to match the phonopy primitive cell, and the (3, 3) dielectric tensor.

Return type:

dict