Add tests for phono3py-load script

This commit is contained in:
Atsushi Togo 2023-07-02 18:14:23 +09:00
parent 995d65a66c
commit baacb00a90
4 changed files with 114 additions and 85 deletions

View File

@ -1,94 +1,32 @@
This is the example of NaCl calculation. The supercell is 2x2x2 of the
conventional unit cell. The VASP calculation was made for force calculations
with 500 eV, 2x2x2 off-Gamma-centre k-point sampling mesh for the supercell, and
PBE-sol. For dielectric constant and Born effective charges were calculated in a
similar calculation settings with `LEPSILON = .TRUE.` and 4x4x4 off-Gamma-centre
k-point sampling mesh.
This is the example of NaCl calculation. Since all atoms are displaced, to
obtain force constants, an external force constants calculator is necessary,
i.e., build-in force constants calculator has no ability to compute force
constants for such dataset. In this example, ALM is used. See
https://phonopy.github.io/phonopy/setting-tags.html#alm. The easiest way to
install ALM is to use conda.
The supercell is 2x2x2 of the conventional unit cell. The VASP calculation was
made for force calculations with 500 eV, 2x2x2 off-Gamma-centre k-point sampling
mesh for the supercell, and PBE-sol. For dielectric constant and Born effective
charges were calculated in a similar calculation settings with `LEPSILON =
.TRUE.` and 4x4x4 off-Gamma-centre k-point sampling mesh.
200 supercells were generated with random displacements of 0.03 A displacement
distance.
distance. The calculated forces, displacements, dielectric constant, and Born
effective charges are all stored in `phono3py_params_NaCl222.yaml.xz`.
Force constants are calculated by
```
% phono3py -d --dim="2 2 2" -c POSCAR-unitcell --pa="F"
% phono3py-load phono3py_params_NaCl222.yaml.xz -v --alm
```
To create `fc3.hdf5` and `fc2.hdf5`,
This calculation may require a few minutes depending on computer hardware and
some amount of memory space. By this `fc2.hdf5` and `fc3.hdf5` are obtained. The
lattice thermal conductivity at 300 K is calculated by
```
% phono3py --sym-fc
% phono3py-load phono3py_params_NaCl222.yaml.xz --mesh 50 --ts 300 --br
```
Using 11x11x11 sampling mesh, lattice thermal conductivity is calculated by
```
% phono3py --mesh 11 11 11 --fc3 --fc2 --br
```
`kappa-m111111.hdf5` is written as the result. The lattice thermal conductivity
is calculated as 109.0 W/m-K at 300 K. This becomes, with 19x19x19 sampling
mesh, 123.2 W/m-K.
Accumulated lattice thermal conductivity is calculated using `phono3py-kaccum`
script.
```
% phono3py-kaccum kappa-m111111.hdf5 |tee kaccum.dat
```
`kaccum.dat` is plotted using gnuplot by
```
gnuplot> p 'kaccum.dat' i 30 u 1:2 w l, 'kaccum.dat' i 30 u 1:8 w l
```
![Si-kaccum.png](Si-kaccum.png)
It is found that most of the lattice thermal conductivity owes the phonon modes
below 6 THz.
`fc2.hdf5` can be read by harmonic phonopy to rename it to force_constants.hdf5.
The phonon band structure and DOS are plotted by
```
% ln -s fc2.hdf5 force_constants.hdf5
% phonopy --mesh 19 19 19 --band 1/2 1/2 0 0 0 0 1/2 1/2 1/2 --hdf5 --readfc -p
```
![Si-band-DOS.png](Si-band-DOS.png)
The shape of phonon DOS below 6 THz is similar to the derivative of the
accumulated lattice thermal conductivity, i.e., the heat is conducted by the low
frequency longitudinal-acoustic-like modes.
The file `vasprun_xmls.tar.lzma` in this example contains VASP output files of
`vasprun.xml`s that are used to generate `FORCES_FC3`. To test the `FORCES_FC3`
generation, after decompressing this file, the following command is executed at
current directory:
```
% phono3py --cf3 vasprun_xmls/disp-{00001..00111}/vasprun.xml
```
It is possible to combine different supercell sizes for fc2 and fc3, for which
`FORCES_FC2` is required. Displacements for fc2 and its dataset
(`phono3py_disp.yaml`) can be created by
```
% phono3py -d --dim 2 2 2 --dim-fc2 4 4 4 -c POSCAR-unitcell --pa auto
```
In this example directory, the dataset is renamed to
`phono3py_disp_dimfc2.yaml`. The result of the VASP force calculation is found
at `vasprun_xml_fc2/disp-fc2-00001/vasprun.xml`. `FORCES_FC2` is generated by
```
% phono3py phono3py_disp_dimfc2.yaml --cf2 vasprun_xml_fc2/disp-fc2-00001/vasprun.xml
```
A lattice thermal conductivity calculation is performed by, e.g.,
```
% phono3py-load phono3py_disp_dimfc2.yaml --mesh 11 11 11 --br --ts 300
```
The result is 108.0 W/m-K, and with the 19x19x19 mesh, 125.4 W/m-K.
The result is ~7.2 W/m-K at 300 K.

