Writing docstrings following pydocstring

This commit is contained in:
Atsushi Togo 2021-10-25 10:01:15 +09:00
parent eb344cb67c
commit fe68d75f1a
34 changed files with 540 additions and 480 deletions

View File

@ -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

View File

@ -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"]

View File

@ -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()

View File

@ -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

View File

@ -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.

View File

@ -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,

View File

@ -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)

View File

@ -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):

View File

@ -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

View File

@ -1,3 +1,4 @@
"""Routines for user and calculator interfaces to phonopy."""
# Copyright (C) 2019 Atsushi Togo
# All rights reserved.
#

View File

@ -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

View File

@ -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):

View File

@ -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)):

View File

@ -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):

View File

@ -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")

View File

@ -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):

View File

@ -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))

View File

@ -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.

View File

@ -1,3 +1,4 @@
"""Collection of physical units."""
# Copyright (C) 2011 Atsushi Togo
# All rights reserved.
#

View File

@ -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

View File

@ -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])

View File

@ -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

View File

@ -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

View File

@ -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."""

View File

@ -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

View File

@ -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))

View File

@ -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."""

View File

@ -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]

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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()."""

View File

@ -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):

View File

@ -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