mirror of https://github.com/phonopy/phonopy.git
Writing docstrings following pydocstring
This commit is contained in:
parent
eb344cb67c
commit
fe68d75f1a
|
@ -1,5 +1,4 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""Example of QHA calculation by Al."""
|
||||
import numpy as np
|
||||
import yaml
|
||||
from yaml import CLoader as Loader
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
"""Example of NaCl calculation."""
|
||||
from typing import List
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy import Phonopy
|
||||
|
@ -7,7 +10,7 @@ from phonopy.interface.vasp import read_vasp
|
|||
# from phonopy.structure.atoms import PhonopyAtoms
|
||||
|
||||
|
||||
def append_band(bands, q_start, q_end):
|
||||
def _append_band(bands, q_start, q_end):
|
||||
band = []
|
||||
for i in range(51):
|
||||
band.append(np.array(q_start) + (np.array(q_end) - np.array(q_start)) / 50 * i)
|
||||
|
@ -61,11 +64,11 @@ nac_params = parse_BORN(primitive, filename="BORN")
|
|||
phonon.nac_params = nac_params
|
||||
|
||||
# BAND = 0.0 0.0 0.0 0.5 0.0 0.0 0.5 0.5 0.0 0.0 0.0 0.0 0.5 0.5 0.5
|
||||
bands = []
|
||||
append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.0, 0.0])
|
||||
append_band(bands, [0.5, 0.0, 0.0], [0.5, 0.5, 0.0])
|
||||
append_band(bands, [0.5, 0.5, 0.0], [0.0, 0.0, 0.0])
|
||||
append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.5, 0.5])
|
||||
bands = List[List]
|
||||
_append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.0, 0.0])
|
||||
_append_band(bands, [0.5, 0.0, 0.0], [0.5, 0.5, 0.0])
|
||||
_append_band(bands, [0.5, 0.5, 0.0], [0.0, 0.0, 0.0])
|
||||
_append_band(bands, [0.0, 0.0, 0.0], [0.5, 0.5, 0.5])
|
||||
phonon.set_band_structure(bands)
|
||||
band_dict = phonon.get_band_structure_dict()
|
||||
q_points = band_dict["qpoints"]
|
||||
|
|
|
@ -1,108 +0,0 @@
|
|||
import numpy as np
|
||||
from ase import Atoms
|
||||
from gpaw import GPAW, PW
|
||||
|
||||
from phonopy import Phonopy
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
|
||||
|
||||
def get_gpaw(kpts_size=None):
|
||||
if kpts_size is None:
|
||||
calc = GPAW(mode=PW(300), kpts={"size": (2, 2, 2)})
|
||||
else:
|
||||
calc = GPAW(mode=PW(300), kpts={"size": kpts_size})
|
||||
return calc
|
||||
|
||||
|
||||
def get_crystal():
|
||||
a = 5.404
|
||||
cell = PhonopyAtoms(
|
||||
symbols=(["Si"] * 8),
|
||||
cell=np.diag((a, a, a)),
|
||||
scaled_positions=[
|
||||
(0, 0, 0),
|
||||
(0, 0.5, 0.5),
|
||||
(0.5, 0, 0.5),
|
||||
(0.5, 0.5, 0),
|
||||
(0.25, 0.25, 0.25),
|
||||
(0.25, 0.75, 0.75),
|
||||
(0.75, 0.25, 0.75),
|
||||
(0.75, 0.75, 0.25),
|
||||
],
|
||||
)
|
||||
return cell
|
||||
|
||||
|
||||
def phonopy_pre_process(cell, supercell_matrix=None):
|
||||
|
||||
if supercell_matrix is None:
|
||||
smat = ([[2, 0, 0], [0, 2, 0], [0, 0, 2]],)
|
||||
else:
|
||||
smat = supercell_matrix
|
||||
phonon = Phonopy(
|
||||
cell, smat, primitive_matrix=[[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]
|
||||
)
|
||||
phonon.generate_displacements(distance=0.03)
|
||||
print("[Phonopy] Atomic displacements:")
|
||||
disps = phonon.get_displacements()
|
||||
for d in disps:
|
||||
print("[Phonopy] %d %s" % (d[0], d[1:]))
|
||||
return phonon
|
||||
|
||||
|
||||
def run_gpaw(calc, phonon):
|
||||
supercells = phonon.get_supercells_with_displacements()
|
||||
# Force calculations by calculator
|
||||
set_of_forces = []
|
||||
for scell in supercells:
|
||||
cell = Atoms(
|
||||
symbols=scell.get_chemical_symbols(),
|
||||
scaled_positions=scell.get_scaled_positions(),
|
||||
cell=scell.get_cell(),
|
||||
pbc=True,
|
||||
)
|
||||
cell.set_calculator(calc)
|
||||
forces = cell.get_forces()
|
||||
drift_force = forces.sum(axis=0)
|
||||
print(("[Phonopy] Drift force:" + "%11.5f" * 3) % tuple(drift_force))
|
||||
# Simple translational invariance
|
||||
for force in forces:
|
||||
force -= drift_force / forces.shape[0]
|
||||
set_of_forces.append(forces)
|
||||
return set_of_forces
|
||||
|
||||
|
||||
def phonopy_post_process(phonon, set_of_forces):
|
||||
phonon.produce_force_constants(forces=set_of_forces)
|
||||
print("")
|
||||
print("[Phonopy] Phonon frequencies at Gamma:")
|
||||
for i, freq in enumerate(phonon.get_frequencies((0, 0, 0))):
|
||||
print("[Phonopy] %3d: %10.5f THz" % (i + 1, freq)) # THz
|
||||
|
||||
# DOS
|
||||
phonon.set_mesh([21, 21, 21])
|
||||
phonon.set_total_DOS(tetrahedron_method=True)
|
||||
print("")
|
||||
print("[Phonopy] Phonon DOS:")
|
||||
for omega, dos in np.array(phonon.get_total_DOS()).T:
|
||||
print("%15.7f%15.7f" % (omega, dos))
|
||||
|
||||
|
||||
def main():
|
||||
cell = get_crystal()
|
||||
|
||||
# 1x1x1 supercell of conventional unit cell
|
||||
calc = get_gpaw(kpts_size=(4, 4, 4))
|
||||
phonon = phonopy_pre_process(cell, supercell_matrix=np.eye(3, dtype="intc"))
|
||||
|
||||
# # 2x2x2 supercell of conventional unit cell
|
||||
# calc = get_gpaw(kpts_size=(2, 2, 2))
|
||||
# phonon = phonopy_pre_process(cell,
|
||||
# supercell_matrix=(np.eye(3, dtype='intc') * 2))
|
||||
|
||||
set_of_forces = run_gpaw(calc, phonon)
|
||||
phonopy_post_process(phonon, set_of_forces)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
|
@ -2677,7 +2677,7 @@ class Phonopy:
|
|||
if temperatures is None:
|
||||
td.set_temperature_range(t_min, t_max, t_step)
|
||||
else:
|
||||
td.set_temperatures(temperatures)
|
||||
td.temperatures = temperatures
|
||||
td.run()
|
||||
|
||||
self._thermal_displacements = td
|
||||
|
@ -2802,7 +2802,7 @@ class Phonopy:
|
|||
if temperatures is None:
|
||||
tdm.set_temperature_range(t_min, t_max, t_step)
|
||||
else:
|
||||
tdm.set_temperatures(temperatures)
|
||||
tdm.temperatures = temperatures
|
||||
tdm.run()
|
||||
|
||||
self._thermal_displacement_matrices = tdm
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
"""Routines for command user interface."""
|
||||
# Copyright (C) 2021 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of phonopy.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# * Neither the name of the phonopy project nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1347,7 +1347,7 @@ def run(phonon: Phonopy, settings, plot_conf, log_level):
|
|||
if ph_mode[1] < 0 or ph_mode[1] >= num_band:
|
||||
error_indices.append(i)
|
||||
if log_level:
|
||||
text = "%d: q%s, band index=%d, amplitude=%f" % (
|
||||
text = "%d: q=%s, band index=%d, amplitude=%f" % (
|
||||
i + 1,
|
||||
ph_mode[0],
|
||||
ph_mode[1] + 1,
|
||||
|
|
|
@ -33,22 +33,28 @@
|
|||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from typing import Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix, DynamicalMatrixNAC
|
||||
from phonopy.phonon.band_structure import estimate_band_connection
|
||||
from phonopy.phonon.degeneracy import rotate_eigenvectors
|
||||
|
||||
|
||||
class GruneisenBase:
|
||||
"""Base class of mode Grueneisen parameter calculation classes."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
dynmat,
|
||||
dynmat_plus,
|
||||
dynmat_minus,
|
||||
dynmat: Union[DynamicalMatrix, DynamicalMatrixNAC],
|
||||
dynmat_plus: Union[DynamicalMatrix, DynamicalMatrixNAC],
|
||||
dynmat_minus: Union[DynamicalMatrix, DynamicalMatrixNAC],
|
||||
delta_strain=None,
|
||||
qpoints=None,
|
||||
is_band_connection=False,
|
||||
):
|
||||
"""Init method."""
|
||||
self._dynmat = dynmat
|
||||
self._dynmat_plus = dynmat_plus
|
||||
self._dynmat_minus = dynmat_minus
|
||||
|
@ -69,16 +75,20 @@ class GruneisenBase:
|
|||
self._set_gruneisen()
|
||||
|
||||
def set_qpoints(self, qpoints):
|
||||
"""Set q-points."""
|
||||
self._qpoints = qpoints
|
||||
self._set_gruneisen()
|
||||
|
||||
def get_gruneisen(self):
|
||||
"""Return mode Grueneisen parameters."""
|
||||
return self._gruneisen
|
||||
|
||||
def get_eigenvalues(self):
|
||||
"""Return eigenvalues."""
|
||||
return self._eigenvalues
|
||||
|
||||
def get_eigenvectors(self):
|
||||
"""Return eigenvectors."""
|
||||
return self._eigenvectors
|
||||
|
||||
def _set_gruneisen(self):
|
||||
|
@ -124,7 +134,12 @@ class GruneisenBase:
|
|||
)
|
||||
self._gruneisen = -edDe / self._delta_strain / self._eigenvalues / 2
|
||||
|
||||
def _get_dD(self, q, d_a, d_b):
|
||||
def _get_dD(
|
||||
self,
|
||||
q,
|
||||
d_a: Union[DynamicalMatrix, DynamicalMatrixNAC],
|
||||
d_b: Union[DynamicalMatrix, DynamicalMatrixNAC],
|
||||
):
|
||||
if self._is_band_connection and d_a.is_nac() and d_b.is_nac():
|
||||
d_a.run(q, q_direction=self._q_direction)
|
||||
d_b.run(q, q_direction=self._q_direction)
|
||||
|
|
|
@ -33,8 +33,12 @@
|
|||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import warnings
|
||||
from typing import Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix, DynamicalMatrixNAC
|
||||
from phonopy.structure.cells import sparse_to_dense_svecs
|
||||
|
||||
|
||||
|
@ -50,7 +54,7 @@ class DerivativeOfDynamicalMatrix:
|
|||
|
||||
"""
|
||||
|
||||
def __init__(self, dynamical_matrix):
|
||||
def __init__(self, dynamical_matrix: Union[DynamicalMatrix, DynamicalMatrixNAC]):
|
||||
"""Init method.
|
||||
|
||||
Parameters
|
||||
|
@ -117,6 +121,11 @@ class DerivativeOfDynamicalMatrix:
|
|||
|
||||
def get_derivative_of_dynamical_matrix(self):
|
||||
"""Return derivative of dynamical matrix."""
|
||||
warnings.warn(
|
||||
"DerivativeOfDynamicalMatrix.get_derivative_of_dynamical_matrix() is "
|
||||
"deprecated. Use d_dynamical_matrix attribute instead.",
|
||||
DeprecationWarning,
|
||||
)
|
||||
return self.d_dynamical_matrix
|
||||
|
||||
def _run_c(self, q, q_direction=None):
|
||||
|
|
|
@ -36,56 +36,13 @@
|
|||
|
||||
import sys
|
||||
import warnings
|
||||
from typing import Type, Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy.harmonic.dynmat_to_fc import DynmatToForceConstants
|
||||
from phonopy.structure.cells import sparse_to_dense_svecs
|
||||
|
||||
|
||||
def get_dynamical_matrix(
|
||||
fc2,
|
||||
supercell,
|
||||
primitive,
|
||||
nac_params=None,
|
||||
frequency_scale_factor=None,
|
||||
decimals=None,
|
||||
symprec=1e-5,
|
||||
log_level=0,
|
||||
):
|
||||
"""Return dynamical matrix.
|
||||
|
||||
The instance of a class inherited from DynamicalMatrix will be returned
|
||||
depending on paramters.
|
||||
|
||||
"""
|
||||
if frequency_scale_factor is None:
|
||||
_fc2 = fc2
|
||||
else:
|
||||
_fc2 = fc2 * frequency_scale_factor ** 2
|
||||
|
||||
if nac_params is None:
|
||||
dm = DynamicalMatrix(supercell, primitive, _fc2, decimals=decimals)
|
||||
else:
|
||||
if "method" not in nac_params:
|
||||
method = "gonze"
|
||||
else:
|
||||
method = nac_params["method"]
|
||||
|
||||
if method == "wang":
|
||||
DM_cls = DynamicalMatrixWang
|
||||
else:
|
||||
DM_cls = DynamicalMatrixGL
|
||||
dm = DM_cls(
|
||||
supercell,
|
||||
primitive,
|
||||
_fc2,
|
||||
decimals=decimals,
|
||||
symprec=symprec,
|
||||
log_level=log_level,
|
||||
)
|
||||
dm.nac_params = nac_params
|
||||
return dm
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
from phonopy.structure.cells import Primitive, sparse_to_dense_svecs
|
||||
|
||||
|
||||
class DynamicalMatrix:
|
||||
|
@ -109,8 +66,8 @@ class DynamicalMatrix:
|
|||
primitive: Primitive
|
||||
Primitive cell instance. Note that Primitive is inherited from
|
||||
PhonopyAtoms.
|
||||
supercell: Supercell
|
||||
Supercell instance. Note that Supercell is inherited from PhonopyAtoms.
|
||||
supercell: PhonopyAtoms.
|
||||
Supercell instance.
|
||||
force_constants: ndarray
|
||||
Supercell force constants. Full and compact shapes of arrays are
|
||||
supported.
|
||||
|
@ -127,12 +84,18 @@ class DynamicalMatrix:
|
|||
# Non analytical term correction
|
||||
_nac = False
|
||||
|
||||
def __init__(self, supercell, primitive, force_constants, decimals=None):
|
||||
def __init__(
|
||||
self,
|
||||
supercell: PhonopyAtoms,
|
||||
primitive: Primitive,
|
||||
force_constants,
|
||||
decimals=None,
|
||||
):
|
||||
"""Init method.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
supercell : Supercell
|
||||
supercell : PhonopyAtoms.
|
||||
Supercell.
|
||||
primitive : Primitive
|
||||
Primitive cell.
|
||||
|
@ -208,7 +171,7 @@ class DynamicalMatrix:
|
|||
return self.supercell
|
||||
|
||||
@property
|
||||
def primitive(self):
|
||||
def primitive(self) -> Primitive:
|
||||
"""Return primitive cell."""
|
||||
return self._pcell
|
||||
|
||||
|
@ -287,8 +250,6 @@ class DynamicalMatrix:
|
|||
|
||||
def _run(self, q, lang="C"):
|
||||
if lang == "C":
|
||||
import phonopy._phonopy as phonoc # noqa F401
|
||||
|
||||
self._run_c_dynamical_matrix(q)
|
||||
else:
|
||||
self._run_py_dynamical_matrix(q)
|
||||
|
@ -392,8 +353,8 @@ class DynamicalMatrixNAC(DynamicalMatrix):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
supercell,
|
||||
primitive,
|
||||
supercell: PhonopyAtoms,
|
||||
primitive: Primitive,
|
||||
force_constants,
|
||||
symprec=1e-5,
|
||||
decimals=None,
|
||||
|
@ -403,7 +364,7 @@ class DynamicalMatrixNAC(DynamicalMatrix):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
supercell : Supercell
|
||||
supercell : PhonopyAtoms
|
||||
Supercell.
|
||||
primitive : Primitive
|
||||
Primitive cell.
|
||||
|
@ -577,8 +538,8 @@ class DynamicalMatrixGL(DynamicalMatrixNAC):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
supercell,
|
||||
primitive,
|
||||
supercell: PhonopyAtoms,
|
||||
primitive: Primitive,
|
||||
force_constants,
|
||||
nac_params=None,
|
||||
num_G_points=None, # For Gonze NAC
|
||||
|
@ -937,8 +898,8 @@ class DynamicalMatrixWang(DynamicalMatrixNAC):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
supercell,
|
||||
primitive,
|
||||
supercell: PhonopyAtoms,
|
||||
primitive: Primitive,
|
||||
force_constants,
|
||||
nac_params=None,
|
||||
decimals=None,
|
||||
|
@ -949,7 +910,7 @@ class DynamicalMatrixWang(DynamicalMatrixNAC):
|
|||
|
||||
Parameters
|
||||
----------
|
||||
supercell : Supercell
|
||||
supercell : PhonopyAtoms
|
||||
Supercell.
|
||||
primitive : Primitive
|
||||
Primitive cell.
|
||||
|
@ -1068,3 +1029,49 @@ class DynamicalMatrixWang(DynamicalMatrixNAC):
|
|||
for s2 in range(len(self._scell)):
|
||||
p2 = self._s2pp_map[s2]
|
||||
fc[s1, s2] += nac_q[p1, p2] / N
|
||||
|
||||
|
||||
def get_dynamical_matrix(
|
||||
fc2,
|
||||
supercell: PhonopyAtoms,
|
||||
primitive: Primitive,
|
||||
nac_params=None,
|
||||
frequency_scale_factor=None,
|
||||
decimals=None,
|
||||
symprec=1e-5,
|
||||
log_level=0,
|
||||
):
|
||||
"""Return dynamical matrix.
|
||||
|
||||
The instance of a class inherited from DynamicalMatrix will be returned
|
||||
depending on paramters.
|
||||
|
||||
"""
|
||||
if frequency_scale_factor is None:
|
||||
_fc2 = fc2
|
||||
else:
|
||||
_fc2 = fc2 * frequency_scale_factor ** 2
|
||||
|
||||
if nac_params is None:
|
||||
dm = DynamicalMatrix(supercell, primitive, _fc2, decimals=decimals)
|
||||
else:
|
||||
if "method" not in nac_params:
|
||||
method = "gonze"
|
||||
else:
|
||||
method = nac_params["method"]
|
||||
|
||||
DM_cls: Union[Type[DynamicalMatrixGL], Type[DynamicalMatrixWang]]
|
||||
if method == "wang":
|
||||
DM_cls = DynamicalMatrixWang
|
||||
else:
|
||||
DM_cls = DynamicalMatrixGL
|
||||
dm = DM_cls(
|
||||
supercell,
|
||||
primitive,
|
||||
_fc2,
|
||||
decimals=decimals,
|
||||
symprec=symprec,
|
||||
log_level=log_level,
|
||||
)
|
||||
dm.nac_params = nac_params
|
||||
return dm
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Routines for user and calculator interfaces to phonopy."""
|
||||
# Copyright (C) 2019 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Tests for CIF tools."""
|
||||
# Copyright (C) 2016 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -36,14 +37,16 @@ from phonopy.structure.cells import get_angles, get_cell_parameters
|
|||
|
||||
|
||||
def write_cif_P1(cell, U_cif=None, filename=None):
|
||||
"""Write P1 symmetry CIF file."""
|
||||
if filename:
|
||||
with open(filename, "w") as w:
|
||||
w.write(get_cif_P1(cell, U_cif=U_cif))
|
||||
|
||||
|
||||
def get_cif_P1(cell, U_cif=None):
|
||||
a, b, c = get_cell_parameters(cell.get_cell())
|
||||
alpha, beta, gamma = get_angles(cell.get_cell())
|
||||
"""Return P1 symmetry CIF text."""
|
||||
a, b, c = get_cell_parameters(cell.cell)
|
||||
alpha, beta, gamma = get_angles(cell.cell)
|
||||
|
||||
cif = """data_crystal_structure_P1
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Elk calculator interface."""
|
||||
# Copyright (C) 2015 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -48,6 +49,7 @@ from phonopy.structure.atoms import symbol_map
|
|||
|
||||
|
||||
def parse_set_of_forces(num_atoms, forces_filenames, verbose=True):
|
||||
"""Parse forces from output files."""
|
||||
hook = "Forces :"
|
||||
is_parsed = True
|
||||
force_sets = []
|
||||
|
@ -72,6 +74,7 @@ def parse_set_of_forces(num_atoms, forces_filenames, verbose=True):
|
|||
|
||||
|
||||
def read_elk(filename):
|
||||
"""Read crystal structure."""
|
||||
elk_in = ElkIn(open(filename).readlines())
|
||||
tags = elk_in.get_variables()
|
||||
avec = [tags["scale"][i] * np.array(tags["avec"][i]) for i in range(3)]
|
||||
|
@ -100,6 +103,7 @@ def read_elk(filename):
|
|||
|
||||
|
||||
def write_elk(filename, cell, sp_filenames):
|
||||
"""Write cell to file."""
|
||||
f = open(filename, "w")
|
||||
f.write(get_elk_structure(cell, sp_filenames))
|
||||
|
||||
|
@ -112,6 +116,7 @@ def write_supercells_with_displacements(
|
|||
pre_filename="supercell",
|
||||
width=3,
|
||||
):
|
||||
"""Write supercells with displacements to files."""
|
||||
write_elk("%s.in" % pre_filename, supercell, sp_filenames)
|
||||
for i, cell in zip(ids, cells_with_displacements):
|
||||
filename = "{pre_filename}-{0:0{width}}.in".format(
|
||||
|
@ -121,6 +126,7 @@ def write_supercells_with_displacements(
|
|||
|
||||
|
||||
def get_elk_structure(cell, sp_filenames=None):
|
||||
"""Return Elk structure in text."""
|
||||
lattice = cell.get_cell()
|
||||
(num_atoms, symbols, scaled_positions, sort_list) = sort_positions_by_symbols(
|
||||
cell.get_chemical_symbols(), cell.get_scaled_positions()
|
||||
|
@ -149,7 +155,10 @@ def get_elk_structure(cell, sp_filenames=None):
|
|||
|
||||
|
||||
class ElkIn:
|
||||
"""Class to create Elk input file."""
|
||||
|
||||
def __init__(self, lines):
|
||||
"""Init method."""
|
||||
self._set_methods = {
|
||||
"atoms": self._set_atoms,
|
||||
"avec": self._set_avec,
|
||||
|
@ -163,6 +172,7 @@ class ElkIn:
|
|||
self._collect()
|
||||
|
||||
def get_variables(self):
|
||||
"""Return tags."""
|
||||
return self._tags
|
||||
|
||||
def _collect(self):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""QE calculator interface."""
|
||||
# Copyright (C) 2014 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -55,6 +56,7 @@ from phonopy.units import Bohr
|
|||
|
||||
|
||||
def parse_set_of_forces(num_atoms, forces_filenames, verbose=True):
|
||||
"""Parse forces from output files."""
|
||||
hook = "Forces acting on atoms"
|
||||
is_parsed = True
|
||||
force_sets = []
|
||||
|
@ -80,6 +82,7 @@ def parse_set_of_forces(num_atoms, forces_filenames, verbose=True):
|
|||
|
||||
|
||||
def read_pwscf(filename):
|
||||
"""Read crystal structure."""
|
||||
with open(filename) as f:
|
||||
pwscf_in = PwscfIn(f.readlines())
|
||||
tags = pwscf_in.get_tags()
|
||||
|
@ -140,6 +143,7 @@ def read_pwscf(filename):
|
|||
|
||||
|
||||
def write_pwscf(filename, cell, pp_filenames):
|
||||
"""Write cell to file."""
|
||||
f = open(filename, "w")
|
||||
f.write(get_pwscf_structure(cell, pp_filenames=pp_filenames))
|
||||
|
||||
|
@ -152,6 +156,7 @@ def write_supercells_with_displacements(
|
|||
pre_filename="supercell",
|
||||
width=3,
|
||||
):
|
||||
"""Write supercells with displacements to files."""
|
||||
write_pwscf("%s.in" % pre_filename, supercell, pp_filenames)
|
||||
for i, cell in zip(ids, cells_with_displacements):
|
||||
filename = "{pre_filename}-{0:0{width}}.in".format(
|
||||
|
@ -161,10 +166,11 @@ def write_supercells_with_displacements(
|
|||
|
||||
|
||||
def get_pwscf_structure(cell, pp_filenames=None):
|
||||
lattice = cell.get_cell()
|
||||
positions = cell.get_scaled_positions()
|
||||
masses = cell.get_masses()
|
||||
chemical_symbols = cell.get_chemical_symbols()
|
||||
"""Return QE structure in text."""
|
||||
lattice = cell.cell
|
||||
positions = cell.scaled_positions
|
||||
masses = cell.masses
|
||||
chemical_symbols = cell.symbols
|
||||
unique_symbols = []
|
||||
atomic_species = []
|
||||
for symbol, m in zip(chemical_symbols, masses):
|
||||
|
@ -197,6 +203,8 @@ def get_pwscf_structure(cell, pp_filenames=None):
|
|||
|
||||
|
||||
class PwscfIn:
|
||||
"""Class to create QE input file."""
|
||||
|
||||
_set_methods = OrderedDict(
|
||||
[
|
||||
("ibrav", "_set_ibrav"),
|
||||
|
@ -210,12 +218,14 @@ class PwscfIn:
|
|||
)
|
||||
|
||||
def __init__(self, lines):
|
||||
"""Init method."""
|
||||
self._tags = {}
|
||||
self._current_tag_name = None
|
||||
self._values = None
|
||||
self._collect(lines)
|
||||
|
||||
def get_tags(self):
|
||||
"""Return tags."""
|
||||
return self._tags
|
||||
|
||||
def _collect(self, lines):
|
||||
|
@ -284,7 +294,6 @@ class PwscfIn:
|
|||
Invoked by CELL_PARAMETERS tag_name.
|
||||
|
||||
"""
|
||||
|
||||
unit = self._values[0].lower()
|
||||
if unit == "alat":
|
||||
if not self._tags["celldm(1)"]:
|
||||
|
@ -344,8 +353,9 @@ class PwscfIn:
|
|||
|
||||
|
||||
class PH_Q2R:
|
||||
"""Parse QE/q2r output and create supercell force constants array
|
||||
that is readable by phonopy. A simple usage is as follows:
|
||||
"""Parse QE/q2r output and create supercell force constants array.
|
||||
|
||||
A simple usage is as follows:
|
||||
|
||||
---------
|
||||
#!/usr/bin/env python
|
||||
|
@ -408,6 +418,7 @@ class PH_Q2R:
|
|||
"""
|
||||
|
||||
def __init__(self, filename, symprec=1e-5):
|
||||
"""Init method."""
|
||||
self.fc = None
|
||||
self.dimension = None
|
||||
self.epsilon = None
|
||||
|
@ -418,7 +429,7 @@ class PH_Q2R:
|
|||
self._filename = filename
|
||||
|
||||
def run(self, cell, is_full_fc=False, parse_fc=True):
|
||||
"""Make supercell force constants readable for phonopy
|
||||
"""Make supercell force constants readable for phonopy.
|
||||
|
||||
Note
|
||||
----
|
||||
|
@ -438,7 +449,6 @@ class PH_Q2R:
|
|||
False may be used when expected to parse only epsilon and born.
|
||||
|
||||
"""
|
||||
|
||||
with open(self._filename) as f:
|
||||
fc_dct = self._parse_q2r(f)
|
||||
self.dimension = fc_dct["dimension"]
|
||||
|
@ -450,15 +460,15 @@ class PH_Q2R:
|
|||
)
|
||||
|
||||
def write_force_constants(self, fc_format="hdf5"):
|
||||
"""Write force constatns to file in hdf5."""
|
||||
if self.fc is not None:
|
||||
if fc_format == "hdf5":
|
||||
p2s_map = self.primitive.get_primitive_to_supercell_map()
|
||||
write_force_constants_to_hdf5(self.fc, p2s_map=p2s_map)
|
||||
write_force_constants_to_hdf5(self.fc, p2s_map=self.primitive.p2s_map)
|
||||
else:
|
||||
write_FORCE_CONSTANTS(self.fc)
|
||||
|
||||
def _parse_q2r(self, f):
|
||||
"""Parse q2r output file
|
||||
"""Parse q2r output file.
|
||||
|
||||
The format of q2r output is described at the mailing list below:
|
||||
http://www.democritos.it/pipermail/pw_forum/2005-April/002408.html
|
||||
|
@ -467,7 +477,6 @@ class PH_Q2R:
|
|||
https://www.mail-archive.com/pw_forum@pwscf.org/msg24388.html
|
||||
|
||||
"""
|
||||
|
||||
natom, dim, epsilon, borns = self._parse_parameters(f)
|
||||
fc_dct = {
|
||||
"fc": self._parse_fc(f, natom, dim),
|
||||
|
@ -510,12 +519,11 @@ class PH_Q2R:
|
|||
return epsilon, borns
|
||||
|
||||
def _parse_fc(self, f, natom, dim):
|
||||
"""Parse force constants part
|
||||
"""Parse force constants part.
|
||||
|
||||
Physical unit of force cosntants in the file is Ry/au^2.
|
||||
|
||||
"""
|
||||
|
||||
ndim = np.prod(dim)
|
||||
fc = np.zeros((natom, natom * ndim, 3, 3), dtype="double", order="C")
|
||||
for k, l, i, j in np.ndindex((3, 3, natom, natom)):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""CRYSTAL calculator interface."""
|
||||
# Copyright (C) 2019 Antti J. Karttunen (antti.j.karttunen@iki.fi)
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -42,6 +43,7 @@ from phonopy.structure.atoms import PhonopyAtoms as Atoms
|
|||
|
||||
|
||||
def parse_set_of_forces(num_atoms, forces_filenames, verbose=True):
|
||||
"""Parse forces from output files."""
|
||||
# Filenames = subdirectories supercell-001, supercell-002, ...
|
||||
force_sets = []
|
||||
for i, filename in enumerate(forces_filenames):
|
||||
|
@ -82,6 +84,7 @@ def parse_set_of_forces(num_atoms, forces_filenames, verbose=True):
|
|||
|
||||
|
||||
def read_turbomole(filename):
|
||||
"""Read crystal structure."""
|
||||
# filename is typically "control"
|
||||
f_turbomole = open(filename)
|
||||
turbomole_in = TurbomoleIn(f_turbomole.readlines())
|
||||
|
@ -97,6 +100,7 @@ def read_turbomole(filename):
|
|||
|
||||
|
||||
def write_turbomole(filename, cell):
|
||||
"""Write cell to file."""
|
||||
# Write geometry in a new directory
|
||||
# Check if directory exists (directory supercell will already exist for phono3py)
|
||||
if not os.path.exists(filename):
|
||||
|
@ -134,7 +138,7 @@ def write_turbomole(filename, cell):
|
|||
def write_supercells_with_displacements(
|
||||
supercell, cells_with_displacements, ids, pre_filename="supercell", width=3
|
||||
):
|
||||
|
||||
"""Write supercells with displacements to files."""
|
||||
write_turbomole(pre_filename, supercell)
|
||||
for i, cell in zip(ids, cells_with_displacements):
|
||||
filename = "{pre_filename}-{0:0{width}}".format(
|
||||
|
@ -144,7 +148,10 @@ def write_supercells_with_displacements(
|
|||
|
||||
|
||||
class TurbomoleIn:
|
||||
"""Class to create TURBOMOLE input file."""
|
||||
|
||||
def __init__(self, lines):
|
||||
"""Init method."""
|
||||
self._tags = {
|
||||
"lattice_vectors": None,
|
||||
"atomic_species": None,
|
||||
|
@ -155,6 +162,7 @@ class TurbomoleIn:
|
|||
self._collect(lines)
|
||||
|
||||
def get_tags(self):
|
||||
"""Return tags."""
|
||||
return self._tags
|
||||
|
||||
def _collect(self, lines):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Wien2k calculator interface."""
|
||||
# Copyright (C) 2011 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -51,6 +52,7 @@ def parse_set_of_forces(
|
|||
symmetry_tolerance=None,
|
||||
verbose=True,
|
||||
):
|
||||
"""Parse forces from output files."""
|
||||
if symmetry_tolerance is None:
|
||||
symprec = 1e-5
|
||||
else:
|
||||
|
@ -90,6 +92,7 @@ def parse_set_of_forces(
|
|||
|
||||
|
||||
def parse_wien2k_struct(filename):
|
||||
"""Read crystal structure."""
|
||||
with open(filename) as f:
|
||||
# 1
|
||||
_ = f.readline().rstrip()
|
||||
|
@ -169,6 +172,7 @@ def write_supercells_with_displacements(
|
|||
pre_filename="wien2k",
|
||||
width=3,
|
||||
):
|
||||
"""Write supercells with displacements to files."""
|
||||
npts_super = []
|
||||
r0s_super = []
|
||||
rmts_super = []
|
||||
|
@ -194,6 +198,7 @@ def write_supercells_with_displacements(
|
|||
|
||||
|
||||
def write_wein2k(filename, cell, npts, r0s, rmts):
|
||||
"""Write cell to file."""
|
||||
with open(filename, "w") as w:
|
||||
w.write(_get_wien2k_struct(cell, npts, r0s, rmts))
|
||||
|
||||
|
@ -408,7 +413,7 @@ if __name__ == "__main__":
|
|||
|
||||
from phonopy.interface.vasp import read_vasp, write_vasp
|
||||
|
||||
def clean_scaled_positions(cell):
|
||||
def _clean_scaled_positions(cell):
|
||||
positions = cell.get_scaled_positions()
|
||||
for pos in positions:
|
||||
for i in (0, 1, 2):
|
||||
|
@ -443,7 +448,7 @@ if __name__ == "__main__":
|
|||
lattice = cell.get_cell() * Bohr
|
||||
cell.set_cell(lattice)
|
||||
cell.set_scaled_positions(positions)
|
||||
clean_scaled_positions(cell)
|
||||
_clean_scaled_positions(cell)
|
||||
write_vasp("POSCAR.wien2k", cell, direct=True)
|
||||
w = open("wien2k_core.dat", "w")
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Create atomic displacements."""
|
||||
# Copyright (C) 2011 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -32,9 +33,12 @@
|
|||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
from typing import List, Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy.harmonic.derivative_dynmat import DerivativeOfDynamicalMatrix
|
||||
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix, DynamicalMatrixNAC
|
||||
from phonopy.interface.vasp import write_vasp
|
||||
from phonopy.phonon.degeneracy import get_eigenvectors
|
||||
from phonopy.structure.cells import get_supercell
|
||||
|
@ -42,9 +46,11 @@ from phonopy.units import VaspToTHz
|
|||
|
||||
|
||||
class Modulation:
|
||||
"""Class to create atomic displacements."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
dynamical_matrix,
|
||||
dynamical_matrix: Union[DynamicalMatrix, DynamicalMatrixNAC],
|
||||
dimension,
|
||||
phonon_modes,
|
||||
delta_q=None,
|
||||
|
@ -52,14 +58,9 @@ class Modulation:
|
|||
nac_q_direction=None,
|
||||
factor=VaspToTHz,
|
||||
):
|
||||
|
||||
"""Class describe atomic modulations
|
||||
|
||||
Atomic modulations corresponding to phonon modes are created.
|
||||
|
||||
"""
|
||||
"""Init method."""
|
||||
self._dm = dynamical_matrix
|
||||
self._primitive = dynamical_matrix.get_primitive()
|
||||
self._primitive = dynamical_matrix.primitive
|
||||
self._phonon_modes = phonon_modes
|
||||
self._dimension = np.array(dimension).ravel()
|
||||
self._delta_q = delta_q # 1st/2nd order perturbation direction
|
||||
|
@ -77,6 +78,7 @@ class Modulation:
|
|||
self._supercell = get_supercell(self._primitive, dim)
|
||||
|
||||
def run(self):
|
||||
"""Calculate modulations."""
|
||||
for ph_mode in self._phonon_modes:
|
||||
q, band_index, amplitude, argument = ph_mode
|
||||
eigvals, eigvecs = get_eigenvectors(
|
||||
|
@ -93,15 +95,18 @@ class Modulation:
|
|||
self._eigvals.append(eigvals[band_index])
|
||||
|
||||
def get_modulated_supercells(self):
|
||||
"""Return modulations."""
|
||||
modulations = []
|
||||
for u in self._u:
|
||||
modulations.append(self._get_cell_with_modulation(u))
|
||||
return modulations
|
||||
|
||||
def get_modulations_and_supercell(self):
|
||||
"""Return modulations and perfect supercell."""
|
||||
return self._u, self._supercell
|
||||
|
||||
def write(self, filename="MPOSCAR"):
|
||||
"""Write supercells with modulations to MPOSCARs."""
|
||||
deltas = []
|
||||
for i, u in enumerate(self._u):
|
||||
cell = self._get_cell_with_modulation(u)
|
||||
|
@ -115,12 +120,13 @@ class Modulation:
|
|||
cell = self._get_cell_with_modulation(no_modulations)
|
||||
write_vasp(filename + "-orig", cell, direct=True)
|
||||
|
||||
def write_yaml(self):
|
||||
self._write_yaml()
|
||||
def write_yaml(self, filename="modulation.yaml"):
|
||||
"""Write modulations to file in yaml."""
|
||||
self._write_yaml(filename=filename)
|
||||
|
||||
def _get_cell_with_modulation(self, modulation):
|
||||
lattice = self._supercell.get_cell()
|
||||
positions = self._supercell.get_positions()
|
||||
lattice = self._supercell.cell
|
||||
positions = self._supercell.positions
|
||||
positions += modulation.real
|
||||
scaled_positions = np.dot(positions, np.linalg.inv(lattice))
|
||||
for p in scaled_positions:
|
||||
|
@ -146,12 +152,12 @@ class Modulation:
|
|||
return dim
|
||||
|
||||
def _get_displacements(self, eigvec, q, amplitude, argument):
|
||||
m = self._supercell.get_masses()
|
||||
s2u_map = self._supercell.get_supercell_to_unitcell_map()
|
||||
u2u_map = self._supercell.get_unitcell_to_unitcell_map()
|
||||
m = self._supercell.masses
|
||||
s2u_map = self._supercell.s2u_map
|
||||
u2u_map = self._supercell.u2u_map
|
||||
s2uu_map = [u2u_map[x] for x in s2u_map]
|
||||
spos = self._supercell.get_scaled_positions()
|
||||
dim = self._supercell.get_supercell_matrix()
|
||||
spos = self._supercell.scaled_positions
|
||||
dim = self._supercell.supercell_matrix
|
||||
coefs = np.exp(2j * np.pi * np.dot(np.dot(spos, dim.T), q)) / np.sqrt(m)
|
||||
u = []
|
||||
for i, coef in enumerate(coefs):
|
||||
|
@ -177,10 +183,10 @@ class Modulation:
|
|||
e = np.array(eigvals).real
|
||||
return np.sqrt(np.abs(e)) * np.sign(e) * self._factor
|
||||
|
||||
def _write_yaml(self):
|
||||
w = open("modulation.yaml", "w")
|
||||
primitive = self._dm.get_primitive()
|
||||
num_atom = primitive.get_number_of_atoms()
|
||||
def _write_yaml(self, filename="modulation.yaml"):
|
||||
w = open(filename, "w")
|
||||
primitive = self._dm.primitive
|
||||
num_atom = len(primitive)
|
||||
|
||||
w.write("primitive_cell:\n")
|
||||
self._write_cell_yaml(primitive, w)
|
||||
|
@ -190,7 +196,7 @@ class Modulation:
|
|||
for v in dim:
|
||||
w.write(" - [ %d, %d, %d ]\n" % tuple(v))
|
||||
self._write_cell_yaml(self._supercell, w)
|
||||
inv_lattice = np.linalg.inv(self._supercell.get_cell().T)
|
||||
inv_lattice = np.linalg.inv(self._supercell.cell.T)
|
||||
|
||||
w.write("modulations:\n")
|
||||
for u, mode in zip(self._u, self._phonon_modes):
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Calculations of thermal displacements."""
|
||||
# Copyright (C) 2011 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
@ -32,14 +33,21 @@
|
|||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
import warnings
|
||||
from typing import Union
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy.interface.cif import write_cif_P1
|
||||
from phonopy.phonon.mesh import IterMesh, Mesh
|
||||
from phonopy.units import AMU, EV, Angstrom, Hbar, Kb, THzToEv
|
||||
|
||||
|
||||
class ThermalMotion:
|
||||
def __init__(self, iter_mesh, freq_min=None, freq_max=None):
|
||||
"""Base class of thermal displacement calculation classes."""
|
||||
|
||||
def __init__(self, iter_mesh: Union[IterMesh, Mesh], freq_min=None, freq_max=None):
|
||||
"""Init method."""
|
||||
self._iter_mesh = iter_mesh
|
||||
if freq_min is None:
|
||||
self._fmin = 0
|
||||
|
@ -50,7 +58,7 @@ class ThermalMotion:
|
|||
else:
|
||||
self._fmax = freq_max
|
||||
|
||||
masses = iter_mesh.dynamical_matrix.primitive.get_masses()
|
||||
masses = iter_mesh.dynamical_matrix.primitive.masses
|
||||
self._masses = masses * AMU
|
||||
self._masses3 = np.array([[m] * 3 for m in masses]).ravel() * AMU
|
||||
self._temperatures = None
|
||||
|
@ -65,12 +73,35 @@ class ThermalMotion:
|
|||
|
||||
@property
|
||||
def temperatures(self):
|
||||
"""Setter and getter of temperatures."""
|
||||
return self._temperatures
|
||||
|
||||
@temperatures.setter
|
||||
def temperatures(self, temperatures):
|
||||
t_array = np.array(temperatures)
|
||||
condition = np.logical_not(t_array < 0)
|
||||
self._temperatures = np.extract(condition, t_array)
|
||||
|
||||
def get_temperatures(self):
|
||||
"""Return temperatures."""
|
||||
warnings.warn(
|
||||
"ThermalMotion.get_temperatures() is deprecated. "
|
||||
"Use temperatures attribute instead.",
|
||||
DeprecationWarning,
|
||||
)
|
||||
return self.temperatures
|
||||
|
||||
def set_temperatures(self, temperatures):
|
||||
"""Set temperatures."""
|
||||
warnings.warn(
|
||||
"ThermalMotion.set_temperatures() is deprecated. "
|
||||
"Use temperatures attribute instead.",
|
||||
DeprecationWarning,
|
||||
)
|
||||
self.temperatures = temperatures
|
||||
|
||||
def set_temperature_range(self, t_min=None, t_max=None, t_step=None):
|
||||
"""Set temperatures by range."""
|
||||
if t_min is None:
|
||||
_t_min = 10
|
||||
elif t_min < 0:
|
||||
|
@ -96,13 +127,8 @@ class ThermalMotion:
|
|||
_t_min, _t_max + _t_step / 2.0, _t_step, dtype="double"
|
||||
)
|
||||
|
||||
def set_temperatures(self, temperatures):
|
||||
t_array = np.array(temperatures)
|
||||
condition = np.logical_not(t_array < 0)
|
||||
self._temperatures = np.extract(condition, t_array)
|
||||
|
||||
def _get_population(self, freq, t): # freq in THz
|
||||
"""Return phonon population number
|
||||
"""Return phonon population number.
|
||||
|
||||
Three types of combinations of array inputs are possible.
|
||||
- single freq and single t
|
||||
|
@ -123,10 +149,16 @@ class ThermalMotion:
|
|||
|
||||
|
||||
class ThermalDisplacements(ThermalMotion):
|
||||
"""Class to calculate thermal displacements (mean square displacements)."""
|
||||
|
||||
def __init__(
|
||||
self, iter_mesh, projection_direction=None, freq_min=None, freq_max=None
|
||||
self,
|
||||
iter_mesh: Union[IterMesh, Mesh],
|
||||
projection_direction=None,
|
||||
freq_min=None,
|
||||
freq_max=None,
|
||||
):
|
||||
"""Calculate mean square displacements
|
||||
"""Init method.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -143,7 +175,6 @@ class ThermalDisplacements(ThermalMotion):
|
|||
Maximum phonon frequency to determine wheather include or not.
|
||||
|
||||
"""
|
||||
|
||||
super().__init__(iter_mesh, freq_min=freq_min, freq_max=freq_max)
|
||||
if projection_direction is None:
|
||||
self._projection_direction = None
|
||||
|
@ -155,12 +186,20 @@ class ThermalDisplacements(ThermalMotion):
|
|||
|
||||
@property
|
||||
def thermal_displacements(self):
|
||||
"""Return thermal displacements."""
|
||||
return self._displacements
|
||||
|
||||
def get_thermal_displacements(self):
|
||||
"""Return thermal displacements and temperatures."""
|
||||
warnings.warn(
|
||||
"ThermalDisplacements.get_thermal_displacements() is deprecated. "
|
||||
"Use thermal_displacements and temperatures attributes instead.",
|
||||
DeprecationWarning,
|
||||
)
|
||||
return (self._temperatures, self._displacements)
|
||||
|
||||
def run(self):
|
||||
"""Calculate thermal displacements."""
|
||||
if self._projection_direction is not None:
|
||||
masses = self._masses
|
||||
else:
|
||||
|
@ -191,7 +230,8 @@ class ThermalDisplacements(ThermalMotion):
|
|||
assert np.prod(self._iter_mesh.mesh_numbers) == count + 1
|
||||
self._displacements = disps / (count + 1)
|
||||
|
||||
def write_yaml(self):
|
||||
def write_yaml(self, filename="thermal_displacements.yaml"):
|
||||
"""Write results to file in yaml."""
|
||||
natom = len(self._masses)
|
||||
lines = []
|
||||
lines.append("# Thermal displacements")
|
||||
|
@ -209,10 +249,11 @@ class ThermalDisplacements(ThermalMotion):
|
|||
text += " ] # atom %d" % (i + 1)
|
||||
lines.append(text)
|
||||
|
||||
with open("thermal_displacements.yaml", "w") as w:
|
||||
with open(filename, "w") as w:
|
||||
w.write("\n".join(lines))
|
||||
|
||||
def plot(self, pyplot, is_legend=False):
|
||||
"""Return pyplot of thermal displacements calculation result."""
|
||||
xyz = ["x", "y", "z"]
|
||||
for i, u in enumerate(self._displacements.transpose()):
|
||||
pyplot.plot(
|
||||
|
@ -223,8 +264,11 @@ class ThermalDisplacements(ThermalMotion):
|
|||
pyplot.legend(loc="upper left")
|
||||
|
||||
def _project_eigenvectors(self):
|
||||
"""Eigenvectors are projected along Cartesian direction"""
|
||||
"""Project eigenvectors to specific direction.
|
||||
|
||||
Eigenvectors are projected along Cartesian direction.
|
||||
|
||||
"""
|
||||
self._p_eigenvectors = []
|
||||
for vecs_q in self._eigenvectors:
|
||||
p_vecs_q = []
|
||||
|
@ -235,8 +279,16 @@ class ThermalDisplacements(ThermalMotion):
|
|||
|
||||
|
||||
class ThermalDisplacementMatrices(ThermalMotion):
|
||||
def __init__(self, iter_mesh, freq_min=None, freq_max=None, lattice=None):
|
||||
"""Calculate mean square displacement matrices
|
||||
"""Class to calculate thermal displacement (mean square displacement) matrices."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
iter_mesh: Union[IterMesh, Mesh],
|
||||
freq_min=None,
|
||||
freq_max=None,
|
||||
lattice=None,
|
||||
):
|
||||
"""Init method.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
|
@ -253,7 +305,6 @@ class ThermalDisplacementMatrices(ThermalMotion):
|
|||
dtype='double', shape=(3, 3)
|
||||
|
||||
"""
|
||||
|
||||
super().__init__(iter_mesh, freq_min=freq_min, freq_max=freq_max)
|
||||
self._disp_matrices = None
|
||||
self._disp_matrices_cif = None
|
||||
|
@ -267,26 +318,33 @@ class ThermalDisplacementMatrices(ThermalMotion):
|
|||
|
||||
@property
|
||||
def thermal_displacement_matrices(self):
|
||||
"""Return thermal displacement matrices."""
|
||||
return self._disp_matrices
|
||||
|
||||
@property
|
||||
def thermal_displacement_matrices_cif(self):
|
||||
"""Return thermal displacement matrices in cif definition."""
|
||||
return self._disp_matrices_cif
|
||||
|
||||
def get_thermal_displacement_matrices(self):
|
||||
"""Return thermal displacement matrices."""
|
||||
warnings.warn(
|
||||
"ThermalDisplacementMatrices.get_thermal_displacement_matrices() is "
|
||||
"deprecated. Use thermal_displacement_matrices and temperatures "
|
||||
"attributes instead.",
|
||||
DeprecationWarning,
|
||||
)
|
||||
return (self._temperatures, self._disp_matrices)
|
||||
|
||||
def run(self, np_overflow=None):
|
||||
"""
|
||||
"""Calculate thermal displacement matrices.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
np_overflow: str or None
|
||||
Switch of error handling of numpy. 'raise' to see which phonon it
|
||||
is.
|
||||
Switch of error handling of numpy. 'raise' to see which phonon it is.
|
||||
|
||||
"""
|
||||
|
||||
np.seterr(over=np_overflow)
|
||||
self._get_disp_matrices()
|
||||
np.seterr(over=None)
|
||||
|
@ -336,14 +394,16 @@ class ThermalDisplacementMatrices(ThermalMotion):
|
|||
assert (abs(disps.imag) < 1e-10).all()
|
||||
self._disp_matrices = disps.real / (count + 1)
|
||||
|
||||
def write_cif(self, cell, temperature_index):
|
||||
def write_cif(self, cell, temperature_index, filename="tdispmat.cif"):
|
||||
"""Write results to file in P1 symmetry CIF format."""
|
||||
write_cif_P1(
|
||||
cell,
|
||||
U_cif=self._disp_matrices_cif[temperature_index],
|
||||
filename="tdispmat.cif",
|
||||
filename=filename,
|
||||
)
|
||||
|
||||
def write_yaml(self):
|
||||
def write_yaml(self, filename="thermal_displacement_matrices.yaml"):
|
||||
"""Write results to file in yaml."""
|
||||
natom = len(self._masses)
|
||||
lines = []
|
||||
|
||||
|
@ -377,5 +437,5 @@ class ThermalDisplacementMatrices(ThermalMotion):
|
|||
% (m[0, 0], m[1, 1], m[2, 2], m[1, 2], m[0, 2], m[0, 1], j + 1)
|
||||
)
|
||||
|
||||
with open("thermal_displacement_matrices.yaml", "w") as w:
|
||||
with open(filename, "w") as w:
|
||||
w.write("\n".join(lines))
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
"""Routines to calculate power spectrum from MD data."""
|
||||
# Copyright (C) 2021 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
# This file is part of phonopy.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
#
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
#
|
||||
# * Neither the name of the phonopy project nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
|
@ -1,3 +1,4 @@
|
|||
"""Collection of physical units."""
|
||||
# Copyright (C) 2011 Atsushi Togo
|
||||
# All rights reserved.
|
||||
#
|
||||
|
|
|
@ -247,17 +247,17 @@ def helper_methods():
|
|||
|
||||
class HelperMethods:
|
||||
@classmethod
|
||||
def compare_cells_with_order(cls, cell, cell_ref):
|
||||
def compare_cells_with_order(cls, cell, cell_ref, symprec=1e-5):
|
||||
"""Compare two cells with the same orders of positions."""
|
||||
np.testing.assert_allclose(cell.cell, cell_ref.cell, atol=1e-5)
|
||||
np.testing.assert_allclose(cell.cell, cell_ref.cell, atol=symprec)
|
||||
cls.compare_positions_with_order(
|
||||
cell.scaled_positions, cell_ref.scaled_positions, cell.cell
|
||||
)
|
||||
np.testing.assert_array_equal(cell.numbers, cell_ref.numbers)
|
||||
np.testing.assert_allclose(cell.masses, cell_ref.masses, atol=1e-5)
|
||||
np.testing.assert_allclose(cell.masses, cell_ref.masses, atol=symprec)
|
||||
|
||||
@classmethod
|
||||
def compare_positions_with_order(cls, pos, pos_ref, lattice):
|
||||
def compare_positions_with_order(cls, pos, pos_ref, lattice, symprec=1e-5):
|
||||
"""Compare two lists of positions and orders.
|
||||
|
||||
lattice :
|
||||
|
@ -267,21 +267,25 @@ def helper_methods():
|
|||
diff = pos - pos_ref
|
||||
diff -= np.rint(diff)
|
||||
dist = (np.dot(diff, lattice) ** 2).sum(axis=1)
|
||||
assert (dist < 1e-5).all()
|
||||
assert (dist < symprec).all()
|
||||
|
||||
@classmethod
|
||||
def compare_cells(cls, cell, cell_ref):
|
||||
def compare_cells(cls, cell, cell_ref, symprec=1e-5):
|
||||
"""Compare two cells where position orders can be different."""
|
||||
np.testing.assert_allclose(cell.cell, cell_ref.cell, atol=1e-5)
|
||||
np.testing.assert_allclose(cell.cell, cell_ref.cell, atol=symprec)
|
||||
|
||||
indices = cls.compare_positions_in_arbitrary_order(
|
||||
cell.scaled_positions, cell_ref.scaled_positions, cell.cell
|
||||
)
|
||||
np.testing.assert_array_equal(cell.numbers, cell_ref.numbers[indices])
|
||||
np.testing.assert_allclose(cell.masses, cell_ref.masses[indices], atol=1e-5)
|
||||
np.testing.assert_allclose(
|
||||
cell.masses, cell_ref.masses[indices], atol=symprec
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def compare_positions_in_arbitrary_order(cls, pos_in, pos_ref, lattice):
|
||||
def compare_positions_in_arbitrary_order(
|
||||
cls, pos_in, pos_ref, lattice, symprec=1e-5
|
||||
):
|
||||
"""Compare two sets of positions irrespective of orders.
|
||||
|
||||
lattice :
|
||||
|
@ -293,7 +297,7 @@ def helper_methods():
|
|||
diff = pos_ref - pos
|
||||
diff -= np.rint(diff)
|
||||
dist = (np.dot(diff, lattice) ** 2).sum(axis=1)
|
||||
matches = np.where(dist < 1e-5)[0]
|
||||
matches = np.where(dist < symprec)[0]
|
||||
assert len(matches) == 1
|
||||
indices.append(matches[0])
|
||||
return indices
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
"""Tests for routines in derivative_dynmat.py."""
|
||||
import numpy as np
|
||||
|
||||
from phonopy import Phonopy
|
||||
from phonopy.harmonic.derivative_dynmat import DerivativeOfDynamicalMatrix
|
||||
|
||||
ddm_ph_nacl = [
|
||||
|
@ -65,23 +67,27 @@ ddm_ph_nacl_nonac = [
|
|||
]
|
||||
|
||||
|
||||
def test_ddm_nac(ph_nacl):
|
||||
def test_ddm_nac(ph_nacl: Phonopy):
|
||||
"""Test by NaCl."""
|
||||
_assert(ph_nacl, ddm_ph_nacl)
|
||||
|
||||
|
||||
def test_ddm_nac_compact(ph_nacl_compact_fcsym):
|
||||
def test_ddm_nac_compact(ph_nacl_compact_fcsym: Phonopy):
|
||||
"""Test by NaCl with compact fc."""
|
||||
_assert(ph_nacl_compact_fcsym, ddm_ph_nacl)
|
||||
|
||||
|
||||
def test_ddm_nonac(ph_nacl_nonac):
|
||||
def test_ddm_nonac(ph_nacl_nonac: Phonopy):
|
||||
"""Test by NaCl without NAC."""
|
||||
_assert(ph_nacl_nonac, ddm_ph_nacl_nonac)
|
||||
|
||||
|
||||
def test_ddm_nonac_compact(ph_nacl_nonac_compact_fc):
|
||||
def test_ddm_nonac_compact(ph_nacl_nonac_compact_fc: Phonopy):
|
||||
"""Test by NaCl without NAC and with compact fc."""
|
||||
_assert(ph_nacl_nonac_compact_fc, ddm_ph_nacl_nonac)
|
||||
|
||||
|
||||
def _assert(ph, ref_vals, show=False):
|
||||
def _assert(ph: Phonopy, ref_vals, show=False):
|
||||
dynmat = ph.dynamical_matrix
|
||||
ddynmat = DerivativeOfDynamicalMatrix(dynmat)
|
||||
ddynmat.run([0, 0.1, 0.1])
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Tests for CRYSTAL calculator interface."""
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
@ -9,26 +9,14 @@ from phonopy.interface.phonopy_yaml import read_cell_yaml
|
|||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
class TestCrystal(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_read_crystal(self):
|
||||
cell, pp_filenames = read_crystal(os.path.join(data_dir, "Si-CRYSTAL.o"))
|
||||
filename = os.path.join(data_dir, "Si-CRYSTAL.yaml")
|
||||
cell_ref = read_cell_yaml(filename)
|
||||
self.assertTrue((np.abs(cell.get_cell() - cell_ref.get_cell()) < 1e-5).all())
|
||||
diff_pos = cell.get_scaled_positions() - cell_ref.get_scaled_positions()
|
||||
diff_pos -= np.rint(diff_pos)
|
||||
self.assertTrue((np.abs(diff_pos) < 1e-5).all())
|
||||
for s, s_r in zip(cell.get_chemical_symbols(), cell_ref.get_chemical_symbols()):
|
||||
self.assertTrue(s == s_r)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestCrystal)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
# unittest.main()
|
||||
def test_read_crystal():
|
||||
"""Test of read_crystal."""
|
||||
cell, pp_filenames = read_crystal(os.path.join(data_dir, "Si-CRYSTAL.o"))
|
||||
filename = os.path.join(data_dir, "Si-CRYSTAL.yaml")
|
||||
cell_ref = read_cell_yaml(filename)
|
||||
assert (np.abs(cell.cell - cell_ref.cell) < 1e-5).all()
|
||||
diff_pos = cell.scaled_positions - cell_ref.scaled_positions
|
||||
diff_pos -= np.rint(diff_pos)
|
||||
assert (np.abs(diff_pos) < 1e-5).all()
|
||||
for s, s_r in zip(cell.symbols, cell_ref.symbols):
|
||||
assert s == s_r
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
"""Tests of Abinit calculator interface."""
|
||||
import os
|
||||
import unittest
|
||||
|
||||
import numpy as np
|
||||
|
||||
|
@ -9,26 +9,14 @@ from phonopy.interface.phonopy_yaml import read_cell_yaml
|
|||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
class TestAbinit(unittest.TestCase):
|
||||
def setUp(self):
|
||||
pass
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def test_read_abinit(self):
|
||||
cell = read_abinit(os.path.join(data_dir, "NaCl-abinit.in"))
|
||||
filename = os.path.join(data_dir, "NaCl-abinit-pwscf.yaml")
|
||||
cell_ref = read_cell_yaml(filename)
|
||||
self.assertTrue((np.abs(cell.get_cell() - cell_ref.get_cell()) < 1e-5).all())
|
||||
diff_pos = cell.get_scaled_positions() - cell_ref.get_scaled_positions()
|
||||
diff_pos -= np.rint(diff_pos)
|
||||
self.assertTrue((np.abs(diff_pos) < 1e-5).all())
|
||||
for s, s_r in zip(cell.get_chemical_symbols(), cell_ref.get_chemical_symbols()):
|
||||
self.assertTrue(s == s_r)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestAbinit)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
# unittest.main()
|
||||
def test_read_abinit():
|
||||
"""Test of read_abinit."""
|
||||
cell = read_abinit(os.path.join(data_dir, "NaCl-abinit.in"))
|
||||
filename = os.path.join(data_dir, "NaCl-abinit-pwscf.yaml")
|
||||
cell_ref = read_cell_yaml(filename)
|
||||
assert (np.abs(cell.cell - cell_ref.cell) < 1e-5).all()
|
||||
diff_pos = cell.scaled_positions - cell_ref.scaled_positions
|
||||
diff_pos -= np.rint(diff_pos)
|
||||
assert (np.abs(diff_pos) < 1e-5).all()
|
||||
for s, s_r in zip(cell.symbols, cell_ref.symbols):
|
||||
assert s == s_r
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
"""Tests for band structure calculation."""
|
||||
import os
|
||||
|
||||
from phonopy.phonon.band_structure import get_band_qpoints
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def test_band_structure(ph_nacl):
|
||||
"""Test band structure calculation by NaCl."""
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
"""Tests for DOS."""
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy import Phonopy
|
||||
from phonopy.phonon.dos import get_pdos_indices
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
tp_str = """0.000000 100.000000 200.000000 300.000000 400.000000
|
||||
500.000000 600.000000 700.000000 800.000000 900.000000
|
||||
4.856373 3.916036 -0.276031 -6.809284 -14.961974
|
||||
|
|
|
@ -1,21 +1,11 @@
|
|||
import unittest
|
||||
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import StringIO
|
||||
|
||||
import os
|
||||
"""Tests for PhononMoment."""
|
||||
from io import StringIO
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy import Phonopy
|
||||
from phonopy.file_IO import parse_BORN, parse_FORCE_SETS
|
||||
from phonopy.interface.vasp import read_vasp
|
||||
from phonopy.phonon.moment import PhononMoment
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
result_full_range = """
|
||||
1.000000 1.000000 1.000000
|
||||
4.063222 4.236805 3.889623
|
||||
|
@ -26,77 +16,50 @@ result_full_range = """
|
|||
"""
|
||||
|
||||
|
||||
class TestMoment(unittest.TestCase):
|
||||
def setUp(self):
|
||||
self._cell = read_vasp(os.path.join(data_dir, "..", "POSCAR_NaCl"))
|
||||
def test_moment(ph_nacl_nofcsym: Phonopy):
|
||||
"""Test PhononMoment."""
|
||||
phonon = ph_nacl_nofcsym
|
||||
data = np.loadtxt(StringIO(result_full_range), dtype="double")
|
||||
moment = phonon.run_mesh(
|
||||
[13, 13, 13], with_eigenvectors=True, is_mesh_symmetry=False
|
||||
)
|
||||
num_atom = len(phonon.primitive)
|
||||
w = phonon.mesh.weights
|
||||
f = phonon.mesh.frequencies
|
||||
e = phonon.mesh.eigenvectors
|
||||
vals = np.zeros((6, num_atom + 1), dtype="double")
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
moment = PhononMoment(f, w)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
vals[i, 0] = moment.moment
|
||||
assert np.abs(moment.moment - data[i, 0]) < 1e-5
|
||||
|
||||
def test_moment(self):
|
||||
data = np.loadtxt(StringIO(result_full_range), dtype="double")
|
||||
moment = PhononMoment(f, w, eigenvectors=e)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
moms = moment.moment
|
||||
vals[i, 1:] = moms
|
||||
assert (np.abs(moms - data[i, 1:]) < 1e-5).all()
|
||||
|
||||
phonon = self._get_phonon(self._cell)
|
||||
moment = phonon.run_mesh(
|
||||
[13, 13, 13], with_eigenvectors=True, is_mesh_symmetry=False
|
||||
)
|
||||
num_atom = len(phonon.primitive)
|
||||
w = phonon.mesh.weights
|
||||
f = phonon.mesh.frequencies
|
||||
e = phonon.mesh.eigenvectors
|
||||
vals = np.zeros((6, num_atom + 1), dtype="double")
|
||||
moment = PhononMoment(f, w)
|
||||
moment.set_frequency_range(freq_min=3, freq_max=4)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
vals[i + 3, 0] = moment.moment
|
||||
assert np.abs(moment.moment - data[i + 3, 0]) < 1e-5
|
||||
|
||||
moment = PhononMoment(f, w)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
vals[i, 0] = moment.moment
|
||||
self.assertTrue(np.abs(moment.moment - data[i, 0]) < 1e-5)
|
||||
moment = PhononMoment(f, w, eigenvectors=e)
|
||||
moment.set_frequency_range(freq_min=3, freq_max=4)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
moms = moment.moment
|
||||
vals[i + 3, 1:] = moms
|
||||
assert (np.abs(moms - data[i + 3, 1:]) < 1e-5).all()
|
||||
|
||||
moment = PhononMoment(f, w, eigenvectors=e)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
moms = moment.moment
|
||||
vals[i, 1:] = moms
|
||||
self.assertTrue((np.abs(moms - data[i, 1:]) < 1e-5).all())
|
||||
|
||||
moment = PhononMoment(f, w)
|
||||
moment.set_frequency_range(freq_min=3, freq_max=4)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
vals[i + 3, 0] = moment.moment
|
||||
self.assertTrue(np.abs(moment.moment - data[i + 3, 0]) < 1e-5)
|
||||
|
||||
moment = PhononMoment(f, w, eigenvectors=e)
|
||||
moment.set_frequency_range(freq_min=3, freq_max=4)
|
||||
for i in range(3):
|
||||
moment.run(order=i)
|
||||
moms = moment.moment
|
||||
vals[i + 3, 1:] = moms
|
||||
self.assertTrue((np.abs(moms - data[i + 3, 1:]) < 1e-5).all())
|
||||
|
||||
# self._show(vals)
|
||||
|
||||
def _show(self, vals):
|
||||
for v in vals:
|
||||
print(("%9.6f " * len(v)) % tuple(v))
|
||||
|
||||
def _get_phonon(self, cell):
|
||||
phonon = Phonopy(
|
||||
cell,
|
||||
np.diag([2, 2, 2]),
|
||||
primitive_matrix=[[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]],
|
||||
)
|
||||
filename = os.path.join(data_dir, "..", "FORCE_SETS_NaCl")
|
||||
force_sets = parse_FORCE_SETS(filename=filename)
|
||||
phonon.dataset = force_sets
|
||||
phonon.produce_force_constants()
|
||||
filename_born = os.path.join(data_dir, "..", "BORN_NaCl")
|
||||
nac_params = parse_BORN(phonon.primitive, filename=filename_born)
|
||||
phonon.nac_params = nac_params
|
||||
|
||||
return phonon
|
||||
# self._show(vals)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(TestMoment)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
def _show(vals):
|
||||
for v in vals:
|
||||
print(("%9.6f " * len(v)) % tuple(v))
|
||||
|
|
|
@ -1,13 +1,9 @@
|
|||
"""Tests for phonon calculation at specific q-points."""
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy import Phonopy
|
||||
from phonopy.units import VaspToTHz
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def testQpoints(ph_nacl_nofcsym: Phonopy):
|
||||
"""Test phonon calculation at specific q-points by NaCl."""
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Tests for TetrahedronMesh."""
|
||||
import os
|
||||
from io import StringIO
|
||||
|
||||
|
@ -23,6 +24,7 @@ dos_str = """-0.672024 0.000000 0.029844 0.005522 0.731712 0.029450 1.433580 0.1
|
|||
|
||||
|
||||
def test_Amm2():
|
||||
"""Test of DOS calculation using TetrahedronMesh for Amm2 crystal."""
|
||||
data = np.loadtxt(StringIO(dos_str))
|
||||
phonon = _get_phonon("Amm2", [3, 2, 2], [[1, 0, 0], [0, 0.5, -0.5], [0, 0.5, 0.5]])
|
||||
mesh = [11, 11, 11]
|
||||
|
|
|
@ -1,12 +1,8 @@
|
|||
"""Tests for dynamic structure factor."""
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy.spectrum.dynamic_structure_factor import atomic_form_factor_WK1995
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
# D. Waasmaier and A. Kirfel, Acta Cryst. A51, 416 (1995)
|
||||
# f(Q) = \sum_i a_i \exp((-b_i Q^2) + c
|
||||
# Q is in angstron^-1
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
"""Tests of routines in cells.py."""
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from phonopy import Phonopy
|
||||
from phonopy.interface.phonopy_yaml import read_cell_yaml
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
from phonopy.structure.cells import (
|
||||
|
@ -157,19 +159,22 @@ svecs_nacl_ref30 = [
|
|||
]
|
||||
|
||||
|
||||
def test_compute_permutation_sno2(ph_sno2):
|
||||
def test_compute_permutation_sno2(ph_sno2: Phonopy):
|
||||
"""Test of compute_permutation by SnO2."""
|
||||
_test_compute_permutation(ph_sno2)
|
||||
|
||||
|
||||
def test_compute_permutation_tio2(ph_tio2):
|
||||
def test_compute_permutation_tio2(ph_tio2: Phonopy):
|
||||
"""Test of compute_permutation by TiO2."""
|
||||
_test_compute_permutation(ph_tio2)
|
||||
|
||||
|
||||
def test_compute_permutation_nacl(ph_nacl):
|
||||
def test_compute_permutation_nacl(ph_nacl: Phonopy):
|
||||
"""Test of compute_permutation by NaCl."""
|
||||
_test_compute_permutation(ph_nacl)
|
||||
|
||||
|
||||
def _test_compute_permutation(ph):
|
||||
def _test_compute_permutation(ph: Phonopy):
|
||||
symmetry = ph.primitive_symmetry
|
||||
ppos = ph.primitive.scaled_positions
|
||||
plat = ph.primitive.cell.T
|
||||
|
@ -187,16 +192,21 @@ def _test_compute_permutation(ph):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("nosnf", [True, False])
|
||||
def test_get_supercell_convcell_sio2(convcell_sio2, nosnf, helper_methods):
|
||||
def test_get_supercell_convcell_sio2(
|
||||
convcell_sio2: PhonopyAtoms, nosnf, helper_methods
|
||||
):
|
||||
"""Test of get_supercell with/without SNF by SiO2."""
|
||||
_test_get_supercell_convcell_sio2(convcell_sio2, helper_methods, is_old_style=nosnf)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("nosnf", [True, False])
|
||||
def test_get_supercell_primcell_si(primcell_si, nosnf, helper_methods):
|
||||
def test_get_supercell_primcell_si(primcell_si: PhonopyAtoms, nosnf, helper_methods):
|
||||
"""Test of get_supercell with/without SNF by Si."""
|
||||
_test_get_supercell_primcell_si(primcell_si, helper_methods, is_old_style=nosnf)
|
||||
|
||||
|
||||
def test_get_supercell_nacl_snf(convcell_nacl, helper_methods):
|
||||
def test_get_supercell_nacl_snf(convcell_nacl: PhonopyAtoms, helper_methods):
|
||||
"""Test of get_supercell using SNF by NaCl."""
|
||||
cell = convcell_nacl
|
||||
smat = [[-1, 1, 1], [1, -1, 1], [1, 1, -1]]
|
||||
scell = get_supercell(cell, smat, is_old_style=True)
|
||||
|
@ -204,7 +214,9 @@ def test_get_supercell_nacl_snf(convcell_nacl, helper_methods):
|
|||
helper_methods.compare_cells(scell, scell_snf)
|
||||
|
||||
|
||||
def _test_get_supercell_convcell_sio2(convcell_sio2, helper_methods, is_old_style=True):
|
||||
def _test_get_supercell_convcell_sio2(
|
||||
convcell_sio2: PhonopyAtoms, helper_methods, is_old_style=True
|
||||
):
|
||||
smat = np.diag([1, 2, 3])
|
||||
fname = "SiO2-123.yaml"
|
||||
scell = get_supercell(convcell_sio2, smat, is_old_style=is_old_style)
|
||||
|
@ -215,7 +227,9 @@ def _test_get_supercell_convcell_sio2(convcell_sio2, helper_methods, is_old_styl
|
|||
helper_methods.compare_cells(scell, cell_ref)
|
||||
|
||||
|
||||
def _test_get_supercell_primcell_si(primcell_si, helper_methods, is_old_style=True):
|
||||
def _test_get_supercell_primcell_si(
|
||||
primcell_si: PhonopyAtoms, helper_methods, is_old_style=True
|
||||
):
|
||||
smat = [[-1, 1, 1], [1, -1, 1], [1, 1, -1]]
|
||||
fname = "Si-conv.yaml"
|
||||
scell = get_supercell(primcell_si, smat, is_old_style=is_old_style)
|
||||
|
@ -226,15 +240,19 @@ def _test_get_supercell_primcell_si(primcell_si, helper_methods, is_old_style=Tr
|
|||
helper_methods.compare_cells(scell, cell_ref)
|
||||
|
||||
|
||||
def test_get_primitive_convcell_nacl(convcell_nacl, primcell_nacl, helper_methods):
|
||||
def test_get_primitive_convcell_nacl(
|
||||
convcell_nacl: PhonopyAtoms, primcell_nacl: PhonopyAtoms, helper_methods
|
||||
):
|
||||
"""Test get_primitive by NaCl."""
|
||||
pcell = get_primitive(convcell_nacl, primitive_matrix_nacl)
|
||||
helper_methods.compare_cells_with_order(pcell, primcell_nacl)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("store_dense_svecs", [True, False])
|
||||
def test_get_primitive_convcell_nacl_svecs(
|
||||
convcell_nacl, primcell_nacl, store_dense_svecs
|
||||
convcell_nacl: PhonopyAtoms, store_dense_svecs
|
||||
):
|
||||
"""Test shortest vectors by NaCl."""
|
||||
pcell = get_primitive(
|
||||
convcell_nacl, primitive_matrix_nacl, store_dense_svecs=store_dense_svecs
|
||||
)
|
||||
|
@ -249,7 +267,8 @@ def test_get_primitive_convcell_nacl_svecs(
|
|||
assert multi.shape == (8, 2)
|
||||
|
||||
|
||||
def test_TrimmedCell(convcell_nacl, helper_methods):
|
||||
def test_TrimmedCell(convcell_nacl: PhonopyAtoms, helper_methods):
|
||||
"""Test TrimmedCell by NaCl."""
|
||||
pmat = [[0, 0.5, 0.5], [0.5, 0, 0.5], [0.5, 0.5, 0]]
|
||||
smat2 = np.eye(3, dtype="intc") * 2
|
||||
pmat2 = np.dot(np.linalg.inv(smat2), pmat)
|
||||
|
@ -274,7 +293,8 @@ def test_TrimmedCell(convcell_nacl, helper_methods):
|
|||
helper_methods.compare_cells_with_order(tcell2, tcell3)
|
||||
|
||||
|
||||
def test_ShortestPairs_sparse_nacl(ph_nacl, helper_methods):
|
||||
def test_ShortestPairs_sparse_nacl(ph_nacl: Phonopy, helper_methods):
|
||||
"""Test ShortestPairs (parse) by NaCl."""
|
||||
scell = ph_nacl.supercell
|
||||
pcell = ph_nacl.primitive
|
||||
pos = scell.scaled_positions
|
||||
|
@ -288,7 +308,8 @@ def test_ShortestPairs_sparse_nacl(ph_nacl, helper_methods):
|
|||
helper_methods.compare_positions_with_order(pos_from_svecs, pos, scell.cell)
|
||||
|
||||
|
||||
def test_ShortestPairs_dense_nacl(ph_nacl, helper_methods):
|
||||
def test_ShortestPairs_dense_nacl(ph_nacl: Phonopy, helper_methods):
|
||||
"""Test ShortestPairs (dense) by NaCl."""
|
||||
scell = ph_nacl.supercell
|
||||
pcell = ph_nacl.primitive
|
||||
pos = scell.scaled_positions
|
||||
|
@ -307,7 +328,7 @@ def test_ShortestPairs_dense_nacl(ph_nacl, helper_methods):
|
|||
helper_methods.compare_positions_with_order(pos_from_svecs, pos, scell.cell)
|
||||
|
||||
|
||||
def test_sparse_to_dense_nacl(ph_nacl):
|
||||
def test_sparse_to_dense_nacl(ph_nacl: Phonopy):
|
||||
"""Test for sparse_to_dense_svecs."""
|
||||
scell = ph_nacl.supercell
|
||||
pcell = ph_nacl.primitive
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
"""Tests for routines in grid_points.py."""
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from phonopy import Phonopy
|
||||
from phonopy.interface.phonopy_yaml import read_cell_yaml
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
from phonopy.structure.grid_points import GeneralizedRegularGridPoints, GridPoints
|
||||
|
||||
current_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
@ -36,11 +40,13 @@ ga234 = [
|
|||
|
||||
|
||||
def test_GridPoints():
|
||||
"""Test of GridPoints."""
|
||||
gp = GridPoints([2, 3, 4], [[-1, 1, 1], [1, -1, 1], [1, 1, -1]])
|
||||
np.testing.assert_array_equal(gp.grid_address, ga234)
|
||||
|
||||
|
||||
def test_GridPoints_NaCl_with_rotations(ph_nacl):
|
||||
def test_GridPoints_NaCl_with_rotations(ph_nacl: Phonopy):
|
||||
"""Test of GridPoints with rotations from NaCl."""
|
||||
rec_lat = np.linalg.inv(ph_nacl.primitive.cell)
|
||||
rotations = ph_nacl.primitive_symmetry.pointgroup_operations
|
||||
gp = GridPoints([4, 4, 4], rec_lat, rotations=rotations)
|
||||
|
@ -131,47 +137,51 @@ def test_GridPoints_NaCl_with_rotations(ph_nacl):
|
|||
)
|
||||
|
||||
|
||||
def test_GridPoints_NaCl_with_rotations_fit_BZ(ph_nacl):
|
||||
@pytest.mark.parametrize("fit_in_BZ", [True, False])
|
||||
def test_GridPoints_NaCl_with_rotations_fit_BZ(ph_nacl: Phonopy, fit_in_BZ):
|
||||
"""Test of GridPoints with rotations from NaCl and fit_in_BZ."""
|
||||
rec_lat = np.linalg.inv(ph_nacl.primitive.cell)
|
||||
rotations = ph_nacl.primitive_symmetry.pointgroup_operations
|
||||
mesh = [5, 5, 5]
|
||||
gpf = GridPoints(mesh, rec_lat, rotations=rotations, fit_in_BZ=False)
|
||||
gpt = GridPoints(mesh, rec_lat, rotations=rotations, fit_in_BZ=True)
|
||||
np.testing.assert_allclose(
|
||||
gpf.qpoints,
|
||||
[
|
||||
[0.0, 0.0, 0.0],
|
||||
[0.2, 0.0, 0.0],
|
||||
[0.4, 0.0, 0.0],
|
||||
[0.2, 0.2, 0.0],
|
||||
[0.4, 0.2, 0.0],
|
||||
[-0.4, 0.2, 0.0],
|
||||
[-0.2, 0.2, 0.0],
|
||||
[0.4, 0.4, 0.0],
|
||||
[-0.4, 0.4, 0.0],
|
||||
[-0.4, 0.4, 0.2],
|
||||
],
|
||||
atol=1e-8,
|
||||
)
|
||||
np.testing.assert_allclose(
|
||||
gpt.qpoints,
|
||||
[
|
||||
[0.0, 0.0, 0.0],
|
||||
[0.2, 0.0, 0.0],
|
||||
[0.4, 0.0, 0.0],
|
||||
[0.2, 0.2, 0.0],
|
||||
[0.4, 0.2, 0.0],
|
||||
[-0.4, 0.2, 0.0],
|
||||
[-0.2, 0.2, 0.0],
|
||||
[0.4, 0.4, 0.0],
|
||||
[-0.4, -0.6, 0.0],
|
||||
[0.6, 0.4, 0.2],
|
||||
],
|
||||
atol=1e-8,
|
||||
)
|
||||
gpts = GridPoints(mesh, rec_lat, rotations=rotations, fit_in_BZ=fit_in_BZ)
|
||||
if fit_in_BZ:
|
||||
np.testing.assert_allclose(
|
||||
gpts.qpoints,
|
||||
[
|
||||
[0.0, 0.0, 0.0],
|
||||
[0.2, 0.0, 0.0],
|
||||
[0.4, 0.0, 0.0],
|
||||
[0.2, 0.2, 0.0],
|
||||
[0.4, 0.2, 0.0],
|
||||
[-0.4, 0.2, 0.0],
|
||||
[-0.2, 0.2, 0.0],
|
||||
[0.4, 0.4, 0.0],
|
||||
[-0.4, -0.6, 0.0],
|
||||
[0.6, 0.4, 0.2],
|
||||
],
|
||||
atol=1e-8,
|
||||
)
|
||||
else:
|
||||
np.testing.assert_allclose(
|
||||
gpts.qpoints,
|
||||
[
|
||||
[0.0, 0.0, 0.0],
|
||||
[0.2, 0.0, 0.0],
|
||||
[0.4, 0.0, 0.0],
|
||||
[0.2, 0.2, 0.0],
|
||||
[0.4, 0.2, 0.0],
|
||||
[-0.4, 0.2, 0.0],
|
||||
[-0.2, 0.2, 0.0],
|
||||
[0.4, 0.4, 0.0],
|
||||
[-0.4, 0.4, 0.0],
|
||||
[-0.4, 0.4, 0.2],
|
||||
],
|
||||
atol=1e-8,
|
||||
)
|
||||
|
||||
|
||||
def test_GridPoints_SnO2_with_rotations(ph_sno2):
|
||||
def test_GridPoints_SnO2_with_rotations(ph_sno2: Phonopy):
|
||||
"""Test of GridPoints with rotations from SnO2."""
|
||||
rec_lat = np.linalg.inv(ph_sno2.primitive.cell)
|
||||
rotations = ph_sno2.primitive_symmetry.pointgroup_operations
|
||||
gp = GridPoints([4, 4, 4], rec_lat, rotations=rotations)
|
||||
|
@ -277,7 +287,8 @@ def test_GridPoints_SnO2_with_rotations(ph_sno2):
|
|||
)
|
||||
|
||||
|
||||
def test_GridPoints_SnO2_with_rotations_MP(ph_sno2):
|
||||
def test_GridPoints_SnO2_with_rotations_MP(ph_sno2: Phonopy):
|
||||
"""Test of GridPoints with non-gamma-centre mesh and rotations from SnO2."""
|
||||
rec_lat = np.linalg.inv(ph_sno2.primitive.cell)
|
||||
rotations = ph_sno2.primitive_symmetry.pointgroup_operations
|
||||
gp = GridPoints([4, 4, 4], rec_lat, rotations=rotations, is_gamma_center=False)
|
||||
|
@ -367,7 +378,8 @@ def test_GridPoints_SnO2_with_rotations_MP(ph_sno2):
|
|||
|
||||
|
||||
@pytest.mark.parametrize("suggest", [True, False])
|
||||
def test_GeneralizedRegularGridPoints(ph_tio2, suggest):
|
||||
def test_SNF_from_GeneralizedRegularGridPoints(ph_tio2: Phonopy, suggest):
|
||||
"""Test for grid rotation matrix and SNF by TiO2."""
|
||||
grgp = GeneralizedRegularGridPoints(
|
||||
ph_tio2.unitcell, 60, suggest=suggest, x_fastest=False
|
||||
)
|
||||
|
@ -409,6 +421,7 @@ def test_GeneralizedRegularGridPoints(ph_tio2, suggest):
|
|||
|
||||
@pytest.mark.parametrize("suggest", [True, False])
|
||||
def test_GeneralizedRegularGridPoints_rotations_tio2(ph_tio2, suggest):
|
||||
"""Test for GeneralizedRegularGridPoints by TiO2."""
|
||||
matches = _get_matches(ph_tio2, suggest, True)
|
||||
if suggest:
|
||||
matches_ref = [
|
||||
|
@ -574,7 +587,7 @@ def test_GeneralizedRegularGridPoints_rotations_tio2(ph_tio2, suggest):
|
|||
def test_GeneralizedRegularGridPoints_rotations_zr3n4(
|
||||
ph_zr3n4, suggest, is_time_reversal
|
||||
):
|
||||
"""Non-centrosymmetric Zr3N4"""
|
||||
"""Test for GeneralizedRegularGridPoints by non-centrosymmetric Zr3N4."""
|
||||
matches = _get_matches(ph_zr3n4, suggest, is_time_reversal)
|
||||
if suggest:
|
||||
matches_ref = [
|
||||
|
@ -686,10 +699,8 @@ def _get_matches(ph, suggest, is_time_reversal):
|
|||
return matches
|
||||
|
||||
|
||||
def test_watch_GeneralizedRegularGridPoints(ph_tio2, helper_methods):
|
||||
from phonopy.interface.phonopy_yaml import read_cell_yaml
|
||||
from phonopy.structure.atoms import PhonopyAtoms
|
||||
|
||||
def test_watch_GeneralizedRegularGridPoints(ph_tio2: Phonopy, helper_methods):
|
||||
"""Test for q-points positions obtained from GeneralizedRegularGridPoints."""
|
||||
grgp = GeneralizedRegularGridPoints(ph_tio2.unitcell, 10, x_fastest=False)
|
||||
tmat = grgp.transformation_matrix
|
||||
# direct basis vectors in row vectors
|
||||
|
|
|
@ -1,6 +1,4 @@
|
|||
"""Tests for symmetry tools."""
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
|
||||
from phonopy.structure.cells import get_supercell
|
||||
|
@ -11,8 +9,6 @@ from phonopy.structure.symmetry import (
|
|||
symmetrize_borns_and_epsilon,
|
||||
)
|
||||
|
||||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def test_get_map_operations(convcell_nacl):
|
||||
"""Test get_map_operations()."""
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
"""Tests for routines in tetrahedron_method.py."""
|
||||
import numpy as np
|
||||
|
||||
from phonopy.structure.tetrahedron_method import (
|
||||
|
@ -1193,6 +1194,7 @@ iw_J_ref = [0.05740597, 0.76331859]
|
|||
|
||||
|
||||
def test_get_all_tetrahedra_relative_grid_address():
|
||||
"""Test of get_all_tetrahedra_relative_grid_address."""
|
||||
rel_ga = get_all_tetrahedra_relative_grid_address()
|
||||
# for i, line in enumerate(rel_ga.reshape(-1, 12)):
|
||||
# print("%03d: " % i + "".join(["%d, " % v for v in line]))
|
||||
|
@ -1200,6 +1202,7 @@ def test_get_all_tetrahedra_relative_grid_address():
|
|||
|
||||
|
||||
def test_get_tetrahedra_integration_weight():
|
||||
"""Test of get_tetrahedra_integration_weight."""
|
||||
iw_I = get_tetrahedra_integration_weight(freqs, tetra_freqs, function="I")
|
||||
iw_J = get_tetrahedra_integration_weight(freqs, tetra_freqs, function="J")
|
||||
np.testing.assert_allclose(iw_I_ref, iw_I, atol=1e-5)
|
||||
|
@ -1207,6 +1210,7 @@ def test_get_tetrahedra_integration_weight():
|
|||
|
||||
|
||||
def test_get_tetrahedra_integration_weight_one_freq():
|
||||
"""Test of get_tetrahedra_integration_weight with float as first parameter."""
|
||||
iw_I = []
|
||||
iw_J = []
|
||||
for i in range(2):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# from phonopy.interface.vasp import write_vasp
|
||||
"""Tests for band unfolding calculations."""
|
||||
import os
|
||||
|
||||
import numpy as np
|
||||
|
@ -9,8 +9,8 @@ from phonopy.unfolding.core import Unfolding
|
|||
data_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
def test_Unfolding_NaCl(ph_nacl):
|
||||
"""Test to reproduce proper band structure of primitive cell
|
||||
def test_Unfolding_NaCl(ph_nacl: Phonopy):
|
||||
"""Test to reproduce proper band structure of primitive cell.
|
||||
|
||||
Results are written to "bin-unfolding-test.dat".
|
||||
This data can be plotted by
|
||||
|
@ -21,7 +21,6 @@ def test_Unfolding_NaCl(ph_nacl):
|
|||
The test is done with nd=10.
|
||||
|
||||
"""
|
||||
|
||||
# ph = _get_phonon(ph_nacl)
|
||||
ph = ph_nacl
|
||||
nd = 10
|
||||
|
@ -50,8 +49,8 @@ def test_Unfolding_NaCl(ph_nacl):
|
|||
_compare(weights, os.path.join(data_dir, "bin-unfolding.dat"), filename_out=None)
|
||||
|
||||
|
||||
def test_Unfolding_SC(ph_nacl):
|
||||
"""Test to reproduce unfoled band structure
|
||||
def test_Unfolding_SC(ph_nacl: Phonopy):
|
||||
"""Test to reproduce unfoled band structure.
|
||||
|
||||
Atomic positions are considered as the lattice ponts.
|
||||
|
||||
|
@ -64,7 +63,6 @@ def test_Unfolding_SC(ph_nacl):
|
|||
The test is done with nd=10.
|
||||
|
||||
"""
|
||||
|
||||
# ph = _get_phonon(ph_nacl)
|
||||
ph = ph_nacl
|
||||
nd = 10
|
||||
|
|
Loading…
Reference in New Issue