mirror of https://github.com/phonopy/phono3py.git
Support symfc
This commit is contained in:
parent
97a0305391
commit
936e3af709
|
@ -1329,6 +1329,7 @@ class Phono3py:
|
||||||
fc_calculator=fc3_calculator,
|
fc_calculator=fc3_calculator,
|
||||||
fc_calculator_options=fc3_calculator_options,
|
fc_calculator_options=fc3_calculator_options,
|
||||||
is_compact_fc=is_compact_fc,
|
is_compact_fc=is_compact_fc,
|
||||||
|
symmetry=self._symmetry,
|
||||||
log_level=self._log_level,
|
log_level=self._log_level,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
@ -1425,6 +1426,8 @@ class Phono3py:
|
||||||
fc_calculator=fc2_calculator,
|
fc_calculator=fc2_calculator,
|
||||||
fc_calculator_options=fc2_calculator_options,
|
fc_calculator_options=fc2_calculator_options,
|
||||||
atom_list=p2s_map,
|
atom_list=p2s_map,
|
||||||
|
symmetry=self._phonon_supercell_symmetry,
|
||||||
|
symprec=self._symprec,
|
||||||
log_level=self._log_level,
|
log_level=self._log_level,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -713,6 +713,13 @@ def get_parser(fc_symmetry=False, is_nac=False, load_phono3py_yaml=False):
|
||||||
default=None,
|
default=None,
|
||||||
help="Cutoff width of smearing function (ratio to sigma value)",
|
help="Cutoff width of smearing function (ratio to sigma value)",
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--symfc",
|
||||||
|
dest="use_symfc",
|
||||||
|
action="store_true",
|
||||||
|
default=None,
|
||||||
|
help="Use symfc for generating force constants",
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"--spf",
|
"--spf",
|
||||||
dest="is_spectral_function",
|
dest="is_spectral_function",
|
||||||
|
|
|
@ -34,16 +34,26 @@
|
||||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
# POSSIBILITY OF SUCH DAMAGE.
|
# POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
|
import numpy as np
|
||||||
|
from phonopy.structure.atoms import PhonopyAtoms
|
||||||
|
from phonopy.structure.cells import Primitive
|
||||||
|
from phonopy.structure.symmetry import Symmetry
|
||||||
|
|
||||||
|
|
||||||
def get_fc3(
|
def get_fc3(
|
||||||
supercell,
|
supercell: PhonopyAtoms,
|
||||||
primitive,
|
primitive: Primitive,
|
||||||
displacements,
|
displacements: np.ndarray,
|
||||||
forces,
|
forces: np.ndarray,
|
||||||
fc_calculator=None,
|
fc_calculator: Optional[str] = None,
|
||||||
fc_calculator_options=None,
|
fc_calculator_options: Optional[str] = None,
|
||||||
is_compact_fc=False,
|
is_compact_fc: bool = False,
|
||||||
log_level=0,
|
symmetry: Optional[Symmetry] = None,
|
||||||
|
log_level: int = 0,
|
||||||
):
|
):
|
||||||
"""Supercell 2nd order force constants (fc2) are calculated.
|
"""Supercell 2nd order force constants (fc2) are calculated.
|
||||||
|
|
||||||
|
@ -86,9 +96,9 @@ def get_fc3(
|
||||||
|
|
||||||
"""
|
"""
|
||||||
if fc_calculator == "alm":
|
if fc_calculator == "alm":
|
||||||
from phono3py.interface.alm import get_fc3
|
from phono3py.interface.alm import get_fc3 as get_fc3_alm
|
||||||
|
|
||||||
return get_fc3(
|
return get_fc3_alm(
|
||||||
supercell,
|
supercell,
|
||||||
primitive,
|
primitive,
|
||||||
displacements,
|
displacements,
|
||||||
|
@ -97,6 +107,19 @@ def get_fc3(
|
||||||
is_compact_fc=is_compact_fc,
|
is_compact_fc=is_compact_fc,
|
||||||
log_level=log_level,
|
log_level=log_level,
|
||||||
)
|
)
|
||||||
|
elif fc_calculator == "symfc":
|
||||||
|
from phonopy.interface.symfc import run_symfc
|
||||||
|
|
||||||
|
return run_symfc(
|
||||||
|
supercell,
|
||||||
|
primitive,
|
||||||
|
displacements,
|
||||||
|
forces,
|
||||||
|
orders=[2, 3],
|
||||||
|
is_compact_fc=is_compact_fc,
|
||||||
|
symmetry=symmetry,
|
||||||
|
log_level=log_level,
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
msg = "Force constants calculator of %s was not found ." % fc_calculator
|
msg = "Force constants calculator of %s was not found ." % fc_calculator
|
||||||
raise RuntimeError(msg)
|
raise RuntimeError(msg)
|
||||||
|
|
|
@ -170,21 +170,21 @@ def si_pbesol_111(request) -> Phono3py:
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def si_pbesol_111_alm(request) -> Phono3py:
|
def si_pbesol_111_symfc(request) -> Phono3py:
|
||||||
"""Return Phono3py instance of Si 1x1x1.
|
"""Return Phono3py instance of Si 1x1x1.
|
||||||
|
|
||||||
* with symmetry
|
* with symmetry
|
||||||
* full fc
|
* full fc
|
||||||
* use alm if available on test side
|
* use symfc if available on test side
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pytest.importorskip("alm")
|
pytest.importorskip("symfc")
|
||||||
|
|
||||||
yaml_filename = cwd / "phono3py_params_Si111.yaml"
|
yaml_filename = cwd / "phono3py_params_Si111.yaml"
|
||||||
enable_v2 = request.config.getoption("--v2")
|
enable_v2 = request.config.getoption("--v2")
|
||||||
return phono3py.load(
|
return phono3py.load(
|
||||||
yaml_filename,
|
yaml_filename,
|
||||||
fc_calculator="alm",
|
fc_calculator="symfc",
|
||||||
make_r0_average=not enable_v2,
|
make_r0_average=not enable_v2,
|
||||||
log_level=1,
|
log_level=1,
|
||||||
)
|
)
|
||||||
|
@ -208,7 +208,7 @@ def si_pbesol_111_222_fd(request) -> Phono3py:
|
||||||
|
|
||||||
* with symmetry
|
* with symmetry
|
||||||
* full fc
|
* full fc
|
||||||
* use alm if available on test side
|
* use symfc if available on test side
|
||||||
|
|
||||||
"""
|
"""
|
||||||
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
||||||
|
@ -221,63 +221,63 @@ def si_pbesol_111_222_fd(request) -> Phono3py:
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def si_pbesol_111_222_alm(request) -> Phono3py:
|
def si_pbesol_111_222_symfc(request) -> Phono3py:
|
||||||
"""Return Phono3py instance of Si 1x1x1.
|
"""Return Phono3py instance of Si 1x1x1.
|
||||||
|
|
||||||
* with symmetry
|
* with symmetry
|
||||||
* full fc
|
* full fc
|
||||||
* use alm if available on test side
|
* use symfc if available on test side
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pytest.importorskip("alm")
|
pytest.importorskip("symfc")
|
||||||
|
|
||||||
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
||||||
enable_v2 = request.config.getoption("--v2")
|
enable_v2 = request.config.getoption("--v2")
|
||||||
return phono3py.load(
|
return phono3py.load(
|
||||||
yaml_filename,
|
yaml_filename,
|
||||||
fc_calculator="alm",
|
fc_calculator="symfc",
|
||||||
make_r0_average=not enable_v2,
|
make_r0_average=not enable_v2,
|
||||||
log_level=1,
|
log_level=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def si_pbesol_111_222_alm_fd(request) -> Phono3py:
|
def si_pbesol_111_222_symfc_fd(request) -> Phono3py:
|
||||||
"""Return Phono3py instance of Si 1x1x1.
|
"""Return Phono3py instance of Si 1x1x1.
|
||||||
|
|
||||||
* with symmetry
|
* with symmetry
|
||||||
* full fc
|
* full fc
|
||||||
* use alm for fc2 if available on test side
|
* use symfc for fc2 if available on test side
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pytest.importorskip("alm")
|
pytest.importorskip("symfc")
|
||||||
|
|
||||||
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
||||||
enable_v2 = request.config.getoption("--v2")
|
enable_v2 = request.config.getoption("--v2")
|
||||||
return phono3py.load(
|
return phono3py.load(
|
||||||
yaml_filename,
|
yaml_filename,
|
||||||
fc_calculator="alm|",
|
fc_calculator="symfc|",
|
||||||
make_r0_average=not enable_v2,
|
make_r0_average=not enable_v2,
|
||||||
log_level=1,
|
log_level=1,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(scope="session")
|
@pytest.fixture(scope="session")
|
||||||
def si_pbesol_111_222_fd_alm(request) -> Phono3py:
|
def si_pbesol_111_222_fd_symfc(request) -> Phono3py:
|
||||||
"""Return Phono3py instance of Si 1x1x1.
|
"""Return Phono3py instance of Si 1x1x1.
|
||||||
|
|
||||||
* with symmetry
|
* with symmetry
|
||||||
* full fc
|
* full fc
|
||||||
* use alm for fc3 if available on test side
|
* use symfc for fc3 if available on test side
|
||||||
|
|
||||||
"""
|
"""
|
||||||
pytest.importorskip("alm")
|
pytest.importorskip("symfc")
|
||||||
|
|
||||||
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
yaml_filename = cwd / "phono3py_params_Si-111-222.yaml"
|
||||||
enable_v2 = request.config.getoption("--v2")
|
enable_v2 = request.config.getoption("--v2")
|
||||||
return phono3py.load(
|
return phono3py.load(
|
||||||
yaml_filename,
|
yaml_filename,
|
||||||
fc_calculator="|alm",
|
fc_calculator="|symfc",
|
||||||
make_r0_average=not enable_v2,
|
make_r0_average=not enable_v2,
|
||||||
log_level=1,
|
log_level=1,
|
||||||
)
|
)
|
||||||
|
|
|
@ -65,12 +65,10 @@ def test_phono3py_load():
|
||||||
file_path.unlink()
|
file_path.unlink()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("fc_calculator,exit_code", [(None, 1), ("alm", 0)])
|
@pytest.mark.parametrize("fc_calculator,exit_code", [(None, 1), ("symfc", 0)])
|
||||||
def test_phono3py_load_with_typeII_dataset(fc_calculator, exit_code):
|
def test_phono3py_load_with_typeII_dataset(fc_calculator, exit_code):
|
||||||
"""Test phono3py-load script with typeII dataset."""
|
"""Test phono3py-load script with typeII dataset."""
|
||||||
# Check sys.exit(0)
|
pytest.importorskip("symfc")
|
||||||
if fc_calculator == "alm":
|
|
||||||
pytest.importorskip("alm")
|
|
||||||
argparse_control = _get_phono3py_load_args(
|
argparse_control = _get_phono3py_load_args(
|
||||||
cwd / ".." / "phono3py_params-Si111-rd.yaml.xz", fc_calculator=fc_calculator
|
cwd / ".." / "phono3py_params-Si111-rd.yaml.xz", fc_calculator=fc_calculator
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
import phono3py
|
import phono3py
|
||||||
|
from phono3py import Phono3py
|
||||||
from phono3py.phonon3.displacement_fc3 import get_smallest_vector_of_atom_pair
|
from phono3py.phonon3.displacement_fc3 import get_smallest_vector_of_atom_pair
|
||||||
|
|
||||||
distances_NaCl = [
|
distances_NaCl = [
|
||||||
|
@ -97,9 +98,13 @@ def test_duplicates_agno2(agno2_cell):
|
||||||
np.testing.assert_equal(duplicates_ref, ph3.dataset["duplicates"])
|
np.testing.assert_equal(duplicates_ref, ph3.dataset["duplicates"])
|
||||||
|
|
||||||
|
|
||||||
def test_nacl_pbe(nacl_pbe):
|
def test_nacl_pbe(nacl_pbe: Phono3py):
|
||||||
"""Test generated displacements and duplicates."""
|
"""Test generated displacements and duplicates."""
|
||||||
ph3 = nacl_pbe
|
ph3 = Phono3py(
|
||||||
|
nacl_pbe.unitcell,
|
||||||
|
supercell_matrix=nacl_pbe.supercell_matrix,
|
||||||
|
primitive_matrix=nacl_pbe.primitive_matrix,
|
||||||
|
)
|
||||||
ph3.generate_displacements()
|
ph3.generate_displacements()
|
||||||
duplicates_ref = [[77, 41]]
|
duplicates_ref = [[77, 41]]
|
||||||
ph3.dataset["duplicates"]
|
ph3.dataset["duplicates"]
|
||||||
|
|
|
@ -127,9 +127,9 @@ def test_phonon_smat_fd(si_pbesol_111_222_fd: Phono3py):
|
||||||
np.testing.assert_allclose(ph.fc2[0, 33], fc2_ref, atol=1e-6, rtol=0)
|
np.testing.assert_allclose(ph.fc2[0, 33], fc2_ref, atol=1e-6, rtol=0)
|
||||||
|
|
||||||
|
|
||||||
def test_phonon_smat_alm(si_pbesol_111_222_alm: Phono3py):
|
def test_phonon_smat_symfc(si_pbesol_111_222_symfc: Phono3py):
|
||||||
"""Test phonon smat and ALM with Si PBEsol 1x1x1-2x2x2."""
|
"""Test phonon smat and symfc with Si PBEsol 1x1x1-2x2x2."""
|
||||||
ph = si_pbesol_111_222_alm
|
ph = si_pbesol_111_222_symfc
|
||||||
fc3_ref = [
|
fc3_ref = [
|
||||||
[
|
[
|
||||||
[0.10725082, 0.0, 0.0],
|
[0.10725082, 0.0, 0.0],
|
||||||
|
@ -156,9 +156,9 @@ def test_phonon_smat_alm(si_pbesol_111_222_alm: Phono3py):
|
||||||
np.testing.assert_allclose(ph.fc2[0, 33], fc2_ref, atol=1e-6, rtol=0)
|
np.testing.assert_allclose(ph.fc2[0, 33], fc2_ref, atol=1e-6, rtol=0)
|
||||||
|
|
||||||
|
|
||||||
def test_phonon_smat_alm_fd(si_pbesol_111_222_alm_fd: Phono3py):
|
def test_phonon_smat_symfc_fd(si_pbesol_111_222_symfc_fd: Phono3py):
|
||||||
"""Test phonon smat and ALM (fc2) FD (fc3) with Si PBEsol 1x1x1-2x2x2."""
|
"""Test phonon smat and symfc (fc2) FD (fc3) with Si PBEsol 1x1x1-2x2x2."""
|
||||||
ph = si_pbesol_111_222_alm_fd
|
ph = si_pbesol_111_222_symfc_fd
|
||||||
fc3_ref = [
|
fc3_ref = [
|
||||||
[
|
[
|
||||||
[1.07250822e-01, 1.86302073e-17, -4.26452855e-18],
|
[1.07250822e-01, 1.86302073e-17, -4.26452855e-18],
|
||||||
|
@ -185,9 +185,9 @@ def test_phonon_smat_alm_fd(si_pbesol_111_222_alm_fd: Phono3py):
|
||||||
np.testing.assert_allclose(ph.fc2[0, 33], fc2_ref, atol=1e-6, rtol=0)
|
np.testing.assert_allclose(ph.fc2[0, 33], fc2_ref, atol=1e-6, rtol=0)
|
||||||
|
|
||||||
|
|
||||||
def test_phonon_smat_fd_alm(si_pbesol_111_222_fd_alm: Phono3py):
|
def test_phonon_smat_fd_symfc(si_pbesol_111_222_fd_symfc: Phono3py):
|
||||||
"""Test phonon smat and FD (fc2) ALM (fc3) with Si PBEsol 1x1x1-2x2x2."""
|
"""Test phonon smat and FD (fc2) symfc (fc3) with Si PBEsol 1x1x1-2x2x2."""
|
||||||
ph = si_pbesol_111_222_fd_alm
|
ph = si_pbesol_111_222_fd_symfc
|
||||||
fc3_ref = [
|
fc3_ref = [
|
||||||
[
|
[
|
||||||
[0.10725082, 0.0, 0.0],
|
[0.10725082, 0.0, 0.0],
|
||||||
|
@ -215,14 +215,14 @@ def test_phonon_smat_fd_alm(si_pbesol_111_222_fd_alm: Phono3py):
|
||||||
|
|
||||||
|
|
||||||
def test_phonon_smat_alm_cutoff(si_pbesol_111_222_alm_cutoff: Phono3py):
|
def test_phonon_smat_alm_cutoff(si_pbesol_111_222_alm_cutoff: Phono3py):
|
||||||
"""Test phonon smat and ALM with Si PBEsol 1x1x1-2x2x2 cutoff."""
|
"""Test phonon smat and alm with Si PBEsol 1x1x1-2x2x2 cutoff."""
|
||||||
ph = si_pbesol_111_222_alm_cutoff
|
ph = si_pbesol_111_222_alm_cutoff
|
||||||
np.testing.assert_allclose(ph.fc3[0, 1, 7], 0, atol=1e-6, rtol=0)
|
np.testing.assert_allclose(ph.fc3[0, 1, 7], 0, atol=1e-6, rtol=0)
|
||||||
np.testing.assert_allclose(ph.fc2[0, 33], 0, atol=1e-6, rtol=0)
|
np.testing.assert_allclose(ph.fc2[0, 33], 0, atol=1e-6, rtol=0)
|
||||||
|
|
||||||
|
|
||||||
def test_phonon_smat_alm_cutoff_fc2(si_pbesol_111_222_alm_cutoff_fc2: Phono3py):
|
def test_phonon_smat_alm_cutoff_fc2(si_pbesol_111_222_alm_cutoff_fc2: Phono3py):
|
||||||
"""Test phonon smat and ALM with Si PBEsol 1x1x1-2x2x2 cutoff fc2."""
|
"""Test phonon smat and alm with Si PBEsol 1x1x1-2x2x2 cutoff fc2."""
|
||||||
ph = si_pbesol_111_222_alm_cutoff_fc2
|
ph = si_pbesol_111_222_alm_cutoff_fc2
|
||||||
fc3_ref = [
|
fc3_ref = [
|
||||||
[
|
[
|
||||||
|
@ -246,7 +246,7 @@ def test_phonon_smat_alm_cutoff_fc2(si_pbesol_111_222_alm_cutoff_fc2: Phono3py):
|
||||||
|
|
||||||
|
|
||||||
def test_phonon_smat_alm_cutoff_fc3(si_pbesol_111_222_alm_cutoff_fc3: Phono3py):
|
def test_phonon_smat_alm_cutoff_fc3(si_pbesol_111_222_alm_cutoff_fc3: Phono3py):
|
||||||
"""Test phonon smat and ALM with Si PBEsol 1x1x1-2x2x2 cutoff fc3."""
|
"""Test phonon smat and alm with Si PBEsol 1x1x1-2x2x2 cutoff fc3."""
|
||||||
ph = si_pbesol_111_222_alm_cutoff_fc3
|
ph = si_pbesol_111_222_alm_cutoff_fc3
|
||||||
np.testing.assert_allclose(ph.fc3[0, 1, 7], 0, atol=1e-6, rtol=0)
|
np.testing.assert_allclose(ph.fc3[0, 1, 7], 0, atol=1e-6, rtol=0)
|
||||||
fc2_ref = [
|
fc2_ref = [
|
||||||
|
@ -293,10 +293,9 @@ def test_fc3_lapacke_solver(si_pbesol_111: Phono3py, pinv_solver: str):
|
||||||
np.testing.assert_allclose(fc3[0, 1, 7], fc3_ref, atol=1e-8, rtol=0)
|
np.testing.assert_allclose(fc3[0, 1, 7], fc3_ref, atol=1e-8, rtol=0)
|
||||||
|
|
||||||
|
|
||||||
# @pytest.mark.skipif(not FC_CALCULATOR_ALM_AVAILABLE, reason="not found ALM package")
|
def test_fc3_symfc(si_pbesol_111_symfc: Phono3py):
|
||||||
def test_fc3_alm(si_pbesol_111_alm: Phono3py):
|
"""Test fc3 with Si PBEsol 1x1x1 calcualted using symfc."""
|
||||||
"""Test fc3 with Si PBEsol 1x1x1 calcualted using ALM."""
|
ph = si_pbesol_111_symfc
|
||||||
ph = si_pbesol_111_alm
|
|
||||||
fc3_ref = [
|
fc3_ref = [
|
||||||
[
|
[
|
||||||
[0.10725082233069763, 0.0, 0.0],
|
[0.10725082233069763, 0.0, 0.0],
|
||||||
|
|
|
@ -277,13 +277,12 @@ def _test_disp_corr_matrix(ph3):
|
||||||
|
|
||||||
def test_fc3(si_pbesol_iterha_111):
|
def test_fc3(si_pbesol_iterha_111):
|
||||||
"""Test of ThirdOrderFC class."""
|
"""Test of ThirdOrderFC class."""
|
||||||
try:
|
pytest.importorskip("symfc")
|
||||||
import alm # noqa F401
|
|
||||||
except ModuleNotFoundError:
|
|
||||||
pytest.skip("Skip this test because ALM module was not found.")
|
|
||||||
|
|
||||||
ph = si_pbesol_iterha_111
|
ph = si_pbesol_iterha_111
|
||||||
ph.produce_force_constants(calculate_full_force_constants=True, fc_calculator="alm")
|
ph.produce_force_constants(
|
||||||
|
calculate_full_force_constants=True, fc_calculator="symfc"
|
||||||
|
)
|
||||||
supercell_phonon = SupercellPhonon(
|
supercell_phonon = SupercellPhonon(
|
||||||
ph.supercell,
|
ph.supercell,
|
||||||
ph.force_constants,
|
ph.force_constants,
|
||||||
|
|
Loading…
Reference in New Issue