Skip to content

Commit

Permalink
Merge pull request #208 from phonopy/kappadosthm
Browse files Browse the repository at this point in the history
Add KappaDOSTHM to replace KappaDOS
  • Loading branch information
atztogo authored Feb 19, 2024
2 parents d40986a + b9c7bd2 commit 3019fe9
Show file tree
Hide file tree
Showing 2 changed files with 165 additions and 46 deletions.
94 changes: 78 additions & 16 deletions phono3py/other/kaccum.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
"""Calculated accumulated property with respect to other property."""

from typing import Optional
from __future__ import annotations

import warnings
from collections.abc import Sequence
from typing import Optional, Union

import numpy as np
from phonopy.phonon.dos import NormalDistribution
Expand All @@ -11,34 +15,57 @@
epsilon = 1.0e-8


class KappaDOS:
"""Class to calculate thermal conductivity spectram."""
class KappaDOSTHM:
"""Class to calculate DOS like spectram with tetrahedron method.
To compute usual DOS,
kappados = KappaDOSTHM(
np.ones(freqs.shape)[None, :, :, None],
freqs,
bzgrid,
ir_grid_points,
ir_grid_weights=ir_weights,
ir_grid_map=ir_grid_map,
num_sampling_points=201
)
"""

def __init__(
self,
mode_kappa,
frequencies,
mode_kappa: np.ndarray,
frequencies: np.ndarray,
bz_grid: BZGrid,
ir_grid_points,
ir_grid_map=None,
frequency_points=None,
num_sampling_points=100,
ir_grid_points: np.ndarray,
ir_grid_weights: Optional[np.ndarray] = None,
ir_grid_map: Optional[np.ndarray] = None,
frequency_points: Optional[Union[np.ndarray, Sequence]] = None,
num_sampling_points: int = 100,
):
"""Init method.
Parameters
----------
mode_kappa : ndarray
Target value.
shape=(temperatures, ir_grid_points, num_band, num_elem),
dtype='double'
frequencies : ndarray
Frequencies at ir-grid points.
shape=(ir_grid_points, num_band), dtype='double'
bz_grid : BZGrid
ir_grid_points : ndarray
Ir-grid point indices in BZ-grid.
shape=(ir_grid_points, ), dtype='int_'
ir_grid_map : ndarray, optional, default=None
Mapping table to ir-grid point indices in GR-grid.
None gives `np.arange(len(frequencies), 'int_')`.
Irreducible grid point indices in GR-grid.
shape=(num_ir_grid_points, ), dtype='int_'
ir_grid_weights : ndarray
Weights of irreducible grid points. Its sum is the number of
grid points in GR-grid (prod(D_diag)).
shape=(num_ir_grid_points, ), dtype='int_'
ir_grid_map : ndarray
Index mapping table to irreducible grid points from all grid points
such as, [0, 0, 2, 3, 3, ...].
shape=(prod(D_diag), ), dtype='int_'
frequency_points : array_like, optional, default=None
This is used as the frequency points. When None,
frequency points are created from `num_sampling_points`.
Expand All @@ -64,18 +91,22 @@ def __init__(
bzgp2irgp_map = None
else:
bzgp2irgp_map = self._get_bzgp2irgp_map(bz_grid, ir_grid_map)
if ir_grid_weights is None:
grid_weights = np.ones(mode_kappa.shape[1])
else:
grid_weights = ir_grid_weights
for j, function in enumerate(("J", "I")):
iweights = get_integration_weights(
self._frequency_points,
frequencies,
bz_grid,
grid_points=ir_grid_points,
grid_points=bz_grid.grg2bzg[ir_grid_points],
bzgp2irgp_map=bzgp2irgp_map,
function=function,
)
for i, iw in enumerate(iweights):
self._kdos[:, :, j] += np.transpose(
np.dot(iw, mode_kappa[:, i]), axes=(1, 0, 2)
np.dot(iw, mode_kappa[:, i] * grid_weights[i]), axes=(1, 0, 2)
)
self._kdos /= np.prod(bz_grid.D_diag)

Expand Down Expand Up @@ -103,6 +134,37 @@ def _get_bzgp2irgp_map(self, bz_grid, ir_grid_map):
return bzgp2irgp_map


class KappaDOS(KappaDOSTHM):
"""Deprecated class to calculate DOS like spectram with tetrahedron method."""

def __init__(
self,
mode_kappa: np.ndarray,
frequencies: np.ndarray,
bz_grid: BZGrid,
ir_grid_points: np.ndarray,
ir_grid_map: Optional[np.ndarray] = None,
frequency_points: Optional[np.ndarray] = None,
num_sampling_points: int = 100,
):
"""Init method."""
warnings.warn(
"KappaDOS is deprecated."
"Use KappaDOSTHM instead with replacing ir_grid_points in BZ-grid "
"by ir_grid_points in GR-grid.",
DeprecationWarning,
)
super().__init__(
mode_kappa,
frequencies,
bz_grid,
bz_grid.bzg2grg[ir_grid_points],
ir_grid_map=ir_grid_map,
frequency_points=frequency_points,
num_sampling_points=num_sampling_points,
)


class GammaDOSsmearing:
"""Class to calculate Gamma spectram by smearing method."""

Expand Down
117 changes: 87 additions & 30 deletions test/other/test_kaccum.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,19 @@
"""Test for kaccum.py."""

from __future__ import annotations

from typing import Optional

import numpy as np
import pytest

from phono3py import Phono3py
from phono3py.other.kaccum import GammaDOSsmearing, KappaDOS, get_mfp
from phono3py.other.kaccum import GammaDOSsmearing, KappaDOS, KappaDOSTHM, get_mfp
from phono3py.phonon.grid import get_ir_grid_points


def test_kappados_si(si_pbesol: Phono3py):
@pytest.mark.parametrize("use_legacy_class", [False, True])
def test_kappados_si(si_pbesol: Phono3py, use_legacy_class: bool):
"""Test KappaDOS class with Si.
* 3x3 tensor vs frequency
Expand Down Expand Up @@ -101,7 +107,10 @@ def test_kappados_si(si_pbesol: Phono3py):
tc = ph3.thermal_conductivity
freq_points_in = np.array(kappados_si).reshape(-1, 3)[:, 0]
freq_points, kdos = _calculate_kappados(
ph3, tc.mode_kappa[0], freq_points=freq_points_in
ph3,
tc.mode_kappa[0],
freq_points=freq_points_in,
use_legacy_class=use_legacy_class,
)
# for f, (jval, ival) in zip(freq_points, kdos):
# print("[%.7f, %.7f, %.7f]," % (f, jval, ival))
Expand All @@ -110,7 +119,10 @@ def test_kappados_si(si_pbesol: Phono3py):
)