View File

@ -1099,6 +1099,10 @@ def main(**argparse_control):
# warnings.simplefilter("error")
load_phono3py_yaml = argparse_control.get("load_phono3py_yaml", False)
if "args" in argparse_control: # For pytest
args = argparse_control["args"]
log_level = args.log_level
else:
args, log_level = start_phono3py(**argparse_control)
if load_phono3py_yaml:

View File

@ -0,0 +1,87 @@
"""Tests of Phono3py API."""
import os
import pathlib
from collections.abc import Sequence
from dataclasses import dataclass, fields
from typing import Optional
import pytest
from phono3py.cui.phono3py_script import main
cwd = pathlib.Path(__file__).parent
cwd_called = pathlib.Path.cwd()
@dataclass
class MockArgs:
"""Mock args of ArgumentParser."""
filename: Sequence[os.PathLike]
conf_filename: Optional[os.PathLike] = None
fc_calculator: Optional[str] = None
force_sets_mode: bool = False
force_sets_to_forces_fc2_mode: bool = False
log_level: Optional[int] = None
output_yaml_filename: Optional[os.PathLike] = None
show_num_triplets: bool = False
write_grid_points: bool = False
def __iter__(self):
"""Make self iterable to support in."""
return (getattr(self, field.name) for field in fields(self))
def test_phono3py_load():
"""Test phono3py-load script."""
# Check sys.exit(0)
argparse_control = _get_phono3py_load_args(
cwd / ".." / "phono3py_params_Si-111-222.yaml"
)
with pytest.raises(SystemExit) as excinfo:
main(**argparse_control)
assert excinfo.value.code == 0
# Clean files created by phono3py-load script.
for created_filename in ("phono3py.yaml", "fc2.hdf5", "fc3.hdf5"):
file_path = pathlib.Path(cwd_called / created_filename)
if file_path.exists():
file_path.unlink()
@pytest.mark.parametrize("fc_calculator,exit_code", [(None, 1), ("alm", 0)])
def test_phono3py_load_with_typeII_dataset(fc_calculator, exit_code):
"""Test phono3py-load script with typeII dataset."""
# Check sys.exit(0)
if fc_calculator == "alm":
pytest.importorskip("alm")
argparse_control = _get_phono3py_load_args(
cwd / ".." / "phono3py_params-Si111-rd.yaml.xz", fc_calculator=fc_calculator
)
with pytest.raises(SystemExit) as excinfo:
main(**argparse_control)
assert excinfo.value.code == exit_code
# Clean files created by phono3py-load script.
for created_filename in ("phono3py.yaml", "fc2.hdf5", "fc3.hdf5"):
file_path = pathlib.Path(cwd_called / created_filename)
if file_path.exists():
file_path.unlink()
def _get_phono3py_load_args(phono3py_yaml_filepath, fc_calculator=None):
# Mock of ArgumentParser.args.
mockargs = MockArgs(
filename=[phono3py_yaml_filepath],
fc_calculator=fc_calculator,
log_level=1,
)
# See phono3py-load script.
argparse_control = {
"fc_symmetry": True,
"is_nac": True,
"load_phono3py_yaml": True,
"args": mockargs,
}
return argparse_control

Binary file not shown.