Plus-minus random directional displacements

This commit is contained in:
Atsushi Togo 2022-05-30 11:40:33 +09:00
parent d80681a27b
commit e89e856aed
4 changed files with 82 additions and 25 deletions

View File

@ -36,6 +36,7 @@
import sys
import textwrap
import warnings
from typing import Optional, Union
import numpy as np
@ -885,14 +886,14 @@ class Phonopy:
def generate_displacements(
self,
distance=0.01,
is_plusminus="auto",
is_diagonal=True,
is_trigonal=False,
number_of_snapshots=None,
random_seed=None,
temperature=None,
cutoff_frequency=None,
distance: float = 0.01,
is_plusminus: Union[str, bool] = "auto",
is_diagonal: bool = True,
is_trigonal: bool = False,
number_of_snapshots: Optional[int] = None,
random_seed: Optional[int] = None,
temperature: Optional[float] = None,
cutoff_frequency: Optional[float] = None,
):
"""Generate displacement dataset.
@ -945,16 +946,14 @@ class Phonopy:
this value.
"""
if (
np.issubdtype(type(number_of_snapshots), np.integer)
and number_of_snapshots > 0
): # noqa: E129
if number_of_snapshots is not None and number_of_snapshots > 0:
if temperature is None:
displacement_dataset = get_random_displacements_dataset(
number_of_snapshots,
distance,
len(self._supercell),
random_seed=random_seed,
is_plusminus=(is_plusminus is True),
)
else:
self.run_random_displacements(
@ -3262,11 +3261,11 @@ class Phonopy:
def run_random_displacements(
self,
temperature,
number_of_snapshots=1,
random_seed=None,
dist_func=None,
cutoff_frequency=None,
temperature: float,
number_of_snapshots: int = 1,
random_seed: Optional[int] = None,
dist_func: Optional[str] = None,
cutoff_frequency: Optional[float] = None,
):
"""Generate random displacements from phonon structure.
@ -3434,7 +3433,7 @@ class Phonopy:
self._dynamical_matrix.is_nac()
and self._dynamical_matrix.nac_method == "gonze"
and self._gv_delta_q is None
): # noqa E129
):
if self._log_level:
msg = "Group velocity calculation:\n"
text = (

View File

@ -33,6 +33,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from typing import Optional
import numpy as np
directions_axis = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
@ -238,14 +240,14 @@ def _determinant(a, b, c):
def get_random_displacements_dataset(
num_supercells, distance, num_atoms, random_seed=None
num_supercells: int,
distance: float,
num_atoms: int,
random_seed: Optional[int] = None,
is_plusminus: bool = False,
):
"""Return random displacements at constant displacement distance."""
if (
np.issubdtype(type(random_seed), np.integer)
and random_seed >= 0
and random_seed < 2**32
):
if random_seed is not None and random_seed >= 0 and random_seed < 2**32:
seed = random_seed
else:
seed = None
@ -257,6 +259,9 @@ def get_random_displacements_dataset(
supercell_disps = np.array(
disps.reshape(num_supercells, num_atoms, 3), dtype="double", order="C"
)
if is_plusminus is True:
supercell_disps = np.concatenate((supercell_disps, -supercell_disps), axis=0)
dataset = {"displacements": supercell_disps}
if seed is not None:

View File

@ -33,6 +33,8 @@
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from typing import Optional, Tuple
import numpy as np
from phonopy.harmonic.dynamical_matrix import get_dynamical_matrix
@ -185,7 +187,13 @@ class RandomDisplacements:
self._uu = None
self._uu_inv = None
def run(self, T, number_of_snapshots=1, random_seed=None, randn=None):
def run(
self,
T: float,
number_of_snapshots: int = 1,
random_seed: Optional[int] = None,
randn: Optional[Tuple] = None,
):
"""Calculate random displacements.
Parameters

View File

@ -70,6 +70,51 @@ def test_tio2(ph_tio2: Phonopy):
ph_tio2.dataset = dataset
def test_tio2_random_disp(ph_tio2: Phonopy):
"""Test random displacements of TiO2."""
dataset = deepcopy(ph_tio2.dataset)
disp_ref = [
[0, 0.01, 0.0, 0.0],
[0, 0.0, 0.01, 0.0],
[0, 0.0, 0.0, 0.01],
[0, 0.0, 0.0, -0.01],
[72, 0.01, 0.0, 0.0],
[72, 0.0, 0.0, 0.01],
]
np.testing.assert_allclose(ph_tio2.displacements, disp_ref, atol=1e-8)
ph_tio2.generate_displacements(number_of_snapshots=4, distance=0.03)
d = ph_tio2.displacements
np.testing.assert_allclose(np.linalg.norm(d, axis=2).ravel(), 0.03, atol=1e-8)
ph_tio2.dataset = dataset
def test_tio2_random_disp_plusminus(ph_tio2: Phonopy):
"""Test random plus-minus displacements of TiO2.
Note
----
Displacements of last 4 supercells are minus of those of first 4 supercells.
"""
dataset = deepcopy(ph_tio2.dataset)
disp_ref = [
[0, 0.01, 0.0, 0.0],
[0, 0.0, 0.01, 0.0],
[0, 0.0, 0.0, 0.01],
[0, 0.0, 0.0, -0.01],
[72, 0.01, 0.0, 0.0],
[72, 0.0, 0.0, 0.01],
]
np.testing.assert_allclose(ph_tio2.displacements, disp_ref, atol=1e-8)
ph_tio2.generate_displacements(
number_of_snapshots=4, distance=0.03, is_plusminus=True
)
d = ph_tio2.displacements
np.testing.assert_allclose(d[:4], -d[4:], atol=1e-8)
np.testing.assert_allclose(np.linalg.norm(d, axis=2).ravel(), 0.03, atol=1e-8)
ph_tio2.dataset = dataset
def test_zr3n4(ph_zr3n4: Phonopy):
"""Test displacements of Zr3N4."""
dataset = deepcopy(ph_zr3n4.dataset)