mirror of https://github.com/phonopy/phono3py.git
Add tests
This commit is contained in:
parent
426a193729
commit
cc0879dde0
|
@ -539,15 +539,15 @@ def run_pypolymlp_to_compute_forces(
|
|||
)
|
||||
|
||||
cutoff_pair_distance = determine_cutoff_pair_distance(
|
||||
fc_calculator,
|
||||
fc_calculator_options,
|
||||
cutoff_pair_distance,
|
||||
random_displacements,
|
||||
symfc_memory_size,
|
||||
ph3py.supercell,
|
||||
ph3py.primitive,
|
||||
ph3py.symmetry,
|
||||
log_level,
|
||||
fc_calculator=fc_calculator,
|
||||
fc_calculator_options=fc_calculator_options,
|
||||
cutoff_pair_distance=cutoff_pair_distance,
|
||||
random_displacements=random_displacements,
|
||||
symfc_memory_size=symfc_memory_size,
|
||||
supercell=ph3py.supercell,
|
||||
primitive=ph3py.primitive,
|
||||
symmetry=ph3py.symmetry,
|
||||
log_level=log_level,
|
||||
)
|
||||
ph3py.generate_displacements(
|
||||
distance=_displacement_distance,
|
||||
|
|
|
@ -91,15 +91,15 @@ def create_phono3py_supercells(
|
|||
print("Displacement distance: %s" % distance)
|
||||
|
||||
cutoff_pair_distance = determine_cutoff_pair_distance(
|
||||
settings.fc_calculator,
|
||||
settings.fc_calculator_options,
|
||||
settings.cutoff_pair_distance,
|
||||
settings.random_displacements,
|
||||
settings.symfc_memory_size,
|
||||
ph3.supercell,
|
||||
ph3.primitive,
|
||||
ph3.symmetry,
|
||||
log_level,
|
||||
fc_calculator=settings.fc_calculator,
|
||||
fc_calculator_options=settings.fc_calculator_options,
|
||||
cutoff_pair_distance=settings.cutoff_pair_distance,
|
||||
random_displacements=settings.random_displacements,
|
||||
symfc_memory_size=settings.symfc_memory_size,
|
||||
supercell=ph3.supercell,
|
||||
primitive=ph3.primitive,
|
||||
symmetry=ph3.symmetry,
|
||||
log_level=log_level,
|
||||
)
|
||||
ph3.generate_displacements(
|
||||
distance=distance,
|
||||
|
|
|
@ -95,7 +95,7 @@ from phono3py.file_IO import (
|
|||
write_fc3_to_hdf5,
|
||||
write_phonon_to_hdf5,
|
||||
)
|
||||
from phono3py.interface.fc_calculator import get_cutoff_pair_distance
|
||||
from phono3py.interface.fc_calculator import determine_cutoff_pair_distance
|
||||
from phono3py.interface.phono3py_yaml import Phono3pyYaml
|
||||
from phono3py.phonon.grid import get_grid_point_from_address, get_ir_grid_points
|
||||
from phono3py.phonon3.dataset import forces_in_dataset
|
||||
|
@ -598,10 +598,10 @@ def _store_force_constants(ph3py: Phono3py, settings: Phono3pySettings, log_leve
|
|||
|
||||
load_fc2_and_fc3(ph3py, log_level=log_level)
|
||||
|
||||
cutoff_pair_distance = get_cutoff_pair_distance(
|
||||
settings.fc_calculator,
|
||||
settings.fc_calculator_options,
|
||||
settings.cutoff_pair_distance,
|
||||
cutoff_pair_distance = determine_cutoff_pair_distance(
|
||||
fc_calculator=settings.fc_calculator,
|
||||
fc_calculator_options=settings.fc_calculator_options,
|
||||
cutoff_pair_distance=settings.cutoff_pair_distance,
|
||||
)
|
||||
(fc_calculator, fc_calculator_options) = get_fc_calculator_params(
|
||||
settings.fc_calculator,
|
||||
|
|
|
@ -176,30 +176,6 @@ def update_cutoff_fc_calculator_options(
|
|||
return fc_calc_opts
|
||||
|
||||
|
||||
def get_cutoff_pair_distance(
|
||||
fc_calculator: Optional[str],
|
||||
fc_calculator_options: Optional[str],
|
||||
cutoff_pair_distance: Optional[float],
|
||||
) -> Optional[float]:
|
||||
"""Return cutoff_pair_distance from settings."""
|
||||
_, _fc_calculator_options = get_fc_calculator_params(
|
||||
fc_calculator,
|
||||
fc_calculator_options,
|
||||
cutoff_pair_distance,
|
||||
)
|
||||
if cutoff_pair_distance is None:
|
||||
cutoff = parse_symfc_options(
|
||||
extract_fc2_fc3_calculators(_fc_calculator_options, 3), 3
|
||||
).get("cutoff")
|
||||
if cutoff is None:
|
||||
_cutoff_pair_distance = None
|
||||
else:
|
||||
_cutoff_pair_distance = cutoff.get(3)
|
||||
else:
|
||||
_cutoff_pair_distance = cutoff_pair_distance
|
||||
return _cutoff_pair_distance
|
||||
|
||||
|
||||
def get_fc_calculator_params(
|
||||
fc_calculator: Optional[str],
|
||||
fc_calculator_options: Optional[str],
|
||||
|
@ -235,24 +211,30 @@ def get_fc_calculator_params(
|
|||
|
||||
|
||||
def determine_cutoff_pair_distance(
|
||||
fc_calculator: Optional[str],
|
||||
fc_calculator_options: Optional[str],
|
||||
cutoff_pair_distance: Optional[float],
|
||||
random_displacements: Optional[str],
|
||||
symfc_memory_size: Optional[float],
|
||||
supercell: PhonopyAtoms,
|
||||
primitive: Primitive,
|
||||
symmetry: Symmetry,
|
||||
log_level: int,
|
||||
fc_calculator: Optional[str] = None,
|
||||
fc_calculator_options: Optional[str] = None,
|
||||
cutoff_pair_distance: Optional[float] = None,
|
||||
random_displacements: Optional[str] = None,
|
||||
symfc_memory_size: Optional[float] = None,
|
||||
supercell: Optional[PhonopyAtoms] = None,
|
||||
primitive: Optional[Primitive] = None,
|
||||
symmetry: Optional[Symmetry] = None,
|
||||
log_level: int = 0,
|
||||
) -> float:
|
||||
"""Determine cutoff pair distance for displacements."""
|
||||
_cutoff_pair_distance = get_cutoff_pair_distance(
|
||||
_cutoff_pair_distance, _symfc_memory_size = _get_cutoff_pair_distance(
|
||||
fc_calculator,
|
||||
fc_calculator_options,
|
||||
cutoff_pair_distance,
|
||||
symfc_memory_size,
|
||||
)
|
||||
if random_displacements == "auto" and symfc_memory_size is not None:
|
||||
symfc_options = {"memsize": {3: symfc_memory_size}}
|
||||
if random_displacements == "auto" and _symfc_memory_size is not None:
|
||||
if fc_calculator != "symfc":
|
||||
raise RuntimeError(
|
||||
"Estimation of cutoff_pair_distance by memory size is only "
|
||||
"available for symfc calculator."
|
||||
)
|
||||
symfc_options = {"memsize": {3: _symfc_memory_size}}
|
||||
update_symfc_cutoff_by_memsize(
|
||||
symfc_options, supercell, primitive, symmetry, verbose=log_level > 0
|
||||
)
|
||||
|
@ -286,3 +268,32 @@ def _set_cutoff_in_fc_calculator_options(
|
|||
print(f'Appended "{str_appended}" to fc_calculator_options for fc3.')
|
||||
|
||||
return f"{calc_opts_fc2}|{calc_opts_fc3}"
|
||||
|
||||
|
||||
def _get_cutoff_pair_distance(
|
||||
fc_calculator: Optional[str],
|
||||
fc_calculator_options: Optional[str],
|
||||
cutoff_pair_distance: Optional[float],
|
||||
symfc_memory_size: Optional[float] = None,
|
||||
) -> Optional[float]:
|
||||
"""Return cutoff_pair_distance from settings."""
|
||||
_, _fc_calculator_options = get_fc_calculator_params(
|
||||
fc_calculator,
|
||||
fc_calculator_options,
|
||||
cutoff_pair_distance,
|
||||
)
|
||||
symfc_options = parse_symfc_options(
|
||||
extract_fc2_fc3_calculators(_fc_calculator_options, 3), 3
|
||||
)
|
||||
|
||||
_cutoff_pair_distance = cutoff_pair_distance
|
||||
cutoff = symfc_options.get("cutoff")
|
||||
if cutoff is not None:
|
||||
_cutoff_pair_distance = cutoff.get(3)
|
||||
|
||||
_symfc_memory_size = symfc_memory_size
|
||||
memsize = symfc_options.get("memsize")
|
||||
if memsize is not None:
|
||||
_symfc_memory_size = memsize.get(3)
|
||||
|
||||
return _cutoff_pair_distance, _symfc_memory_size
|
||||
|
|
|
@ -12,6 +12,7 @@ import h5py
|
|||
import numpy as np
|
||||
import pytest
|
||||
|
||||
import phono3py
|
||||
from phono3py.cui.phono3py_script import main
|
||||
|
||||
cwd = pathlib.Path(__file__).parent
|
||||
|
@ -22,24 +23,27 @@ cwd_called = pathlib.Path.cwd()
|
|||
class MockArgs:
|
||||
"""Mock args of ArgumentParser."""
|
||||
|
||||
filename: Optional[Sequence[os.PathLike]] = None
|
||||
cell_filename: Optional[str] = None
|
||||
conf_filename: Optional[os.PathLike] = None
|
||||
fc_calculator: Optional[str] = None
|
||||
fc_calculator_options: Optional[str] = None
|
||||
fc_symmetry: bool = True
|
||||
filename: Optional[Sequence[os.PathLike]] = None
|
||||
force_sets_mode: bool = False
|
||||
force_sets_to_forces_fc2_mode: bool = False
|
||||
input_filename = None
|
||||
input_output_filename = None
|
||||
log_level: Optional[int] = None
|
||||
output_yaml_filename: Optional[os.PathLike] = None
|
||||
show_num_triplets: bool = False
|
||||
write_grid_points: bool = False
|
||||
fc_symmetry: bool = True
|
||||
cell_filename: Optional[str] = None
|
||||
is_bterta: Optional[bool] = None
|
||||
mesh_numbers: Optional[Sequence] = None
|
||||
mlp_params: Optional[str] = None
|
||||
output_filename = None
|
||||
output_yaml_filename: Optional[os.PathLike] = None
|
||||
random_displacements: Optional[Union[int, str]] = None
|
||||
show_num_triplets: bool = False
|
||||
temperatures: Optional[Sequence] = None
|
||||
use_pypolymlp: bool = False
|
||||
input_filename = None
|
||||
output_filename = None
|
||||
input_output_filename = None
|
||||
write_grid_points: bool = False
|
||||
|
||||
def __iter__(self):
|
||||
"""Make self iterable to support in."""
|
||||
|
@ -129,25 +133,36 @@ def test_phono3py_load_with_pypolymlp_si():
|
|||
pytest.importorskip("pypolymlp", minversion="0.9.2")
|
||||
pytest.importorskip("symfc")
|
||||
|
||||
# Create fc2.hdf5
|
||||
argparse_control = _get_phono3py_load_args(
|
||||
cwd / ".." / "phono3py_params_Si-111-222-rd.yaml.xz",
|
||||
fc_calculator="symfc",
|
||||
use_pypolymlp=True,
|
||||
)
|
||||
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main(**argparse_control)
|
||||
assert excinfo.value.code == 0
|
||||
|
||||
# phono3py.yaml and fc2.hd5 are used in the next run. So they are not deleted.
|
||||
for created_filename in ("fc3.hdf5", "phono3py_mlp_eval_dataset.yaml"):
|
||||
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()
|
||||
assert file_path.exists()
|
||||
pathlib.Path(cwd_called / "fc3.hdf5").unlink()
|
||||
|
||||
# Create MLP (polymlp.yaml)
|
||||
argparse_control = _get_phono3py_load_args(
|
||||
cwd / ".." / "phono3py_params_Si-111-222-rd.yaml.xz",
|
||||
use_pypolymlp=True,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main(**argparse_control)
|
||||
assert excinfo.value.code == 0
|
||||
for created_filename in ("phono3py.yaml", "polymlp.yaml"):
|
||||
file_path = pathlib.Path(cwd_called / created_filename)
|
||||
assert file_path.exists()
|
||||
|
||||
# Create phono3py_mlp_eval_dataset.yaml
|
||||
argparse_control = _get_phono3py_load_args(
|
||||
cwd_called / "phono3py.yaml",
|
||||
fc_calculator="symfc",
|
||||
random_displacements="auto",
|
||||
use_pypolymlp=True,
|
||||
)
|
||||
|
||||
|
@ -155,6 +170,9 @@ def test_phono3py_load_with_pypolymlp_si():
|
|||
main(**argparse_control)
|
||||
assert excinfo.value.code == 0
|
||||
|
||||
ph3 = phono3py.load(cwd_called / "phono3py_mlp_eval_dataset.yaml")
|
||||
assert len(ph3.displacements) == 4
|
||||
|
||||
for created_filename in (
|
||||
"phono3py.yaml",
|
||||
"fc2.hdf5",
|
||||
|
@ -163,17 +181,123 @@ def test_phono3py_load_with_pypolymlp_si():
|
|||
"phono3py_mlp_eval_dataset.yaml",
|
||||
):
|
||||
file_path = pathlib.Path(cwd_called / created_filename)
|
||||
if file_path.exists():
|
||||
file_path.unlink()
|
||||
assert file_path.exists()
|
||||
file_path.unlink()
|
||||
|
||||
|
||||
def test_phono3py_load_with_pypolymlp_nacl():
|
||||
"""Test phono3py-load script with pypolymlp using NaCl.
|
||||
|
||||
First run generates polymlp.yaml.
|
||||
Second run uses polymlp.yaml.
|
||||
|
||||
"""
|
||||
pytest.importorskip("pypolymlp", minversion="0.9.2")
|
||||
pytest.importorskip("symfc")
|
||||
|
||||
# Stage1 (preparation)
|
||||
argparse_control = _get_phono3py_load_args(
|
||||
cwd / ".." / "phono3py_params_MgO-222rd-444rd.yaml.xz",
|
||||
mlp_params="cutoff=4.0,gtinv_maxl=4 4,max_p=1,gtinv_order=2",
|
||||
fc_calculator="symfc",
|
||||
random_displacements="auto",
|
||||
use_pypolymlp=True,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main(**argparse_control)
|
||||
assert excinfo.value.code == 0
|
||||
|
||||
ph3 = phono3py.load(cwd_called / "phono3py_mlp_eval_dataset.yaml")
|
||||
assert len(ph3.displacements) == 16
|
||||
|
||||
for created_filename in (
|
||||
"phono3py.yaml",
|
||||
"fc2.hdf5",
|
||||
"fc3.hdf5",
|
||||
"polymlp.yaml",
|
||||
"phono3py_mlp_eval_dataset.yaml",
|
||||
):
|
||||
file_path = pathlib.Path(cwd_called / created_filename)
|
||||
assert file_path.exists()
|
||||
|
||||
for created_filename in (
|
||||
"fc3.hdf5",
|
||||
"phono3py_mlp_eval_dataset.yaml",
|
||||
):
|
||||
file_path = pathlib.Path(cwd_called / created_filename)
|
||||
assert file_path.exists()
|
||||
file_path.unlink()
|
||||
|
||||
# Stage2 (cutoff test)
|
||||
argparse_control = _get_phono3py_load_args(
|
||||
cwd / ".." / "phono3py.yaml",
|
||||
fc_calculator="symfc",
|
||||
fc_calculator_options="|cutoff=4.0",
|
||||
random_displacements="auto",
|
||||
use_pypolymlp=True,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main(**argparse_control)
|
||||
assert excinfo.value.code == 0
|
||||
|
||||
ph3 = phono3py.load(cwd_called / "phono3py_mlp_eval_dataset.yaml")
|
||||
assert len(ph3.displacements) == 4
|
||||
|
||||
for created_filename in (
|
||||
"phono3py.yaml",
|
||||
"fc2.hdf5",
|
||||
"fc3.hdf5",
|
||||
"polymlp.yaml",
|
||||
"phono3py_mlp_eval_dataset.yaml",
|
||||
):
|
||||
file_path = pathlib.Path(cwd_called / created_filename)
|
||||
assert file_path.exists()
|
||||
|
||||
for created_filename in (
|
||||
"fc3.hdf5",
|
||||
"phono3py_mlp_eval_dataset.yaml",
|
||||
):
|
||||
file_path = pathlib.Path(cwd_called / created_filename)
|
||||
assert file_path.exists()
|
||||
file_path.unlink()
|
||||
|
||||
# Stage3 (memsize test)
|
||||
argparse_control = _get_phono3py_load_args(
|
||||
cwd / ".." / "phono3py.yaml",
|
||||
fc_calculator="symfc",
|
||||
fc_calculator_options="|memsize=0.05",
|
||||
random_displacements="auto",
|
||||
use_pypolymlp=True,
|
||||
)
|
||||
with pytest.raises(SystemExit) as excinfo:
|
||||
main(**argparse_control)
|
||||
assert excinfo.value.code == 0
|
||||
|
||||
ph3 = phono3py.load(cwd_called / "phono3py_mlp_eval_dataset.yaml")
|
||||
assert len(ph3.displacements) == 8
|
||||
|
||||
for created_filename in (
|
||||
"phono3py.yaml",
|
||||
"fc2.hdf5",
|
||||
"fc3.hdf5",
|
||||
"polymlp.yaml",
|
||||
"phono3py_mlp_eval_dataset.yaml",
|
||||
):
|
||||
file_path = pathlib.Path(cwd_called / created_filename)
|
||||
assert file_path.exists()
|
||||
file_path.unlink()
|
||||
|
||||
|
||||
def _get_phono3py_load_args(
|
||||
phono3py_yaml_filepath: Union[str, pathlib.Path],
|
||||
fc_calculator: Optional[str] = None,
|
||||
fc_calculator_options: Optional[str] = None,
|
||||
load_phono3py_yaml: bool = True,
|
||||
is_bterta: bool = False,
|
||||
temperatures: Optional[Sequence] = None,
|
||||
mesh_numbers: Optional[Sequence] = None,
|
||||
mlp_params: Optional[str] = None,
|
||||
random_displacements: Optional[Union[int, str]] = None,
|
||||
temperatures: Optional[Sequence] = None,
|
||||
use_pypolymlp: bool = False,
|
||||
):
|
||||
# Mock of ArgumentParser.args.
|
||||
|
@ -181,21 +305,27 @@ def _get_phono3py_load_args(
|
|||
mockargs = MockArgs(
|
||||
filename=[phono3py_yaml_filepath],
|
||||
fc_calculator=fc_calculator,
|
||||
fc_calculator_options=fc_calculator_options,
|
||||
is_bterta=is_bterta,
|
||||
temperatures=temperatures,
|
||||
mesh_numbers=mesh_numbers,
|
||||
use_pypolymlp=use_pypolymlp,
|
||||
log_level=1,
|
||||
mesh_numbers=mesh_numbers,
|
||||
mlp_params=mlp_params,
|
||||
random_displacements=random_displacements,
|
||||
temperatures=temperatures,
|
||||
use_pypolymlp=use_pypolymlp,
|
||||
)
|
||||
else:
|
||||
mockargs = MockArgs(
|
||||
filename=[],
|
||||
fc_calculator=fc_calculator,
|
||||
fc_calculator_options=fc_calculator_options,
|
||||
log_level=1,
|
||||
cell_filename=phono3py_yaml_filepath,
|
||||
is_bterta=is_bterta,
|
||||
temperatures=temperatures,
|
||||
mesh_numbers=mesh_numbers,
|
||||
mlp_params=mlp_params,
|
||||
random_displacements=random_displacements,
|
||||
temperatures=temperatures,
|
||||
use_pypolymlp=use_pypolymlp,
|
||||
)
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
"""Tests of functions in fc_calculator."""
|
||||
|
||||
import pytest
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
|
||||
from phono3py.api_phono3py import Phono3py
|
||||
from phono3py.interface.fc_calculator import determine_cutoff_pair_distance
|
||||
|
||||
|
||||
def test_determine_cutoff_pair_distance() -> None:
|
||||
"""Test determine_cutoff_pair_distance."""
|
||||
cutoff = determine_cutoff_pair_distance(fc_calculator_options="|cutoff=4")
|
||||
assert cutoff == pytest.approx(4.0)
|
||||
|
||||
cutoff = determine_cutoff_pair_distance(cutoff_pair_distance=5.0)
|
||||
assert cutoff == pytest.approx(5.0)
|
||||
|
||||
cutoff = determine_cutoff_pair_distance(
|
||||
fc_calculator_options="|cutoff=4", cutoff_pair_distance=5.0
|
||||
)
|
||||
assert cutoff == pytest.approx(4.0)
|
||||
|
||||
|
||||
def test_determine_cutoff_pair_distance_with_memsize(aln_cell: PhonopyAtoms) -> None:
|
||||
"""Test determine_cutoff_pair_distance estimated by memsize."""
|
||||
pytest.importorskip("symfc")
|
||||
|
||||
ph3 = Phono3py(aln_cell, supercell_matrix=[3, 3, 2])
|
||||
cutoff = determine_cutoff_pair_distance(
|
||||
fc_calculator="symfc",
|
||||
fc_calculator_options="|memsize=0.1",
|
||||
random_displacements="auto",
|
||||
supercell=ph3.supercell,
|
||||
primitive=ph3.primitive,
|
||||
symmetry=ph3.symmetry,
|
||||
log_level=1,
|
||||
)
|
||||
assert cutoff == pytest.approx(3.2)
|
||||
|
||||
cutoff = determine_cutoff_pair_distance(
|
||||
fc_calculator="symfc",
|
||||
random_displacements="auto",
|
||||
symfc_memory_size=0.2,
|
||||
supercell=ph3.supercell,
|
||||
primitive=ph3.primitive,
|
||||
symmetry=ph3.symmetry,
|
||||
log_level=1,
|
||||
)
|
||||
assert cutoff == pytest.approx(3.7)
|
||||
|
||||
cutoff = determine_cutoff_pair_distance(
|
||||
fc_calculator="symfc",
|
||||
fc_calculator_options="|memsize=0.1",
|
||||
random_displacements="auto",
|
||||
symfc_memory_size=0.2,
|
||||
supercell=ph3.supercell,
|
||||
primitive=ph3.primitive,
|
||||
symmetry=ph3.symmetry,
|
||||
log_level=1,
|
||||
)
|
||||
assert cutoff == pytest.approx(3.2)
|
||||
|
||||
with pytest.raises(RuntimeError):
|
||||
cutoff = determine_cutoff_pair_distance(
|
||||
fc_calculator="alm",
|
||||
fc_calculator_options="|memsize=0.1",
|
||||
random_displacements="auto",
|
||||
symfc_memory_size=0.2,
|
||||
supercell=ph3.supercell,
|
||||
primitive=ph3.primitive,
|
||||
symmetry=ph3.symmetry,
|
||||
log_level=1,
|
||||
)
|
Loading…
Reference in New Issue