freq_points, kdos = _calculate_kappados(
ph3, tc.gamma[0, :, :, :, None], freq_points=freq_points_in
ph3,
tc.gamma[0, :, :, :, None],
freq_points=freq_points_in,
use_legacy_class=use_legacy_class,
)
# for f, (jval, ival) in zip(freq_points, kdos):
# print("[%.7f, %.7f, %.7f]," % (f, jval, ival))
Expand All @@ -119,15 +131,18 @@ def test_kappados_si(si_pbesol: Phono3py):
)

mfp_points_in = np.array(mfpdos_si).reshape(-1, 3)[:, 0]
mfp_points, mfpdos = _calculate_mfpdos(ph3, mfp_points_in)
mfp_points, mfpdos = _calculate_mfpdos(
ph3, mfp_points_in, use_legacy_class=use_legacy_class
)
# for f, (jval, ival) in zip(mfp_points, mfpdos):
# print("[%.7f, %.7f, %.7f]," % (f, jval, ival))
np.testing.assert_allclose(
mfpdos_si, np.vstack((mfp_points, mfpdos.T)).T, rtol=0, atol=0.5
)


def test_kappados_nacl(nacl_pbe: Phono3py):
@pytest.mark.parametrize("use_legacy_class", [False, True])
def test_kappados_nacl(nacl_pbe: Phono3py, use_legacy_class: bool):
"""Test KappaDOS class with NaCl.
* 3x3 tensor vs frequency
Expand Down Expand Up @@ -230,7 +245,10 @@ def test_kappados_nacl(nacl_pbe: Phono3py):
)

freq_points, kdos = _calculate_kappados(
ph3, tc.gamma[0, :, :, :, None], freq_points=freq_points_in
ph3,
tc.gamma[0, :, :, :, None],
freq_points=freq_points_in,
use_legacy_class=use_legacy_class,
)
for f, (jval, ival) in zip(freq_points, kdos):
print("[%.7f, %.7f, %.7f]," % (f, jval, ival))
Expand All @@ -239,7 +257,9 @@ def test_kappados_nacl(nacl_pbe: Phono3py):
)

mfp_points_in = np.array(mfpdos_nacl).reshape(-1, 3)[:, 0]
mfp_points, mfpdos = _calculate_mfpdos(ph3, mfp_points_in)
mfp_points, mfpdos = _calculate_mfpdos(
ph3, mfp_points_in, use_legacy_class=use_legacy_class
)
# for f, (jval, ival) in zip(mfp_points, mfpdos):
# print("[%.7f, %.7f, %.7f]," % (f, jval, ival))
np.testing.assert_allclose(
Expand Down Expand Up @@ -281,24 +301,45 @@ def test_GammaDOSsmearing(nacl_pbe: Phono3py):
)


def _calculate_kappados(ph3: Phono3py, mode_prop, freq_points=None):
def _calculate_kappados(
ph3: Phono3py,
mode_prop: np.ndarray,
freq_points: Optional[np.ndarray] = None,
use_legacy_class: bool = False,
):
tc = ph3.thermal_conductivity
bz_grid = ph3.grid
frequencies, _, _ = ph3.get_phonon_data()
kappados = KappaDOS(
mode_prop, frequencies, bz_grid, tc.grid_points, frequency_points=freq_points
)
with pytest.deprecated_call():
kappados = KappaDOS(
mode_prop,
frequencies,
bz_grid,
tc.grid_points,
frequency_points=freq_points,
)
freq_points, kdos = kappados.get_kdos()

ir_grid_points, _, ir_grid_map = get_ir_grid_points(bz_grid)
kappados = KappaDOS(
mode_prop,
tc.frequencies,
bz_grid,
tc.grid_points,
ir_grid_map=ir_grid_map,
frequency_points=freq_points,
)
if use_legacy_class:
with pytest.deprecated_call():
kappados = KappaDOS(
mode_prop,
tc.frequencies,
bz_grid,
tc.grid_points,
ir_grid_map=ir_grid_map,
frequency_points=freq_points,
)
else:
kappados = KappaDOSTHM(
mode_prop,
tc.frequencies,
bz_grid,
bz_grid.bzg2grg[tc.grid_points],
ir_grid_map=ir_grid_map,
frequency_points=freq_points,
)
ir_freq_points, ir_kdos = kappados.get_kdos()
np.testing.assert_equal(bz_grid.bzg2grg[tc.grid_points], ir_grid_points)
np.testing.assert_allclose(ir_freq_points, freq_points, rtol=0, atol=1e-5)
Expand All @@ -307,20 +348,36 @@ def _calculate_kappados(ph3: Phono3py, mode_prop, freq_points=None):
return freq_points, kdos[0, :, :, 0]


def _calculate_mfpdos(ph3: Phono3py, mfp_points=None):
def _calculate_mfpdos(
ph3: Phono3py,
mfp_points=None,
use_legacy_class: bool = False,
):
tc = ph3.thermal_conductivity
bz_grid = ph3.grid
mean_freepath = get_mfp(tc.gamma[0], tc.group_velocities)
_, _, ir_grid_map = get_ir_grid_points(bz_grid)
mfpdos = KappaDOS(
tc.mode_kappa[0],
mean_freepath[0],
bz_grid,
tc.grid_points,
ir_grid_map=ir_grid_map,
frequency_points=mfp_points,
num_sampling_points=10,
)
if use_legacy_class:
with pytest.deprecated_call():
mfpdos = KappaDOS(
tc.mode_kappa[0],
mean_freepath[0],
bz_grid,
tc.grid_points,
ir_grid_map=ir_grid_map,
frequency_points=mfp_points,
num_sampling_points=10,
)
else:
mfpdos = KappaDOSTHM(
tc.mode_kappa[0],
mean_freepath[0],
bz_grid,
bz_grid.bzg2grg[tc.grid_points],
ir_grid_map=ir_grid_map,
frequency_points=mfp_points,
num_sampling_points=10,
)
freq_points, kdos = mfpdos.get_kdos()

return freq_points, kdos[0, :, :, 0]

0 comments on commit 3019fe9

Please sign in to comment.