Remove files for phono3py

This commit is contained in:
Atsushi Togo 2016-10-31 09:54:02 +09:00
parent 556cc16730
commit e809e937af
78 changed files with 1 additions and 32724 deletions

View File

@ -1,7 +0,0 @@
graft c/harmonic_h
graft c/anharmonic_h
graft c/spglib_h
graft c/kspclib_h
graft example
graft example-phono3py
include setup.py

View File

View File

@ -1,336 +0,0 @@
# Copyright (C) 2015 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.
import sys
from phonopy.harmonic.force_constants import show_drift_force_constants
from anharmonic.phonon3.fc3 import show_drift_fc3
from anharmonic.file_IO import (parse_disp_fc3_yaml,
parse_disp_fc2_yaml,
parse_FORCES_FC2,
parse_FORCES_FC3,
read_fc3_from_hdf5,
read_fc2_from_hdf5,
write_fc3_to_hdf5,
write_fc2_to_hdf5)
from anharmonic.cui.show_log import (show_phono3py_force_constants_settings,
print_error, file_exists)
def create_phono3py_force_constants(phono3py,
phonon_supercell_matrix,
settings,
energy_to_eV=None,
distance_to_A=None,
input_filename=None,
output_filename=None,
log_level=1):
read_fc3 = settings.get_read_fc3()
read_fc2 = settings.get_read_fc2()
symmetrize_fc3_r = settings.get_is_symmetrize_fc3_r()
symmetrize_fc3_q = settings.get_is_symmetrize_fc3_q()
symmetrize_fc2 = settings.get_is_symmetrize_fc2()
if settings.get_is_translational_symmetry():
tsym_type = 1
elif settings.get_tsym_type() > 0:
tsym_type = settings.get_tsym_type()
else:
tsym_type = 0
if log_level:
show_phono3py_force_constants_settings(read_fc3,
read_fc2,
tsym_type,
symmetrize_fc3_r,
symmetrize_fc3_q,
symmetrize_fc2,
settings)
# fc3
if (settings.get_is_joint_dos() or
(settings.get_is_isotope() and
not (settings.get_is_bterta() or settings.get_is_lbte())) or
settings.get_read_gamma() or
settings.get_read_amplitude() or
settings.get_constant_averaged_pp_interaction() is not None):
pass
else:
if read_fc3: # Read fc3.hdf5
if input_filename is None:
filename = 'fc3.hdf5'
else:
filename = 'fc3.' + input_filename + '.hdf5'
file_exists(filename, log_level)
if log_level:
print("Reading fc3 from %s" % filename)
fc3 = read_fc3_from_hdf5(filename=filename)
num_atom = phono3py.get_supercell().get_number_of_atoms()
if fc3.shape[0] != num_atom:
print("Matrix shape of fc3 doesn't agree with supercell size.")
if log_level:
print_error()
sys.exit(1)
phono3py.set_fc3(fc3)
else: # fc3 from FORCES_FC3
if not _create_phono3py_fc3(phono3py,
energy_to_eV,
distance_to_A,
tsym_type,
symmetrize_fc3_r,
symmetrize_fc2,
settings.get_cutoff_fc3_distance(),
input_filename,
output_filename,
log_level):
print("fc3 was not created properly.")
if log_level:
print_error()
sys.exit(1)
if log_level:
show_drift_fc3(phono3py.get_fc3())
# fc2
if read_fc2:
if input_filename is None:
filename = 'fc2.hdf5'
else:
filename = 'fc2.' + input_filename + '.hdf5'
file_exists(filename, log_level)
if log_level:
print("Reading fc2 from %s" % filename)
num_atom = phono3py.get_phonon_supercell().get_number_of_atoms()
phonon_fc2 = read_fc2_from_hdf5(filename=filename)
if phonon_fc2.shape[0] != num_atom:
print("Matrix shape of fc2 doesn't agree with supercell size.")
if log_level:
print_error()
sys.exit(1)
phono3py.set_fc2(phonon_fc2)
else:
if log_level:
print("Solving fc2")
if phonon_supercell_matrix is None:
if phono3py.get_fc2() is None:
if not _create_phono3py_fc2(phono3py,
energy_to_eV,
distance_to_A,
tsym_type,
symmetrize_fc2,
input_filename,
log_level):
print("fc2 was not created properly.")
if log_level:
print_error()
sys.exit(1)
else:
if not _create_phono3py_phonon_fc2(phono3py,
energy_to_eV,
distance_to_A,
tsym_type,
symmetrize_fc2,
input_filename,
log_level):
print("fc2 was not created properly.")
if log_level:
print_error()
sys.exit(1)
if output_filename is None:
filename = 'fc2.hdf5'
else:
filename = 'fc2.' + output_filename + '.hdf5'
if log_level:
print("Writing fc2 to %s" % filename)
write_fc2_to_hdf5(phono3py.get_fc2(), filename=filename)
if log_level:
show_drift_force_constants(phono3py.get_fc2(), name='fc2')
def _create_phono3py_fc3(phono3py,
energy_to_eV,
distance_to_A,
tsym_type,
symmetrize_fc3_r,
symmetrize_fc2,
cutoff_distance,
input_filename,
output_filename,
log_level):
if input_filename is None:
filename = 'disp_fc3.yaml'
else:
filename = 'disp_fc3.' + input_filename + '.yaml'
file_exists(filename, log_level)
if log_level:
print("Displacement dataset is read from %s." % filename)
disp_dataset = parse_disp_fc3_yaml(filename=filename)
num_atom = phono3py.get_supercell().get_number_of_atoms()
if disp_dataset['natom'] != num_atom:
print("Number of atoms in supercell is not consistent with %s" %
filename)
if log_level:
print_error()
sys.exit(1)
_convert_displacement_unit(disp_dataset, distance_to_A)
file_exists("FORCES_FC3", log_level)
if log_level:
print("Sets of supercell forces are read from %s." % "FORCES_FC3")
forces_fc3 = parse_FORCES_FC3(disp_dataset)
if not forces_fc3:
return False
_convert_force_unit(forces_fc3, energy_to_eV, distance_to_A)
phono3py.produce_fc3(
forces_fc3,
displacement_dataset=disp_dataset,
cutoff_distance=cutoff_distance,
translational_symmetry_type=tsym_type,
is_permutation_symmetry=symmetrize_fc3_r,
is_permutation_symmetry_fc2=symmetrize_fc2)
if output_filename is None:
filename = 'fc3.hdf5'
else:
filename = 'fc3.' + output_filename + '.hdf5'
if log_level:
print("Writing fc3 to %s" % filename)
write_fc3_to_hdf5(phono3py.get_fc3(), filename=filename)
return True
def _create_phono3py_fc2(phono3py,
energy_to_eV,
distance_to_A,
tsym_type,
symmetrize_fc2,
input_filename,
log_level):
if input_filename is None:
filename = 'disp_fc3.yaml'
else:
filename = 'disp_fc3.' + input_filename + '.yaml'
if log_level:
print("Displacement dataset is read from %s." % filename)
file_exists(filename, log_level)
disp_dataset = parse_disp_fc3_yaml(filename=filename)
num_atom = phono3py.get_supercell().get_number_of_atoms()
if disp_dataset['natom'] != num_atom:
print("Number of atoms in supercell is not consistent with %s" %
filename)
if log_level:
print_error()
sys.exit(1)
_convert_displacement_unit(disp_dataset, distance_to_A, is_fc2=True)
if log_level:
print("Sets of supercell forces are read from %s." % "FORCES_FC3")
file_exists("FORCES_FC3", log_level)
forces_fc2 = parse_FORCES_FC2(disp_dataset, filename="FORCES_FC3")
if not forces_fc2:
return False
_convert_force_unit(forces_fc2, energy_to_eV, distance_to_A)
phono3py.produce_fc2(
forces_fc2,
displacement_dataset=disp_dataset,
translational_symmetry_type=tsym_type,
is_permutation_symmetry=symmetrize_fc2)
return True
def _create_phono3py_phonon_fc2(phono3py,
energy_to_eV,
distance_to_A,
tsym_type,
symmetrize_fc2,
input_filename,
log_level):
if input_filename is None:
filename = 'disp_fc2.yaml'
else:
filename = 'disp_fc2.' + input_filename + '.yaml'
if log_level:
print("Displacement dataset is read from %s." % filename)
file_exists(filename, log_level)
disp_dataset = parse_disp_fc2_yaml(filename=filename)
num_atom = phono3py.get_phonon_supercell().get_number_of_atoms()
if disp_dataset['natom'] != num_atom:
print("Number of atoms in supercell is not consistent with %s" %
filename)
if log_level:
print_error()
sys.exit(1)
_convert_displacement_unit(disp_dataset, distance_to_A, is_fc2=True)
if log_level:
print("Sets of supercell forces are read from %s." %
"FORCES_FC2")
file_exists("FORCES_FC2", log_level)
forces_fc2 = parse_FORCES_FC2(disp_dataset)
if not forces_fc2:
return False
_convert_force_unit(forces_fc2, energy_to_eV, distance_to_A)
phono3py.produce_fc2(
forces_fc2,
displacement_dataset=disp_dataset,
translational_symmetry_type=tsym_type,
is_permutation_symmetry=symmetrize_fc2)
return True
def _convert_force_unit(force_sets, energy_to_eV, distance_to_A):
if energy_to_eV is not None and distance_to_A is not None:
if energy_to_eV is None:
unit_conversion_factor = 1.0 / distance_to_A
elif distance_to_A is None:
unit_conversion_factor = energy_to_eV
else:
unit_conversion_factor = energy_to_eV / distance_to_A
for forces in force_sets:
if forces is not None:
forces *= unit_conversion_factor
def _convert_displacement_unit(disp_dataset, distance_to_A, is_fc2=False):
if distance_to_A is not None:
for first_atom in disp_dataset['first_atoms']:
for i in range(3):
first_atom['displacement'][i] *= distance_to_A
if not is_fc2:
for second_atom in first_atom['second_atoms']:
for i in range(3):
second_atom['displacement'][i] *= distance_to_A

View File

@ -1,130 +0,0 @@
# Copyright (C) 2015 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.
import sys
from anharmonic.phonon3 import Phono3py
from anharmonic.file_IO import write_disp_fc3_yaml, write_disp_fc2_yaml
def create_phono3py_supercells(unitcell,
supercell_matrix,
phonon_supercell_matrix,
displacement_distance,
is_plusminus,
is_diagonal,
cutoff_pair_distance,
write_supercells_with_displacements,
optional_structure_file_information,
symprec,
interface_mode='vasp',
output_filename=None,
log_level=1):
if displacement_distance is None:
if interface_mode == 'pwscf':
distance = 0.06
else:
distance = 0.03
else:
distance = displacement_distance
phono3py = Phono3py(
unitcell,
supercell_matrix,
phonon_supercell_matrix=phonon_supercell_matrix,
symprec=symprec)
supercell = phono3py.get_supercell()
phono3py.generate_displacements(
distance=distance,
cutoff_pair_distance=cutoff_pair_distance,
is_plusminus=is_plusminus,
is_diagonal=is_diagonal)
dds = phono3py.get_displacement_dataset()
if log_level:
print('')
print("Displacement distance: %s" % distance)
if output_filename is None:
filename = 'disp_fc3.yaml'
else:
filename = 'disp_fc3.' + output_filename + '.yaml'
num_disps, num_disp_files = write_disp_fc3_yaml(dds,
supercell,
filename=filename)
cells_with_disps = phono3py.get_supercells_with_displacements()
if interface_mode == 'pwscf':
pp_filenames = optional_structure_file_information[1]
write_supercells_with_displacements(supercell,
cells_with_disps,
pp_filenames,
width=5)
else:
write_supercells_with_displacements(supercell,
cells_with_disps,
width=5)
if log_level:
print("Number of displacements: %d" % num_disps)
if cutoff_pair_distance is not None:
print("Cutoff distance for displacements: %s" %
cutoff_pair_distance)
print("Number of displacement supercell files created: %d" %
num_disp_files)
if phonon_supercell_matrix is not None:
phonon_dds = phono3py.get_phonon_displacement_dataset()
phonon_supercell = phono3py.get_phonon_supercell()
if output_filename is None:
filename = 'disp_fc2.yaml'
else:
filename = 'disp_fc2.' + output_filename + '.yaml'
num_disps = write_disp_fc2_yaml(phonon_dds,
phonon_supercell,
filename=filename)
cells_with_disps = phono3py.get_phonon_supercells_with_displacements()
if interface_mode == 'pwscf':
pp_filenames = optional_structure_file_information[1]
write_supercells_with_displacements(phonon_supercell,
cells_with_disps,
pp_filenames,
pre_filename="supercell_fc2",
width=5)
else:
write_supercells_with_displacements(phonon_supercell,
cells_with_disps,
pre_filename="POSCAR_FC2",
width=5)
if log_level:
print("Number of displacements for special fc2: %d" % num_disps)

View File

@ -1,418 +0,0 @@
# Copyright (C) 2015 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.
from optparse import OptionParser
def get_parser():
parser = OptionParser()
parser.set_defaults(band_indices=None,
band_paths=None,
band_points=None,
cell_filename=None,
constant_averaged_pp_interaction=None,
cutoff_fc3_distance=None,
cutoff_frequency=None,
boundary_mfp=None,
cutoff_pair_distance=None,
delta_fc2=False,
delta_fc2_sets_mode=False,
displacement_distance=None,
force_sets_to_forces_fc2_mode=None,
forces_fc3_mode=False,
forces_fc3_file_mode=False,
forces_fc2_mode=False,
force_sets_mode=False,
frequency_conversion_factor=None,
fpitch=None,
frequency_scale_factor=None,
num_frequency_points=None,
freq_scale=None,
gamma_unit_conversion=None,
grid_addresses=None,
grid_points=None,
gv_delta_q=None,
input_filename=None,
input_output_filename=None,
ion_clamped=False,
is_bterta=False,
is_decay_channel=False,
is_nodiag=False,
is_displacement=False,
is_nomeshsym=False,
is_gruneisen=False,
is_isotope=False,
is_joint_dos=False,
is_linewidth=False,
is_lbte=False,
is_frequency_shift=False,
is_full_pp=False,
is_nac=False,
is_plusminus_displacements=False,
is_reducible_collision_matrix=False,
is_translational_symmetry=False,
is_symmetrize_fc2=False,
is_symmetrize_fc3_r=False,
is_symmetrize_fc3_q=False,
is_tetrahedron_method=False,
log_level=None,
max_freepath=None,
masses=None,
mass_variances=None,
mesh_numbers=None,
mesh_divisors=None,
no_kappa_stars=False,
output_filename=None,
phonon_supercell_dimension=None,
pinv_cutoff=1.0e-8,
pp_unit_conversion=None,
primitive_axis=None,
qpoints=None,
quiet=False,
q_direction=None,
read_amplitude=False,
read_collision=None,
read_fc2=False,
read_fc3=False,
read_gamma=False,
run_with_g=True,
scattering_event_class=None,
show_num_triplets=False,
sigma=None,
supercell_dimension=None,
symprec=1e-5,
temperatures=None,
tmax=None,
tmin=None,
tstep=None,
tsym_type=None,
uplo='L',
use_ave_pp=False,
verbose=False,
write_amplitude=False,
write_collision=False,
write_gamma_detail=False,
write_gamma=False,
write_phonon=False,
write_grid_points=False)
parser.add_option(
"--amplitude", dest="displacement_distance", type="float",
help="Distance of displacements")
parser.add_option(
"--band", dest="band_paths", action="store", type="string",
help="Band structure paths calculated for Gruneisen parameter")
parser.add_option(
"--band_points", dest="band_points", type="int",
help=("Number of points calculated on a band segment in the band "
"structure Gruneisen parameter calculation"))
parser.add_option(
"--bi", "--band_indices", dest="band_indices", type="string",
help="Band indices where life time is calculated")
parser.add_option(
"--boundary_mfp", "--bmfp", dest="boundary_mfp", type="float",
help=("Boundary mean free path in micrometre for thermal conductivity "
"calculation"))
parser.add_option(
"--br", "--bterta", dest="is_bterta", action="store_true",
help="Calculate thermal conductivity in BTE-RTA")
parser.add_option(
"-c", "--cell", dest="cell_filename", action="store", type="string",
help="Read unit cell", metavar="FILE")
parser.add_option(
"--cf2", "--create_f2", dest="forces_fc2_mode",
action="store_true", help="Create FORCES_FC2")
parser.add_option(
"--cf3", "--create_f3", dest="forces_fc3_mode",
action="store_true", help="Create FORCES_FC3")
parser.add_option(
"--cf3_file", "--create_f3_from_file",
dest="forces_fc3_file_mode",
action="store_true",
help="Create FORCES_FC3 from file name list")
parser.add_option(
"--cfs", "--create_force_sets", dest="force_sets_mode",
action="store_true",
help="Create phonopy FORCE_SETS from FORCES_FC2")
parser.add_option(
"--const_ave_pp",
dest="constant_averaged_pp_interaction",
type="float",
help="Set constant averaged ph-ph interaction (Pqj)")
parser.add_option(
"--cutoff_fc3", "--cutoff_fc3_distance",
dest="cutoff_fc3_distance", type="float",
help=("Cutoff distance of third-order force constants. Elements where "
"any pair of atoms has larger distance than cut-off distance are "
"set zero."))
parser.add_option(
"--cutoff_freq", "--cutoff_frequency", dest="cutoff_frequency",
type="float",
help="Phonon modes below this frequency are ignored.")
parser.add_option(
"--cutoff_pair", "--cutoff_pair_distance",
dest="cutoff_pair_distance", type="float",
help=("Cutoff distance between pairs of displaced atoms used for "
"supercell creation with displacements and making third-order "
"force constants"))
parser.add_option(
"-d", "--disp", dest="is_displacement", action="store_true",
help="As first stage, get least displacements")
parser.add_option(
"--dim", dest="supercell_dimension", type="string",
help="Supercell dimension")
parser.add_option(
"--dim_fc2", dest="phonon_supercell_dimension", type="string",
help="Supercell dimension for extra fc2")
parser.add_option(
"--factor", dest="frequency_conversion_factor", type="float",
help="Conversion factor to favorite frequency unit")
parser.add_option(
"--fc2", dest="read_fc2", action="store_true",
help="Read second order force constants")
parser.add_option(
"--fc3", dest="read_fc3", action="store_true",
help="Read third order force constants")
parser.add_option(
"--fs2f2", "--force_sets_to_forces_fc2",
dest="force_sets_to_forces_fc2_mode",
action="store_true", help="Create FORCES_FC2 from FORCE_SETS")
parser.add_option(
"--freq_scale", dest="frequency_scale_factor", type="float",
help=("Squared scale factor multiplied with fc2. Therefore frequency "
"is changed but the contribution from NAC is not changed."))
parser.add_option(
"--freq_pitch", dest="fpitch", type="float",
help="Pitch in frequency for spectrum")
parser.add_option(
"--full_pp", dest="is_full_pp",
action="store_true",
help=("Calculate full ph-ph interaction for RTA conductivity."
"This may be activated when full elements of ph-ph interaction "
"strength are needed, i.e., to calculate average ph-ph "
"interaction strength."))
parser.add_option(
"--gamma_unit_conversion", dest="gamma_unit_conversion", type="float",
help="Conversion factor for gamma")
parser.add_option(
"--gp", "--grid_points", dest="grid_points", type="string",
help="Fixed grid points where anharmonic properties are calculated")
parser.add_option(
"--ga", "--grid_addresses", dest="grid_addresses", type="string",
help="Fixed grid addresses where anharmonic properties are calculated")
parser.add_option(
"--gruneisen", dest="is_gruneisen", action="store_true",
help="Calculate phonon Gruneisen parameter")
parser.add_option(
"--gv_delta_q", dest="gv_delta_q", type="float",
help="Delta-q distance used for group velocity calculation")
parser.add_option(
"-i", dest="input_filename", type="string",
help="Input filename extension")
parser.add_option(
"--io", dest="input_output_filename", type="string",
help="Input and output filename extension")
parser.add_option(
"--ion_clamped", dest="ion_clamped", action="store_true",
help=("Atoms are clamped under applied strain in Gruneisen parameter "
"calculation"))
parser.add_option(
"--ise", dest="is_imag_self_energy", action="store_true",
help="Calculate imaginary part of self energy")
parser.add_option(
"--isotope", dest="is_isotope", action="store_true",
help="Isotope scattering lifetime")
parser.add_option(
"--jdos", dest="is_joint_dos", action="store_true",
help="Calculate joint density of states")
parser.add_option(
"--lbte", dest="is_lbte", action="store_true",
help="Calculate thermal conductivity LBTE with Chaput's method")
parser.add_option(
"--loglevel", dest="log_level", type="int", help="Log level")
parser.add_option(
"--lw", "--linewidth", dest="is_linewidth",
action="store_true", help="Calculate linewidths")
parser.add_option(
"--fst", "--frequency_shift", dest="is_frequency_shift",
action="store_true", help="Calculate frequency shifts")
parser.add_option(
"--mass", dest="masses", action="store", type="string",
help="Same as MASS tag")
parser.add_option(
"--md", "--mesh_divisors", dest="mesh_divisors", type="string",
help="Divisors for mesh numbers")
parser.add_option(
"--mesh", dest="mesh_numbers", type="string",
help="Mesh numbers")
parser.add_option(
"--mv", "--mass_variances", dest="mass_variances",
type="string",
help="Mass variance parameters for isotope scattering")
parser.add_option(
"--nac", dest="is_nac", action="store_true",
help="Non-analytical term correction")
parser.add_option(
"--nodiag", dest="is_nodiag", action="store_true",
help="Set displacements parallel to axes")
parser.add_option(
"--noks", "--no_kappa_stars", dest="no_kappa_stars", action="store_true",
help="Deactivate summation of partial kappa at q-stars"),
parser.add_option(
"--nomeshsym", dest="is_nomeshsym", action="store_true",
help="No symmetrization of triplets is made.")
parser.add_option(
"--num_freq_points", dest="num_frequency_points", type="int",
help="Number of sampling points for spectrum")
parser.add_option(
"-o", dest="output_filename", type="string",
help="Output filename extension")
parser.add_option(
"--pa", "--primitive_axis", dest="primitive_axis", action="store",
type="string", help="Same as PRIMITIVE_AXIS tags")
parser.add_option(
"--pinv_cutoff", dest="pinv_cutoff", type="float",
help="Cutoff frequency (THz) for pseudo inversion of collision matrix")
parser.add_option(
"--pm", dest="is_plusminus_displacements", action="store_true",
help="Set plus minus displacements")
parser.add_option(
"--pp_unit_conversion", dest="pp_unit_conversion", type="float",
help="Conversion factor for ph-ph interaction")
parser.add_option(
"--pwscf", dest="pwscf_mode",
action="store_true", help="Invoke Pwscf mode")
parser.add_option(
"--qpoints", dest="qpoints", type="string",
help="Calculate at specified q-points")
parser.add_option(
"--q_direction", dest="q_direction", type="string",
help="q-vector direction at q->0 for non-analytical term correction")
parser.add_option(
"-q", "--quiet", dest="quiet", action="store_true",
help="Print out smallest information")
# parser.add_option(
# "--read_amplitude", dest="read_amplitude", action="store_true",
# help="Read phonon-phonon interaction amplitudes")
parser.add_option(
"--use_ave_pp", dest="use_ave_pp", action="store_true",
help="Use averaged ph-ph interaction")
parser.add_option(
"--read_collision", dest="read_collision", type="string",
help="Read collision matrix and Gammas from files")
parser.add_option(
"--read_gamma", dest="read_gamma", action="store_true",
help="Read Gammas from files")
parser.add_option(
"--read_phonon", dest="read_phonon", action="store_true",
help="Read phonons from files")
parser.add_option(
"--reducible_colmat", dest="is_reducible_collision_matrix",
action="store_true", help="Solve reducible collision matrix")
parser.add_option(
"--run_without_g", dest="run_with_g", action="store_false",
help=("Calculate imag-part self energy without using "
"integration weights from gaussian smearing function"))
parser.add_option(
"--scattering_event_class", dest="scattering_event_class", type="int",
help=("Scattering event class 1 or 2 to draw imaginary part of self "
"energy"))
parser.add_option(
"--stp", "--show_num_triplets", dest="show_num_triplets",
action="store_true",
help=("Show reduced number of triplets to be calculated at "
"specified grid points"))
parser.add_option(
"--sigma", dest="sigma", type="string",
help=("A sigma value or multiple sigma values (separated by space) for "
"smearing width used for limited functions"))
parser.add_option(
"--sym_fc2", dest="is_symmetrize_fc2", action="store_true",
help="Symmetrize fc2 by index exchange")
parser.add_option(
"--sym_fc3r", dest="is_symmetrize_fc3_r", action="store_true",
help="Symmetrize fc3 in real space by index exchange")
parser.add_option(
"--sym_fc3q", dest="is_symmetrize_fc3_q", action="store_true",
help="Symmetrize fc3 in reciprocal space by index exchange")
parser.add_option(
"--thm", "--tetrahedron_method", dest="is_tetrahedron_method",
action="store_true", help="Use tetrahedron method")
parser.add_option(
"--tmax", dest="tmax", type="string",
help="Maximum calculated temperature")
parser.add_option(
"--tmin", dest="tmin", type="string",
help="Minimum calculated temperature")
parser.add_option(
"--ts", dest="temperatures", type="string",
help="Temperatures for damping functions")
parser.add_option(
"--tstep", dest="tstep", type="string",
help="Calculated temperature step")
parser.add_option(
"--tsym", dest="is_translational_symmetry", action="store_true",
help="Impose translational invariance condition")
parser.add_option(
"--tsym_type", dest="tsym_type", type="int",
help="Imposing type of translational invariance")
parser.add_option(
"--tolerance", dest="symprec", type="float",
help="Symmetry tolerance to search")
parser.add_option(
"--uplo", dest="uplo", type="string", help="Lapack zheev UPLO")
parser.add_option(
"-v", "--verbose", dest="verbose", action="store_true",
help="Detailed run-time information is displayed")
parser.add_option(
"--wgp", "--write_grid_points", dest="write_grid_points",
action="store_true",
help=("Write grid address of irreducible grid points for specified "
"mesh numbers to ir_grid_address.yaml"))
# parser.add_option("--write_amplitude", dest="write_amplitude",
# action="store_true",
# help="Write phonon-phonon interaction amplitudes")
parser.add_option(
"--write_collision", dest="write_collision", action="store_true",
help="Write collision matrix and Gammas to files")
parser.add_option(
"--write_gamma_detail", "--write_detailed_gamma",
dest="write_gamma_detail",
action="store_true", help="Write out detailed imag-part of self energy")
parser.add_option(
"--write_gamma", dest="write_gamma", action="store_true",
help="Write imag-part of self energy to files")
parser.add_option(
"--write_phonon", dest="write_phonon", action="store_true",
help="Write all phonons on grid points to files")
return parser

View File

@ -1,949 +0,0 @@
import numpy as np
from phonopy.cui.settings import Settings, ConfParser, fracval
class Phono3pySettings(Settings):
def __init__(self):
Settings.__init__(self)
self._boundary_mfp = 1.0e6 # In micrometre. The default value is
# just set to avoid divergence.
self._coarse_mesh_shifts = None
self._constant_averaged_pp_interaction = None
self._create_displacements = False
self._cutoff_fc3_distance = None
self._cutoff_pair_distance = None
self._frequency_scale_factor = None
self._gamma_conversion_factor = None
self._grid_addresses = None
self._grid_points = None
self._ion_clamped = False
self._is_bterta = False
self._is_frequency_shift = False
self._is_full_pp = False
self._is_gruneisen = False
self._is_imag_self_energy = False
self._is_isotope = False
self._is_joint_dos = False
self._is_kappa_star = True
self._is_lbte = False
self._is_linewidth = False
self._is_reducible_collision_matrix = False
self._is_symmetrize_fc2 = False
self._is_symmetrize_fc3_q = False
self._is_symmetrize_fc3_r = False
self._mass_variances = None
self._max_freepath = None
self._mesh_divisors = None
self._read_amplitude = False
self._read_collision = None
self._read_fc2 = False
self._read_fc3 = False
self._read_gamma = False
self._read_phonon = False
self._run_with_g = True
self._phonon_supercell_matrix = None
self._pinv_cutoff = 1.0e-8
self._pp_conversion_factor = None
self._scattering_event_class = None # scattering event class 1 or 2
self._temperatures = None
self._use_ave_pp = False
self._write_amplitude = False
self._write_collision = False
self._write_gamma_detail = False
self._write_gamma = False
self._write_phonon = False
def set_boundary_mfp(self, boundary_mfp):
self._boundary_mfp = boundary_mfp
def get_boundary_mfp(self):
return self._boundary_mfp
def set_coarse_mesh_shifts(self, coarse_mesh_shifts):
self._coarse_mesh_shifts = coarse_mesh_shifts
def get_coarse_mesh_shifts(self):
return self._coarse_mesh_shifts
def set_create_displacements(self, create_displacements):
self._create_displacements = create_displacements
def get_create_displacements(self):
return self._create_displacements
def set_constant_averaged_pp_interaction(self, ave_pp):
self._constant_averaged_pp_interaction = ave_pp
def get_constant_averaged_pp_interaction(self):
return self._constant_averaged_pp_interaction
def set_cutoff_fc3_distance(self, cutoff_fc3_distance):
self._cutoff_fc3_distance = cutoff_fc3_distance
def get_cutoff_fc3_distance(self):
return self._cutoff_fc3_distance
def set_cutoff_pair_distance(self, cutoff_pair_distance):
self._cutoff_pair_distance = cutoff_pair_distance
def get_cutoff_pair_distance(self):
return self._cutoff_pair_distance
def set_frequency_scale_factor(self, frequency_scale_factor):
self._frequency_scale_factor = frequency_scale_factor
def get_frequency_scale_factor(self):
return self._frequency_scale_factor
def set_gamma_conversion_factor(self, gamma_conversion_factor):
self._gamma_conversion_factor = gamma_conversion_factor
def get_gamma_conversion_factor(self):
return self._gamma_conversion_factor
def set_grid_addresses(self, grid_addresses):
self._grid_addresses = grid_addresses
def get_grid_addresses(self):
return self._grid_addresses
def set_grid_points(self, grid_points):
self._grid_points = grid_points
def get_grid_points(self):
return self._grid_points
def set_ion_clamped(self, ion_clamped):
self._ion_clamped = ion_clamped
def get_ion_clamped(self):
return self._ion_clamped
def set_is_bterta(self, is_bterta):
self._is_bterta = is_bterta
def get_is_bterta(self):
return self._is_bterta
def set_is_frequency_shift(self, is_frequency_shift):
self._is_frequency_shift = is_frequency_shift
def get_is_frequency_shift(self):
return self._is_frequency_shift
def set_is_full_pp(self, is_full_pp):
self._is_full_pp = is_full_pp
def get_is_full_pp(self):
return self._is_full_pp
def set_is_gruneisen(self, is_gruneisen):
self._is_gruneisen = is_gruneisen
def get_is_gruneisen(self):
return self._is_gruneisen
def set_is_imag_self_energy(self, is_imag_self_energy):
self._is_imag_self_energy = is_imag_self_energy
def get_is_imag_self_energy(self):
return self._is_imag_self_energy
def set_is_isotope(self, is_isotope):
self._is_isotope = is_isotope
def get_is_isotope(self):
return self._is_isotope
def set_is_joint_dos(self, is_joint_dos):
self._is_joint_dos = is_joint_dos
def get_is_joint_dos(self):
return self._is_joint_dos
def set_is_kappa_star(self, is_kappa_star):
self._is_kappa_star = is_kappa_star
def get_is_kappa_star(self):
return self._is_kappa_star
def set_is_lbte(self, is_lbte):
self._is_lbte = is_lbte
def get_is_lbte(self):
return self._is_lbte
def set_is_linewidth(self, is_linewidth):
self._is_linewidth = is_linewidth
def get_is_linewidth(self):
return self._is_linewidth
def set_is_reducible_collision_matrix(self, is_reducible_collision_matrix):
self._is_reducible_collision_matrix = is_reducible_collision_matrix
def get_is_reducible_collision_matrix(self):
return self._is_reducible_collision_matrix
def set_is_symmetrize_fc2(self, is_symmetrize_fc2):
self._is_symmetrize_fc2 = is_symmetrize_fc2
def get_is_symmetrize_fc2(self):
return self._is_symmetrize_fc2
def set_is_symmetrize_fc3_q(self, is_symmetrize_fc3_q):
self._is_symmetrize_fc3_q = is_symmetrize_fc3_q
def get_is_symmetrize_fc3_q(self):
return self._is_symmetrize_fc3_q
def set_is_symmetrize_fc3_r(self, is_symmetrize_fc3_r):
self._is_symmetrize_fc3_r = is_symmetrize_fc3_r
def get_is_symmetrize_fc3_r(self):
return self._is_symmetrize_fc3_r
def set_mass_variances(self, mass_variances):
self._mass_variances = mass_variances
def get_mass_variances(self):
return self._mass_variances
def set_max_freepath(self, max_freepath):
self._max_freepath = max_freepath
def get_max_freepath(self):
return self._max_freepath
def set_mesh_divisors(self, mesh_divisors):
self._mesh_divisors = mesh_divisors
def get_mesh_divisors(self):
return self._mesh_divisors
def set_phonon_supercell_matrix(self, matrix):
self._phonon_supercell_matrix = matrix
def get_phonon_supercell_matrix(self):
return self._phonon_supercell_matrix
def set_pinv_cutoff(self, pinv_cutoff):
self._pinv_cutoff = pinv_cutoff
def get_pinv_cutoff(self):
return self._pinv_cutoff
def set_pp_conversion_factor(self, pp_conversion_factor):
self._pp_conversion_factor = pp_conversion_factor
def get_pp_conversion_factor(self):
return self._pp_conversion_factor
def set_read_amplitude(self, read_amplitude):
self._read_amplitude = read_amplitude
def get_read_amplitude(self):
return self._read_amplitude
def set_read_collision(self, read_collision):
self._read_collision = read_collision
def get_read_collision(self):
return self._read_collision
def set_read_fc2(self, read_fc2):
self._read_fc2 = read_fc2
def get_read_fc2(self):
return self._read_fc2
def set_read_fc3(self, read_fc3):
self._read_fc3 = read_fc3
def get_read_fc3(self):
return self._read_fc3
def set_read_gamma(self, read_gamma):
self._read_gamma = read_gamma
def get_read_gamma(self):
return self._read_gamma
def set_read_phonon(self, read_phonon):
self._read_phonon = read_phonon
def get_read_phonon(self):
return self._read_phonon
def set_run_with_g(self, run_with_g):
self._run_with_g = run_with_g
def get_run_with_g(self):
return self._run_with_g
def set_scattering_event_class(self, scattering_event_class):
self._scattering_event_class = scattering_event_class
def get_scattering_event_class(self):
return self._scattering_event_class
def set_temperatures(self, temperatures):
self._temperatures = temperatures
def get_temperatures(self):
return self._temperatures
def set_use_ave_pp(self, use_ave_pp):
self._use_ave_pp = use_ave_pp
def get_use_ave_pp(self):
return self._use_ave_pp
def set_write_amplitude(self, write_amplitude):
self._write_amplitude = write_amplitude
def get_write_amplitude(self):
return self._write_amplitude
def set_write_collision(self, write_collision):
self._write_collision = write_collision
def get_write_collision(self):
return self._write_collision
def set_write_gamma_detail(self, write_gamma_detail):
self._write_gamma_detail = write_gamma_detail
def get_write_gamma_detail(self):
return self._write_gamma_detail
def set_write_gamma(self, write_gamma):
self._write_gamma = write_gamma
def get_write_gamma(self):
return self._write_gamma
def set_write_phonon(self, write_phonon):
self._write_phonon = write_phonon
def get_write_phonon(self):
return self._write_phonon
class Phono3pyConfParser(ConfParser):
def __init__(self, filename=None, options=None, option_list=None):
ConfParser.__init__(self, filename, options, option_list)
self._read_options()
self._parse_conf()
self._settings = Phono3pySettings()
self._set_settings()
def _read_options(self):
for opt in self._option_list:
if opt.dest == 'phonon_supercell_dimension':
if self._options.phonon_supercell_dimension is not None:
self._confs['dim_fc2'] = self._options.phonon_supercell_dimension
if opt.dest == 'boundary_mfp':
if self._options.boundary_mfp is not None:
self._confs['boundary_mfp'] = self._options.boundary_mfp
if opt.dest == 'constant_averaged_pp_interaction':
if self._options.constant_averaged_pp_interaction is not None:
self._confs['constant_averaged_pp_interaction'] = self._options.constant_averaged_pp_interaction
if opt.dest == 'cutoff_fc3_distance':
if self._options.cutoff_fc3_distance is not None:
self._confs['cutoff_fc3_distance'] = self._options.cutoff_fc3_distance
if opt.dest == 'cutoff_pair_distance':
if self._options.cutoff_pair_distance is not None:
self._confs['cutoff_pair_distance'] = self._options.cutoff_pair_distance
if opt.dest == 'frequency_scale_factor':
if self._options.frequency_scale_factor is not None:
self._confs['frequency_scale_factor'] = self._options.frequency_scale_factor
if opt.dest == 'gamma_conversion_factor':
if self._options.gamma_conversion_factor is not None:
self._confs['gamma_conversion_factor'] = self._options.gamma_conversion_factor
if opt.dest == 'grid_addresses':
if self._options.grid_addresses is not None:
self._confs['grid_addresses'] = self._options.grid_addresses
if opt.dest == 'grid_points':
if self._options.grid_points is not None:
self._confs['grid_points'] = self._options.grid_points
if opt.dest == 'ion_clamped':
if self._options.ion_clamped:
self._confs['ion_clamped'] = '.true.'
if opt.dest == 'is_bterta':
if self._options.is_bterta:
self._confs['bterta'] = '.true.'
if opt.dest == 'is_gruneisen':
if self._options.is_gruneisen:
self._confs['gruneisen'] = '.true.'
if opt.dest == 'is_displacement':
if self._options.is_displacement:
self._confs['create_displacements'] = '.true.'
if opt.dest == 'is_frequency_shift':
if self._options.is_frequency_shift:
self._confs['frequency_shift'] = '.true.'
if opt.dest == 'is_full_pp':
if self._options.is_full_pp:
self._confs['full_pp'] = '.true.'
if opt.dest == 'is_imag_self_energy':
if self._options.is_imag_self_energy:
self._confs['imag_self_energy'] = '.true.'
if opt.dest == 'is_isotope':
if self._options.is_isotope:
self._confs['isotope'] = '.true.'
if opt.dest == 'is_joint_dos':
if self._options.is_joint_dos:
self._confs['joint_dos'] = '.true.'
if opt.dest == 'is_kappa_star':
if self._options.no_kappa_stars:
self._confs['kappa_star'] = '.false.'
if opt.dest == 'is_lbte':
if self._options.is_lbte:
self._confs['lbte'] = '.true.'
if opt.dest == 'is_linewidth':
if self._options.is_linewidth:
self._confs['linewidth'] = '.true.'
if opt.dest == 'is_reducible_collision_matrix':
if self._options.is_reducible_collision_matrix:
self._confs['reducible_collision_matrix'] = '.true.'
if opt.dest == 'is_symmetrize_fc2':
if self._options.is_symmetrize_fc2:
self._confs['symmetrize_fc2'] = '.true.'
if opt.dest == 'is_symmetrize_fc3_q':
if self._options.is_symmetrize_fc3_q:
self._confs['symmetrize_fc3_q'] = '.true.'
if opt.dest == 'is_symmetrize_fc3_r':
if self._options.is_symmetrize_fc3_r:
self._confs['symmetrize_fc3_r'] = '.true.'
if opt.dest == 'mass_variances':
if self._options.mass_variances is not None:
self._confs['mass_variances'] = self._options.mass_variances
if opt.dest == 'max_freepath':
if self._options.max_freepath is not None:
self._confs['max_freepath'] = self._options.max_freepath
if opt.dest == 'mesh_divisors':
if self._options.mesh_divisors is not None:
self._confs['mesh_divisors'] = self._options.mesh_divisors
if opt.dest == 'pinv_cutoff':
if self._options.pinv_cutoff is not None:
self._confs['pinv_cutoff'] = self._options.pinv_cutoff
if opt.dest == 'pp_conversion_factor':
if self._options.pp_conversion_factor is not None:
self._confs['pp_conversion_factor'] = self._options.pp_conversion_factor
if opt.dest == 'read_amplitude':
if self._options.read_amplitude:
self._confs['read_amplitude'] = '.true.'
if opt.dest == 'read_fc2':
if self._options.read_fc2:
self._confs['read_fc2'] = '.true.'
if opt.dest == 'read_fc3':
if self._options.read_fc3:
self._confs['read_fc3'] = '.true.'
if opt.dest == 'read_gamma':
if self._options.read_gamma:
self._confs['read_gamma'] = '.true.'
if opt.dest == 'read_phonon':
if self._options.read_phonon:
self._confs['read_phonon'] = '.true.'
if opt.dest == 'run_with_g':
if not self._options.run_with_g:
self._confs['run_with_g'] = '.false.'
if opt.dest == 'read_collision':
if self._options.read_collision is not None:
self._confs['read_collision'] = self._options.read_collision
if opt.dest == 'scattering_event_class':
if self._options.scattering_event_class is not None:
self._confs['scattering_event_class'] = self._options.scattering_event_class
if opt.dest == 'temperatures':
if self._options.temperatures is not None:
self._confs['temperatures'] = self._options.temperatures
if opt.dest == 'use_ave_pp':
if self._options.use_ave_pp:
self._confs['use_ave_pp'] = '.true.'
if opt.dest == 'write_amplitude':
if self._options.write_amplitude:
self._confs['write_amplitude'] = '.true.'
if opt.dest == 'write_gamma_detail':
if self._options.write_gamma_detail:
self._confs['write_gamma_detail'] = '.true.'
if opt.dest == 'write_gamma':
if self._options.write_gamma:
self._confs['write_gamma'] = '.true.'
if opt.dest == 'write_collision':
if self._options.write_collision:
self._confs['write_collision'] = '.true.'
if opt.dest == 'write_phonon':
if self._options.write_phonon:
self._confs['write_phonon'] = '.true.'
def _parse_conf(self):
confs = self._confs
for conf_key in confs.keys():
if conf_key == 'create_displacements':
if confs['create_displacements'] == '.true.':
self.set_parameter('create_displacements', True)
if conf_key == 'dim_fc2':
matrix = [ int(x) for x in confs['dim_fc2'].split() ]
if len(matrix) == 9:
matrix = np.array(matrix).reshape(3, 3)
elif len(matrix) == 3:
matrix = np.diag(matrix)
else:
self.setting_error(
"Number of elements of dim2 has to be 3 or 9.")
if matrix.shape == (3, 3):
if np.linalg.det(matrix) < 1:
self.setting_error(
"Determinant of supercell matrix has " +
"to be positive.")
else:
self.set_parameter('dim_fc2', matrix)
if conf_key == 'boundary_mfp':
self.set_parameter('boundary_mfp',
float(confs['boundary_mfp']))
if conf_key == 'constant_averaged_pp_interaction':
self.set_parameter(
'constant_averaged_pp_interaction',
float(confs['constant_averaged_pp_interaction']))
if conf_key == 'cutoff_fc3_distance':
self.set_parameter('cutoff_fc3_distance',
float(confs['cutoff_fc3_distance']))
if conf_key == 'cutoff_pair_distance':
self.set_parameter('cutoff_pair_distance',
float(confs['cutoff_pair_distance']))
if conf_key == 'frequency_scale_factor':
self.set_parameter('frequency_scale_factor',
float(confs['frequency_scale_factor']))
if conf_key == 'full_pp':
if confs['full_pp'] == '.true.':
self.set_parameter('is_full_pp', True)
if conf_key == 'gamma_conversion_factor':
self.set_parameter('gamma_conversion_factor',
float(confs['gamma_conversion_factor']))
if conf_key == 'grid_addresses':
vals = [int(x) for x in
confs['grid_addresses'].replace(',', ' ').split()]
if len(vals) % 3 == 0 and len(vals) > 0:
self.set_parameter('grid_addresses',
np.reshape(vals, (-1, 3)))
else:
self.setting_error("Grid addresses are incorrectly set.")
if conf_key == 'grid_points':
vals = [int(x) for x in
confs['grid_points'].replace(',', ' ').split()]
self.set_parameter('grid_points', vals)
if conf_key == 'ion_clamped':
if confs['ion_clamped'] == '.true.':
self.set_parameter('ion_clamped', True)
if conf_key == 'bterta':
if confs['bterta'] == '.true.':
self.set_parameter('is_bterta', True)
if conf_key == 'frequency_shift':
if confs['frequency_shift'] == '.true.':
self.set_parameter('is_frequency_shift', True)
if conf_key == 'gruneisen':
if confs['gruneisen'] == '.true.':
self.set_parameter('is_gruneisen', True)
if conf_key == 'imag_self_energy':
if confs['imag_self_energy'] == '.true.':
self.set_parameter('is_imag_self_energy', True)
if conf_key == 'isotope':
if confs['isotope'] == '.true.':
self.set_parameter('is_isotope', True)
if conf_key == 'joint_dos':
if confs['joint_dos'] == '.true.':
self.set_parameter('is_joint_dos', True)
if conf_key == 'lbte':
if confs['lbte'] == '.true.':
self.set_parameter('is_lbte', True)
if conf_key == 'linewidth':
if confs['linewidth'] == '.true.':
self.set_parameter('is_linewidth', True)
if conf_key == 'reducible_collision_matrix':
if confs['reducible_collision_matrix'] == '.true.':
self.set_parameter('is_reducible_collision_matrix', True)
if conf_key == 'symmetrize_fc2':
if confs['symmetrize_fc2'] == '.true.':
self.set_parameter('is_symmetrize_fc2', True)
if conf_key == 'symmetrize_fc3_q':
if confs['symmetrize_fc3_q'] == '.true.':
self.set_parameter('is_symmetrize_fc3_q', True)
if conf_key == 'symmetrize_fc3_r':
if confs['symmetrize_fc3_r'] == '.true.':
self.set_parameter('is_symmetrize_fc3_r', True)
if conf_key == 'mass_variances':
vals = [fracval(x) for x in confs['mass_variances'].split()]
if len(vals) < 1:
self.setting_error("Mass variance parameters are incorrectly set.")
else:
self.set_parameter('mass_variances', vals)
if conf_key == 'max_freepath':
self.set_parameter('max_freepath', float(confs['max_freepath']))
if conf_key == 'mesh_divisors':
vals = [x for x in confs['mesh_divisors'].split()]
if len(vals) == 3:
self.set_parameter('mesh_divisors', [int(x) for x in vals])
elif len(vals) == 6:
divs = [int(x) for x in vals[:3]]
is_shift = [x.lower() == 't' for x in vals[3:]]
for i in range(3):
if is_shift[i] and (divs[i] % 2 != 0):
is_shift[i] = False
self.setting_error("Coarse grid shift along the " +
["first", "second", "third"][i] +
" axis is not allowed.")
self.set_parameter('mesh_divisors', divs + is_shift)
else:
self.setting_error("Mesh divisors are incorrectly set.")
if conf_key == 'kappa_star':
if confs['kappa_star'] == '.false.':
self.set_parameter('is_kappa_star', False)
if conf_key == 'pinv_cutoff':
self.set_parameter('pinv_cutoff', float(confs['pinv_cutoff']))
if conf_key == 'pp_conversion_factor':
self.set_parameter('pp_conversion_factor',
float(confs['pp_conversion_factor']))
if conf_key == 'read_amplitude':
if confs['read_amplitude'] == '.true.':
self.set_parameter('read_amplitude', True)
if conf_key == 'read_collision':
if confs['read_collision'] == 'all':
self.set_parameter('read_collision', 'all')
else:
vals = [int(x) for x in confs['read_collision'].split()]
self.set_parameter('read_collision', vals)
if conf_key == 'read_fc2':
if confs['read_fc2'] == '.true.':
self.set_parameter('read_fc2', True)
if conf_key == 'read_fc3':
if confs['read_fc3'] == '.true.':
self.set_parameter('read_fc3', True)
if conf_key == 'read_gamma':
if confs['read_gamma'] == '.true.':
self.set_parameter('read_gamma', True)
if conf_key == 'read_phonon':
if confs['read_phonon'] == '.true.':
self.set_parameter('read_phonon', True)
if conf_key == 'run_with_g':
if confs['run_with_g'] == '.false.':
self.set_parameter('run_with_g', False)
if conf_key == 'scattering_event_class':
self.set_parameter('scattering_event_class',
confs['scattering_event_class'])
if conf_key == 'temperatures':
vals = [fracval(x) for x in confs['temperatures'].split()]
if len(vals) < 1:
self.setting_error("Temperatures are incorrectly set.")
else:
self.set_parameter('temperatures', vals)
if conf_key == 'use_ave_pp':
if confs['use_ave_pp'] == '.true.':
self.set_parameter('use_ave_pp', True)
if conf_key == 'write_amplitude':
if confs['write_amplitude'] == '.true.':
self.set_parameter('write_amplitude', True)
if conf_key == 'write_gamma_detail':
if confs['write_gamma_detail'] == '.true.':
self.set_parameter('write_gamma_detail', True)
if conf_key == 'write_gamma':
if confs['write_gamma'] == '.true.':
self.set_parameter('write_gamma', True)
if conf_key == 'write_collision':
if confs['write_collision'] == '.true.':
self.set_parameter('write_collision', True)
if conf_key == 'write_phonon':
if confs['write_phonon'] == '.true.':
self.set_parameter('write_phonon', True)
def _set_settings(self):
ConfParser.set_settings(self)
params = self._parameters
# Is getting least displacements?
if 'create_displacements' in params:
if params['create_displacements']:
self._settings.set_create_displacements('displacements')
# Supercell dimension for fc2
if 'dim_fc2' in params:
self._settings.set_phonon_supercell_matrix(params['dim_fc2'])
# Boundary mean free path for thermal conductivity calculation
if 'boundary_mfp' in params:
self._settings.set_boundary_mfp(params['boundary_mfp'])
# Peierls type approximation for squared ph-ph interaction strength
if 'constant_averaged_pp_interaction' in params:
self._settings.set_constant_averaged_pp_interaction(
params['constant_averaged_pp_interaction'])
# Cutoff distance of third-order force constants. Elements where any
# pair of atoms has larger distance than cut-off distance are set zero.
if 'cutoff_fc3_distance' in params:
self._settings.set_cutoff_fc3_distance(params['cutoff_fc3_distance'])
# Cutoff distance between pairs of displaced atoms used for supercell
# creation with displacements and making third-order force constants
if 'cutoff_pair_distance' in params:
self._settings.set_cutoff_pair_distance(
params['cutoff_pair_distance'])
# This scale factor is multiplied to frequencies only, i.e., changes
# frequencies but assumed not to change the physical unit
if 'frequency_scale_factor' in params:
self._settings.set_frequency_scale_factor(
params['frequency_scale_factor'])
# Gamma unit conversion factor
if 'gamma_conversion_factor' in params:
self._settings.set_gamma_conversion_factor(
params['gamma_conversion_factor'])
# Grid addresses (sets of three integer values)
if 'grid_addresses' in params:
self._settings.set_grid_addresses(params['grid_addresses'])
# Grid points
if 'grid_points' in params:
self._settings.set_grid_points(params['grid_points'])
# Atoms are clamped under applied strain in Gruneisen parameter calculation
if 'ion_clamped' in params:
self._settings.set_ion_clamped(params['ion_clamped'])
# Calculate thermal conductivity in BTE-RTA
if 'is_bterta' in params:
self._settings.set_is_bterta(params['is_bterta'])
# Calculate frequency_shifts
if 'is_frequency_shift' in params:
self._settings.set_is_frequency_shift(params['is_frequency_shift'])
# Calculate full ph-ph interaction strength for RTA conductivity
if 'is_full_pp' in params:
self._settings.set_is_full_pp(params['is_full_pp'])
# Calculate phonon-Gruneisen parameters
if 'is_gruneisen' in params:
self._settings.set_is_gruneisen(params['is_gruneisen'])
# Calculate imaginary part of self energy
if 'is_imag_self_energy' in params:
self._settings.set_is_imag_self_energy(params['is_imag_self_energy'])
# Calculate lifetime due to isotope scattering
if 'is_isotope' in params:
self._settings.set_is_isotope(params['is_isotope'])
# Calculate joint-DOS
if 'is_joint_dos' in params:
self._settings.set_is_joint_dos(params['is_joint_dos'])
# Calculate thermal conductivity in LBTE with Chaput's method
if 'is_lbte' in params:
self._settings.set_is_lbte(params['is_lbte'])
# Calculate linewidths
if 'is_linewidth' in params:
self._settings.set_is_linewidth(params['is_linewidth'])
# Solve reducible collision matrix but not reduced matrix
if 'is_reducible_collision_matrix' in params:
self._settings.set_is_reducible_collision_matrix(
params['is_reducible_collision_matrix'])
# Symmetrize fc2 by index exchange
if 'is_symmetrize_fc2' in params:
self._settings.set_is_symmetrize_fc2(params['is_symmetrize_fc2'])
# Symmetrize phonon fc3 by index exchange
if 'is_symmetrize_fc3_q' in params:
self._settings.set_is_symmetrize_fc3_q(params['is_symmetrize_fc3_q'])
# Symmetrize fc3 by index exchange
if 'is_symmetrize_fc3_r' in params:
self._settings.set_is_symmetrize_fc3_r(params['is_symmetrize_fc3_r'])
# Mass variance parameters
if 'mass_variances' in params:
self._settings.set_mass_variances(params['mass_variances'])
# Maximum mean free path
if 'max_freepath' in params:
self._settings.set_max_freepath(params['max_freepath'])
# Divisors for mesh numbers
if 'mesh_divisors' in params:
self._settings.set_mesh_divisors(params['mesh_divisors'][:3])
if len(params['mesh_divisors']) > 3:
self._settings.set_coarse_mesh_shifts(
params['mesh_divisors'][3:])
# Cutoff frequency for pseudo inversion of collision matrix
if 'pinv_cutoff' in params:
self._settings.set_pinv_cutoff(params['pinv_cutoff'])
# Ph-ph interaction unit conversion factor
if 'pp_conversion_factor' in params:
self._settings.set_pp_conversion_factor(params['pp_conversion_factor'])
# Read phonon-phonon interaction amplitudes from hdf5
if 'read_amplitude' in params:
self._settings.set_read_amplitude(params['read_amplitude'])
# Read collision matrix and gammas from hdf5
if 'read_collision' in params:
self._settings.set_read_collision(params['read_collision'])
# Read fc2 from hdf5
if 'read_fc2' in params:
self._settings.set_read_fc2(params['read_fc2'])
# Read fc3 from hdf5
if 'read_fc3' in params:
self._settings.set_read_fc3(params['read_fc3'])
# Read gammas from hdf5
if 'read_gamma' in params:
self._settings.set_read_gamma(params['read_gamma'])
# Read phonons from hdf5
if 'read_phonon' in params:
self._settings.set_read_phonon(params['read_phonon'])
# Calculate imag-part self energy with integration weights from gaussian
# smearing function
if 'run_with_g' in params:
self._settings.set_run_with_g(params['run_with_g'])
# Sum partial kappa at q-stars
if 'is_kappa_star' in params:
self._settings.set_is_kappa_star(params['is_kappa_star'])
# Scattering event class 1 or 2
if 'scattering_event_class' in params:
self._settings.set_scattering_event_class(
params['scattering_event_class'])
# Temperatures
if 'temperatures' in params:
self._settings.set_temperatures(params['temperatures'])
# Use averaged ph-ph interaction
if 'use_ave_pp' in params:
self._settings.set_use_ave_pp(params['use_ave_pp'])
# Write phonon-phonon interaction amplitudes to hdf5
if 'write_amplitude' in params:
self._settings.set_write_amplitude(params['write_amplitude'])
# Write detailed imag-part of self energy to hdf5
if 'write_gamma_detail' in params:
self._settings.set_write_gamma_detail(
params['write_gamma_detail'])
# Write imag-part of self energy to hdf5
if 'write_gamma' in params:
self._settings.set_write_gamma(params['write_gamma'])
# Write collision matrix and gammas to hdf5
if 'write_collision' in params:
self._settings.set_write_collision(params['write_collision'])
# Write all phonons on grid points to hdf5
if 'write_phonon' in params:
self._settings.set_write_phonon(params['write_phonon'])

View File

@ -1,214 +0,0 @@
# Copyright (C) 2015 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.
import os
import sys
import numpy as np
from phonopy.structure.cells import print_cell
def file_exists(filename, log_level):
if os.path.exists(filename):
return True
else:
error_text = "%s not found." % filename
print(error_text)
if log_level > 0:
print_error()
sys.exit(1)
# AA is created at http://www.network-science.de/ascii/.
def print_phono3py():
print(""" _ _____
_ __ | |__ ___ _ __ ___|___ / _ __ _ _
| '_ \| '_ \ / _ \| '_ \ / _ \ |_ \| '_ \| | | |
| |_) | | | | (_) | | | | (_) |__) | |_) | |_| |
| .__/|_| |_|\___/|_| |_|\___/____/| .__/ \__, |
|_| |_| |___/ """)
def print_version(version):
print(" " * 42 + "%s" % version)
print('')
def print_end():
print(""" _
___ _ __ __| |
/ _ \ '_ \ / _` |
| __/ | | | (_| |
\___|_| |_|\__,_|
""")
def print_error():
print(""" ___ _ __ _ __ ___ _ __
/ _ \ '__| '__/ _ \| '__|
| __/ | | | | (_) | |
\___|_| |_| \___/|_|
""")
def print_error_message(message):
print('')
print(message)
def show_phono3py_cells(symmetry,
primitive,
supercell,
phonon_primitive,
phonon_supercell,
settings):
print("Spacegroup: %s" % symmetry.get_international_table())
print("-" * 30 + " primitive cell " + "-" * 30)
print_cell(primitive)
print("-" * 32 + " super cell " + "-" * 32)
print_cell(supercell, mapping=primitive.get_supercell_to_primitive_map())
print("-" * 19 + " ratio (supercell for fc)/(primitive) " + "-" * 19)
for vec in np.dot(supercell.get_cell(),
np.linalg.inv(primitive.get_cell())):
print(("%5.2f" * 3) % tuple(vec))
if settings.get_phonon_supercell_matrix() is not None:
print("-" * 19 + " primitive cell for harmonic phonon " + "-" * 20)
print_cell(phonon_primitive)
print("-" * 21 + " supercell for harmonic phonon " + "-" * 22)
print_cell(phonon_supercell,
mapping=phonon_primitive.get_supercell_to_primitive_map())
print("-" * 15 + " ratio (phonon supercell)/(phonon primitive) " +
"-" * 15)
for vec in np.dot(phonon_supercell.get_cell(),
np.linalg.inv(phonon_primitive.get_cell())):
print(("%5.2f" * 3) % tuple(vec))
def show_phono3py_force_constants_settings(read_fc3,
read_fc2,
tsym_type,
is_symmetrize_fc3_r,
is_symmetrize_fc3_q,
is_symmetrize_fc2,
settings):
print("-" * 29 + " Force constants " + "-" * 30)
if not read_fc2:
print("Imposing translational symmetry to fc2: %s" %
(tsym_type > 0))
print("Imposing symmetry of index exchange to fc2: %s" %
is_symmetrize_fc2)
if not (read_fc3 or
settings.get_is_isotope() or
settings.get_is_joint_dos()):
print("Imposing translational symmetry to fc3: %s" %
(tsym_type > 0))
print("Imposing symmetry of index exchange to fc3 in real space: %s" %
is_symmetrize_fc3_r)
print(("Imposing symmetry of index exchange to fc3 in reciprocal space: "
"%s") % is_symmetrize_fc3_q)
if settings.get_cutoff_fc3_distance() is not None:
print("FC3 cutoff distance: %s" % settings.get_cutoff_fc3_distance())
def show_phono3py_settings(settings,
mesh,
mesh_divs,
band_indices,
sigmas,
temperatures,
temperature_points,
grid_points,
cutoff_frequency,
frequency_factor_to_THz,
frequency_step,
num_frequency_points,
log_level):
print("-" * 33 + " Settings " + "-" * 33)
if settings.get_is_nac():
print("Non-analytical term correction: %s" % settings.get_is_nac())
if mesh is not None:
print("Mesh sampling: [ %d %d %d ]" % tuple(mesh))
if mesh_divs is not None and settings.get_is_bterta():
print("Mesh divisors: [ %d %d %d ]" % tuple(mesh_divs))
if band_indices is not None and not settings.get_is_bterta():
print(("Band indices: [" + " %s" * len(band_indices) + " ]") %
tuple([np.array(bi) + 1 for bi in band_indices]))
if sigmas:
text = "BZ integration: "
for i, sigma in enumerate(sigmas):
if sigma:
text += "Smearing=%s" % sigma
else:
text += "Tetrahedron-method"
if i < len(sigmas) - 1:
text += ", "
print(text)
if (settings.get_is_linewidth() or
settings.get_is_frequency_shift() or
settings.get_is_bterta() or
settings.get_is_lbte()):
if len(temperatures) > 5:
text = (" %.1f " * 5 + "...") % tuple(temperatures[:5])
text += " %.1f" % temperatures[-1]
else:
text = (" %.1f " * len(temperatures)) % tuple(temperatures)
print("Temperature: " + text)
elif temperature_points is not None:
print(("Temperatures:" + " %.1f " * len(temperature_points))
% tuple(temperature_points))
if settings.get_scattering_event_class() is not None:
print("Scattering event class: %s" %
settings.get_scattering_event_class())
if grid_points is not None:
text = "Grid point to be calculated: "
if len(grid_points) > 8:
for i, gp in enumerate(grid_points):
if i % 10 == 0:
text += "\n"
text += " "
text += "%d " % gp
else:
for gp in grid_points:
text += "%d " % gp
print(text)
if cutoff_frequency:
print("Cutoff frequency: %s" % cutoff_frequency)
if (settings.get_use_ave_pp() and
(settings.get_is_bterta() or settings.get_is_lbte())):
print("Use averaged ph-ph interaction")
if log_level > 1:
print("Frequency factor to THz: %s" % frequency_factor_to_THz)
if frequency_step is not None:
print("Frequency step for spectrum: %s" % frequency_step)
if num_frequency_points is not None:
print("Number of frequency sampling points: %d" %
num_frequency_points)
sys.stdout.flush()

View File

@ -1,126 +0,0 @@
# Copyright (C) 2015 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.
import numpy as np
from phonopy.units import VaspToTHz
from anharmonic.phonon3.triplets import get_grid_point_from_address
def get_phono3py_configurations(settings):
primitive_matrix = settings.get_primitive_matrix()
supercell_matrix = settings.get_supercell_matrix()
phonon_supercell_matrix = settings.get_phonon_supercell_matrix()
masses = settings.get_masses()
mesh = settings.get_mesh_numbers()
mesh_divs = settings.get_mesh_divisors()
coarse_mesh_shifts = settings.get_coarse_mesh_shifts()
grid_points = settings.get_grid_points()
grid_addresses = settings.get_grid_addresses()
if grid_addresses is not None:
grid_points = [get_grid_point_from_address(ga, mesh)
for ga in grid_addresses]
band_indices = settings.get_band_indices()
# Brillouin zone integration: Tetrahedron (default) or smearing method
sigma = settings.get_sigma()
if sigma is None:
sigmas = []
elif isinstance(sigma, float):
sigmas = [sigma]
else:
sigmas = sigma
if settings.get_is_tetrahedron_method():
sigmas = [None] + sigmas
if len(sigmas) == 0:
sigmas = [None]
if settings.get_temperatures() is None:
if settings.get_is_joint_dos():
temperature_points = None
temperatures = None
else:
t_max = settings.get_max_temperature()
t_min = settings.get_min_temperature()
t_step = settings.get_temperature_step()
temperature_points = [0.0, 300.0] # For spectra
temperatures = np.arange(t_min, t_max + float(t_step) / 10, t_step)
else:
temperature_points = settings.get_temperatures() # For spectra
temperatures = settings.get_temperatures() # For others
if settings.get_frequency_conversion_factor() is None:
frequency_factor_to_THz = VaspToTHz
else:
frequency_factor_to_THz = settings.get_frequency_conversion_factor()
if settings.get_num_frequency_points() is None:
if settings.get_frequency_pitch() is None:
num_frequency_points = 201
frequency_step = None
else:
num_frequency_points = None
frequency_step = settings.get_frequency_pitch()
else:
num_frequency_points = settings.get_num_frequency_points()
frequency_step = None
if settings.get_frequency_scale_factor() is None:
frequency_scale_factor = 1.0
else:
frequency_scale_factor = settings.get_frequency_scale_factor()
if settings.get_cutoff_frequency() is None:
cutoff_frequency = 1e-2
else:
cutoff_frequency = settings.get_cutoff_frequency()
conf = {}
conf['primitive_matrix'] = primitive_matrix
conf['supercell_matrix'] = supercell_matrix
conf['phonon_supercell_matrix'] = phonon_supercell_matrix
conf['masses'] = masses
conf['mesh'] = mesh
conf['mesh_divs'] = mesh_divs
conf['coarse_mesh_shifts'] = coarse_mesh_shifts
conf['grid_points'] = grid_points
conf['band_indices'] = band_indices
conf['sigmas'] = sigmas
conf['temperature_points'] = temperature_points
conf['temperatures'] = temperatures
conf['frequency_factor_to_THz'] = frequency_factor_to_THz
conf['num_frequency_points'] = num_frequency_points
conf['frequency_step'] = frequency_step
conf['frequency_scale_factor'] = frequency_scale_factor
conf['cutoff_frequency'] = cutoff_frequency
return conf

View File

@ -1,107 +0,0 @@
# Copyright (C) 2015 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.
import sys
import numpy as np
from anharmonic.file_IO import (write_ir_grid_points,
write_grid_address_to_hdf5)
from anharmonic.phonon3.triplets import (get_coarse_ir_grid_points,
get_number_of_triplets)
def write_grid_points(primitive,
mesh,
mesh_divs,
coarse_mesh_shifts,
is_kappa_star,
symprec,
log_level):
print("-" * 76)
if mesh is None:
print("To write grid points, mesh numbers have to be specified.")
else:
(ir_grid_points,
grid_weights,
bz_grid_address,
grid_mapping_table) = get_coarse_ir_grid_points(
primitive,
mesh,
mesh_divs,
coarse_mesh_shifts,
is_kappa_star=is_kappa_star,
symprec=symprec)
write_ir_grid_points(mesh,
mesh_divs,
ir_grid_points,
grid_weights,
bz_grid_address,
np.linalg.inv(primitive.get_cell()))
gadrs_hdf5_fname = write_grid_address_to_hdf5(bz_grid_address,
mesh,
grid_mapping_table)
print("Ir-grid points are written into \"ir_grid_points.yaml\".")
print("Grid addresses are written into \"%s\"." % gadrs_hdf5_fname)
def show_num_triplets(primitive,
mesh,
mesh_divs,
grid_points,
coarse_mesh_shifts,
is_kappa_star,
symprec,
log_level):
print("-" * 76)
ir_grid_points, _, grid_address, _ = get_coarse_ir_grid_points(
primitive,
mesh,
mesh_divs,
coarse_mesh_shifts,
is_kappa_star=is_kappa_star,
symprec=symprec)
if grid_points:
_grid_points = grid_points
else:
_grid_points = ir_grid_points
print("Grid point q-point No. of triplets")
for gp in _grid_points:
num_triplets = get_number_of_triplets(primitive,
mesh,
gp,
symprec=symprec)
q = grid_address[gp] / np.array(mesh, dtype='double')
print(" %5d (%5.2f %5.2f %5.2f) %8d" %
(gp, q[0], q[1], q[2], num_triplets))

File diff suppressed because it is too large Load Diff

View File

@ -1,307 +0,0 @@
# Copyright (C) 2015 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.
import numpy as np
from phonopy.phonon.solver import set_phonon_c, set_phonon_py
from anharmonic.phonon3.triplets import get_bz_grid_address, gaussian
from phonopy.harmonic.dynamical_matrix import get_dynamical_matrix
from phonopy.structure.tetrahedron_method import TetrahedronMethod
from phonopy.phonon.tetrahedron_mesh import get_tetrahedra_frequencies
from phonopy.units import VaspToTHz
from phonopy.structure.atoms import isotope_data
def get_mass_variances(primitive):
symbols = primitive.get_chemical_symbols()
mass_variances = []
for s in symbols:
masses = np.array([x[1] for x in isotope_data[s]])
fractions = np.array([x[2] for x in isotope_data[s]])
m_ave = np.dot(masses, fractions)
g = np.dot(fractions, (1 - masses / m_ave) ** 2)
mass_variances.append(g)
return np.array(mass_variances, dtype='double')
class Isotope(object):
def __init__(self,
mesh,
primitive,
mass_variances=None, # length of list is num_atom.
band_indices=None,
sigma=None,
frequency_factor_to_THz=VaspToTHz,
symprec=1e-5,
cutoff_frequency=None,
lapack_zheev_uplo='L'):
self._mesh = np.array(mesh, dtype='intc')
if mass_variances is None:
self._mass_variances = get_mass_variances(primitive)
else:
self._mass_variances = np.array(mass_variances, dtype='double')
self._primitive = primitive
self._band_indices = band_indices
self._sigma = sigma
self._symprec = symprec
if cutoff_frequency is None:
self._cutoff_frequency = 0
else:
self._cutoff_frequency = cutoff_frequency
self._frequency_factor_to_THz = frequency_factor_to_THz
self._lapack_zheev_uplo = lapack_zheev_uplo
self._nac_q_direction = None
self._grid_address = None
self._bz_map = None
self._grid_points = None
self._frequencies = None
self._eigenvectors = None
self._phonon_done = None
self._dm = None
self._band_indices = None
self._grid_point = None
self._gamma = None
self._tetrahedron_method = None
def set_grid_point(self, grid_point):
self._grid_point = grid_point
num_band = self._primitive.get_number_of_atoms() * 3
if self._band_indices is None:
self._band_indices = np.arange(num_band, dtype='intc')
else:
self._band_indices = np.array(self._band_indices, dtype='intc')
self._grid_points = np.arange(np.prod(self._mesh), dtype='intc')
if self._grid_address is None:
primitive_lattice = np.linalg.inv(self._primitive.get_cell())
self._grid_address, self._bz_map = get_bz_grid_address(
self._mesh, primitive_lattice, with_boundary=True)
if self._phonon_done is None:
self._allocate_phonon()
def set_sigma(self, sigma):
if sigma is None:
self._sigma = None
else:
self._sigma = float(sigma)
def run(self):
self._run_c()
def get_gamma(self):
return self._gamma
def get_grid_address(self):
return self._grid_address
def get_mass_variances(self):
return self._mass_variances
def get_phonons(self):
return self._frequencies, self._eigenvectors, self._phonon_done
def set_phonons(self, frequencies, eigenvectors, phonon_done, dm=None):
self._frequencies = frequencies
self._eigenvectors = eigenvectors
self._phonon_done = phonon_done
if dm is not None:
self._dm = dm
def set_dynamical_matrix(self,
fc2,
supercell,
primitive,
nac_params=None,
frequency_scale_factor=None,
decimals=None):
self._primitive = primitive
self._dm = get_dynamical_matrix(
fc2,
supercell,
primitive,
nac_params=nac_params,
frequency_scale_factor=frequency_scale_factor,
decimals=decimals,
symprec=self._symprec)
def set_nac_q_direction(self, nac_q_direction=None):
if nac_q_direction is not None:
self._nac_q_direction = np.array(nac_q_direction, dtype='double')
def _run_c(self):
self._set_phonon_c(self._grid_points)
import anharmonic._phono3py as phono3c
gamma = np.zeros(len(self._band_indices), dtype='double')
if self._sigma is None:
self._set_integration_weights()
weights = np.ones(len(self._grid_points), dtype='intc')
phono3c.thm_isotope_strength(gamma,
self._grid_point,
self._grid_points,
weights,
self._mass_variances,
self._frequencies,
self._eigenvectors,
self._band_indices,
self._integration_weights,
self._cutoff_frequency)
else:
phono3c.isotope_strength(gamma,
self._grid_point,
self._mass_variances,
self._frequencies,
self._eigenvectors,
self._band_indices,
np.prod(self._mesh),
self._sigma,
self._cutoff_frequency)
self._gamma = gamma / np.prod(self._mesh)
def _set_integration_weights(self):
primitive_lattice = np.linalg.inv(self._primitive.get_cell())
thm = TetrahedronMethod(primitive_lattice, mesh=self._mesh)
num_grid_points = len(self._grid_points)
num_band = self._primitive.get_number_of_atoms() * 3
self._integration_weights = np.zeros(
(num_grid_points, len(self._band_indices), num_band), dtype='double')
self._set_integration_weights_c(thm)
def _set_integration_weights_c(self, thm):
import anharmonic._phono3py as phono3c
unique_vertices = thm.get_unique_tetrahedra_vertices()
neighboring_grid_points = np.zeros(
len(unique_vertices) * len(self._grid_points), dtype='intc')
phono3c.neighboring_grid_points(
neighboring_grid_points,
self._grid_points,
unique_vertices,
self._mesh,
self._grid_address,
self._bz_map)
self._set_phonon_c(np.unique(neighboring_grid_points))
freq_points = np.array(
self._frequencies[self._grid_point, self._band_indices],
dtype='double', order='C')
phono3c.integration_weights(
self._integration_weights,
freq_points,
thm.get_tetrahedra(),
self._mesh,
self._grid_points,
self._frequencies,
self._grid_address,
self._bz_map)
def _set_integration_weights_py(self, thm):
for i, gp in enumerate(self._grid_points):
tfreqs = get_tetrahedra_frequencies(
gp,
self._mesh,
[1, self._mesh[0], self._mesh[0] * self._mesh[1]],
self._grid_address,
thm.get_tetrahedra(),
self._grid_points,
self._frequencies)
for bi, frequencies in enumerate(tfreqs):
thm.set_tetrahedra_omegas(frequencies)
thm.run(self._frequencies[self._grid_point, self._band_indices])
iw = thm.get_integration_weight()
self._integration_weights[i, :, bi] = iw
def _run_py(self):
for gp in self._grid_points:
self._set_phonon_py(gp)
if self._sigma is None:
self._set_integration_weights()
t_inv = []
for bi in self._band_indices:
vec0 = self._eigenvectors[self._grid_point][:, bi].conj()
f0 = self._frequencies[self._grid_point][bi]
ti_sum = 0.0
for i, gp in enumerate(self._grid_points):
for j, (f, vec) in enumerate(
zip(self._frequencies[i], self._eigenvectors[i].T)):
if f < self._cutoff_frequency:
continue
ti_sum_band = np.sum(
np.abs((vec * vec0).reshape(-1, 3).sum(axis=1)) ** 2
* self._mass_variances)
if self._sigma is None:
ti_sum += ti_sum_band * self._integration_weights[
i, bi, j]
else:
ti_sum += ti_sum_band * gaussian(f0 - f, self._sigma)
t_inv.append(np.pi / 2 / np.prod(self._mesh) * f0 ** 2 * ti_sum)
self._gamma = np.array(t_inv, dtype='double') / 2
def _set_phonon_c(self, grid_points):
set_phonon_c(self._dm,
self._frequencies,
self._eigenvectors,
self._phonon_done,
grid_points,
self._grid_address,
self._mesh,
self._frequency_factor_to_THz,
self._nac_q_direction,
self._lapack_zheev_uplo)
def _set_phonon_py(self, grid_point):
set_phonon_py(grid_point,
self._phonon_done,
self._frequencies,
self._eigenvectors,
self._grid_address,
self._mesh,
self._dm,
self._frequency_factor_to_THz,
self._lapack_zheev_uplo)
def _allocate_phonon(self):
num_band = self._primitive.get_number_of_atoms() * 3
num_grid = len(self._grid_address)
self._phonon_done = np.zeros(num_grid, dtype='byte')
self._frequencies = np.zeros((num_grid, num_band), dtype='double')
itemsize = self._frequencies.itemsize
self._eigenvectors = np.zeros((num_grid, num_band, num_band),
dtype=("c%d" % (itemsize * 2)))

View File

@ -1,858 +0,0 @@
import numpy as np
from phonopy.structure.symmetry import Symmetry
from phonopy.structure.cells import get_supercell, get_primitive
from phonopy.structure.atoms import PhonopyAtoms as Atoms
from phonopy.units import VaspToTHz
from phonopy.harmonic.force_constants import (get_fc2, set_permutation_symmetry,
set_translational_invariance)
from phonopy.harmonic.displacement import get_least_displacements
from phonopy.harmonic.displacement import direction_to_displacement as \
direction_to_displacement_fc2
from anharmonic.phonon3.imag_self_energy import (get_imag_self_energy,
write_imag_self_energy,
get_linewidth,
write_linewidth)
from anharmonic.phonon3.frequency_shift import get_frequency_shift
from anharmonic.phonon3.interaction import Interaction
from anharmonic.phonon3.conductivity_RTA import get_thermal_conductivity_RTA
from anharmonic.phonon3.conductivity_LBTE import get_thermal_conductivity_LBTE
from anharmonic.phonon3.joint_dos import JointDos
from anharmonic.phonon3.displacement_fc3 import (get_third_order_displacements,
direction_to_displacement)
from anharmonic.file_IO import write_joint_dos, write_phonon_to_hdf5
from anharmonic.other.isotope import Isotope
from anharmonic.phonon3.fc3 import (get_fc3,
set_permutation_symmetry_fc3,
set_translational_invariance_fc3,
cutoff_fc3_by_zero)
class Phono3py(object):
def __init__(self,
unitcell,
supercell_matrix,
primitive_matrix=None,
phonon_supercell_matrix=None,
masses=None,
mesh=None,
band_indices=None,
sigmas=None,
cutoff_frequency=1e-4,
frequency_factor_to_THz=VaspToTHz,
is_symmetry=True,
is_mesh_symmetry=True,
symmetrize_fc3_q=False,
symprec=1e-5,
log_level=0,
lapack_zheev_uplo='L'):
if sigmas is None:
self._sigmas = [None]
else:
self._sigmas = sigmas
self._symprec = symprec
self._frequency_factor_to_THz = frequency_factor_to_THz
self._is_symmetry = is_symmetry
self._is_mesh_symmetry = is_mesh_symmetry
self._lapack_zheev_uplo = lapack_zheev_uplo
self._symmetrize_fc3_q = symmetrize_fc3_q
self._cutoff_frequency = cutoff_frequency
self._log_level = log_level
# Create supercell and primitive cell
self._unitcell = unitcell
self._supercell_matrix = supercell_matrix
self._primitive_matrix = primitive_matrix
self._phonon_supercell_matrix = phonon_supercell_matrix # optional
self._supercell = None
self._primitive = None
self._phonon_supercell = None
self._phonon_primitive = None
self._build_supercell()
self._build_primitive_cell()
self._build_phonon_supercell()
self._build_phonon_primitive_cell()
if masses is not None:
self._set_masses(masses)
# Set supercell, primitive, and phonon supercell symmetries
self._symmetry = None
self._primitive_symmetry = None
self._phonon_supercell_symmetry = None
self._search_symmetry()
self._search_primitive_symmetry()
self._search_phonon_supercell_symmetry()
# Displacements and supercells
self._supercells_with_displacements = None
self._displacement_dataset = None
self._phonon_displacement_dataset = None
self._phonon_supercells_with_displacements = None
# Thermal conductivity
self._thermal_conductivity = None # conductivity_RTA object
# Imaginary part of self energy at frequency points
self._imag_self_energy = None
self._scattering_event_class = None
# Linewidth (Imaginary part of self energy x 2) at temperatures
self._linewidth = None
self._grid_points = None
self._frequency_points = None
self._temperatures = None
# Other variables
self._fc2 = None
self._fc3 = None
# Setup interaction
self._interaction = None
self._mesh = None
self._band_indices = None
self._band_indices_flatten = None
if mesh is not None:
self._mesh = np.array(mesh, dtype='intc')
self.set_band_indices(band_indices)
def set_band_indices(self, band_indices):
if band_indices is None:
num_band = self._primitive.get_number_of_atoms() * 3
self._band_indices = [np.arange(num_band, dtype='intc')]
else:
self._band_indices = band_indices
self._band_indices_flatten = np.hstack(self._band_indices).astype('intc')
def set_phph_interaction(self,
nac_params=None,
nac_q_direction=None,
constant_averaged_interaction=None,
frequency_scale_factor=None,
unit_conversion=None):
self._interaction = Interaction(
self._supercell,
self._primitive,
self._mesh,
self._primitive_symmetry,
fc3=self._fc3,
band_indices=self._band_indices_flatten,
constant_averaged_interaction=constant_averaged_interaction,
frequency_factor_to_THz=self._frequency_factor_to_THz,
unit_conversion=unit_conversion,
cutoff_frequency=self._cutoff_frequency,
is_mesh_symmetry=self._is_mesh_symmetry,
symmetrize_fc3_q=self._symmetrize_fc3_q,
lapack_zheev_uplo=self._lapack_zheev_uplo)
self._interaction.set_dynamical_matrix(
self._fc2,
self._phonon_supercell,
self._phonon_primitive,
nac_params=nac_params,
frequency_scale_factor=frequency_scale_factor)
self._interaction.set_nac_q_direction(nac_q_direction=nac_q_direction)
def set_phonon_data(self, frequencies, eigenvectors, grid_address):
if self._interaction is not None:
return self._interaction.set_phonon_data(frequencies,
eigenvectors,
grid_address)
else:
return False
def write_phonons(self, filename=None):
if self._interaction is not None:
grid_address = self._interaction.get_grid_address()
grid_points = np.arange(len(grid_address), dtype='intc')
self._interaction.set_phonons(grid_points)
freqs, eigvecs, _ = self._interaction.get_phonons()
hdf5_filename = write_phonon_to_hdf5(freqs,
eigvecs,
grid_address,
self._mesh,
filename=filename)
return hdf5_filename
else:
return False
def generate_displacements(self,
distance=0.03,
cutoff_pair_distance=None,
is_plusminus='auto',
is_diagonal=True):
direction_dataset = get_third_order_displacements(
self._supercell,
self._symmetry,
is_plusminus=is_plusminus,
is_diagonal=is_diagonal)
self._displacement_dataset = direction_to_displacement(
direction_dataset,
distance,
self._supercell,
cutoff_distance=cutoff_pair_distance)
if self._phonon_supercell_matrix is not None:
phonon_displacement_directions = get_least_displacements(
self._phonon_supercell_symmetry,
is_plusminus=is_plusminus,
is_diagonal=False)
self._phonon_displacement_dataset = direction_to_displacement_fc2(
phonon_displacement_directions,
distance,
self._phonon_supercell)
def produce_fc2(self,
forces_fc2,
displacement_dataset=None,
is_translational_symmetry=False,
is_permutation_symmetry=False,
translational_symmetry_type=None):
if displacement_dataset is None:
disp_dataset = self._displacement_dataset
else:
disp_dataset = displacement_dataset
for forces, disp1 in zip(forces_fc2, disp_dataset['first_atoms']):
disp1['forces'] = forces
self._fc2 = get_fc2(self._phonon_supercell,
self._phonon_supercell_symmetry,
disp_dataset)
if is_permutation_symmetry:
set_permutation_symmetry(self._fc2)
if is_translational_symmetry:
tsym_type = 1
else:
tsym_type = 0
if translational_symmetry_type:
tsym_type = translational_symmetry_type
if tsym_type:
set_translational_invariance(
self._fc2,
translational_symmetry_type=tsym_type)
def produce_fc3(self,
forces_fc3,
displacement_dataset=None,
cutoff_distance=None, # set fc3 zero
is_translational_symmetry=False,
is_permutation_symmetry=False,
is_permutation_symmetry_fc2=False,
translational_symmetry_type=None):
if displacement_dataset is None:
disp_dataset = self._displacement_dataset
else:
disp_dataset = displacement_dataset
for forces, disp1 in zip(forces_fc3, disp_dataset['first_atoms']):
disp1['forces'] = forces
fc2 = get_fc2(self._supercell, self._symmetry, disp_dataset)
if is_permutation_symmetry_fc2:
set_permutation_symmetry(fc2)
if is_translational_symmetry:
tsym_type = 1
else:
tsym_type = 0
if translational_symmetry_type:
tsym_type = translational_symmetry_type
if tsym_type:
set_translational_invariance(
fc2,
translational_symmetry_type=tsym_type)
count = len(disp_dataset['first_atoms'])
for disp1 in disp_dataset['first_atoms']:
for disp2 in disp1['second_atoms']:
disp2['delta_forces'] = forces_fc3[count] - disp1['forces']
count += 1
self._fc3 = get_fc3(
self._supercell,
disp_dataset,
fc2,
self._symmetry,
translational_symmetry_type=tsym_type,
is_permutation_symmetry=is_permutation_symmetry,
verbose=self._log_level)
# Set fc3 elements zero beyond cutoff_distance
if cutoff_distance:
if self._log_level:
print("Cutting-off fc3 by zero (cut-off distance: %f)" %
cutoff_distance)
self.cutoff_fc3_by_zero(cutoff_distance)
# Set fc2
if self._fc2 is None:
self._fc2 = fc2
def cutoff_fc3_by_zero(self, cutoff_distance):
cutoff_fc3_by_zero(self._fc3,
self._supercell,
cutoff_distance,
self._symprec)
def set_permutation_symmetry(self):
if self._fc2 is not None:
set_permutation_symmetry(self._fc2)
if self._fc3 is not None:
set_permutation_symmetry_fc3(self._fc3)
def set_translational_invariance(self,
translational_symmetry_type=1):
if self._fc2 is not None:
set_translational_invariance(
self._fc2,
translational_symmetry_type=translational_symmetry_type)
if self._fc3 is not None:
set_translational_invariance_fc3(
self._fc3,
translational_symmetry_type=translational_symmetry_type)
def get_interaction_strength(self):
return self._interaction
def get_fc2(self):
return self._fc2
def set_fc2(self, fc2):
self._fc2 = fc2
def get_fc3(self):
return self._fc3
def set_fc3(self, fc3):
self._fc3 = fc3
def get_primitive(self):
return self._primitive
def get_unitcell(self):
return self._unitcell
def get_supercell(self):
return self._supercell
def get_phonon_supercell(self):
return self._phonon_supercell
def get_phonon_primitive(self):
return self._phonon_primitive
def get_symmetry(self):
"""return symmetry of supercell"""
return self._symmetry
def get_primitive_symmetry(self):
return self._primitive_symmetry
def get_phonon_supercell_symmetry(self):
return self._phonon_supercell_symmetry
def set_displacement_dataset(self, dataset):
self._displacement_dataset = dataset
def get_displacement_dataset(self):
return self._displacement_dataset
def get_phonon_displacement_dataset(self):
return self._phonon_displacement_dataset
def get_supercells_with_displacements(self):
if self._supercells_with_displacements is None:
self._build_supercells_with_displacements()
return self._supercells_with_displacements
def get_phonon_supercells_with_displacements(self):
if self._phonon_supercells_with_displacements is None:
if self._phonon_displacement_dataset is not None:
self._phonon_supercells_with_displacements = \
self._build_phonon_supercells_with_displacements(
self._phonon_supercell,
self._phonon_displacement_dataset)
return self._phonon_supercells_with_displacements
def run_imag_self_energy(self,
grid_points,
frequency_step=None,
num_frequency_points=None,
temperatures=None,
scattering_event_class=None,
run_with_g=True,
write_gamma_detail=False):
if self._interaction is None:
self.set_phph_interaction()
if temperatures is None:
temperatures = [0.0, 300.0]
self._grid_points = grid_points
self._temperatures = temperatures
self._scattering_event_class = scattering_event_class
self._imag_self_energy, self._frequency_points = get_imag_self_energy(
self._interaction,
grid_points,
self._sigmas,
frequency_step=frequency_step,
num_frequency_points=num_frequency_points,
temperatures=temperatures,
scattering_event_class=scattering_event_class,
run_with_g=run_with_g,
write_detail=write_gamma_detail,
log_level=self._log_level)
def write_imag_self_energy(self, filename=None):
write_imag_self_energy(
self._imag_self_energy,
self._mesh,
self._grid_points,
self._band_indices,
self._frequency_points,
self._temperatures,
self._sigmas,
scattering_event_class=self._scattering_event_class,
filename=filename,
is_mesh_symmetry=self._is_mesh_symmetry)
def run_linewidth(self,
grid_points,
temperatures=np.arange(0, 1001, 10, dtype='double'),
run_with_g=True,
write_gamma_detail=False):
if self._interaction is None:
self.set_phph_interaction()
self._grid_points = grid_points
self._temperatures = temperatures
self._linewidth = get_linewidth(self._interaction,
grid_points,
self._sigmas,
temperatures=temperatures,
run_with_g=run_with_g,
write_detail=write_gamma_detail,
log_level=self._log_level)
def write_linewidth(self, filename=None):
write_linewidth(self._linewidth,
self._band_indices,
self._mesh,
self._grid_points,
self._sigmas,
self._temperatures,
filename=filename,
is_mesh_symmetry=self._is_mesh_symmetry)
def run_thermal_conductivity(
self,
is_LBTE=False,
temperatures=np.arange(0, 1001, 10, dtype='double'),
is_isotope=False,
mass_variances=None,
grid_points=None,
boundary_mfp=None, # in micrometre
use_ave_pp=False,
gamma_unit_conversion=None,
mesh_divisors=None,
coarse_mesh_shifts=None,
is_reducible_collision_matrix=False,
is_kappa_star=True,
gv_delta_q=None, # for group velocity
run_with_g=True, # integration weights for smearing method, too
is_full_pp=False,
pinv_cutoff=1.0e-8, # for pseudo-inversion of collision matrix
write_gamma=False,
read_gamma=False,
write_kappa=False,
write_gamma_detail=False,
write_collision=False,
read_collision=False,
write_amplitude=False,
read_amplitude=False,
input_filename=None,
output_filename=None):
if self._interaction is None:
self.set_phph_interaction()
if is_LBTE:
self._thermal_conductivity = get_thermal_conductivity_LBTE(
self._interaction,
self._primitive_symmetry,
temperatures=temperatures,
sigmas=self._sigmas,
is_isotope=is_isotope,
mass_variances=mass_variances,
grid_points=grid_points,
boundary_mfp=boundary_mfp,
is_reducible_collision_matrix=is_reducible_collision_matrix,
is_kappa_star=is_kappa_star,
gv_delta_q=gv_delta_q,
pinv_cutoff=pinv_cutoff,
write_collision=write_collision,
read_collision=read_collision,
write_kappa=write_kappa,
input_filename=input_filename,
output_filename=output_filename,
log_level=self._log_level)
else:
self._thermal_conductivity = get_thermal_conductivity_RTA(
self._interaction,
self._primitive_symmetry,
temperatures=temperatures,
sigmas=self._sigmas,
is_isotope=is_isotope,
mass_variances=mass_variances,
grid_points=grid_points,
boundary_mfp=boundary_mfp,
use_ave_pp=use_ave_pp,
gamma_unit_conversion=gamma_unit_conversion,
mesh_divisors=mesh_divisors,
coarse_mesh_shifts=coarse_mesh_shifts,
is_kappa_star=is_kappa_star,
gv_delta_q=gv_delta_q,
run_with_g=run_with_g,
is_full_pp=is_full_pp,
write_gamma=write_gamma,
read_gamma=read_gamma,
write_kappa=write_kappa,
write_gamma_detail=write_gamma_detail,
input_filename=input_filename,
output_filename=output_filename,
log_level=self._log_level)
def get_thermal_conductivity(self):
return self._thermal_conductivity
def get_frequency_shift(self,
grid_points,
temperatures=np.arange(0, 1001, 10, dtype='double'),
output_filename=None):
if self._interaction is None:
self.set_phph_interaction()
if epsilons is None:
epsilons = [0.1]
self._grid_points = grid_points
get_frequency_shift(self._interaction,
self._grid_points,
self._band_indices,
self._sigmas,
temperatures,
output_filename=output_filename,
log_level=self._log_level)
def _search_symmetry(self):
self._symmetry = Symmetry(self._supercell,
self._symprec,
self._is_symmetry)
def _search_primitive_symmetry(self):
self._primitive_symmetry = Symmetry(self._primitive,
self._symprec,
self._is_symmetry)
if (len(self._symmetry.get_pointgroup_operations()) !=
len(self._primitive_symmetry.get_pointgroup_operations())):
print("Warning: point group symmetries of supercell and primitive"
"cell are different.")
def _search_phonon_supercell_symmetry(self):
if self._phonon_supercell_matrix is None:
self._phonon_supercell_symmetry = self._symmetry
else:
self._phonon_supercell_symmetry = Symmetry(self._phonon_supercell,
self._symprec,
self._is_symmetry)
def _build_supercell(self):
self._supercell = get_supercell(self._unitcell,
self._supercell_matrix,
self._symprec)
def _build_primitive_cell(self):
"""
primitive_matrix:
Relative axes of primitive cell to the input unit cell.
Relative axes to the supercell is calculated by:
supercell_matrix^-1 * primitive_matrix
Therefore primitive cell lattice is finally calculated by:
(supercell_lattice * (supercell_matrix)^-1 * primitive_matrix)^T
"""
self._primitive = self._get_primitive_cell(
self._supercell, self._supercell_matrix, self._primitive_matrix)
def _build_phonon_supercell(self):
"""
phonon_supercell:
This supercell is used for harmonic phonons (frequencies,
eigenvectors, group velocities, ...)
phonon_supercell_matrix:
Different supercell size can be specified.
"""
if self._phonon_supercell_matrix is None:
self._phonon_supercell = self._supercell
else:
self._phonon_supercell = get_supercell(
self._unitcell, self._phonon_supercell_matrix, self._symprec)
def _build_phonon_primitive_cell(self):
if self._phonon_supercell_matrix is None:
self._phonon_primitive = self._primitive
else:
self._phonon_primitive = self._get_primitive_cell(
self._phonon_supercell,
self._phonon_supercell_matrix,
self._primitive_matrix)
if self._primitive is not None:
if (self._primitive.get_atomic_numbers() !=
self._phonon_primitive.get_atomic_numbers()).any():
print("********************* Warning *********************")
print(" Primitive cells for fc2 and fc3 can be different.")
print("********************* Warning *********************")
def _build_phonon_supercells_with_displacements(self,
supercell,
displacement_dataset):
supercells = []
magmoms = supercell.get_magnetic_moments()
masses = supercell.get_masses()
numbers = supercell.get_atomic_numbers()
lattice = supercell.get_cell()
for disp1 in displacement_dataset['first_atoms']:
disp_cart1 = disp1['displacement']
positions = supercell.get_positions()
positions[disp1['number']] += disp_cart1
supercells.append(
Atoms(numbers=numbers,
masses=masses,
magmoms=magmoms,
positions=positions,
cell=lattice,
pbc=True))
return supercells
def _build_supercells_with_displacements(self):
supercells = []
magmoms = self._supercell.get_magnetic_moments()
masses = self._supercell.get_masses()
numbers = self._supercell.get_atomic_numbers()
lattice = self._supercell.get_cell()
supercells = self._build_phonon_supercells_with_displacements(
self._supercell,
self._displacement_dataset)
for disp1 in self._displacement_dataset['first_atoms']:
disp_cart1 = disp1['displacement']
for disp2 in disp1['second_atoms']:
if 'included' in disp2:
included = disp2['included']
else:
included = True
if included:
positions = self._supercell.get_positions()
positions[disp1['number']] += disp_cart1
positions[disp2['number']] += disp2['displacement']
supercells.append(Atoms(numbers=numbers,
masses=masses,
magmoms=magmoms,
positions=positions,
cell=lattice,
pbc=True))
else:
supercells.append(None)
self._supercells_with_displacements = supercells
def _get_primitive_cell(self, supercell, supercell_matrix, primitive_matrix):
inv_supercell_matrix = np.linalg.inv(supercell_matrix)
if primitive_matrix is None:
t_mat = inv_supercell_matrix
else:
t_mat = np.dot(inv_supercell_matrix, primitive_matrix)
return get_primitive(supercell, t_mat, self._symprec)
def _set_masses(self, masses):
p_masses = np.array(masses)
self._primitive.set_masses(p_masses)
p2p_map = self._primitive.get_primitive_to_primitive_map()
s_masses = p_masses[[p2p_map[x] for x in
self._primitive.get_supercell_to_primitive_map()]]
self._supercell.set_masses(s_masses)
u2s_map = self._supercell.get_unitcell_to_supercell_map()
u_masses = s_masses[u2s_map]
self._unitcell.set_masses(u_masses)
self._phonon_primitive.set_masses(p_masses)
p2p_map = self._phonon_primitive.get_primitive_to_primitive_map()
s_masses = p_masses[
[p2p_map[x] for x in
self._phonon_primitive.get_supercell_to_primitive_map()]]
self._phonon_supercell.set_masses(s_masses)
class Phono3pyIsotope(object):
def __init__(self,
mesh,
primitive,
mass_variances=None, # length of list is num_atom.
band_indices=None,
sigmas=None,
frequency_factor_to_THz=VaspToTHz,
symprec=1e-5,
cutoff_frequency=None,
lapack_zheev_uplo='L'):
if sigmas is None:
self._sigmas = [None]
else:
self._sigmas = sigmas
self._mesh = mesh
self._iso = Isotope(mesh,
primitive,
mass_variances=mass_variances,
band_indices=band_indices,
frequency_factor_to_THz=frequency_factor_to_THz,
symprec=symprec,
cutoff_frequency=cutoff_frequency,
lapack_zheev_uplo=lapack_zheev_uplo)
def run(self, grid_points):
for gp in grid_points:
self._iso.set_grid_point(gp)
print("--------------- Isotope scattering ---------------")
print("Grid point: %d" % gp)
adrs = self._iso.get_grid_address()[gp]
q = adrs.astype('double') / self._mesh
print("q-point: %s" % q)
if self._sigmas:
for sigma in self._sigmas:
if sigma is None:
print("Tetrahedron method")
else:
print("Sigma: %s" % sigma)
self._iso.set_sigma(sigma)
self._iso.run()
frequencies = self._iso.get_phonons()[0]
print('')
print("Phonon-isotope scattering rate in THz (1/4pi-tau)")
print(" Frequency Rate")
for g, f in zip(self._iso.get_gamma(), frequencies[gp]):
print("%8.3f %5.3e" % (f, g))
else:
print("sigma or tetrahedron method has to be set.")
def set_dynamical_matrix(self,
fc2,
supercell,
primitive,
nac_params=None,
frequency_scale_factor=None,
decimals=None):
self._primitive = primitive
self._iso.set_dynamical_matrix(
fc2,
supercell,
primitive,
nac_params=nac_params,
frequency_scale_factor=frequency_scale_factor,
decimals=decimals)
def set_sigma(self, sigma):
self._iso.set_sigma(sigma)
class Phono3pyJointDos(object):
def __init__(self,
supercell,
primitive,
mesh,
fc2,
nac_params=None,
nac_q_direction=None,
sigmas=None,
cutoff_frequency=1e-4,
frequency_step=None,
num_frequency_points=None,
temperatures=None,
frequency_factor_to_THz=VaspToTHz,
frequency_scale_factor=None,
is_mesh_symmetry=True,
symprec=1e-5,
output_filename=None,
log_level=0):
if sigmas is None:
self._sigmas = [None]
else:
self._sigmas = sigmas
self._supercell = supercell
self._primitive = primitive
self._mesh = mesh
self._fc2 = fc2
self._nac_params = nac_params
self._nac_q_direction = nac_q_direction
self._cutoff_frequency = cutoff_frequency
self._frequency_step = frequency_step
self._num_frequency_points = num_frequency_points
self._temperatures = temperatures
self._frequency_factor_to_THz = frequency_factor_to_THz
self._frequency_scale_factor = frequency_scale_factor
self._is_mesh_symmetry = is_mesh_symmetry
self._symprec = symprec
self._filename = output_filename
self._log_level = log_level
self._jdos = JointDos(
self._mesh,
self._primitive,
self._supercell,
self._fc2,
nac_params=self._nac_params,
nac_q_direction=self._nac_q_direction,
cutoff_frequency=self._cutoff_frequency,
frequency_step=self._frequency_step,
num_frequency_points=self._num_frequency_points,
temperatures=self._temperatures,
frequency_factor_to_THz=self._frequency_factor_to_THz,
frequency_scale_factor=self._frequency_scale_factor,
is_mesh_symmetry=self._is_mesh_symmetry,
symprec=self._symprec,
filename=output_filename,
log_level=self._log_level)
def run(self, grid_points):
for gp in grid_points:
self._jdos.set_grid_point(gp)
if self._log_level:
weights = self._jdos.get_triplets_at_q()[1]
print("--------------------------------- Joint DOS "
"---------------------------------")
print("Grid point: %d" % gp)
print("Number of ir-triplets: "
"%d / %d" % (len(weights), weights.sum()))
adrs = self._jdos.get_grid_address()[gp]
q = adrs.astype('double') / self._mesh
print("q-point: %s" % q)
print("Phonon frequency:")
frequencies = self._jdos.get_phonons()[0]
print("%s" % frequencies[gp])
if self._sigmas:
for sigma in self._sigmas:
if sigma is None:
print("Tetrahedron method")
else:
print("Sigma: %s" % sigma)
self._jdos.set_sigma(sigma)
self._jdos.run()
self._write(gp, sigma=sigma)
else:
print("sigma or tetrahedron method has to be set.")
def _write(self, gp, sigma=None):
write_joint_dos(gp,
self._mesh,
self._jdos.get_frequency_points(),
self._jdos.get_joint_dos(),
sigma=sigma,
temperatures=self._temperatures,
filename=self._filename,
is_mesh_symmetry=self._is_mesh_symmetry)

View File

@ -1,217 +0,0 @@
import sys
import numpy as np
from phonopy.units import THzToEv, Kb
from phonopy.harmonic.force_constants import similarity_transformation
from anharmonic.phonon3.imag_self_energy import ImagSelfEnergy
from anharmonic.phonon3.triplets import get_triplets_third_q_list
class CollisionMatrix(ImagSelfEnergy):
"""
Main diagonal part (imag-self-energy) and
the other part are separately stored.
"""
def __init__(self,
interaction,
point_operations=None,
ir_grid_points=None,
rotated_grid_points=None,
temperature=None,
sigma=None,
is_reducible_collision_matrix=False,
lang='C'):
self._pp = None
self._sigma = None
self._frequency_points = None
self._temperature = None
self._grid_point = None
self._lang = None
self._imag_self_energy = None
self._collision_matrix = None
self._pp_strength = None
self._frequencies = None
self._triplets_at_q = None
self._triplets_map_at_q = None
self._weights_at_q = None
self._band_indices = None
self._unit_conversion = None
self._cutoff_frequency = None
self._g = None
self._mesh = None
self._is_collision_matrix = None
self._unit_conversion = None
ImagSelfEnergy.__init__(self,
interaction,
temperature=temperature,
sigma=sigma,
lang=lang)
self._is_reducible_collision_matrix = is_reducible_collision_matrix
self._is_collision_matrix = True
if not self._is_reducible_collision_matrix:
self._ir_grid_points = ir_grid_points
self._rot_grid_points = rotated_grid_points
self._point_operations = point_operations
self._primitive = self._pp.get_primitive()
rec_lat = np.linalg.inv(self._primitive.get_cell())
self._rotations_cartesian = np.array(
[similarity_transformation(rec_lat, r)
for r in self._point_operations], dtype='double', order='C')
def run(self):
if self._pp_strength is None:
self.run_interaction()
# num_band0 is supposed to be equal to num_band.
num_band0 = self._pp_strength.shape[1]
num_band = self._pp_strength.shape[2]
if num_band0 != num_band:
print("--bi option is not allowed to use with collision matrix.")
sys.exit(1)
num_triplets = len(self._triplets_at_q)
self._imag_self_energy = np.zeros(num_band, dtype='double')
if self._is_reducible_collision_matrix:
num_mesh_points = np.prod(self._mesh)
self._collision_matrix = np.zeros(
(num_band, num_mesh_points, num_band), dtype='double')
else:
self._collision_matrix = np.zeros(
(num_band, 3, len(self._ir_grid_points), num_band, 3),
dtype='double')
self._run_with_band_indices()
self._run_collision_matrix()
def get_collision_matrix(self):
return self._collision_matrix
def set_grid_point(self, grid_point=None):
if grid_point is None:
self._grid_point = None
else:
self._pp.set_grid_point(grid_point, stores_triplets_map=True)
self._pp_strength = None
(self._triplets_at_q,
self._weights_at_q,
self._triplets_map_at_q,
self._ir_map_at_q) = self._pp.get_triplets_at_q()
self._grid_address = self._pp.get_grid_address()
self._grid_point = grid_point
self._third_q_list = get_triplets_third_q_list(
grid_point,
self._grid_address,
self._pp.get_bz_map(),
self._mesh)
self._bz_map = self._pp.get_bz_map()
self._frequencies, self._eigenvectors, _ = self._pp.get_phonons()
def _run_collision_matrix(self):
self._run_with_band_indices()
if self._temperature > 0:
if self._lang == 'C':
if self._is_reducible_collision_matrix:
self._run_c_reducible_collision_matrix()
else:
self._run_c_collision_matrix()
else:
if self._is_reducible_collision_matrix:
self._run_py_reducible_collision_matrix()
else:
self._run_py_collision_matrix()
def _run_c_collision_matrix(self):
import anharmonic._phono3py as phono3c
phono3c.collision_matrix(self._collision_matrix,
self._pp_strength,
self._frequencies,
self._g,
self._triplets_at_q,
self._triplets_map_at_q,
self._ir_map_at_q,
self._ir_grid_points,
self._rot_grid_points,
self._rotations_cartesian,
self._temperature,
self._unit_conversion,
self._cutoff_frequency)
def _run_c_reducible_collision_matrix(self):
import anharmonic._phono3py as phono3c
phono3c.reducible_collision_matrix(self._collision_matrix,
self._pp_strength,
self._frequencies,
self._g,
self._triplets_at_q,
self._triplets_map_at_q,
self._ir_map_at_q,
self._temperature,
self._unit_conversion,
self._cutoff_frequency)
def _run_py_collision_matrix(self):
num_mesh_points = np.prod(self._mesh)
num_band = self._pp_strength.shape[1]
gp2tp_map = self._get_gp2tp_map()
for i, ir_gp in enumerate(self._ir_grid_points):
r_gps = self._rot_grid_points[i]
multi = len(r_gps) // (r_gps < num_mesh_points).sum()
for r, r_gp in zip(self._rotations_cartesian, r_gps):
if r_gp > num_mesh_points - 1:
continue
ti = gp2tp_map[self._triplets_map_at_q[r_gp]]
inv_sinh = self._get_inv_sinh(r_gp, gp2tp_map)
for j, k in list(np.ndindex((num_band, num_band))):
collision = (self._pp_strength[ti, j, k]
* inv_sinh
* self._g[2, ti, j, k]).sum()
collision *= self._unit_conversion * multi
self._collision_matrix[j, :, i, k, :] += collision * r
def _run_py_reducible_collision_matrix(self):
num_mesh_points = np.prod(self._mesh)
num_band = self._pp_strength.shape[1]
gp2tp_map = self._get_gp2tp_map()
for i in range(num_mesh_points):
ti = gp2tp_map[self._triplets_map_at_q[i]]
inv_sinh = self._get_inv_sinh(i, gp2tp_map)
for j, k in list(np.ndindex((num_band, num_band))):
collision = (self._pp_strength[ti, j, k]
* inv_sinh
* self._g[2, ti, j, k]).sum()
collision *= self._unit_conversion
self._collision_matrix[j, i, k] += collision
def _get_gp2tp_map(self):
gp2tp_map = {}
count = 0
for i, j in enumerate(self._triplets_map_at_q):
if i == j:
gp2tp_map[i] = count
count += 1
return gp2tp_map
def _get_inv_sinh(self, gp, gp2tp_map):
ti = gp2tp_map[self._triplets_map_at_q[gp]]
tp = self._triplets_at_q[ti]
if self._triplets_map_at_q[gp] == self._ir_map_at_q[gp]:
gp2 = tp[2]
else:
gp2 = tp[1]
freqs = self._frequencies[gp2]
sinh = np.where(
freqs > self._cutoff_frequency,
np.sinh(freqs * THzToEv / (2 * Kb * self._temperature)),
-1.0)
inv_sinh = np.where(sinh > 0, 1.0 / sinh, 0)
return inv_sinh

View File

@ -1,360 +0,0 @@
import numpy as np
from phonopy.phonon.group_velocity import get_group_velocity
from phonopy.harmonic.force_constants import similarity_transformation
from phonopy.units import EV, THz, Angstrom
from anharmonic.phonon3.triplets import (get_grid_address, reduce_grid_points,
get_ir_grid_points,
from_coarse_to_dense_grid_points)
from anharmonic.other.isotope import Isotope
unit_to_WmK = ((THz * Angstrom) ** 2 / (Angstrom ** 3) * EV / THz /
(2 * np.pi)) # 2pi comes from definition of lifetime.
class Conductivity(object):
def __init__(self,
interaction,
symmetry,
grid_points=None,
temperatures=None,
sigmas=None,
is_isotope=False,
mass_variances=None,
mesh_divisors=None,
coarse_mesh_shifts=None,
boundary_mfp=None, # in micrometre
is_kappa_star=True,
gv_delta_q=None, # finite difference for group veolocity
log_level=0):
if sigmas is None:
self._sigmas = []
else:
self._sigmas = sigmas
self._pp = interaction
self._collision = None # has to be set derived class
self._temperatures = temperatures
self._is_kappa_star = is_kappa_star
self._gv_delta_q = gv_delta_q
self._log_level = log_level
self._primitive = self._pp.get_primitive()
self._dm = self._pp.get_dynamical_matrix()
self._frequency_factor_to_THz = self._pp.get_frequency_factor_to_THz()
self._cutoff_frequency = self._pp.get_cutoff_frequency()
self._boundary_mfp = boundary_mfp
self._symmetry = symmetry
if not self._is_kappa_star:
self._point_operations = np.array([np.eye(3, dtype='intc')],
dtype='intc')
else:
self._point_operations = symmetry.get_reciprocal_operations()
rec_lat = np.linalg.inv(self._primitive.get_cell())
self._rotations_cartesian = np.array(
[similarity_transformation(rec_lat, r)
for r in self._point_operations], dtype='double')
self._grid_points = None
self._grid_weights = None
self._grid_address = None
self._ir_grid_points = None
self._ir_grid_weights = None
self._kappa = None
self._mode_kappa = None
self._gamma = None
self._read_gamma = False
self._read_gamma_iso = False
self._frequencies = None
self._gv = None
self._gamma_iso = None
self._mesh = None
self._mesh_divisors = None
self._coarse_mesh = None
self._coarse_mesh_shifts = None
self._set_mesh_numbers(mesh_divisors=mesh_divisors,
coarse_mesh_shifts=coarse_mesh_shifts)
volume = self._primitive.get_volume()
self._conversion_factor = unit_to_WmK / volume
self._isotope = None
self._mass_variances = None
self._is_isotope = is_isotope
if mass_variances is not None:
self._is_isotope = True
if self._is_isotope:
self._set_isotope(mass_variances)
self._grid_point_count = None
self._set_grid_properties(grid_points)
def __iter__(self):
return self
def __next__(self):
if self._grid_point_count == len(self._grid_points):
if self._log_level:
print("=================== End of collection of collisions "
"===================")
raise StopIteration
else:
self._run_at_grid_point()
self._grid_point_count += 1
return self._grid_point_count - 1
def next(self):
return self.__next__()
def get_mesh_divisors(self):
return self._mesh_divisors
def get_mesh_numbers(self):
return self._mesh
def get_group_velocities(self):
return self._gv
def get_frequencies(self):
return self._frequencies[self._grid_points]
def get_qpoints(self):
return self._qpoints
def get_grid_points(self):
return self._grid_points
def get_grid_weights(self):
return self._grid_weights
def get_temperatures(self):
return self._temperatures
def set_temperatures(self, temperatures):
self._temperatures = temperatures
self._allocate_values()
def set_gamma(self, gamma):
self._gamma = gamma
self._read_gamma = True
def set_gamma_isotope(self, gamma_iso):
self._gamma_iso = gamma_iso
self._read_gamma_iso = True
def get_gamma(self):
return self._gamma
def get_gamma_isotope(self):
return self._gamma_iso
def get_kappa(self):
return self._kappa
def get_mode_kappa(self):
return self._mode_kappa
def get_sigmas(self):
return self._sigmas
def get_grid_point_count(self):
return self._grid_point_count
def _run_at_grid_point(self):
"""This has to be implementated in the derived class"""
pass
def _allocate_values(self):
"""This has to be implementated in the derived class"""
pass
def _set_grid_properties(self, grid_points):
self._grid_address = self._pp.get_grid_address()
if grid_points is not None: # Specify grid points
self._grid_points = reduce_grid_points(
self._mesh_divisors,
self._grid_address,
grid_points,
coarse_mesh_shifts=self._coarse_mesh_shifts)
(self._ir_grid_points,
self._ir_grid_weights) = self._get_ir_grid_points()
elif not self._is_kappa_star: # All grid points
coarse_grid_address = get_grid_address(self._coarse_mesh)
coarse_grid_points = np.arange(np.prod(self._coarse_mesh),
dtype='intc')
self._grid_points = from_coarse_to_dense_grid_points(
self._mesh,
self._mesh_divisors,
coarse_grid_points,
coarse_grid_address,
coarse_mesh_shifts=self._coarse_mesh_shifts)
self._grid_weights = np.ones(len(self._grid_points), dtype='intc')
self._ir_grid_points = self._grid_points
self._ir_grid_weights = self._grid_weights
else: # Automatic sampling
self._grid_points, self._grid_weights = self._get_ir_grid_points()
self._ir_grid_points = self._grid_points
self._ir_grid_weights = self._grid_weights
self._qpoints = np.array(self._grid_address[self._grid_points] /
self._mesh.astype('double'),
dtype='double', order='C')
self._grid_point_count = 0
self._pp.set_phonons(self._grid_points)
self._frequencies = self._pp.get_phonons()[0]
def _set_gamma_isotope_at_sigmas(self, i):
for j, sigma in enumerate(self._sigmas):
if self._log_level:
text = "Calculating Gamma of ph-isotope with "
if sigma is None:
text += "tetrahedron method"
else:
text += "sigma=%s" % sigma
print(text)
pp_freqs, pp_eigvecs, pp_phonon_done = self._pp.get_phonons()
self._isotope.set_sigma(sigma)
self._isotope.set_phonons(pp_freqs,
pp_eigvecs,
pp_phonon_done,
dm=self._dm)
gp = self._grid_points[i]
self._isotope.set_grid_point(gp)
self._isotope.run()
self._gamma_iso[j, i] = self._isotope.get_gamma()
def _set_mesh_numbers(self, mesh_divisors=None, coarse_mesh_shifts=None):
self._mesh = self._pp.get_mesh_numbers()
if mesh_divisors is None:
self._mesh_divisors = np.array([1, 1, 1], dtype='intc')
else:
self._mesh_divisors = []
for i, (m, n) in enumerate(zip(self._mesh, mesh_divisors)):
if m % n == 0:
self._mesh_divisors.append(n)
else:
self._mesh_divisors.append(1)
print(("Mesh number %d for the " +
["first", "second", "third"][i] +
" axis is not dividable by divisor %d.") % (m, n))
self._mesh_divisors = np.array(self._mesh_divisors, dtype='intc')
if coarse_mesh_shifts is None:
self._coarse_mesh_shifts = [False, False, False]
else:
self._coarse_mesh_shifts = coarse_mesh_shifts
for i in range(3):
if (self._coarse_mesh_shifts[i] and
(self._mesh_divisors[i] % 2 != 0)):
print("Coarse grid along " +
["first", "second", "third"][i] +
" axis can not be shifted. Set False.")
self._coarse_mesh_shifts[i] = False
self._coarse_mesh = self._mesh // self._mesh_divisors
if self._log_level:
print("Lifetime sampling mesh: [ %d %d %d ]" %
tuple(self._mesh // self._mesh_divisors))
def _get_ir_grid_points(self):
if self._coarse_mesh_shifts is None:
mesh_shifts = [False, False, False]
else:
mesh_shifts = self._coarse_mesh_shifts
(coarse_grid_points,
coarse_grid_weights,
coarse_grid_address, _) = get_ir_grid_points(
self._coarse_mesh,
self._symmetry.get_pointgroup_operations(),
mesh_shifts=mesh_shifts)
grid_points = from_coarse_to_dense_grid_points(
self._mesh,
self._mesh_divisors,
coarse_grid_points,
coarse_grid_address,
coarse_mesh_shifts=self._coarse_mesh_shifts)
grid_weights = coarse_grid_weights
assert grid_weights.sum() == np.prod(self._mesh // self._mesh_divisors)
return grid_points, grid_weights
def _set_isotope(self, mass_variances):
if mass_variances is True:
mv = None
else:
mv = mass_variances
self._isotope = Isotope(
self._mesh,
self._primitive,
mass_variances=mv,
frequency_factor_to_THz=self._frequency_factor_to_THz,
symprec=self._symmetry.get_symmetry_tolerance(),
cutoff_frequency=self._cutoff_frequency,
lapack_zheev_uplo=self._pp.get_lapack_zheev_uplo())
self._mass_variances = self._isotope.get_mass_variances()
def _set_gv(self, i):
# Group velocity [num_freqs, 3]
gv = self._get_gv(self._qpoints[i])
self._gv[i] = gv[self._pp.get_band_indices(), :]
def _get_gv(self, q):
return get_group_velocity(
q,
self._dm,
q_length=self._gv_delta_q,
symmetry=self._symmetry,
frequency_factor_to_THz=self._frequency_factor_to_THz)
def _get_main_diagonal(self, i, j, k):
num_band = self._primitive.get_number_of_atoms() * 3
main_diagonal = self._gamma[j, k, i].copy()
if self._gamma_iso is not None:
main_diagonal += self._gamma_iso[j, i]
if self._boundary_mfp is not None:
main_diagonal += self._get_boundary_scattering(i)
# if self._boundary_mfp is not None:
# for l in range(num_band):
# # Acoustic modes at Gamma are avoided.
# if i == 0 and l < 3:
# continue
# gv_norm = np.linalg.norm(self._gv[i, l])
# mean_free_path = (gv_norm * Angstrom * 1e6 /
# (4 * np.pi * main_diagonal[l]))
# if mean_free_path > self._boundary_mfp:
# main_diagonal[l] = (
# gv_norm / (4 * np.pi * self._boundary_mfp))
return main_diagonal
def _get_boundary_scattering(self, i):
num_band = self._primitive.get_number_of_atoms() * 3
g_boundary = np.zeros(num_band, dtype='double')
for l in range(num_band):
g_boundary[l] = (np.linalg.norm(self._gv[i, l]) * Angstrom * 1e6 /
(4 * np.pi * self._boundary_mfp))
return g_boundary
def _show_log_header(self, i):
if self._log_level:
gp = self._grid_points[i]
print("======================= Grid point %d (%d/%d) "
"=======================" %
(gp, i + 1, len(self._grid_points)))
print("q-point: (%5.2f %5.2f %5.2f)" % tuple(self._qpoints[i]))
if self._boundary_mfp is not None:
if self._boundary_mfp > 1000:
print("Boundary mean free path (millimetre): %.3f" %
(self._boundary_mfp / 1000.0))
else:
print("Boundary mean free path (micrometre): %.5f" %
self._boundary_mfp)
if self._is_isotope:
print(("Mass variance parameters: " +
"%5.2e " * len(self._mass_variances)) %
tuple(self._mass_variances))

View File

@ -1,861 +0,0 @@
import sys
import numpy as np
from phonopy.phonon.degeneracy import degenerate_sets
from phonopy.units import THz, Angstrom
from anharmonic.phonon3.conductivity import Conductivity
from anharmonic.phonon3.collision_matrix import CollisionMatrix
from anharmonic.phonon3.triplets import (get_grid_points_by_rotations,
get_BZ_grid_points_by_rotations)
from anharmonic.file_IO import (write_kappa_to_hdf5,
write_collision_to_hdf5,
read_collision_from_hdf5,
write_collision_eigenvalues_to_hdf5)
from phonopy.units import THzToEv, Kb
def get_thermal_conductivity_LBTE(
interaction,
symmetry,
temperatures=np.arange(0, 1001, 10, dtype='double'),
sigmas=None,
is_isotope=False,
mass_variances=None,
grid_points=None,
boundary_mfp=None, # in micrometre
is_reducible_collision_matrix=False,
is_kappa_star=True,
gv_delta_q=1e-4, # for group velocity
is_full_pp=False,
pinv_cutoff=1.0e-8,
write_collision=False,
read_collision=False,
write_kappa=False,
input_filename=None,
output_filename=None,
log_level=0):
if sigmas is None:
sigmas = []
if log_level:
print("-------------------- Lattice thermal conducitivity (LBTE) "
"--------------------")
print("Cutoff frequency of pseudo inversion of collision matrix: %s" %
pinv_cutoff)
if read_collision:
temps = None
else:
temps = temperatures
lbte = Conductivity_LBTE(
interaction,
symmetry,
grid_points=grid_points,
temperatures=temps,
sigmas=sigmas,
is_isotope=is_isotope,
mass_variances=mass_variances,
boundary_mfp=boundary_mfp,
is_reducible_collision_matrix=is_reducible_collision_matrix,
is_kappa_star=is_kappa_star,
gv_delta_q=gv_delta_q,
is_full_pp=is_full_pp,
pinv_cutoff=pinv_cutoff,
log_level=log_level)
if read_collision:
read_from = _set_collision_from_file(
lbte,
indices=read_collision,
filename=input_filename)
if not read_from:
print("Reading collisions failed.")
return False
for i in lbte:
if write_collision:
_write_collision(lbte, i=i, filename=output_filename)
if not read_collision or read_from == "grid_points":
_write_collision(lbte, filename=output_filename)
if write_kappa and grid_points is None:
lbte.set_kappa_at_sigmas()
_write_kappa(lbte, filename=output_filename, log_level=log_level)
return lbte
def _write_collision(lbte, i=None, filename=None):
temperatures = lbte.get_temperatures()
sigmas = lbte.get_sigmas()
gamma = lbte.get_gamma()
gamma_isotope = lbte.get_gamma_isotope()
collision_matrix = lbte.get_collision_matrix()
mesh = lbte.get_mesh_numbers()
if i is not None:
gp = lbte.get_grid_points()[i]
for j, sigma in enumerate(sigmas):
if gamma_isotope is not None:
gamma_isotope_at_sigma = gamma_isotope[j, i]
else:
gamma_isotope_at_sigma = None
write_collision_to_hdf5(temperatures,
mesh,
gamma=gamma[j, :, i],
gamma_isotope=gamma_isotope_at_sigma,
collision_matrix=collision_matrix[j, :, i],
grid_point=gp,
sigma=sigma,
filename=filename)
else:
for j, sigma in enumerate(sigmas):
if gamma_isotope is not None:
gamma_isotope_at_sigma = gamma_isotope[j]
else:
gamma_isotope_at_sigma = None
write_collision_to_hdf5(temperatures,
mesh,
gamma=gamma[j],
gamma_isotope=gamma_isotope_at_sigma,
collision_matrix=collision_matrix[j],
sigma=sigma,
filename=filename)
def _write_kappa(lbte, filename=None, log_level=0):
temperatures = lbte.get_temperatures()
sigmas = lbte.get_sigmas()
gamma = lbte.get_gamma()
mesh = lbte.get_mesh_numbers()
frequencies = lbte.get_frequencies()
gv = lbte.get_group_velocities()
ave_pp = lbte.get_averaged_pp_interaction()
qpoints = lbte.get_qpoints()
kappa = lbte.get_kappa()
mode_kappa = lbte.get_mode_kappa()
coleigs = lbte.get_collision_eigenvalues()
for i, sigma in enumerate(sigmas):
write_kappa_to_hdf5(temperatures,
mesh,
frequency=frequencies,
group_velocity=gv,
kappa=kappa[i],
mode_kappa=mode_kappa[i],
gamma=gamma[i],
averaged_pp_interaction=ave_pp,
qpoint=qpoints,
sigma=sigma,
filename=filename,
verbose=log_level)
write_collision_eigenvalues_to_hdf5(temperatures,
mesh,
coleigs[i],
sigma=sigma,
filename=filename,
verbose=log_level)
def _set_collision_from_file(lbte,
indices='all',
filename=None):
sigmas = lbte.get_sigmas()
mesh = lbte.get_mesh_numbers()
grid_points = lbte.get_grid_points()
gamma = []
collision_matrix = []
read_from = None
for j, sigma in enumerate(sigmas):
collisions = read_collision_from_hdf5(mesh,
sigma=sigma,
filename=filename)
if collisions is False:
gamma_of_gps = []
collision_matrix_of_gps = []
for i, gp in enumerate(grid_points):
collision_gp = read_collision_from_hdf5(
mesh,
grid_point=gp,
sigma=sigma,
filename=filename)
if collision_gp is False:
print("Gamma at grid point %d doesn't exist." % gp)
return False
else:
(collision_matrix_at_gp,
gamma_at_gp,
temperatures_at_gp) = collision_gp
gamma_at_t = []
collision_matrix_at_t = []
if indices == 'all':
gamma_of_gps.append(gamma_at_gp)
collision_matrix_of_gps.append(collision_matrix_at_gp)
temperatures = temperatures_at_gp
else:
gamma_of_gps.append(gamma_at_gp[indices])
collision_matrix_of_gps.append(
collision_matrix_at_gp[indices])
temperatures = temperatures_at_gp[indices]
gamma_at_sigma = np.zeros((len(temperatures),
len(grid_points),
len(gamma_of_gps[0][0])),
dtype='double')
collision_matrix_at_sigma = np.zeros((len(temperatures),
len(grid_points),
len(gamma_of_gps[0][0]),
3,
len(grid_points),
len(gamma_of_gps[0][0]),
3),
dtype='double')
for i in range(len(temperatures)):
for j in range(len(grid_points)):
gamma_at_sigma[i, j] = gamma_of_gps[j][i]
collision_matrix_at_sigma[
i, j] = collision_matrix_of_gps[j][i]
gamma.append(gamma_at_sigma)
collision_matrix.append(collision_matrix_at_sigma)
read_from = "grid_points"
else:
(collision_matrix_at_sigma,
gamma_at_sigma,
temperatures_at_sigma) = collisions
if indices == 'all':
collision_matrix.append(collision_matrix_at_sigma)
gamma.append(gamma_at_sigma)
temperatures = temperatures_at_sigma
else:
collision_matrix.append(collision_matrix_at_sigma[indices])
gamma.append(gamma_at_sigma[indices])
temperatures = temperatures_at_sigma[indices]
read_from = "full_matrix"
temperatures = np.array(temperatures, dtype='double', order='C')
gamma = np.array(gamma, dtype='double', order='C')
collision_matrix = np.array(collision_matrix, dtype='double', order='C')
lbte.set_temperatures(temperatures)
lbte.set_gamma(gamma)
lbte.set_collision_matrix(collision_matrix)
return read_from
class Conductivity_LBTE(Conductivity):
def __init__(self,
interaction,
symmetry,
grid_points=None,
temperatures=None,
sigmas=None,
is_isotope=False,
mass_variances=None,
boundary_mfp=None, # in micrometre
is_reducible_collision_matrix=False,
is_kappa_star=True,
gv_delta_q=None, # finite difference for group veolocity
is_full_pp=False,
pinv_cutoff=1.0e-8,
log_level=0):
if sigmas is None:
sigmas = []
self._pp = None
self._temperatures = None
self._sigmas = None
self._is_kappa_star = None
self._gv_delta_q = None
self._is_full_pp = is_full_pp
self._log_level = None
self._primitive = None
self._dm = None
self._frequency_factor_to_THz = None
self._cutoff_frequency = None
self._boundary_mfp = None
self._symmetry = None
self._point_operations = None
self._rotations_cartesian = None
self._grid_points = None
self._grid_weights = None
self._grid_address = None
self._ir_grid_points = None
self._ir_grid_weights = None
self._gamma = None
self._read_gamma = False
self._read_gamma_iso = False
self._frequencies = None
self._gv = None
self._gamma_iso = None
self._averaged_pp_interaction = None
self._mesh = None
self._coarse_mesh = None
self._coarse_mesh_shifts = None
self._conversion_factor = None
self._is_isotope = None
self._isotope = None
self._mass_variances = None
self._grid_point_count = None
self._collision_eigenvalues = None
Conductivity.__init__(self,
interaction,
symmetry,
grid_points=grid_points,
temperatures=temperatures,
sigmas=sigmas,
is_isotope=is_isotope,
mass_variances=mass_variances,
boundary_mfp=boundary_mfp,
is_kappa_star=is_kappa_star,
gv_delta_q=gv_delta_q,
log_level=log_level)
self._is_reducible_collision_matrix = is_reducible_collision_matrix
if not self._is_kappa_star:
self._is_reducible_collision_matrix = True
self._collision_matrix = None
self._pinv_cutoff = pinv_cutoff
if self._temperatures is not None:
self._allocate_values()
def set_kappa_at_sigmas(self):
if len(self._grid_points) != len(self._ir_grid_points):
print("Collision matrix is not well created.")
import sys
sys.exit(1)
else:
self._set_kappa_at_sigmas()
def set_collision_matrix(self, collision_matrix):
self._collision_matrix = collision_matrix
def get_collision_matrix(self):
return self._collision_matrix
def get_collision_eigenvalues(self):
return self._collision_eigenvalues
def get_averaged_pp_interaction(self):
return self._averaged_pp_interaction
def _run_at_grid_point(self):
i = self._grid_point_count
self._show_log_header(i)
grid_point = self._grid_points[i]
if not self._read_gamma:
self._collision.set_grid_point(grid_point)
if self._log_level:
print("Number of triplets: %s" %
len(self._pp.get_triplets_at_q()[0]))
print("Calculating interaction...")
self._set_collision_matrix_at_sigmas(i)
if self._isotope is not None:
self._set_gamma_isotope_at_sigmas(i)
self._set_gv(i)
if self._log_level:
self._show_log(i)
def _allocate_values(self):
num_band = self._primitive.get_number_of_atoms() * 3
num_grid_points = len(self._grid_points)
num_ir_grid_points = len(self._ir_grid_points)
self._kappa = np.zeros((len(self._sigmas),
len(self._temperatures),
6), dtype='double')
self._gv = np.zeros((num_grid_points,
num_band,
3), dtype='double')
if self._is_full_pp:
self._averaged_pp_interaction = np.zeros(
(num_grid_points, num_band), dtype='double')
self._gamma = np.zeros((len(self._sigmas),
len(self._temperatures),
num_grid_points,
num_band), dtype='double')
if self._isotope is not None:
self._gamma_iso = np.zeros((len(self._sigmas),
num_grid_points,
num_band), dtype='double')
if self._is_reducible_collision_matrix:
num_mesh_points = np.prod(self._mesh)
self._mode_kappa = np.zeros((len(self._sigmas),
len(self._temperatures),
num_mesh_points,
num_band,
6), dtype='double')
self._collision = CollisionMatrix(
self._pp,
is_reducible_collision_matrix=True)
self._collision_matrix = np.zeros(
(len(self._sigmas),
len(self._temperatures),
num_grid_points, num_band, num_mesh_points, num_band),
dtype='double')
else:
self._mode_kappa = np.zeros((len(self._sigmas),
len(self._temperatures),
num_grid_points,
num_band,
6), dtype='double')
self._rot_grid_points = np.zeros(
(len(self._ir_grid_points), len(self._point_operations)),
dtype='intc')
self._rot_BZ_grid_points = np.zeros(
(len(self._ir_grid_points), len(self._point_operations)),
dtype='intc')
for i, ir_gp in enumerate(self._ir_grid_points):
self._rot_grid_points[i] = get_grid_points_by_rotations(
self._grid_address[ir_gp],
self._point_operations,
self._mesh)
self._rot_BZ_grid_points[i] = get_BZ_grid_points_by_rotations(
self._grid_address[ir_gp],
self._point_operations,
self._mesh,
self._pp.get_bz_map())
self._collision = CollisionMatrix(
self._pp,
point_operations=self._point_operations,
ir_grid_points=self._ir_grid_points,
rotated_grid_points=self._rot_BZ_grid_points)
self._collision_matrix = np.zeros(
(len(self._sigmas),
len(self._temperatures),
num_grid_points, num_band, 3,
num_ir_grid_points, num_band, 3),
dtype='double')
self._collision_eigenvalues = np.zeros(
(len(self._sigmas),
len(self._temperatures),
num_ir_grid_points * num_band * 3),
dtype='double')
def _set_collision_matrix_at_sigmas(self, i):
for j, sigma in enumerate(self._sigmas):
if self._log_level:
text = "Calculating collision matrix with "
if sigma is None:
text += "tetrahedron method"
else:
text += "sigma=%s" % sigma
print(text)
self._collision.set_sigma(sigma)
self._collision.set_integration_weights()
if self._is_full_pp and j != 0:
pass
else:
self._collision.run_interaction(is_full_pp=self._is_full_pp)
if self._is_full_pp and j == 0:
self._averaged_pp_interaction[i] = (
self._pp.get_averaged_interaction())
for k, t in enumerate(self._temperatures):
self._collision.set_temperature(t)
self._collision.run()
self._gamma[j, k, i] = self._collision.get_imag_self_energy()
self._collision_matrix[j, k, i] = (
self._collision.get_collision_matrix())
def _set_kappa_at_sigmas(self):
if self._log_level:
print("Symmetrizing collision matrix...")
sys.stdout.flush()
if self._is_reducible_collision_matrix:
if self._is_kappa_star:
self._expand_collisions()
self._combine_reducible_collisions()
weights = np.ones(np.prod(self._mesh), dtype='intc')
self._symmetrize_reducible_collision_matrix()
else:
self._combine_collisions()
weights = self._get_weights()
for i, w_i in enumerate(weights):
for j, w_j in enumerate(weights):
self._collision_matrix[:, :, i, :, :, j, :, :] *= w_i * w_j
self._symmetrize_collision_matrix()
for j, sigma in enumerate(self._sigmas):
if self._log_level:
text = "----------- Thermal conductivity (W/m-k) "
if sigma:
text += "for sigma=%s -----------" % sigma
else:
text += "with tetrahedron method -----------"
print(text)
print(("#%6s " + " %-10s" * 6) %
("T(K)", "xx", "yy", "zz", "yz", "xz", "xy"))
for k, t in enumerate(self._temperatures):
if t > 0:
if self._is_reducible_collision_matrix:
self._set_inv_reducible_collision_matrix(j, k)
else:
self._set_inv_collision_matrix(j, k)
X = self._get_X(t, weights)
self._set_kappa(j, k, X)
if self._log_level:
print(("%7.1f " + " %10.3f" * 6) %
((t,) + tuple(self._kappa[j, k])))
if self._log_level:
print('')
def _combine_collisions(self):
num_band = self._primitive.get_number_of_atoms() * 3
for j, k in list(np.ndindex((len(self._sigmas),
len(self._temperatures)))):
for i, ir_gp in enumerate(self._ir_grid_points):
multi = ((self._rot_grid_points == ir_gp).sum() //
(self._rot_BZ_grid_points == ir_gp).sum())
for r, r_BZ_gp in zip(self._rotations_cartesian,
self._rot_BZ_grid_points[i]):
if ir_gp != r_BZ_gp:
continue
main_diagonal = self._get_main_diagonal(i, j, k)
main_diagonal *= multi
for l in range(num_band):
self._collision_matrix[
j, k, i, l, :, i, l, :] += main_diagonal[l] * r
def _combine_reducible_collisions(self):
num_band = self._primitive.get_number_of_atoms() * 3
num_mesh_points = np.prod(self._mesh)
for j, k in list(
np.ndindex((len(self._sigmas), len(self._temperatures)))):
for i in range(num_mesh_points):
main_diagonal = self._get_main_diagonal(i, j, k)
for l in range(num_band):
self._collision_matrix[
j, k, i, l, i, l] += main_diagonal[l]
def _expand_collisions(self):
num_mesh_points = np.prod(self._mesh)
num_rot = len(self._point_operations)
num_band = self._primitive.get_number_of_atoms() * 3
rot_grid_points = np.zeros(
(num_rot, num_mesh_points), dtype='intc')
collision_matrix = np.zeros(
(len(self._sigmas),
len(self._temperatures),
num_mesh_points, num_band, num_mesh_points, num_band),
dtype='double')
gamma = np.zeros((len(self._sigmas),
len(self._temperatures),
num_mesh_points,
num_band), dtype='double')
gv = np.zeros((num_mesh_points,
num_band,
3), dtype='double')
if self._gamma_iso is not None:
gamma_iso = np.zeros((len(self._sigmas),
num_mesh_points,
num_band), dtype='double')
for i in range(num_mesh_points):
rot_grid_points[:, i] = get_grid_points_by_rotations(
self._grid_address[i],
self._point_operations,
self._mesh)
for i, ir_gp in enumerate(self._ir_grid_points):
multi = (rot_grid_points[:, ir_gp] == ir_gp).sum()
g_elem = self._gamma[:, :, i, :] / multi
if self._gamma_iso is not None:
giso_elem = self._gamma_iso[:, i, :] / multi
for j, r in enumerate(self._rotations_cartesian):
gp_r = rot_grid_points[j, ir_gp]
gamma[:, :, gp_r, :] += g_elem
if self._gamma_iso is not None:
gamma_iso[:, gp_r, :] += giso_elem
for k in range(num_mesh_points):
colmat_elem = self._collision_matrix[:, :, i, :, k, :]
colmat_elem = colmat_elem.copy() / multi
gp_c = rot_grid_points[j, k]
collision_matrix[:, :, gp_r, :, gp_c, :] += colmat_elem
gv[gp_r] += np.dot(self._gv[i], r.T) / multi
self._gamma = gamma
self._collision_matrix = collision_matrix
if self._gamma_iso is not None:
self._gamma_iso = gamma_iso
self._gv = gv
def _get_weights(self):
weights = []
for r_gps in self._rot_grid_points:
weights.append(np.sqrt(len(np.unique(r_gps))) / np.sqrt(len(r_gps)))
return weights
def _symmetrize_collision_matrix(self):
import anharmonic._phono3py as phono3c
phono3c.symmetrize_collision_matrix(self._collision_matrix)
# Average matrix elements belonging to degenerate bands
col_mat = self._collision_matrix
for i, gp in enumerate(self._ir_grid_points):
freqs = self._frequencies[gp]
deg_sets = degenerate_sets(freqs)
for dset in deg_sets:
bi_set = []
for j in range(len(freqs)):
if j in dset:
bi_set.append(j)
sum_col = (col_mat[:, :, i, bi_set, :, :, :, :].sum(axis=2) /
len(bi_set))
for j in bi_set:
col_mat[:, :, i, j, :, :, :, :] = sum_col
for i, gp in enumerate(self._ir_grid_points):
freqs = self._frequencies[gp]
deg_sets = degenerate_sets(freqs)
for dset in deg_sets:
bi_set = []
for j in range(len(freqs)):
if j in dset:
bi_set.append(j)
sum_col = (col_mat[:, :, :, :, :, i, bi_set, :].sum(axis=5) /
len(bi_set))
for j in bi_set:
col_mat[:, :, :, :, :, i, j, :] = sum_col
def _symmetrize_reducible_collision_matrix(self):
import anharmonic._phono3py as phono3c
phono3c.symmetrize_collision_matrix(self._collision_matrix)
# Average matrix elements belonging to degenerate bands
col_mat = self._collision_matrix
for i, gp in enumerate(self._ir_grid_points):
freqs = self._frequencies[gp]
deg_sets = degenerate_sets(freqs)
for dset in deg_sets:
bi_set = []
for j in range(len(freqs)):
if j in dset:
bi_set.append(j)
sum_col = (col_mat[:, :, i, bi_set, :, :].sum(axis=2) /
len(bi_set))
for j in bi_set:
col_mat[:, :, i, j, :, :] = sum_col
for i, gp in enumerate(self._ir_grid_points):
freqs = self._frequencies[gp]
deg_sets = degenerate_sets(freqs)
for dset in deg_sets:
bi_set = []
for j in range(len(freqs)):
if j in dset:
bi_set.append(j)
sum_col = (col_mat[:, :, :, :, i, bi_set].sum(axis=4) /
len(bi_set))
for j in bi_set:
col_mat[:, :, :, :, i, j] = sum_col
def _get_X(self, t, weights):
num_band = self._primitive.get_number_of_atoms() * 3
X = self._gv.copy()
if self._is_reducible_collision_matrix:
num_mesh_points = np.prod(self._mesh)
freqs = self._frequencies[:num_mesh_points]
else:
freqs = self._frequencies[self._ir_grid_points]
sinh = np.where(freqs > self._cutoff_frequency,
np.sinh(freqs * THzToEv / (2 * Kb * t)),
-1.0)
inv_sinh = np.where(sinh > 0, 1.0 / sinh, 0)
freqs_sinh = freqs * THzToEv * inv_sinh / (4 * Kb * t ** 2)
for i, f in enumerate(freqs_sinh):
X[i] *= weights[i]
for j in range(num_band):
X[i, j] *= f[j]
if t > 0:
return X.reshape(-1, 3)
else:
return np.zeros_like(X.reshape(-1, 3))
def _set_inv_collision_matrix(self,
i_sigma,
i_temp,
method=0):
num_ir_grid_points = len(self._ir_grid_points)
num_band = self._primitive.get_number_of_atoms() * 3
if method == 0:
col_mat = self._collision_matrix[i_sigma, i_temp].reshape(
num_ir_grid_points * num_band * 3,
num_ir_grid_points * num_band * 3)
w, col_mat[:] = np.linalg.eigh(col_mat)
e = np.zeros_like(w)
v = col_mat
for l, val in enumerate(w):
if val > self._pinv_cutoff:
e[l] = 1 / np.sqrt(val)
v[:] = e * v
v[:] = np.dot(v, v.T) # inv_col
elif method == 1:
import anharmonic._phono3py as phono3c
w = np.zeros(num_ir_grid_points * num_band * 3, dtype='double')
phono3c.inverse_collision_matrix(
self._collision_matrix, w, i_sigma, i_temp, self._pinv_cutoff)
elif method == 2:
import anharmonic._phono3py as phono3c
w = np.zeros(num_ir_grid_points * num_band * 3, dtype='double')
phono3c.inverse_collision_matrix_libflame(
self._collision_matrix, w, i_sigma, i_temp, self._pinv_cutoff)
self._collision_eigenvalues[i_sigma, i_temp] = w
def _set_inv_reducible_collision_matrix(self, i_sigma, i_temp):
t = self._temperatures[i_temp]
num_mesh_points = np.prod(self._mesh)
num_band = self._primitive.get_number_of_atoms() * 3
col_mat = self._collision_matrix[i_sigma, i_temp].reshape(
num_mesh_points * num_band, num_mesh_points * num_band)
w, col_mat[:] = np.linalg.eigh(col_mat)
v = col_mat
e = np.zeros(len(w), dtype='double')
for l, val in enumerate(w):
if val > self._pinv_cutoff:
e[l] = 1 / np.sqrt(val)
v[:] = e * v
v[:] = np.dot(v, v.T) # inv_col
def _set_kappa(self, i_sigma, i_temp, X):
num_band = self._primitive.get_number_of_atoms() * 3
if self._is_reducible_collision_matrix:
num_mesh_points = np.prod(self._mesh)
num_grid_points = num_mesh_points
from phonopy.harmonic.force_constants import similarity_transformation
point_operations = self._symmetry.get_reciprocal_operations()
rec_lat = np.linalg.inv(self._primitive.get_cell())
rotations_cartesian = np.array(
[similarity_transformation(rec_lat, r)
for r in point_operations], dtype='double')
inv_col_mat = np.kron(
self._collision_matrix[i_sigma, i_temp].reshape(
num_mesh_points * num_band,
num_mesh_points * num_band), np.eye(3))
else:
num_ir_grid_points = len(self._ir_grid_points)
num_grid_points = num_ir_grid_points
rotations_cartesian = self._rotations_cartesian
inv_col_mat = self._collision_matrix[i_sigma, i_temp].reshape(
num_ir_grid_points * num_band * 3,
num_ir_grid_points * num_band * 3)
Y = np.dot(inv_col_mat, X.ravel()).reshape(-1, 3)
for i, (v_gp, f_gp) in enumerate(zip(X.reshape(num_grid_points,
num_band, 3),
Y.reshape(num_grid_points,
num_band, 3))):
for j, (v, f) in enumerate(zip(v_gp, f_gp)):
sum_k = np.zeros((3, 3), dtype='double')
for r in rotations_cartesian:
sum_k += np.outer(np.dot(r, v), np.dot(r, f))
sum_k = sum_k + sum_k.T
for k, vxf in enumerate(
((0, 0), (1, 1), (2, 2), (1, 2), (0, 2), (0, 1))):
self._mode_kappa[i_sigma, i_temp, i, j, k] = sum_k[vxf]
t = self._temperatures[i_temp]
self._mode_kappa *= (self._conversion_factor * Kb * t ** 2
/ np.prod(self._mesh))
if self._is_reducible_collision_matrix:
self._mode_kappa /= len(point_operations)
self._kappa[i_sigma, i_temp] = (
self._mode_kappa[i_sigma, i_temp].sum(axis=0).sum(axis=0))
def _show_log(self, i):
q = self._qpoints[i]
gp = self._grid_points[i]
frequencies = self._frequencies[gp]
gv = self._gv[i]
if self._is_full_pp:
ave_pp = self._averaged_pp_interaction[i]
text = "Frequency group velocity (x, y, z) |gv| Pqj"
else:
text = "Frequency group velocity (x, y, z) |gv|"
if self._gv_delta_q is None:
pass
else:
text += " (dq=%3.1e)" % self._gv_delta_q
print(text)
if self._is_full_pp:
for f, v, pp in zip(frequencies, gv, ave_pp):
print("%8.3f (%8.3f %8.3f %8.3f) %8.3f %11.3e" %
(f, v[0], v[1], v[2], np.linalg.norm(v), pp))
else:
for f, v in zip(frequencies, gv):
print("%8.3f (%8.3f %8.3f %8.3f) %8.3f" %
(f, v[0], v[1], v[2], np.linalg.norm(v)))
sys.stdout.flush()
def _py_symmetrize_collision_matrix(self):
num_band = self._primitive.get_number_of_atoms() * 3
num_ir_grid_points = len(self._ir_grid_points)
for i in range(num_ir_grid_points):
for j in range(num_band):
for k in range(3):
for l in range(num_ir_grid_points):
for m in range(num_band):
for n in range(3):
self._py_set_symmetrized_element(
i, j, k, l, m, n)
def _py_set_symmetrized_element(self, i, j, k, l, m, n):
sym_val = (self._collision_matrix[:, :, i, j, k, l, m, n] +
self._collision_matrix[:, :, l, m, n, i, j, k]) / 2
self._collision_matrix[:, :, i, j, k, l, m, n] = sym_val
self._collision_matrix[:, :, l, m, n, i, j, k] = sym_val
def _py_symmetrize_collision_matrix_no_kappa_stars(self):
num_band = self._primitive.get_number_of_atoms() * 3
num_ir_grid_points = len(self._ir_grid_points)
for i in range(num_ir_grid_points):
for j in range(num_band):
for k in range(num_ir_grid_points):
for l in range(num_band):
self._py_set_symmetrized_element_no_kappa_stars(
i, j, k, l)
def _py_set_symmetrized_element_no_kappa_stars(self, i, j, k, l):
sym_val = (self._collision_matrix[:, :, i, j, k, l] +
self._collision_matrix[:, :, k, l, i, j]) / 2
self._collision_matrix[:, :, i, j, k, l] = sym_val
self._collision_matrix[:, :, k, l, i, j] = sym_val

View File

@ -1,640 +0,0 @@
import numpy as np
from phonopy.phonon.group_velocity import get_group_velocity
from phonopy.units import THzToEv, THz, Angstrom
from phonopy.phonon.thermal_properties import mode_cv as get_mode_cv
from anharmonic.file_IO import (write_kappa_to_hdf5, write_triplets,
read_gamma_from_hdf5, write_grid_address)
from anharmonic.phonon3.conductivity import Conductivity, unit_to_WmK
from anharmonic.phonon3.imag_self_energy import ImagSelfEnergy
from anharmonic.phonon3.triplets import get_grid_points_by_rotations
def get_thermal_conductivity_RTA(
interaction,
symmetry,
temperatures=np.arange(0, 1001, 10, dtype='double'),
sigmas=None,
mass_variances=None,
grid_points=None,
is_isotope=False,
boundary_mfp=None, # in micrometre
use_ave_pp=False,
gamma_unit_conversion=None,
mesh_divisors=None,
coarse_mesh_shifts=None,
is_kappa_star=True,
gv_delta_q=1e-4,
run_with_g=True, # integration weights from gaussian smearing function
is_full_pp=False,
write_gamma=False,
read_gamma=False,
write_kappa=False,
write_gamma_detail=False,
input_filename=None,
output_filename=None,
log_level=0):
if log_level:
print("-------------------- Lattice thermal conducitivity (RTA) "
"--------------------")
br = Conductivity_RTA(
interaction,
symmetry,
grid_points=grid_points,
temperatures=temperatures,
sigmas=sigmas,
is_isotope=is_isotope,
mass_variances=mass_variances,
boundary_mfp=boundary_mfp,
use_ave_pp=use_ave_pp,
gamma_unit_conversion=gamma_unit_conversion,
mesh_divisors=mesh_divisors,
coarse_mesh_shifts=coarse_mesh_shifts,
is_kappa_star=is_kappa_star,
gv_delta_q=gv_delta_q,
run_with_g=run_with_g,
is_full_pp=is_full_pp,
with_gamma_detail=write_gamma_detail,
log_level=log_level)
if read_gamma:
if not _set_gamma_from_file(br, filename=input_filename):
print("Reading collisions failed.")
return False
for i in br:
if write_gamma:
_write_gamma(br,
interaction,
i,
filename=output_filename,
verbose=log_level)
if log_level > 1 and read_gamma is False:
_write_triplets(interaction)
if write_kappa:
if (grid_points is None and _all_bands_exist(interaction)):
br.set_kappa_at_sigmas()
_write_kappa(br,
interaction,
filename=output_filename,
log_level=log_level)
return br
def _write_gamma(br, interaction, i, filename=None, verbose=True):
grid_points = br.get_grid_points()
group_velocities = br.get_group_velocities()
gv_by_gv = br.get_gv_by_gv()
mode_heat_capacities = br.get_mode_heat_capacities()
ave_pp = br.get_averaged_pp_interaction()
mesh = br.get_mesh_numbers()
mesh_divisors = br.get_mesh_divisors()
temperatures = br.get_temperatures()
gamma = br.get_gamma()
gamma_isotope = br.get_gamma_isotope()
sigmas = br.get_sigmas()
volume = interaction.get_primitive().get_volume()
gp = grid_points[i]
if _all_bands_exist(interaction):
if ave_pp is None:
ave_pp_i = None
else:
ave_pp_i = ave_pp[i]
frequencies = interaction.get_phonons()[0][gp]
for j, sigma in enumerate(sigmas):
if gamma_isotope is not None:
gamma_isotope_at_sigma = gamma_isotope[j, i]
else:
gamma_isotope_at_sigma = None
write_kappa_to_hdf5(temperatures,
mesh,
frequency=frequencies,
group_velocity=group_velocities[i],
gv_by_gv=gv_by_gv[i],
heat_capacity=mode_heat_capacities[:, i],
gamma=gamma[j, :, i],
gamma_isotope=gamma_isotope_at_sigma,
averaged_pp_interaction=ave_pp_i,
mesh_divisors=mesh_divisors,
grid_point=gp,
sigma=sigma,
kappa_unit_conversion=unit_to_WmK / volume,
filename=filename,
verbose=verbose)
else:
for j, sigma in enumerate(sigmas):
for k, bi in enumerate(interaction.get_band_indices()):
if ave_pp is None:
ave_pp_ik = None
else:
ave_pp_ik = ave_pp[i, k]
frequencies = interaction.get_phonons()[0][gp, k]
if gamma_isotope is not None:
gamma_isotope_at_sigma = gamma_isotope[j, i, k]
else:
gamma_isotope_at_sigma = None
write_kappa_to_hdf5(
temperatures,
mesh,
frequency=frequencies,
group_velocity=group_velocities[i, k],
gv_by_gv=gv_by_gv[i, k],
heat_capacity=mode_heat_capacities[:, i, k],
gamma=gamma[j, :, i, k],
gamma_isotope=gamma_isotope_at_sigma,
averaged_pp_interaction=ave_pp_ik,
mesh_divisors=mesh_divisors,
grid_point=gp,
band_index=bi,
sigma=sigma,
kappa_unit_conversion=unit_to_WmK / volume,
filename=filename,
verbose=verbose)
def _all_bands_exist(interaction):
band_indices = interaction.get_band_indices()
num_band = interaction.get_primitive().get_number_of_atoms() * 3
if len(band_indices) == num_band:
if (band_indices - np.arange(num_band) == 0).all():
return True
return False
def _write_triplets(interaction, filename=None):
triplets, weights = interaction.get_triplets_at_q()[:2]
grid_address = interaction.get_grid_address()
mesh = interaction.get_mesh_numbers()
write_triplets(triplets,
weights,
mesh,
grid_address,
grid_point=triplets[0, 0],
filename=filename)
write_grid_address(grid_address, mesh, filename=filename)
def _write_kappa(br, interaction, filename=None, log_level=0):
temperatures = br.get_temperatures()
sigmas = br.get_sigmas()
gamma = br.get_gamma()
gamma_isotope = br.get_gamma_isotope()
mesh = br.get_mesh_numbers()
mesh_divisors = br.get_mesh_divisors()
frequencies = br.get_frequencies()
gv = br.get_group_velocities()
gv_by_gv = br.get_gv_by_gv()
mode_cv = br.get_mode_heat_capacities()
ave_pp = br.get_averaged_pp_interaction()
qpoints = br.get_qpoints()
weights = br.get_grid_weights()
kappa = br.get_kappa()
mode_kappa = br.get_mode_kappa()
num_ignored_phonon_modes = br.get_number_of_ignored_phonon_modes()
num_band = br.get_frequencies().shape[1]
num_phonon_modes = br.get_number_of_sampling_grid_points() * num_band
volume = interaction.get_primitive().get_volume()
for i, sigma in enumerate(sigmas):
kappa_at_sigma = kappa[i]
if gamma_isotope is not None:
gamma_isotope_at_sigma = gamma_isotope[i]
else:
gamma_isotope_at_sigma = None
if log_level:
text = "----------- Thermal conductivity (W/m-k) "
if sigma:
text += "for sigma=%s -----------" % sigma
else:
text += "with tetrahedron method -----------"
print(text)
if log_level > 1:
print(("#%6s " + " %-10s" * 6 + "#ipm") %
("T(K)", "xx", "yy", "zz", "yz", "xz", "xy"))
for j, (t, k) in enumerate(zip(temperatures, kappa_at_sigma)):
print(("%7.1f" + " %10.3f" * 6 + " %d/%d") %
((t,) + tuple(k) +
(num_ignored_phonon_modes[i, j], num_phonon_modes)))
else:
print(("#%6s " + " %-10s" * 6) %
("T(K)", "xx", "yy", "zz", "yz", "xz", "xy"))
for j, (t, k) in enumerate(zip(temperatures, kappa_at_sigma)):
print(("%7.1f " + " %10.3f" * 6) % ((t,) + tuple(k)))
print('')
write_kappa_to_hdf5(temperatures,
mesh,
frequency=frequencies,
group_velocity=gv,
gv_by_gv=gv_by_gv,
heat_capacity=mode_cv,
kappa=kappa_at_sigma,
mode_kappa=mode_kappa[i],
gamma=gamma[i],
gamma_isotope=gamma_isotope_at_sigma,
averaged_pp_interaction=ave_pp,
qpoint=qpoints,
weight=weights,
mesh_divisors=mesh_divisors,
sigma=sigma,
kappa_unit_conversion=unit_to_WmK / volume,
filename=filename,
verbose=log_level)
def _set_gamma_from_file(br, filename=None, verbose=True):
sigmas = br.get_sigmas()
mesh = br.get_mesh_numbers()
mesh_divisors = br.get_mesh_divisors()
grid_points = br.get_grid_points()
temperatures = br.get_temperatures()
num_band = br.get_frequencies().shape[1]
gamma = np.zeros((len(sigmas),
len(temperatures),
len(grid_points),
num_band), dtype='double')
gamma_iso = np.zeros((len(sigmas),
len(grid_points),
num_band), dtype='double')
ave_pp = np.zeros((len(grid_points), num_band), dtype='double')
is_isotope = False
read_succeeded = True
for j, sigma in enumerate(sigmas):
collisions = read_gamma_from_hdf5(
mesh,
mesh_divisors=mesh_divisors,
sigma=sigma,
filename=filename,
verbose=verbose)
if collisions:
gamma_at_sigma, gamma_iso_at_sigma, ave_pp = collisions
gamma[j] = gamma_at_sigma
if gamma_iso_at_sigma is not None:
is_isotope = True
gamma_iso[j] = gamma_iso_at_sigma
else:
for i, gp in enumerate(grid_points):
collisions_gp = read_gamma_from_hdf5(
mesh,
mesh_divisors=mesh_divisors,
grid_point=gp,
sigma=sigma,
filename=filename,
verbose=verbose)
if collisions_gp:
gamma_gp, gamma_iso_gp, ave_pp_gp = collisions_gp
gamma[j, :, i] = gamma_gp
if gamma_iso_gp is not None:
is_isotope = True
gamma_iso[j, i] = gamma_iso_gp
if ave_pp_gp is not None:
ave_pp[i] = ave_pp_gp
else:
for bi in range(num_band):
collisions_band = read_gamma_from_hdf5(
mesh,
mesh_divisors=mesh_divisors,
grid_point=gp,
band_index=bi,
sigma=sigma,
filename=filename,
verbose=verbose)
if collisions_band:
gamma_bi, gamma_iso_bi, ave_pp_bi = collisions_band
gamma[j, :, i, bi] = gamma_bi
if gamma_iso_bi is not None:
is_isotope = True
gamma_iso[j, i, bi] = gamma_iso_bi
if ave_pp_bi is not None:
ave_pp[i, bi] = ave_pp_bi
else:
read_succeeded = False
if read_succeeded:
br.set_gamma(gamma)
if ave_pp is not None:
br.set_averaged_pp_interaction(ave_pp)
return True
else:
return False
class Conductivity_RTA(Conductivity):
def __init__(self,
interaction,
symmetry,
grid_points=None,
temperatures=np.arange(0, 1001, 10, dtype='double'),
sigmas=None,
is_isotope=False,
mass_variances=None,
boundary_mfp=None, # in micrometre
use_ave_pp=False,
gamma_unit_conversion=None,
mesh_divisors=None,
coarse_mesh_shifts=None,
is_kappa_star=True,
gv_delta_q=None,
run_with_g=True,
is_full_pp=False,
with_gamma_detail=False,
log_level=0):
self._pp = None
self._temperatures = None
self._sigmas = None
self._is_kappa_star = None
self._gv_delta_q = None
self._run_with_g = run_with_g
self._is_full_pp = is_full_pp
self._with_gamma_detail = with_gamma_detail
self._log_level = None
self._primitive = None
self._dm = None
self._frequency_factor_to_THz = None
self._cutoff_frequency = None
self._boundary_mfp = None
self._symmetry = None
self._point_operations = None
self._rotations_cartesian = None
self._grid_points = None
self._grid_weights = None
self._grid_address = None
self._read_gamma = False
self._read_gamma_iso = False
self._frequencies = None
self._gv = None
self._gv_sum2 = None
self._gamma = None
self._gamma_iso = None
self._gamma_unit_conversion = gamma_unit_conversion
self._use_ave_pp = use_ave_pp
self._averaged_pp_interaction = None
self._num_ignored_phonon_modes = None
self._num_sampling_grid_points = None
self._mesh = None
self._mesh_divisors = None
self._coarse_mesh = None
self._coarse_mesh_shifts = None
self._conversion_factor = None
self._is_isotope = None
self._isotope = None
self._mass_variances = None
self._grid_point_count = None
Conductivity.__init__(self,
interaction,
symmetry,
grid_points=grid_points,
temperatures=temperatures,
sigmas=sigmas,
is_isotope=is_isotope,
mass_variances=mass_variances,
mesh_divisors=mesh_divisors,
coarse_mesh_shifts=coarse_mesh_shifts,
boundary_mfp=boundary_mfp,
is_kappa_star=is_kappa_star,
gv_delta_q=gv_delta_q,
log_level=log_level)
self._cv = None
if self._temperatures is not None:
self._allocate_values()
def set_kappa_at_sigmas(self):
num_band = self._primitive.get_number_of_atoms() * 3
self._num_sampling_grid_points = 0
for i, grid_point in enumerate(self._grid_points):
cv = self._cv[:, i, :]
gp = self._grid_points[i]
frequencies = self._frequencies[gp]
# Outer product of group velocities (v x v) [num_k*, num_freqs, 3, 3]
gv_by_gv_tensor, order_kstar = self._get_gv_by_gv(i)
self._num_sampling_grid_points += order_kstar
# Sum all vxv at k*
gv_sum2 = np.zeros((6, num_band), dtype='double')
for j, vxv in enumerate(
([0, 0], [1, 1], [2, 2], [1, 2], [0, 2], [0, 1])):
gv_sum2[j] = gv_by_gv_tensor[:, vxv[0], vxv[1]]
# Kappa
for j in range(len(self._sigmas)):
for k in range(len(self._temperatures)):
g_sum = self._get_main_diagonal(i, j, k)
for l in range(num_band):
if frequencies[l] < self._cutoff_frequency:
self._num_ignored_phonon_modes[j, k] += 1
continue
self._mode_kappa[j, k, i, l] = (
gv_sum2[:, l] * cv[k, l] / (g_sum[l] * 2) *
self._conversion_factor)
self._gv_sum2[i] = gv_sum2.T
self._mode_kappa /= self._num_sampling_grid_points
self._kappa = self._mode_kappa.sum(axis=2).sum(axis=2)
def get_mode_heat_capacities(self):
return self._cv
def get_gv_by_gv(self):
return self._gv_sum2
def get_number_of_ignored_phonon_modes(self):
return self._num_ignored_phonon_modes
def get_number_of_sampling_grid_points(self):
return self._num_sampling_grid_points
def get_averaged_pp_interaction(self):
return self._averaged_pp_interaction
def set_averaged_pp_interaction(self, ave_pp):
self._averaged_pp_interaction = ave_pp
def _run_at_grid_point(self):
i = self._grid_point_count
self._show_log_header(i)
grid_point = self._grid_points[i]
if self._read_gamma:
if self._use_ave_pp:
self._collision.set_grid_point(grid_point)
self._collision.set_averaged_pp_interaction(
self._averaged_pp_interaction[i])
self._set_gamma_at_sigmas(i)
else:
self._collision.set_grid_point(grid_point)
if self._log_level:
print("Number of triplets: %d" %
len(self._pp.get_triplets_at_q()[0]))
print("Calculating interaction...")
self._set_gamma_at_sigmas(i)
if self._isotope is not None and not self._read_gamma_iso:
self._set_gamma_isotope_at_sigmas(i)
freqs = self._frequencies[grid_point][self._pp.get_band_indices()]
self._cv[:, i, :] = self._get_cv(freqs)
self._set_gv(i)
if self._log_level:
self._show_log(self._qpoints[i], i)
def _allocate_values(self):
num_band0 = len(self._pp.get_band_indices())
num_band = self._primitive.get_number_of_atoms() * 3
num_grid_points = len(self._grid_points)
self._kappa = np.zeros((len(self._sigmas),
len(self._temperatures),
6), dtype='double')
self._mode_kappa = np.zeros((len(self._sigmas),
len(self._temperatures),
num_grid_points,
num_band0,
6), dtype='double')
if not self._read_gamma:
self._gamma = np.zeros((len(self._sigmas),
len(self._temperatures),
num_grid_points,
num_band0), dtype='double')
self._gv = np.zeros((num_grid_points, num_band0, 3), dtype='double')
self._gv_sum2 = np.zeros((num_grid_points, num_band0, 6), dtype='double')
self._cv = np.zeros(
(len(self._temperatures), num_grid_points, num_band0), dtype='double')
if self._isotope is not None:
self._gamma_iso = np.zeros(
(len(self._sigmas), num_grid_points, num_band0), dtype='double')
if self._is_full_pp or self._use_ave_pp:
self._averaged_pp_interaction = np.zeros(
(num_grid_points, num_band0), dtype='double')
self._num_ignored_phonon_modes = np.zeros(
(len(self._sigmas), len(self._temperatures)), dtype='intc')
self._collision = ImagSelfEnergy(
self._pp,
with_detail=self._with_gamma_detail,
unit_conversion=self._gamma_unit_conversion)
def _set_gamma_at_sigmas(self, i):
for j, sigma in enumerate(self._sigmas):
if self._log_level:
text = "Calculating Gamma of ph-ph with "
if sigma is None:
text += "tetrahedron method"
else:
text += "sigma=%s" % sigma
print(text)
self._collision.set_sigma(sigma)
if not self._use_ave_pp:
if sigma is None or self._run_with_g:
self._collision.set_integration_weights()
if self._is_full_pp and j != 0:
pass
else:
self._collision.run_interaction(is_full_pp=self._is_full_pp)
if self._is_full_pp and j == 0:
self._averaged_pp_interaction[i] = (
self._pp.get_averaged_interaction())
for k, t in enumerate(self._temperatures):
self._collision.set_temperature(t)
self._collision.run()
self._gamma[j, k, i] = self._collision.get_imag_self_energy()
def _get_gv_by_gv(self, i):
rotation_map = get_grid_points_by_rotations(
self._grid_address[self._grid_points[i]],
self._point_operations,
self._mesh)
gv_by_gv = np.zeros((len(self._gv[i]), 3, 3), dtype='double')
for r in self._rotations_cartesian:
gvs_rot = np.dot(self._gv[i], r.T)
gv_by_gv += [np.outer(r_gv, r_gv) for r_gv in gvs_rot]
gv_by_gv /= len(rotation_map) // len(np.unique(rotation_map))
order_kstar = len(np.unique(rotation_map))
if order_kstar != self._grid_weights[i]:
if self._log_level:
print("*" * 33 + "Warning" + "*" * 33)
print(" Number of elements in k* is unequal "
"to number of equivalent grid-points.")
print("*" * 73)
return gv_by_gv, order_kstar
def _get_cv(self, freqs):
cv = np.zeros((len(self._temperatures), len(freqs)), dtype='double')
# T/freq has to be large enough to avoid divergence.
# Otherwise just set 0.
for i, f in enumerate(freqs):
finite_t = (self._temperatures > f / 100)
if f > self._cutoff_frequency:
cv[:, i] = np.where(
finite_t, get_mode_cv(
np.where(finite_t, self._temperatures, 10000),
f * THzToEv), 0)
return cv
def _show_log(self, q, i):
gp = self._grid_points[i]
frequencies = self._frequencies[gp][self._pp.get_band_indices()]
gv = self._gv[i]
if self._is_full_pp or self._use_ave_pp:
ave_pp = self._averaged_pp_interaction[i]
if self._is_full_pp or self._use_ave_pp:
text = "Frequency group velocity (x, y, z) |gv| Pqj"
else:
text = "Frequency group velocity (x, y, z) |gv|"
if self._gv_delta_q is None:
pass
else:
text += " (dq=%3.1e)" % self._gv_delta_q
print(text)
if self._log_level > 1:
rotation_map = get_grid_points_by_rotations(
self._grid_address[gp],
self._point_operations,
self._mesh)
for i, j in enumerate(np.unique(rotation_map)):
for k, (rot, rot_c) in enumerate(zip(
self._point_operations, self._rotations_cartesian)):
if rotation_map[k] != j:
continue
print(" k*%-2d (%5.2f %5.2f %5.2f)" %
((i + 1,) + tuple(np.dot(rot, q))))
if self._is_full_pp or self._use_ave_pp:
for f, v, pp in zip(frequencies,
np.dot(rot_c, gv.T).T,
ave_pp):
print("%8.3f (%8.3f %8.3f %8.3f) %8.3f %11.3e" %
(f, v[0], v[1], v[2], np.linalg.norm(v), pp))
else:
for f, v in zip(frequencies, np.dot(rot_c, gv.T).T):
print("%8.3f (%8.3f %8.3f %8.3f) %8.3f" %
(f, v[0], v[1], v[2], np.linalg.norm(v)))
print('')
else:
if self._is_full_pp or self._use_ave_pp:
for f, v, pp in zip(frequencies, gv, ave_pp):
print("%8.3f (%8.3f %8.3f %8.3f) %8.3f %11.3e" %
(f, v[0], v[1], v[2], np.linalg.norm(v), pp))
else:
for f, v in zip(frequencies, gv):
print("%8.3f (%8.3f %8.3f %8.3f) %8.3f" %
(f, v[0], v[1], v[2], np.linalg.norm(v)))

View File

@ -1,222 +0,0 @@
import numpy as np
from phonopy.harmonic.displacement import get_least_displacements, \
directions_axis, get_displacement, is_minus_displacement
from phonopy.harmonic.dynamical_matrix import get_equivalent_smallest_vectors
def direction_to_displacement(dataset,
distance,
supercell,
cutoff_distance=None):
lattice = supercell.get_cell()
new_dataset = {}
new_dataset['natom'] = supercell.get_number_of_atoms()
if cutoff_distance is not None:
new_dataset['cutoff_distance'] = cutoff_distance
new_first_atoms = []
for first_atoms in dataset:
atom1 = first_atoms['number']
direction1 = first_atoms['direction']
disp_cart1 = np.dot(direction1, lattice)
disp_cart1 *= distance / np.linalg.norm(disp_cart1)
new_second_atoms = []
for second_atom in first_atoms['second_atoms']:
atom2 = second_atom['number']
pair_distance = second_atom['distance']
included = (pair_distance < cutoff_distance or
cutoff_distance is None)
for direction2 in second_atom['directions']:
disp_cart2 = np.dot(direction2, lattice)
disp_cart2 *= distance / np.linalg.norm(disp_cart2)
if cutoff_distance is None:
new_second_atoms.append({'number': atom2,
'direction': direction2,
'displacement': disp_cart2,
'pair_distance': pair_distance})
else:
new_second_atoms.append({'number': atom2,
'direction': direction2,
'displacement': disp_cart2,
'pair_distance': pair_distance,
'included': included})
new_first_atoms.append({'number': atom1,
'direction': direction1,
'displacement': disp_cart1,
'second_atoms': new_second_atoms})
new_dataset['first_atoms'] = new_first_atoms
return new_dataset
def get_third_order_displacements(cell,
symmetry,
is_plusminus='auto',
is_diagonal=False):
# Atoms 1, 2, and 3 are defined as follows:
#
# Atom 1: The first displaced atom. Third order force constant
# between Atoms 1, 2, and 3 is calculated.
# Atom 2: The second displaced atom. Second order force constant
# between Atoms 2 and 3 is calculated.
# Atom 3: Force is mesuared on this atom.
positions = cell.get_scaled_positions()
lattice = cell.get_cell()
# Least displacements for third order force constants in yaml file
#
# Data structure
# [{'number': atom1,
# 'displacement': [0.00000, 0.007071, 0.007071],
# 'second_atoms': [ {'number': atom2,
# 'displacements': [[0.007071, 0.000000, 0.007071],
# [-0.007071, 0.000000, -0.007071]
# ,...]},
# {'number': ... } ] },
# {'number': atom1, ... } ]
# Least displacements of first atoms (Atom 1) are searched by
# using respective site symmetries of the original crystal.
disps_first = get_least_displacements(symmetry,
is_plusminus=is_plusminus,
is_diagonal=False)
symprec = symmetry.get_symmetry_tolerance()
dds = []
for disp in disps_first:
atom1 = disp[0]
disp1 = disp[1:4]
site_sym = symmetry.get_site_symmetry(atom1)
dds_atom1 = {'number': atom1,
'direction': disp1,
'second_atoms': []}
# Reduced site symmetry at the first atom with respect to
# the displacement of the first atoms.
reduced_site_sym = get_reduced_site_symmetry(site_sym, disp1, symprec)
# Searching orbits (second atoms) with respect to
# the first atom and its reduced site symmetry.
second_atoms = get_least_orbits(atom1,
cell,
reduced_site_sym,
symprec)
for atom2 in second_atoms:
dds_atom2 = get_next_displacements(atom1,
atom2,
reduced_site_sym,
positions,
symprec,
is_diagonal)
min_distance = np.linalg.norm(
np.dot(get_equivalent_smallest_vectors(
atom1,
atom2,
cell,
lattice,
symprec)[0], lattice))
dds_atom2['distance'] = min_distance
dds_atom1['second_atoms'].append(dds_atom2)
dds.append(dds_atom1)
return dds
def get_next_displacements(atom1,
atom2,
reduced_site_sym,
positions,
symprec,
is_diagonal):
# Bond symmetry between first and second atoms.
reduced_bond_sym = get_bond_symmetry(
reduced_site_sym,
positions,
atom1,
atom2,
symprec)
# Since displacement of first atom breaks translation
# symmetry, the crystal symmetry is reduced to point
# symmetry and it is equivalent to the site symmetry
# on the first atom. Therefore site symmetry on the
# second atom with the displacement is equivalent to
# this bond symmetry.
if is_diagonal:
disps_second = get_displacement(reduced_bond_sym)
else:
disps_second = get_displacement(reduced_bond_sym, directions_axis)
dds_atom2 = {'number': atom2, 'directions': []}
for disp2 in disps_second:
dds_atom2['directions'].append(disp2)
if is_minus_displacement(disp2, reduced_bond_sym):
dds_atom2['directions'].append(-disp2)
return dds_atom2
def get_reduced_site_symmetry(site_sym, direction, symprec=1e-5):
reduced_site_sym = []
for rot in site_sym:
if (abs(direction - np.dot(direction, rot.T)) < symprec).all():
reduced_site_sym.append(rot)
return np.array(reduced_site_sym, dtype='intc')
def get_bond_symmetry(site_symmetry,
positions,
atom_center,
atom_disp,
symprec=1e-5):
"""
Bond symmetry is the symmetry operations that keep the symmetry
of the cell containing two fixed atoms.
"""
bond_sym = []
pos = positions
for rot in site_symmetry:
rot_pos = (np.dot(pos[atom_disp] - pos[atom_center], rot.T) +
pos[atom_center])
diff = pos[atom_disp] - rot_pos
if (abs(diff - diff.round()) < symprec).all():
bond_sym.append(rot)
return np.array(bond_sym)
def get_least_orbits(atom_index, cell, site_symmetry, symprec=1e-5):
"""Find least orbits for a centering atom"""
orbits = _get_orbits(atom_index, cell, site_symmetry, symprec)
mapping = range(cell.get_number_of_atoms())
for i, orb in enumerate(orbits):
for num in np.unique(orb):
if mapping[num] > mapping[i]:
mapping[num] = mapping[i]
return np.unique(mapping)
def _get_orbits(atom_index, cell, site_symmetry, symprec=1e-5):
positions = cell.get_scaled_positions()
center = positions[atom_index]
# orbits[num_atoms, num_site_sym]
orbits = []
for pos in positions:
mapping = []
for rot in site_symmetry:
rot_pos = np.dot(pos - center, rot.T) + center
for i, pos in enumerate(positions):
diff = pos - rot_pos
diff -= diff.round()
if (abs(diff) < symprec).all():
mapping.append(i)
break
if len(mapping) < len(site_symmetry):
print("Site symmetry is broken.")
raise ValueError
else:
orbits.append(mapping)
return np.array(orbits)

View File

@ -1,654 +0,0 @@
import sys
import numpy as np
from phonopy.harmonic.force_constants import (similarity_transformation,
set_permutation_symmetry,
distribute_force_constants,
solve_force_constants,
get_rotated_displacement,
get_positions_sent_by_rot_inv,
set_translational_invariance)
from phonopy.harmonic.dynamical_matrix import get_equivalent_smallest_vectors
from anharmonic.phonon3.displacement_fc3 import (get_reduced_site_symmetry,
get_bond_symmetry)
def get_fc3(supercell,
disp_dataset,
fc2,
symmetry,
translational_symmetry_type=0,
is_permutation_symmetry=False,
verbose=False):
num_atom = supercell.get_number_of_atoms()
fc3_least_atoms = np.zeros((num_atom, num_atom, num_atom, 3, 3, 3),
dtype='double')
if 'cutoff_distance' in disp_dataset:
_get_fc3_least_atoms(fc3_least_atoms,
supercell,
disp_dataset,
fc2,
symmetry,
False,
False,
verbose)
else:
_get_fc3_least_atoms(fc3_least_atoms,
supercell,
disp_dataset,
fc2,
symmetry,
translational_symmetry_type,
is_permutation_symmetry,
verbose)
if verbose:
print("Expanding fc3")
first_disp_atoms = np.unique(
[x['number'] for x in disp_dataset['first_atoms']])
rotations = symmetry.get_symmetry_operations()['rotations']
translations = symmetry.get_symmetry_operations()['translations']
symprec = symmetry.get_symmetry_tolerance()
lattice = supercell.get_cell().T
positions = supercell.get_scaled_positions()
fc3 = distribute_fc3(fc3_least_atoms,
first_disp_atoms,
lattice,
positions,
rotations,
translations,
symprec,
overwrite=False,
verbose=verbose)
if 'cutoff_distance' in disp_dataset:
if verbose:
print("Cutting-off fc3 (cut-off distance: %f)" %
disp_dataset['cutoff_distance'])
cutoff_fc3(fc3,
supercell,
disp_dataset,
symmetry,
verbose=verbose)
if translational_symmetry_type:
if verbose:
print("Imposing translational invariance symmetry to fc3")
set_translational_invariance_fc3(
fc3, translational_symmetry_type=translational_symmetry_type)
if is_permutation_symmetry:
if verbose:
print("Imposing index permulation symmetry to fc3")
set_permutation_symmetry_fc3(fc3)
else:
if translational_symmetry_type:
if verbose:
print("Imposing translational invariance symmetry to fc3")
set_translational_invariance_fc3_per_index(
fc3, translational_symmetry_type=translational_symmetry_type)
if is_permutation_symmetry:
if verbose:
print("Imposing index permulation symmetry to fc3")
set_permutation_symmetry_fc3(fc3)
return fc3
def distribute_fc3(fc3_least_atoms,
first_disp_atoms,
lattice,
positions,
rotations,
translations,
symprec,
overwrite=True,
verbose=False):
num_atom = len(positions)
atom_mapping = np.zeros(num_atom, dtype='intc')
if overwrite:
fc3 = fc3_least_atoms
else:
fc3 = np.zeros((num_atom, num_atom, num_atom, 3, 3, 3), dtype='double')
for i in range(num_atom):
# if i in first_disp_atoms:
# continue
for atom_index_done in first_disp_atoms:
rot_num = get_atom_mapping_by_symmetry(positions,
i,
atom_index_done,
rotations,
translations,
symprec)
if rot_num > -1:
i_rot = atom_index_done
rot = rotations[rot_num]
trans = translations[rot_num]
break
if rot_num < 0:
print("Position or symmetry may be wrong.")
raise ValueError
for j in range(num_atom):
atom_mapping[j] = get_atom_by_symmetry(positions,
rot,
trans,
j,
symprec)
rot_cart_inv = np.array(similarity_transformation(lattice, rot).T,
dtype='double', order='C')
if not (overwrite and i == i_rot):
if verbose > 2:
print(" [ %d, x, x ] to [ %d, x, x ]" % (i_rot + 1, i + 1))
sys.stdout.flush()
try:
import anharmonic._phono3py as phono3c
phono3c.distribute_fc3(fc3,
fc3_least_atoms,
i,
atom_mapping,
rot_cart_inv)
except ImportError:
for j in range(num_atom):
j_rot = atom_mapping[j]
for k in range(num_atom):
k_rot = atom_mapping[k]
fc3[i, j, k] = third_rank_tensor_rotation(
rot_cart_inv, fc3_least_atoms[i_rot, j_rot, k_rot])
if not overwrite:
return fc3
def set_permutation_symmetry_fc3(fc3):
try:
import anharmonic._phono3py as phono3c
phono3c.permutation_symmetry_fc3(fc3)
except ImportError:
num_atom = fc3.shape[0]
for i in range(num_atom):
for j in range(i, num_atom):
for k in range(j, num_atom):
fc3_elem = set_permutation_symmetry_fc3_elem(fc3, i, j, k)
copy_permutation_symmetry_fc3_elem(fc3, fc3_elem, i, j, k)
def set_permutation_symmetry_fc3_deprecated(fc3):
fc3_sym = np.zeros(fc3.shape, dtype='double')
for (i, j, k) in list(np.ndindex(fc3.shape[:3])):
fc3_sym[i, j, k] = set_permutation_symmetry_fc3_elem(fc3, i, j, k)
for (i, j, k) in list(np.ndindex(fc3.shape[:3])):
fc3[i, j, k] = fc3_sym[i, j, k]
def copy_permutation_symmetry_fc3_elem(fc3, fc3_elem, a, b, c):
for (i, j, k) in list(np.ndindex(3, 3, 3)):
fc3[a, b, c, i, j, k] = fc3_elem[i, j, k]
fc3[c, a, b, k, i, j] = fc3_elem[i, j, k]
fc3[b, c, a, j, k, i] = fc3_elem[i, j, k]
fc3[a, c, b, i, k, j] = fc3_elem[i, j, k]
fc3[b, a, c, j, i, k] = fc3_elem[i, j, k]
fc3[c, b, a, k, j, i] = fc3_elem[i, j, k]
def set_permutation_symmetry_fc3_elem(fc3, a, b, c, divisor=6):
tensor3 = np.zeros((3, 3, 3), dtype='double')
for (i, j, k) in list(np.ndindex(3, 3, 3)):
tensor3[i, j, k] = (fc3[a, b, c, i, j, k] +
fc3[c, a, b, k, i, j] +
fc3[b, c, a, j, k, i] +
fc3[a, c, b, i, k, j] +
fc3[b, a, c, j, i, k] +
fc3[c, b, a, k, j, i]) / divisor
return tensor3
def set_translational_invariance_fc3(fc3,
translational_symmetry_type=1):
for i in range(3):
set_translational_invariance_fc3_per_index(
fc3,
index=i,
translational_symmetry_type=translational_symmetry_type)
def set_translational_invariance_fc3_per_index(fc3,
index=0,
translational_symmetry_type=1):
for i in range(fc3.shape[(1 + index) % 3]):
for j in range(fc3.shape[(2 + index) % 3]):
for k, l, m in list(np.ndindex(3, 3, 3)):
if translational_symmetry_type == 2: # Type 2
if index == 0:
fc_abs = np.abs(fc3[:, i, j, k, l, m])
fc_sum = np.sum(fc3[:, i, j, k, l, m])
fc_abs_sum = np.sum(fc_abs)
fc3[:, i, j, k, l, m] -= (
fc_sum / fc_abs_sum * fc_abs)
elif index == 1:
fc_abs = np.abs(fc3[i, :, j, k, l, m])
fc_sum = np.sum(fc3[i, :, j, k, l, m])
fc_abs_sum = np.sum(fc_abs)
fc3[i, :, j, k, l, m] -= (
fc_sum / fc_abs_sum * fc_abs)
elif index == 2:
fc_abs = np.abs(fc3[i, j, :, k, l, m])
fc_sum = np.sum(fc3[i, j, :, k, l, m])
fc_abs_sum = np.sum(fc_abs)
fc3[i, j, :, k, l, m] -= (
fc_sum / fc_abs_sum * fc_abs)
else: # Type 1
if index == 0:
fc3[:, i, j, k, l, m] -= np.sum(
fc3[:, i, j, k, l, m]) / fc3.shape[0]
elif index == 1:
fc3[j, :, i, k, l, m] -= np.sum(
fc3[j, :, i, k, l, m]) / fc3.shape[1]
elif index == 2:
fc3[i, j, :, k, l, m] -= np.sum(
fc3[i, j, :, k, l, m]) / fc3.shape[2]
def third_rank_tensor_rotation(rot_cart, tensor):
rot_tensor = np.zeros((3,3,3), dtype='double')
for i in (0,1,2):
for j in (0,1,2):
for k in (0,1,2):
rot_tensor[i, j, k] = _third_rank_tensor_rotation_elem(
rot_cart, tensor, i, j, k)
return rot_tensor
def get_atom_by_symmetry(positions,
rotation,
trans,
atom_number,
symprec=1e-5):
rot_pos = np.dot(positions[atom_number], rotation.T) + trans
for i, pos in enumerate(positions):
diff = pos - rot_pos
diff -= np.rint(diff)
if (abs(diff) < symprec).all():
return i
print("Position or symmetry is wrong.")
raise ValueError
def get_atom_mapping_by_symmetry(positions,
atom_search,
atom_target,
rotations,
translations,
symprec):
map_sym = -1
for i, (r, t) in enumerate(zip(rotations, translations)):
rot_pos = np.dot(positions[atom_search], r.T) + t
diff = rot_pos - positions[atom_target]
diff -= np.rint(diff)
if (abs(diff) < symprec).all():
map_sym = i
break
return map_sym
def get_delta_fc2(dataset_second_atoms,
atom1,
fc2,
supercell,
reduced_site_sym,
translational_symmetry_type,
is_permutation_symmetry,
symprec):
disp_fc2 = get_constrained_fc2(supercell,
dataset_second_atoms,
atom1,
reduced_site_sym,
translational_symmetry_type,
is_permutation_symmetry,
symprec)
return disp_fc2 - fc2
def get_constrained_fc2(supercell,
dataset_second_atoms,
atom1,
reduced_site_sym,
translational_symmetry_type,
is_permutation_symmetry,
symprec):
"""
dataset_second_atoms: [{'number': 7,
'displacement': [],
'delta_forces': []}, ...]
"""
num_atom = supercell.get_number_of_atoms()
fc2 = np.zeros((num_atom, num_atom, 3, 3), dtype='double')
atom_list = np.unique([x['number'] for x in dataset_second_atoms])
for atom2 in atom_list:
disps2 = []
sets_of_forces = []
for disps_second in dataset_second_atoms:
if atom2 != disps_second['number']:
continue
bond_sym = get_bond_symmetry(
reduced_site_sym,
supercell.get_scaled_positions(),
atom1,
atom2,
symprec)
disps2.append(disps_second['displacement'])
sets_of_forces.append(disps_second['delta_forces'])
solve_force_constants(fc2,
atom2,
disps2,
sets_of_forces,
supercell,
bond_sym,
symprec)
# Shift positions according to set atom1 is at origin
lattice = supercell.get_cell().T
positions = supercell.get_scaled_positions()
pos_center = positions[atom1].copy()
positions -= pos_center
distribute_force_constants(fc2,
range(num_atom),
atom_list,
lattice,
positions,
np.array(reduced_site_sym,
dtype='intc', order='C'),
np.zeros((len(reduced_site_sym), 3),
dtype='double'),
symprec)
if translational_symmetry_type:
set_translational_invariance(
fc2,
translational_symmetry_type=translational_symmetry_type)
if is_permutation_symmetry:
set_permutation_symmetry(fc2)
return fc2
def solve_fc3(fc3,
first_atom_num,
supercell,
site_symmetry,
displacements_first,
delta_fc2s,
symprec,
pinv="numpy",
verbose=False):
if verbose:
text = "Solving fc3[ %d, x, x ] with " % (first_atom_num + 1)
if len(displacements_first) > 1:
text += "displacements:"
else:
text += "a displacement:"
print(text)
for i, v in enumerate(displacements_first):
print(" [%7.4f %7.4f %7.4f]" % tuple(v))
sys.stdout.flush()
if verbose > 2:
print(" Site symmetry:")
for i, v in enumerate(site_symmetry):
print(" [%2d %2d %2d] #%2d" % tuple(list(v[0])+[i + 1]))
print(" [%2d %2d %2d]" % tuple(v[1]))
print(" [%2d %2d %2d]\n" % tuple(v[2]))
sys.stdout.flush()
lattice = supercell.get_cell().T
site_sym_cart = [similarity_transformation(lattice, sym)
for sym in site_symmetry]
num_atom = supercell.get_number_of_atoms()
positions = supercell.get_scaled_positions()
pos_center = positions[first_atom_num].copy()
positions -= pos_center
rot_map_syms = get_positions_sent_by_rot_inv(lattice,
positions,
site_symmetry,
symprec)
rot_disps = get_rotated_displacement(displacements_first, site_sym_cart)
if pinv == "numpy":
inv_U = np.linalg.pinv(rot_disps)
else:
try:
import phonopy._lapackepy as lapackepy
inv_U = np.zeros((rot_disps.shape[1], rot_disps.shape[0]),
dtype='double')
lapackepy.pinv(inv_U, rot_disps, 1e-13)
except ImportError:
inv_U = np.linalg.pinv(rot_disps)
for (i, j) in list(np.ndindex(num_atom, num_atom)):
fc3[first_atom_num, i, j] = np.dot(inv_U, _get_rotated_fc2s(
i, j, delta_fc2s, rot_map_syms, site_sym_cart)).reshape(3, 3, 3)
def cutoff_fc3(fc3,
supercell,
disp_dataset,
symmetry,
verbose=False):
if verbose:
print("Building atom mapping table...")
fc3_done = _get_fc3_done(supercell, disp_dataset, symmetry)
if verbose:
print("Creating contracted fc3...")
num_atom = supercell.get_number_of_atoms()
for i in range(num_atom):
for j in range(i, num_atom):
for k in range(j, num_atom):
ave_fc3 = _set_permutation_symmetry_fc3_elem_with_cutoff(
fc3, fc3_done, i, j, k)
copy_permutation_symmetry_fc3_elem(fc3, ave_fc3, i, j, k)
def _set_permutation_symmetry_fc3_elem_with_cutoff(fc3, fc3_done, a, b, c):
sum_done = (fc3_done[a, b, c] +
fc3_done[c, a, b] +
fc3_done[b, c, a] +
fc3_done[b, a, c] +
fc3_done[c, b, a] +
fc3_done[a, c, b])
tensor3 = np.zeros((3, 3, 3), dtype='double')
if sum_done > 0:
for (i, j, k) in list(np.ndindex(3, 3, 3)):
tensor3[i, j, k] = (fc3[a, b, c, i, j, k] * fc3_done[a, b, c] +
fc3[c, a, b, k, i, j] * fc3_done[c, a, b] +
fc3[b, c, a, j, k, i] * fc3_done[b, c, a] +
fc3[a, c, b, i, k, j] * fc3_done[a, c, b] +
fc3[b, a, c, j, i, k] * fc3_done[b, a, c] +
fc3[c, b, a, k, j, i] * fc3_done[c, b, a])
tensor3[i, j, k] /= sum_done
return tensor3
def cutoff_fc3_by_zero(fc3, supercell, cutoff_distance, symprec=1e-5):
num_atom = supercell.get_number_of_atoms()
lattice = supercell.get_cell()
min_distances = np.zeros((num_atom, num_atom), dtype='double')
for i in range(num_atom): # run in supercell
for j in range(num_atom): # run in primitive
min_distances[i, j] = np.linalg.norm(np.dot(
get_equivalent_smallest_vectors(
i, j, supercell, lattice, symprec)[0], lattice))
for i, j, k in np.ndindex(num_atom, num_atom, num_atom):
for pair in ((i, j), (j, k), (k, i)):
if min_distances[pair] > cutoff_distance:
fc3[i, j, k] = 0
break
def show_drift_fc3(fc3, name="fc3"):
num_atom = fc3.shape[0]
maxval1 = 0
maxval2 = 0
maxval3 = 0
klm1 = [0, 0, 0]
klm2 = [0, 0, 0]
klm3 = [0, 0, 0]
for i, j, k, l, m in list(np.ndindex((num_atom, num_atom, 3, 3, 3))):
val1 = fc3[:, i, j, k, l, m].sum()
val2 = fc3[i, :, j, k, l, m].sum()
val3 = fc3[i, j, :, k, l, m].sum()
if abs(val1) > abs(maxval1):
maxval1 = val1
klm1 = [k, l, m]
if abs(val2) > abs(maxval2):
maxval2 = val2
klm2 = [k, l, m]
if abs(val3) > abs(maxval3):
maxval3 = val3
klm3 = [k, l, m]
text = "max drift of %s: " % name
text += "%f (%s%s%s) " % (maxval1,
"xyz"[klm1[0]], "xyz"[klm1[1]], "xyz"[klm1[2]])
text += "%f (%s%s%s) " % (maxval2,
"xyz"[klm2[0]], "xyz"[klm2[1]], "xyz"[klm2[2]])
text += "%f (%s%s%s)" % (maxval3,
"xyz"[klm3[0]], "xyz"[klm3[1]], "xyz"[klm3[2]])
print(text)
def _get_fc3_least_atoms(fc3,
supercell,
disp_dataset,
fc2,
symmetry,
translational_symmetry_type,
is_permutation_symmetry,
verbose):
symprec = symmetry.get_symmetry_tolerance()
unique_first_atom_nums = np.unique(
[x['number'] for x in disp_dataset['first_atoms']])
for first_atom_num in unique_first_atom_nums:
_get_fc3_one_atom(fc3,
supercell,
disp_dataset,
fc2,
first_atom_num,
symmetry.get_site_symmetry(first_atom_num),
translational_symmetry_type,
is_permutation_symmetry,
symprec,
verbose)
def _get_fc3_one_atom(fc3,
supercell,
disp_dataset,
fc2,
first_atom_num,
site_symmetry,
translational_symmetry_type,
is_permutation_symmetry,
symprec,
verbose):
displacements_first = []
delta_fc2s = []
for dataset_first_atom in disp_dataset['first_atoms']:
if first_atom_num != dataset_first_atom['number']:
continue
displacements_first.append(dataset_first_atom['displacement'])
if 'delta_fc2' in dataset_first_atom:
delta_fc2s.append(dataset_first_atom['delta_fc2'])
else:
direction = np.dot(dataset_first_atom['displacement'],
np.linalg.inv(supercell.get_cell()))
reduced_site_sym = get_reduced_site_symmetry(
site_symmetry, direction, symprec)
delta_fc2s.append(get_delta_fc2(
dataset_first_atom['second_atoms'],
dataset_first_atom['number'],
fc2,
supercell,
reduced_site_sym,
translational_symmetry_type,
is_permutation_symmetry,
symprec))
solve_fc3(fc3,
first_atom_num,
supercell,
site_symmetry,
displacements_first,
delta_fc2s,
symprec,
verbose=verbose)
def _get_rotated_fc2s(i, j, fc2s, rot_map_syms, site_sym_cart):
num_sym = len(site_sym_cart)
rotated_fc2s = []
for fc2 in fc2s:
for sym, map_sym in zip(site_sym_cart, rot_map_syms):
fc2_rot = fc2[map_sym[i], map_sym[j]]
rotated_fc2s.append(similarity_transformation(sym, fc2_rot))
return np.reshape(rotated_fc2s, (-1, 9))
def _third_rank_tensor_rotation_elem(rot, tensor, l, m, n):
sum_elems = 0.
for i in (0, 1, 2):
for j in (0, 1, 2):
for k in (0, 1, 2):
sum_elems += rot[l, i] * rot[m, j] * rot[n, k] * tensor[i, j, k]
return sum_elems
def _get_fc3_done(supercell, disp_dataset, symmetry):
num_atom = supercell.get_number_of_atoms()
fc3_done = np.zeros((num_atom, num_atom, num_atom), dtype='byte')
symprec = symmetry.get_symmetry_tolerance()
positions = supercell.get_scaled_positions()
rotations = symmetry.get_symmetry_operations()['rotations']
translations = symmetry.get_symmetry_operations()['translations']
atom_mapping = []
for rot, trans in zip(rotations, translations):
atom_indices = []
for rot_pos in (np.dot(positions, rot.T) + trans):
diff = positions - rot_pos
diff -= np.rint(diff)
atom_indices.append(
np.where((np.abs(diff) < symprec).all(axis=1))[0][0])
atom_mapping.append(atom_indices)
for dataset_first_atom in disp_dataset['first_atoms']:
first_atom_num = dataset_first_atom['number']
site_symmetry = symmetry.get_site_symmetry(first_atom_num)
direction = np.dot(dataset_first_atom['displacement'],
np.linalg.inv(supercell.get_cell()))
reduced_site_sym = get_reduced_site_symmetry(
site_symmetry, direction, symprec)
least_second_atom_nums = []
for second_atoms in dataset_first_atom['second_atoms']:
if second_atoms['included']:
least_second_atom_nums.append(second_atoms['number'])
positions_shifted = positions - positions[first_atom_num]
least_second_atom_nums = np.unique(least_second_atom_nums)
second_atom_nums = []
for red_rot in reduced_site_sym:
for i in least_second_atom_nums:
second_atom_nums.append(
get_atom_by_symmetry(positions_shifted,
red_rot,
np.zeros(3, dtype='double'),
i,
symprec))
second_atom_nums = np.unique(second_atom_nums)
for i in range(len(rotations)):
rotated_atom1 = atom_mapping[i][first_atom_num]
for j in second_atom_nums:
fc3_done[rotated_atom1, atom_mapping[i][j]] = 1
return fc3_done

View File

@ -1,229 +0,0 @@
import numpy as np
from phonopy.units import THzToEv, Kb, VaspToTHz, Hbar, EV, Angstrom, THz, AMU
from phonopy.phonon.degeneracy import degenerate_sets
from anharmonic.phonon3.triplets import occupation
from anharmonic.file_IO import write_frequency_shift
def get_frequency_shift(interaction,
grid_points,
band_indices,
epsilons,
temperatures=None,
output_filename=None,
log_level=0):
if temperatures is None:
temperatures = [0.0, 300.0]
fst = FrequencyShift(interaction)
band_indices_flatten = interaction.get_band_indices()
mesh = interaction.get_mesh_numbers()
for gp in grid_points:
fst.set_grid_point(gp)
if log_level:
weights = interaction.get_triplets_at_q()[1]
print("------ Frequency shift -o- ------")
print("Number of ir-triplets: "
"%d / %d" % (len(weights), weights.sum()))
fst.run_interaction()
for epsilon in epsilons:
fst.set_epsilon(epsilon)
delta = np.zeros((len(temperatures),
len(band_indices_flatten)),
dtype='double')
for i, t in enumerate(temperatures):
fst.set_temperature(t)
fst.run()
delta[i] = fst.get_frequency_shift()
for i, bi in enumerate(band_indices):
pos = 0
for j in range(i):
pos += len(band_indices[j])
write_frequency_shift(gp,
bi,
temperatures,
delta[:, pos:(pos+len(bi))],
mesh,
epsilon=epsilon,
filename=output_filename)
class FrequencyShift(object):
def __init__(self,
interaction,
grid_point=None,
temperature=None,
epsilon=0.1,
lang='C'):
self._pp = interaction
self.set_epsilon(epsilon)
self.set_temperature(temperature)
self.set_grid_point(grid_point=grid_point)
self._lang = lang
self._frequency_ = None
self._pp_strength = None
self._frequencies = None
self._triplets_at_q = None
self._weights_at_q = None
self._band_indices = None
self._unit_conversion = None
self._cutoff_frequency = interaction.get_cutoff_frequency()
self._frequency_shifts = None
self.set_epsilon(epsilon)
def run(self):
if self._pp_strength is None:
self.run_interaction()
num_band0 = self._pp_strength.shape[1]
self._frequency_shifts = np.zeros(num_band0, dtype='double')
self._run_with_band_indices()
def run_interaction(self):
self._pp.run(lang=self._lang)
self._pp_strength = self._pp.get_interaction_strength()
(self._frequencies,
self._eigenvectors) = self._pp.get_phonons()[:2]
(self._triplets_at_q,
self._weights_at_q) = self._pp.get_triplets_at_q()[:2]
self._band_indices = self._pp.get_band_indices()
mesh = self._pp.get_mesh_numbers()
num_grid = np.prod(mesh)
# Unit to THz of Delta
self._unit_conversion = ((Hbar * EV) ** 3 / 36 / 8
* EV ** 2 / Angstrom ** 6
/ (2 * np.pi * THz) ** 3
/ AMU ** 3
* 18 / (Hbar * EV) ** 2
/ (2 * np.pi * THz) ** 2
/ num_grid)
def get_frequency_shift(self):
if self._cutoff_frequency is None:
return self._frequency_shifts
else: # Averaging frequency shifts by degenerate bands
shifts = np.zeros_like(self._frequency_shifts)
freqs = self._frequencies[self._grid_point]
deg_sets = degenerate_sets(freqs) # such like [[0,1], [2], [3,4,5]]
for dset in deg_sets:
bi_set = []
for i, bi in enumerate(self._band_indices):
if bi in dset:
bi_set.append(i)
if len(bi_set) > 0:
for i in bi_set:
shifts[i] = (self._frequency_shifts[bi_set].sum() /
len(bi_set))
return shifts
def set_grid_point(self, grid_point=None):
if grid_point is None:
self._grid_point = None
else:
self._pp.set_grid_point(grid_point)
self._pp_strength = None
(self._triplets_at_q,
self._weights_at_q) = self._pp.get_triplets_at_q()[:2]
self._grid_point = self._triplets_at_q[0, 0]
def set_epsilon(self, epsilon):
if epsilon is None:
self._epsilon = None
else:
self._epsilon = float(epsilon)
def set_temperature(self, temperature):
if temperature is None:
self._temperature = None
else:
self._temperature = float(temperature)
def _run_with_band_indices(self):
if self._lang == 'C':
self._run_c_with_band_indices()
else:
self._run_py_with_band_indices()
def _run_c_with_band_indices(self):
import anharmonic._phono3py as phono3c
phono3c.frequency_shift_at_bands(self._frequency_shifts,
self._pp_strength,
self._triplets_at_q,
self._weights_at_q,
self._frequencies,
self._band_indices,
self._temperature,
self._epsilon,
self._unit_conversion,
self._cutoff_frequency)
def _run_py_with_band_indices(self):
for i, (triplet, w, interaction) in enumerate(
zip(self._triplets_at_q,
self._weights_at_q,
self._pp_strength)):
freqs = self._frequencies[triplet]
for j, bi in enumerate(self._band_indices):
if self._temperature > 0:
self._frequency_shifts[j] += (
self._frequency_shifts_at_bands(
j, bi, freqs, interaction, w))
else:
self._frequency_shifts[j] += (
self._frequency_shifts_at_bands_0K(
j, bi, freqs, interaction, w))
self._frequency_shifts *= self._unit_conversion
def _frequency_shifts_at_bands(self, i, bi, freqs, interaction, weight):
sum_d = 0
for (j, k) in list(np.ndindex(interaction.shape[1:])):
if (freqs[1, j] > self._cutoff_frequency and
freqs[2, k] > self._cutoff_frequency):
d = 0.0
n2 = occupation(freqs[1, j], self._temperature)
n3 = occupation(freqs[2, k], self._temperature)
f1 = freqs[0, bi] + freqs[1, j] + freqs[2, k]
f2 = freqs[0, bi] - freqs[1, j] - freqs[2, k]
f3 = freqs[0, bi] - freqs[1, j] + freqs[2, k]
f4 = freqs[0, bi] + freqs[1, j] - freqs[2, k]
# if abs(f1) > self._epsilon:
# d -= (n2 + n3 + 1) / f1
# if abs(f2) > self._epsilon:
# d += (n2 + n3 + 1) / f2
# if abs(f3) > self._epsilon:
# d -= (n2 - n3) / f3
# if abs(f4) > self._epsilon:
# d += (n2 - n3) / f4
d -= (n2 + n3 + 1) * f1 / (f1 ** 2 + self._epsilon ** 2)
d += (n2 + n3 + 1) * f2 / (f2 ** 2 + self._epsilon ** 2)
d -= (n2 - n3) * f3 / (f3 ** 2 + self._epsilon ** 2)
d += (n2 - n3) * f4 / (f4 ** 2 + self._epsilon ** 2)
sum_d += d * interaction[i, j, k] * weight
return sum_d
def _frequency_shifts_at_bands_0K(self, i, bi, freqs, interaction, weight):
sum_d = 0
for (j, k) in list(np.ndindex(interaction.shape[1:])):
if (freqs[1, j] > self._cutoff_frequency and
freqs[2, k] > self._cutoff_frequency):
d = 0.0
f1 = freqs[0, bi] + freqs[1, j] + freqs[2, k]
f2 = freqs[0, bi] - freqs[1, j] - freqs[2, k]
# if abs(f1) > self._epsilon:
# d -= 1.0 / f1
# if abs(f2) > self._epsilon:
# d += 1.0 / f2
d -= 1.0 * f1 / (f1 ** 2 + self._epsilon ** 2)
d += 1.0 * f2 / (f2 ** 2 + self._epsilon ** 2)
sum_d += d * interaction[i, j, k] * weight
return sum_d

View File

@ -1,389 +0,0 @@
import sys
import numpy as np
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix, DynamicalMatrixNAC, get_smallest_vectors
from phonopy.structure.cells import get_supercell
from anharmonic.file_IO import write_fc3_dat, write_fc2_dat
from phonopy.units import VaspToTHz
from phonopy.structure.grid_points import get_qpoints
def get_gruneisen_parameters(fc2,
fc3,
supercell,
primitive,
band_paths,
mesh,
qpoints,
nac_params=None,
nac_q_direction=None,
ion_clamped=False,
factor=None,
symprec=1e-5,
output_filename=None,
log_level=True):
if log_level:
print("-" * 23 + " Phonon Gruneisen parameter " + "-" * 23)
if mesh is not None:
print("Mesh sampling: [ %d %d %d ]" % tuple(mesh))
elif band_paths is not None:
print("Paths in reciprocal reduced coordinates:")
for path in band_paths:
print("[%5.2f %5.2f %5.2f] --> [%5.2f %5.2f %5.2f]" %
(tuple(path[0]) + tuple(path[-1])))
if ion_clamped:
print("To be calculated with ion clamped.")
sys.stdout.flush()
gruneisen = Gruneisen(fc2,
fc3,
supercell,
primitive,
nac_params=nac_params,
nac_q_direction=nac_q_direction,
ion_clamped=ion_clamped,
factor=factor,
symprec=symprec)
if mesh is not None:
gruneisen.set_sampling_mesh(mesh, is_gamma_center=True)
elif band_paths is not None:
gruneisen.set_band_structure(band_paths)
elif qpoints is not None:
gruneisen.set_qpoints(qpoints)
gruneisen.run()
if output_filename is None:
filename = 'gruneisen3.yaml'
else:
filename = 'gruneisen3.' + output_filename + '.yaml'
gruneisen.write_yaml(filename=filename)
class Gruneisen(object):
def __init__(self,
fc2,
fc3,
supercell,
primitive,
nac_params=None,
nac_q_direction=None,
ion_clamped=False,
factor=VaspToTHz,
symprec=1e-5):
self._fc2 = fc2
self._fc3 = fc3
self._scell = supercell
self._pcell = primitive
self._ion_clamped = ion_clamped
self._factor = factor
self._symprec = symprec
if nac_params is None:
self._dm = DynamicalMatrix(self._scell,
self._pcell,
self._fc2,
symprec=self._symprec)
else:
self._dm = DynamicalMatrixNAC(self._scell,
self._pcell,
self._fc2,
symprec=self._symprec)
self._dm.set_nac_params(nac_params)
self._nac_q_direction = nac_q_direction
self._shortest_vectors, self._multiplicity = get_smallest_vectors(
self._scell, self._pcell, self._symprec)
if self._ion_clamped:
num_atom_prim = self._pcell.get_number_of_atoms()
self._X = np.zeros((num_atom_prim, 3, 3, 3), dtype=float)
else:
self._X = self._get_X()
self._dPhidu = self._get_dPhidu()
self._gruneisen_parameters = None
self._frequencies = None
self._qpoints = None
self._mesh = None
self._band_paths = None
self._band_distances = None
self._run_mode = None
self._weights = None
def run(self):
if self._run_mode == 'band':
(self._gruneisen_parameters,
self._frequencies) = self._calculate_band_paths()
elif self._run_mode == 'qpoints' or self._run_mode == 'mesh':
(self._gruneisen_parameters,
self._frequencies) = self._calculate_at_qpoints(self._qpoints)
else:
sys.stderr.write('Q-points are not specified.\n')
def get_gruneisen_parameters(self):
return self._gruneisen_parameters
def set_qpoints(self, qpoints):
self._run_mode = 'qpoints'
self._qpoints = qpoints
def set_sampling_mesh(self,
mesh,
shift=None,
is_gamma_center=False):
self._run_mode = 'mesh'
self._mesh = mesh
self._qpoints, self._weights = get_qpoints(
self._mesh,
np.linalg.inv(self._pcell.get_cell()),
q_mesh_shift=shift,
is_gamma_center=is_gamma_center)
def set_band_structure(self, paths):
self._run_mode = 'band'
self._band_paths = paths
rec_lattice = np.linalg.inv(self._pcell.get_cell())
self._band_distances = []
for path in paths:
distances_at_path = [0.]
for i in range(len(path) - 1):
distances_at_path.append(np.linalg.norm(
np.dot(rec_lattice, path[i + 1] - path[i])) +
distances_at_path[-1])
self._band_distances.append(distances_at_path)
def write_yaml(self, filename="gruneisen3.yaml"):
if self._gruneisen_parameters is not None:
f = open(filename, 'w')
if self._run_mode == 'band':
self._write_band_yaml(f)
elif self._run_mode == 'qpoints' or self._run_mode == 'mesh':
self._write_yaml(f)
f.close()
def _write_yaml(self, f):
if self._run_mode == 'mesh':
f.write("mesh: [ %5d, %5d, %5d ]\n" % tuple(self._mesh))
f.write("nqpoint: %d\n" % len(self._qpoints))
f.write("phonon:\n")
for i, (q, g_at_q, freqs_at_q) in enumerate(
zip(self._qpoints,
self._gruneisen_parameters,
self._frequencies)):
f.write("- q-position: [ %10.7f, %10.7f, %10.7f ]\n" % tuple(q))
if self._weights is not None:
f.write(" multiplicity: %d\n" % self._weights[i])
f.write(" band:\n")
for j, (g, freq) in enumerate(zip(g_at_q, freqs_at_q)):
f.write(" - # %d\n" % (j + 1))
f.write(" frequency: %15.10f\n" % freq)
f.write(" gruneisen: %15.10f\n" % (g.trace() / 3))
f.write(" gruneisen_tensor:\n")
for g_xyz in g:
f.write(" - [ %10.7f, %10.7f, %10.7f ]\n" %
tuple(g_xyz))
def _write_band_yaml(self, f):
f.write("path:\n\n")
for path, distances, gs, fs in zip(self._band_paths,
self._band_distances,
self._gruneisen_parameters,
self._frequencies):
f.write("- nqpoint: %d\n" % len(path))
f.write(" phonon:\n")
for i, (q, d, g_at_q, freqs_at_q) in enumerate(
zip(path, distances, gs, fs)):
f.write(" - q-position: [ %10.7f, %10.7f, %10.7f ]\n"
% tuple(q))
f.write(" distance: %10.7f\n" % d)
f.write(" band:\n")
for j, (g, freq) in enumerate(zip(g_at_q, freqs_at_q)):
f.write(" - # %d\n" % (j + 1))
f.write(" frequency: %15.10f\n" % freq)
f.write(" gruneisen: %15.10f\n" % (g.trace() / 3))
f.write(" gruneisen_tensor:\n")
for g_xyz in g:
f.write(" - [ %10.7f, %10.7f, %10.7f ]\n" %
tuple(g_xyz))
f.write("\n")
def _calculate_at_qpoints(self, qpoints):
gruneisen_parameters = []
frequencies = []
for i, q in enumerate(qpoints):
if self._dm.is_nac():
if (np.abs(q) < 1e-5).all(): # If q is almost at Gamma
if self._run_mode == 'band':
# Direction estimated from neighboring point
if i > 0:
q_dir = qpoints[i] - qpoints[i - 1]
elif i == 0 and len(qpoints) > 1:
q_dir = qpoints[i + 1] - qpoints[i]
else:
q_dir = None
g, omega2 = self._get_gruneisen_tensor(
q, nac_q_direction=q_dir)
else: # Specified q-vector
g, omega2 = self._get_gruneisen_tensor(
q, nac_q_direction=self._nac_q_direction)
else: # If q is away from Gamma-point, then q-vector
g, omega2 = self._get_gruneisen_tensor(q, nac_q_direction=q)
else: # Without NAC
g, omega2 = self._get_gruneisen_tensor(q)
gruneisen_parameters.append(g)
frequencies.append(
np.sqrt(abs(omega2)) * np.sign(omega2) * self._factor)
return gruneisen_parameters, frequencies
def _calculate_band_paths(self):
gruneisen_parameters = []
frequencies = []
for path in self._band_paths:
(gruneisen_at_path,
frequencies_at_path) = self._calculate_at_qpoints(path)
gruneisen_parameters.append(gruneisen_at_path)
frequencies.append(frequencies_at_path)
return gruneisen_parameters, frequencies
def _get_gruneisen_tensor(self, q, nac_q_direction=None):
if nac_q_direction is None:
self._dm.set_dynamical_matrix(q)
else:
self._dm.set_dynamical_matrix(q, nac_q_direction)
omega2, w = np.linalg.eigh(self._dm.get_dynamical_matrix())
g = np.zeros((len(omega2), 3, 3), dtype=float)
num_atom_prim = self._pcell.get_number_of_atoms()
dDdu = self._get_dDdu(q)
for s in range(len(omega2)):
if (np.abs(q) < 1e-5).all() and s < 3:
continue
for i in range(3):
for j in range(3):
for nu in range(num_atom_prim):
for pi in range(num_atom_prim):
g[s] += (w[nu * 3 + i, s].conjugate() *
dDdu[nu, pi, i, j] * w[pi * 3 + j, s]).real
g[s] *= -1.0 / 2 / omega2[s]
return g, omega2
def _get_dDdu(self, q):
num_atom_prim = self._pcell.get_number_of_atoms()
num_atom_super = self._scell.get_number_of_atoms()
p2s = self._pcell.get_primitive_to_supercell_map()
s2p = self._pcell.get_supercell_to_primitive_map()
vecs = self._shortest_vectors
multi = self._multiplicity
m = self._pcell.get_masses()
dPhidu = self._dPhidu
dDdu = np.zeros((num_atom_prim, num_atom_prim, 3, 3, 3, 3), dtype=complex)
for nu in range(num_atom_prim):
for pi, p in enumerate(p2s):
for Ppi, s in enumerate(s2p):
if not s==p:
continue
phase = np.exp(2j * np.pi * np.dot(
vecs[Ppi,nu,:multi[Ppi, nu], :], q)
).sum() / multi[Ppi, nu]
dDdu[nu, pi] += phase * dPhidu[nu, Ppi]
dDdu[nu, pi] /= np.sqrt(m[nu] * m[pi])
return dDdu
def _get_dPhidu(self):
fc3 = self._fc3
num_atom_prim = self._pcell.get_number_of_atoms()
num_atom_super = self._scell.get_number_of_atoms()
p2s = self._pcell.get_primitive_to_supercell_map()
dPhidu = np.zeros((num_atom_prim, num_atom_super, 3, 3, 3, 3),
dtype=float)
for nu in range(num_atom_prim):
Y = self._get_Y(nu)
for pi in range(num_atom_super):
for i in range(3):
for j in range(3):
for k in range(3):
for l in range(3):
for m in range(3):
dPhidu[nu, pi, i, j, k, l] = (
fc3[p2s[nu], pi, :, i, j, :] *
Y[:, :, k, l]).sum()
# (Y[:,:,k,l] + Y[:,:,l,k]) / 2).sum() # Symmetrization?
return dPhidu
def _get_Y(self, nu):
P = self._fc2
X = self._X
vecs = self._shortest_vectors
multi = self._multiplicity
lat = self._pcell.get_cell()
num_atom_super = self._scell.get_number_of_atoms()
R = np.array(
[np.dot(vecs[Npi, nu, :multi[Npi,nu], :].sum(axis=0) /
multi[Npi,nu], lat) for Npi in range(num_atom_super)])
p2s = self._pcell.get_primitive_to_supercell_map()
s2p = self._pcell.get_supercell_to_primitive_map()
p2p = self._pcell.get_primitive_to_primitive_map()
Y = np.zeros((num_atom_super, 3, 3, 3), dtype=float)
for Mmu in range(num_atom_super):
for i in range(3):
Y[Mmu, i, i, :] = R[Mmu, :]
Y[Mmu] += X[p2p[s2p[Mmu]]]
return Y
def _get_X(self):
num_atom_super = self._scell.get_number_of_atoms()
num_atom_prim = self._pcell.get_number_of_atoms()
p2s = self._pcell.get_primitive_to_supercell_map()
lat = self._pcell.get_cell()
vecs = self._shortest_vectors
multi = self._multiplicity
X = np.zeros((num_atom_prim, 3, 3, 3), dtype=float)
G = self._get_Gamma()
P = self._fc2
for mu in range(num_atom_prim):
for nu in range(num_atom_prim):
R = np.array(
[np.dot(vecs[Npi, nu, :multi[Npi, nu], :].sum(axis=0) /
multi[Npi, nu], lat)
for Npi in range(num_atom_super)])
for i in range(3):
for j in range(3):
for k in range(3):
for l in range(3):
X[mu, i, j, k] -= G[mu, nu, i, l] * \
np.dot(P[p2s[nu], :, l, j], R[:, k])
return X
def _get_Gamma(self):
num_atom_prim = self._pcell.get_number_of_atoms()
m = self._pcell.get_masses()
self._dm.set_dynamical_matrix([0, 0, 0])
vals, vecs = np.linalg.eigh(self._dm.get_dynamical_matrix().real)
G = np.zeros((num_atom_prim, num_atom_prim, 3, 3), dtype=float)
for pi in range(num_atom_prim):
for mu in range(num_atom_prim):
for k in range(3):
for i in range(3):
# Eigenvectors are real.
# 3: means optical modes
G[pi, mu, k, i] = (
1.0 / np.sqrt(m[pi] * m[mu]) *
(vecs[pi * 3 + k, 3:] * vecs[mu * 3 + i, 3:] /
vals[3:]).sum())
return G

View File

@ -1,757 +0,0 @@
import numpy as np
from phonopy.units import VaspToTHz, Hbar, EV, Angstrom, THz, AMU
from phonopy.phonon.degeneracy import degenerate_sets
from anharmonic.phonon3.triplets import (get_triplets_integration_weights,
gaussian, occupation)
from anharmonic.file_IO import (write_gamma_detail_to_hdf5,
write_linewidth_at_grid_point,
write_imag_self_energy_at_grid_point)
def get_imag_self_energy(interaction,
grid_points,
sigmas,
frequency_step=None,
num_frequency_points=None,
temperatures=None,
scattering_event_class=None, # class 1 or 2
run_with_g=True,
write_detail=False,
log_level=0):
"""Imaginary part of self energy at frequency points
Band indices to be calculated at are kept in Interaction instance.
Args:
interaction: Ph-ph interaction
grid_points: Grid-point indices to be caclculated on
sigmas:
A set of sigmas. simga=None means to use tetrahedron method,
otherwise smearing method with real positive value of sigma.
frequency_step: Pitch of frequency to be sampled.
num_frequency_points: Number of sampling sampling points to be used
instead of frequency_step.
temperatures: Temperatures to be calculated at.
scattering_event_class:
Extract scattering event class 1 or 2. This can be enabled only when
run_with_g is True.
run_with_g:
Integration weigths are calculated from gaussian smearing function.
More memory space is required, but a consistent routine can be used
both in tetrahedron method and smearing method.
log_level: Log level. 0 or non 0 in this method.
Returns:
Tuple: (Imaginary part of self energy, sampling frequency points)
"""
if temperatures is None:
temperatures = [0.0, 300.0]
if temperatures is None:
print("Temperatures have to be set.")
return False
mesh = interaction.get_mesh_numbers()
ise = ImagSelfEnergy(interaction, with_detail=write_detail)
imag_self_energy = []
frequency_points = []
for i, gp in enumerate(grid_points):
ise.set_grid_point(gp)
if log_level:
weights = interaction.get_triplets_at_q()[1]
print("------------------- Imaginary part of self energy (%d/%d) "
"-------------------" % (i + 1, len(grid_points)))
print("Grid point: %d" % gp)
print("Number of ir-triplets: "
"%d / %d" % (len(weights), weights.sum()))
ise.run_interaction()
frequencies = interaction.get_phonons()[0]
max_phonon_freq = np.amax(frequencies)
if log_level:
adrs = interaction.get_grid_address()[gp]
q = adrs.astype('double') / mesh
print("q-point: %s" % q)
print("Phonon frequency:")
text = "[ "
for i, freq in enumerate(frequencies[gp]):
if i % 6 == 0 and i != 0:
text += "\n"
text += "%8.4f " % freq
text += "]"
print(text)
gamma_sigmas = []
fp_sigmas = []
if write_detail:
triplets, weights, _, _ = interaction.get_triplets_at_q()
for j, sigma in enumerate(sigmas):
if log_level:
if sigma:
print("Sigma: %s" % sigma)
else:
print("Tetrahedron method")
ise.set_sigma(sigma)
if sigma:
fmax = max_phonon_freq * 2 + sigma * 4
else:
fmax = max_phonon_freq * 2
fmax *= 1.005
fmin = 0
frequency_points_at_sigma = get_frequency_points(
fmin,
fmax,
frequency_step=frequency_step,
num_frequency_points=num_frequency_points)
fp_sigmas.append(frequency_points_at_sigma)
gamma = np.zeros(
(len(temperatures), len(frequency_points_at_sigma),
len(interaction.get_band_indices())), dtype='double')
if write_detail:
num_band0 = len(interaction.get_band_indices())
num_band = frequencies.shape[1]
detailed_gamma = np.zeros(
(len(temperatures), len(frequency_points_at_sigma),
num_band0, num_band, num_band, len(weights)),
dtype='double')
for k, freq_point in enumerate(frequency_points_at_sigma):
ise.set_frequency_points([freq_point])
if sigma is None or run_with_g:
ise.set_integration_weights(
scattering_event_class=scattering_event_class)
for l, t in enumerate(temperatures):
ise.set_temperature(t)
ise.run()
gamma[l, k] = ise.get_imag_self_energy()[0]
if write_detail:
detailed_gamma[l, k] = np.transpose(
ise.get_detailed_imag_self_energy()[0],
axes=(1, 2, 3, 0))
gamma_sigmas.append(gamma)
if write_detail:
filename = write_gamma_detail_to_hdf5(
detailed_gamma,
temperatures,
mesh,
gp,
sigma,
triplets,
weights,
frequency_points=frequency_points_at_sigma)
if log_level:
print("Contribution of each triplet to imaginary part of "
"self energy is written in\n\"%s\"." % filename)
imag_self_energy.append(gamma_sigmas)
frequency_points.append(fp_sigmas)
return imag_self_energy, frequency_points
def get_frequency_points(f_min,
f_max,
frequency_step=None,
num_frequency_points=None):
if num_frequency_points is None:
if frequency_step is not None:
frequency_points = np.arange(
f_min, f_max, frequency_step, dtype='double')
else:
frequency_points = np.array(np.linspace(
f_min, f_max, 201), dtype='double')
else:
frequency_points = np.array(np.linspace(
f_min, f_max, num_frequency_points), dtype='double')
return frequency_points
def get_linewidth(interaction,
grid_points,
sigmas,
temperatures=np.arange(0, 1001, 10, dtype='double'),
run_with_g=True,
write_detail=False,
log_level=0):
ise = ImagSelfEnergy(interaction, with_detail=write_detail)
band_indices = interaction.get_band_indices()
mesh = interaction.get_mesh_numbers()
gamma = np.zeros(
(len(grid_points), len(sigmas), len(temperatures), len(band_indices)),
dtype='double')
for i, gp in enumerate(grid_points):
ise.set_grid_point(gp)
if log_level:
weights = interaction.get_triplets_at_q()[1]
print("------ Linewidth ------")
print("Grid point: %d" % gp)
print("Number of ir-triplets: "
"%d / %d" % (len(weights), weights.sum()))
ise.run_interaction()
frequencies = interaction.get_phonons()[0]
if log_level:
adrs = interaction.get_grid_address()[gp]
q = adrs.astype('double') / mesh
print("q-point: %s" % q)
print("Phonon frequency:")
print("%s" % frequencies[gp])
if write_detail:
triplets, weights, _, _ = interaction.get_triplets_at_q()
for j, sigma in enumerate(sigmas):
if log_level:
if sigma:
print("Sigma: %s" % sigma)
else:
print("Tetrahedron method")
ise.set_sigma(sigma)
if sigma is None or run_with_g:
ise.set_integration_weights()
if write_detail:
num_band0 = len(interaction.get_band_indices())
num_band = frequencies.shape[1]
num_temp = len(temperatures)
detailed_gamma = np.zeros(
(num_temp, num_band0, num_band, num_band, len(weights)),
dtype='double')
for k, t in enumerate(temperatures):
ise.set_temperature(t)
ise.run()
gamma[i, j, k] = ise.get_imag_self_energy()
if write_detail:
detailed_gamma[k] = np.transpose(
ise.get_detailed_imag_self_energy(),
axes=(1, 2, 3, 0))
if write_detail:
filename = write_gamma_detail_to_hdf5(
detailed_gamma,
temperatures,
mesh,
gp,
sigma,
triplets,
weights)
if log_level:
print("Contribution of each triplet to imaginary part of "
"self energy is written in\n\"%s\"." % filename)
return gamma
def write_linewidth(linewidth,
band_indices,
mesh,
grid_points,
sigmas,
temperatures,
filename=None,
is_mesh_symmetry=True):
for i, gp in enumerate(grid_points):
for j, sigma in enumerate(sigmas):
for k, bi in enumerate(band_indices):
pos = 0
for l in range(k):
pos += len(band_indices[l])
write_linewidth_at_grid_point(
gp,
bi,
temperatures,
linewidth[i, j, :, pos:(pos+len(bi))],
mesh,
sigma=sigma,
filename=filename,
is_mesh_symmetry=is_mesh_symmetry)
def write_imag_self_energy(imag_self_energy,
mesh,
grid_points,
band_indices,
frequency_points,
temperatures,
sigmas,
scattering_event_class=None,
filename=None,
is_mesh_symmetry=True):
for gp, ise_sigmas, fp_sigmas in zip(grid_points,
imag_self_energy,
frequency_points):
for sigma, ise_temps, fp in zip(sigmas, ise_sigmas, fp_sigmas):
for t, ise in zip(temperatures, ise_temps):
for i, bi in enumerate(band_indices):
pos = 0
for j in range(i):
pos += len(band_indices[j])
write_imag_self_energy_at_grid_point(
gp,
bi,
mesh,
fp,
ise[:, pos:(pos + len(bi))].sum(axis=1) / len(bi),
sigma=sigma,
temperature=t,
scattering_event_class=scattering_event_class,
filename=filename,
is_mesh_symmetry=is_mesh_symmetry)
class ImagSelfEnergy(object):
def __init__(self,
interaction,
frequency_points=None,
temperature=None,
sigma=None,
with_detail=False,
unit_conversion=None,
lang='C'):
self._pp = interaction
self._sigma = None
self.set_sigma(sigma)
self._temperature = None
self.set_temperature(temperature)
self._frequency_points = None
self.set_frequency_points(frequency_points)
self._grid_point = None
self._lang = lang
self._imag_self_energy = None
self._detailed_imag_self_energy = None
self._pp_strength = None
self._frequencies = None
self._triplets_at_q = None
self._weights_at_q = None
self._with_detail = with_detail
self._unit_conversion = None
self._cutoff_frequency = interaction.get_cutoff_frequency()
self._g = None # integration weights
self._g_zero = None
self._mesh = self._pp.get_mesh_numbers()
self._band_indices = self._pp.get_band_indices()
self._is_collision_matrix = False
# Unit to THz of Gamma
if unit_conversion is None:
self._unit_conversion = (18 * np.pi / (Hbar * EV) ** 2
/ (2 * np.pi * THz) ** 2
* EV ** 2)
else:
self._unit_conversion = unit_conversion
def run(self):
if self._pp_strength is None:
self.run_interaction()
num_band0 = self._pp_strength.shape[1]
if self._frequency_points is None:
self._imag_self_energy = np.zeros(num_band0, dtype='double')
if self._with_detail:
self._detailed_imag_self_energy = np.zeros_like(
self._pp_strength)
self._run_with_band_indices()
else:
self._imag_self_energy = np.zeros(
(len(self._frequency_points), num_band0), dtype='double')
if self._with_detail:
self._detailed_imag_self_energy = np.zeros(
(len(self._frequency_points),) + self._pp_strength.shape,
dtype='double')
self._run_with_frequency_points()
def run_interaction(self, is_full_pp=True):
if is_full_pp or self._frequency_points is not None:
self._pp.run(lang=self._lang)
else:
self._pp.run(g_zero=self._g_zero, lang=self._lang)
self._pp_strength = self._pp.get_interaction_strength()
def set_integration_weights(self, scattering_event_class=None):
if self._frequency_points is None:
f_points = self._frequencies[self._grid_point][self._band_indices]
else:
f_points = self._frequency_points
self._g, _g_zero = get_triplets_integration_weights(
self._pp,
np.array(f_points, dtype='double'),
self._sigma,
is_collision_matrix=self._is_collision_matrix)
if self._frequency_points is None:
self._g_zero = _g_zero
if scattering_event_class == 1 or scattering_event_class == 2:
self._g[scattering_event_class - 1] = 0
def get_imag_self_energy(self):
if self._cutoff_frequency is None:
return self._imag_self_energy
# Averaging imag-self-energies by degenerate bands
imag_se = np.zeros_like(self._imag_self_energy)
freqs = self._frequencies[self._grid_point]
deg_sets = degenerate_sets(freqs)
for dset in deg_sets:
bi_set = []
for i, bi in enumerate(self._band_indices):
if bi in dset:
bi_set.append(i)
for i in bi_set:
if self._frequency_points is None:
imag_se[i] = (self._imag_self_energy[bi_set].sum() /
len(bi_set))
else:
imag_se[:, i] = (
self._imag_self_energy[:, bi_set].sum(axis=1) /
len(bi_set))
return imag_se
def get_detailed_imag_self_energy(self):
return self._detailed_imag_self_energy
def set_grid_point(self, grid_point=None):
if grid_point is None:
self._grid_point = None
else:
self._pp.set_grid_point(grid_point)
self._pp_strength = None
(self._triplets_at_q,
self._weights_at_q) = self._pp.get_triplets_at_q()[:2]
self._grid_point = grid_point
self._frequencies, self._eigenvectors, _ = self._pp.get_phonons()
def set_sigma(self, sigma):
if sigma is None:
self._sigma = None
else:
self._sigma = float(sigma)
self._g = None
self._g_zero = None
def set_frequency_points(self, frequency_points):
if frequency_points is None:
self._frequency_points = None
else:
self._frequency_points = np.array(frequency_points, dtype='double')
def set_temperature(self, temperature):
if temperature is None:
self._temperature = None
else:
self._temperature = float(temperature)
def set_averaged_pp_interaction(self, ave_pp):
self._pp.set_phonons(self._triplets_at_q.ravel())
(self._frequencies,
self._eigenvectors) = self._pp.get_phonons()[:2]
num_triplets = len(self._triplets_at_q)
num_band = self._pp.get_primitive().get_number_of_atoms() * 3
num_grid = np.prod(self._mesh)
self._pp_strength = np.zeros(
(num_triplets, len(self._band_indices), num_band, num_band),
dtype='double')
for i, v_ave in enumerate(ave_pp):
self._pp_strength[:, i, :, :] = v_ave / num_grid
def _run_with_band_indices(self):
if self._g is not None:
if self._lang == 'C':
self._run_c_with_band_indices_with_g()
if self._with_detail:
self._run_c_detailed_with_band_indices_with_g()
else:
self._run_py_with_band_indices_with_g()
else:
if self._lang == 'C':
self._run_c_with_band_indices()
else:
self._run_py_with_band_indices()
def _run_with_frequency_points(self):
if self._g is not None:
if self._lang == 'C':
self._run_c_with_frequency_points_with_g()
if self._with_detail:
self._run_c_detailed_with_frequency_points_with_g()
else:
self._run_py_with_frequency_points_with_g()
else:
if self._lang == 'C':
self._run_c_with_frequency_points()
else:
self._run_py_with_frequency_points()
def _run_c_with_band_indices(self):
import anharmonic._phono3py as phono3c
phono3c.imag_self_energy_at_bands(self._imag_self_energy,
self._pp_strength,
self._triplets_at_q,
self._weights_at_q,
self._frequencies,
self._band_indices,
self._temperature,
self._sigma,
self._unit_conversion,
self._cutoff_frequency)
def _run_c_with_band_indices_with_g(self):
import anharmonic._phono3py as phono3c
if self._g_zero is None:
_g_zero = np.zeros(self._pp_strength.shape,
dtype='byte', order='C')
else:
_g_zero = self._g_zero
phono3c.imag_self_energy_with_g(self._imag_self_energy,
self._pp_strength,
self._triplets_at_q,
self._weights_at_q,
self._frequencies,
self._temperature,
self._g,
_g_zero,
self._unit_conversion,
self._cutoff_frequency)
def _run_c_detailed_with_band_indices_with_g(self):
import anharmonic._phono3py as phono3c
phono3c.detailed_imag_self_energy_with_g(
self._detailed_imag_self_energy,
self._pp_strength,
self._triplets_at_q,
self._frequencies,
self._temperature,
self._g,
self._unit_conversion,
self._cutoff_frequency)
def _run_c_with_frequency_points(self):
import anharmonic._phono3py as phono3c
ise_at_f = np.zeros(self._imag_self_energy.shape[1], dtype='double')
for i, fpoint in enumerate(self._frequency_points):
phono3c.imag_self_energy(ise_at_f,
self._pp_strength,
self._triplets_at_q,
self._weights_at_q,
self._frequencies,
fpoint,
self._temperature,
self._sigma,
self._unit_conversion,
self._cutoff_frequency)
self._imag_self_energy[i] = ise_at_f
def _run_c_with_frequency_points_with_g(self):
import anharmonic._phono3py as phono3c
num_band0 = self._pp_strength.shape[1]
g_shape = list(self._g.shape)
g_shape[2] = num_band0
g = np.zeros(tuple(g_shape), dtype='double', order='C')
ise_at_f = np.zeros(num_band0, dtype='double')
_g_zero = np.zeros(g_shape, dtype='byte', order='C')
for i in range(len(self._frequency_points)):
for j in range(num_band0):
g[:, :, j, :, :] = self._g[:, :, i, :, :]
phono3c.imag_self_energy_with_g(ise_at_f,
self._pp_strength,
self._triplets_at_q,
self._weights_at_q,
self._frequencies,
self._temperature,
g,
_g_zero, # don't use g_zero
self._unit_conversion,
self._cutoff_frequency)
self._imag_self_energy[i] = ise_at_f
def _run_c_detailed_with_frequency_points_with_g(self):
import anharmonic._phono3py as phono3c
g = np.zeros((2,) + self._pp_strength.shape, dtype='double')
detailed_ise_at_f = np.zeros(self._detailed_imag_self_energy.shape[1:5],
dtype='double')
for i in range(len(self._frequency_points)):
for j in range(g.shape[2]):
g[:, :, j, :, :] = self._g[:, :, i, :, :]
phono3c.detailed_imag_self_energy_with_g(detailed_ise_at_f,
self._pp_strength,
self._triplets_at_q,
self._frequencies,
self._temperature,
g,
self._unit_conversion,
self._cutoff_frequency)
self._detailed_imag_self_energy[i] = detailed_ise_at_f
def _run_py_with_band_indices(self):
for i, (triplet, w, interaction) in enumerate(
zip(self._triplets_at_q,
self._weights_at_q,
self._pp_strength)):
print("%d / %d" % (i + 1, len(self._triplets_at_q)))
freqs = self._frequencies[triplet]
for j, bi in enumerate(self._band_indices):
if self._temperature > 0:
self._imag_self_energy[j] += (
self._ise_at_bands(j, bi, freqs, interaction, w))
else:
self._imag_self_energy[j] += (
self._ise_at_bands_0K(j, bi, freqs, interaction, w))
self._imag_self_energy *= self._unit_conversion
def _ise_at_bands(self, i, bi, freqs, interaction, weight):
sum_g = 0
for (j, k) in list(np.ndindex(interaction.shape[1:])):
if (freqs[1][j] > self._cutoff_frequency and
freqs[2][k] > self._cutoff_frequency):
n2 = occupation(freqs[1][j], self._temperature)
n3 = occupation(freqs[2][k], self._temperature)
g1 = gaussian(freqs[0, bi] - freqs[1, j] - freqs[2, k],
self._sigma)
g2 = gaussian(freqs[0, bi] + freqs[1, j] - freqs[2, k],
self._sigma)
g3 = gaussian(freqs[0, bi] - freqs[1, j] + freqs[2, k],
self._sigma)
sum_g += ((n2 + n3 + 1) * g1 +
(n2 - n3) * (g2 - g3)) * interaction[i, j, k] * weight
return sum_g
def _ise_at_bands_0K(self, i, bi, freqs, interaction, weight):
sum_g = 0
for (j, k) in list(np.ndindex(interaction.shape[1:])):
g1 = gaussian(freqs[0, bi] - freqs[1, j] - freqs[2, k],
self._sigma)
sum_g += g1 * interaction[i, j, k] * weight
return sum_g
def _run_py_with_band_indices_with_g(self):
if self._temperature > 0:
self._ise_thm_with_band_indices()
else:
self._ise_thm_with_band_indices_0K()
def _ise_thm_with_band_indices(self):
freqs = self._frequencies[self._triplets_at_q[:, [1, 2]]]
freqs = np.where(freqs > self._cutoff_frequency, freqs, 1)
n = occupation(freqs, self._temperature)
for i, (tp, w, interaction) in enumerate(zip(self._triplets_at_q,
self._weights_at_q,
self._pp_strength)):
for j, k in list(np.ndindex(interaction.shape[1:])):
f1 = self._frequencies[tp[1]][j]
f2 = self._frequencies[tp[2]][k]
if (f1 > self._cutoff_frequency and
f2 > self._cutoff_frequency):
n2 = n[i, 0, j]
n3 = n[i, 1, k]
g1 = self._g[0, i, :, j, k]
g2_g3 = self._g[1, i, :, j, k] # g2 - g3
self._imag_self_energy[:] += (
(n2 + n3 + 1) * g1 +
(n2 - n3) * (g2_g3)) * interaction[:, j, k] * w
self._imag_self_energy *= self._unit_conversion
def _ise_thm_with_band_indices_0K(self):
for i, (w, interaction) in enumerate(zip(self._weights_at_q,
self._pp_strength)):
for j, k in list(np.ndindex(interaction.shape[1:])):
g1 = self._g[0, i, :, j, k]
self._imag_self_energy[:] += g1 * interaction[:, j, k] * w
self._imag_self_energy *= self._unit_conversion
def _run_py_with_frequency_points(self):
for i, (triplet, w, interaction) in enumerate(
zip(self._triplets_at_q,
self._weights_at_q,
self._pp_strength)):
print("%d / %d" % (i + 1, len(self._triplets_at_q)))
# freqs[2, num_band]
freqs = self._frequencies[triplet[1:]]
if self._temperature > 0:
self._ise_with_frequency_points(freqs, interaction, w)
else:
self._ise_with_frequency_points_0K(freqs, interaction, w)
self._imag_self_energy *= self._unit_conversion
def _ise_with_frequency_points(self, freqs, interaction, weight):
for j, k in list(np.ndindex(interaction.shape[1:])):
if (freqs[0][j] > self._cutoff_frequency and
freqs[1][k] > self._cutoff_frequency):
n2 = occupation(freqs[0][j], self._temperature)
n3 = occupation(freqs[1][k], self._temperature)
g1 = gaussian(self._frequency_points
- freqs[0][j] - freqs[1][k], self._sigma)
g2 = gaussian(self._frequency_points
+ freqs[0][j] - freqs[1][k], self._sigma)
g3 = gaussian(self._frequency_points
- freqs[0][j] + freqs[1][k], self._sigma)
else:
continue
for i in range(len(interaction)):
self._imag_self_energy[:, i] += (
(n2 + n3 + 1) * g1 +
(n2 - n3) * (g2 - g3)) * interaction[i, j, k] * weight
def _ise_with_frequency_points_0K(self, freqs, interaction, weight):
for (i, j, k) in list(np.ndindex(interaction.shape)):
g1 = gaussian(self._frequency_points - freqs[0][j] - freqs[1][k],
self._sigma)
self._imag_self_energy[:, i] += g1 * interaction[i, j, k] * weight
def _run_py_with_frequency_points_with_g(self):
if self._temperature > 0:
self._ise_thm_with_frequency_points()
else:
self._ise_thm_with_frequency_points_0K()
def _ise_thm_with_frequency_points(self):
for i, (tp, w, interaction) in enumerate(zip(self._triplets_at_q,
self._weights_at_q,
self._pp_strength)):
for j, k in list(np.ndindex(interaction.shape[1:])):
f1 = self._frequencies[tp[1]][j]
f2 = self._frequencies[tp[2]][k]
if (f1 > self._cutoff_frequency and
f2 > self._cutoff_frequency):
n2 = occupation(f1, self._temperature)
n3 = occupation(f2, self._temperature)
g1 = self._g[0, i, :, j, k]
g2_g3 = self._g[1, i, :, j, k] # g2 - g3
for l in range(len(interaction)):
self._imag_self_energy[:, l] += (
(n2 + n3 + 1) * g1 +
(n2 - n3) * (g2_g3)) * interaction[l, j, k] * w
self._imag_self_energy *= self._unit_conversion
def _ise_thm_with_frequency_points_0K(self):
for i, (w, interaction) in enumerate(zip(self._weights_at_q,
self._pp_strength)):
for j, k in list(np.ndindex(interaction.shape[1:])):
g1 = self._g[0, i, :, j, k]
for l in range(len(interaction)):
self._imag_self_energy[:, l] += g1 * interaction[l, j, k] * w
self._imag_self_energy *= self._unit_conversion

View File

@ -1,332 +0,0 @@
import numpy as np
from phonopy.phonon.solver import set_phonon_c, set_phonon_py
from phonopy.harmonic.dynamical_matrix import (get_smallest_vectors,
get_dynamical_matrix)
from phonopy.units import VaspToTHz, Hbar, EV, Angstrom, THz, AMU, PlanckConstant
from anharmonic.phonon3.real_to_reciprocal import RealToReciprocal
from anharmonic.phonon3.reciprocal_to_normal import ReciprocalToNormal
from anharmonic.phonon3.triplets import (get_triplets_at_q,
get_nosym_triplets_at_q,
get_bz_grid_address)
class Interaction(object):
def __init__(self,
supercell,
primitive,
mesh,
symmetry,
fc3=None,
band_indices=None,
constant_averaged_interaction=None,
frequency_factor_to_THz=VaspToTHz,
unit_conversion=None,
is_mesh_symmetry=True,
symmetrize_fc3_q=False,
cutoff_frequency=None,
lapack_zheev_uplo='L'):
self._fc3 = fc3
self._supercell = supercell
self._primitive = primitive
self._mesh = np.array(mesh, dtype='intc')
self._symmetry = symmetry
self._band_indices = None
self.set_band_indices(band_indices)
self._constant_averaged_interaction = constant_averaged_interaction
self._frequency_factor_to_THz = frequency_factor_to_THz
# Unit to eV^2
if unit_conversion is None:
num_grid = np.prod(self._mesh)
self._unit_conversion = ((Hbar * EV) ** 3 / 36 / 8
* EV ** 2 / Angstrom ** 6
/ (2 * np.pi * THz) ** 3
/ AMU ** 3 / num_grid
/ EV ** 2)
else:
self._unit_conversion = unit_conversion
if cutoff_frequency is None:
self._cutoff_frequency = 0
else:
self._cutoff_frequency = cutoff_frequency
self._is_mesh_symmetry = is_mesh_symmetry
self._symmetrize_fc3_q = symmetrize_fc3_q
self._lapack_zheev_uplo = lapack_zheev_uplo
self._symprec = symmetry.get_symmetry_tolerance()
self._grid_point = None
self._triplets_at_q = None
self._weights_at_q = None
self._triplets_map_at_q = None
self._ir_map_at_q = None
self._grid_address = None
self._bz_map = None
self._interaction_strength = None
self._phonon_done = None
self._frequencies = None
self._eigenvectors = None
self._dm = None
self._nac_q_direction = None
self._allocate_phonon()
def run(self, g_zero=None, lang='C'):
num_band = self._primitive.get_number_of_atoms() * 3
num_triplets = len(self._triplets_at_q)
if self._constant_averaged_interaction is None:
self._interaction_strength = np.zeros(
(num_triplets, len(self._band_indices), num_band, num_band),
dtype='double')
if lang == 'C':
self._run_c(g_zero=g_zero)
else:
self._run_py()
else:
num_grid = np.prod(self._mesh)
self._interaction_strength = np.ones(
(num_triplets, len(self._band_indices), num_band, num_band),
dtype='double') * self._constant_averaged_interaction / num_grid
def get_interaction_strength(self):
return self._interaction_strength
def get_mesh_numbers(self):
return self._mesh
def get_phonons(self):
return self._frequencies, self._eigenvectors, self._phonon_done
def get_dynamical_matrix(self):
return self._dm
def get_primitive(self):
return self._primitive
def get_triplets_at_q(self):
return (self._triplets_at_q,
self._weights_at_q,
self._triplets_map_at_q,
self._ir_map_at_q)
def get_grid_address(self):
return self._grid_address
def get_bz_map(self):
return self._bz_map
def get_band_indices(self):
return self._band_indices
def set_band_indices(self, band_indices):
num_band = self._primitive.get_number_of_atoms() * 3
if band_indices is None:
self._band_indices = np.arange(num_band, dtype='intc')
else:
self._band_indices = np.array(band_indices, dtype='intc')
def get_frequency_factor_to_THz(self):
return self._frequency_factor_to_THz
def get_lapack_zheev_uplo(self):
return self._lapack_zheev_uplo
def get_cutoff_frequency(self):
return self._cutoff_frequency
def set_grid_point(self, grid_point, stores_triplets_map=False):
reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
if not self._is_mesh_symmetry:
(triplets_at_q,
weights_at_q,
grid_address,
bz_map,
triplets_map_at_q,
ir_map_at_q) = get_nosym_triplets_at_q(
grid_point,
self._mesh,
reciprocal_lattice,
stores_triplets_map=stores_triplets_map)
else:
(triplets_at_q,
weights_at_q,
grid_address,
bz_map,
triplets_map_at_q,
ir_map_at_q)= get_triplets_at_q(
grid_point,
self._mesh,
self._symmetry.get_pointgroup_operations(),
reciprocal_lattice,
stores_triplets_map=stores_triplets_map)
for triplet in triplets_at_q:
sum_q = (grid_address[triplet]).sum(axis=0)
if (sum_q % self._mesh != 0).any():
print("============= Warning ==================")
print("%s" % triplet)
for tp in triplet:
print("%s %s" %
(grid_address[tp],
np.linalg.norm(
np.dot(reciprocal_lattice,
grid_address[tp] /
self._mesh.astype('double')))))
print("%s" % sum_q)
print("============= Warning ==================")
self._grid_point = grid_point
self._triplets_at_q = triplets_at_q
self._weights_at_q = weights_at_q
self._triplets_map_at_q = triplets_map_at_q
self._grid_address = grid_address
self._bz_map = bz_map
self._ir_map_at_q = ir_map_at_q
self.set_phonons(self._triplets_at_q.ravel())
def set_dynamical_matrix(self,
fc2,
supercell,
primitive,
nac_params=None,
frequency_scale_factor=None,
decimals=None):
self._dm = get_dynamical_matrix(
fc2,
supercell,
primitive,
nac_params=nac_params,
frequency_scale_factor=frequency_scale_factor,
decimals=decimals,
symprec=self._symprec)
def set_nac_q_direction(self, nac_q_direction=None):
if nac_q_direction is not None:
self._nac_q_direction = np.array(nac_q_direction, dtype='double')
def set_phonon_data(self, frequencies, eigenvectors, grid_address):
if grid_address.shape != self._grid_address.shape:
print("=" * 26 + " Warning " + "=" * 26)
print("Input grid address size is inconsistent. "
"Setting phonons faild.")
print("=" * 26 + " Warning " + "=" * 26)
return False
if (self._grid_address - grid_address).all():
print("=" * 26 + " Warning " + "=" * 26)
print("Input grid addresses are inconsistent. "
"Setting phonons faild.")
print("=" * 26 + " Warning " + "=" * 26)
return False
else:
self._phonon_done[:] = 1
self._frequencies[:] = frequencies
self._eigenvectors[:] = eigenvectors
return True
def set_phonons(self, grid_points):
# for i, grid_triplet in enumerate(self._triplets_at_q):
# for gp in grid_triplet:
# self._set_phonon_py(gp)
self._set_phonon_c(grid_points)
def get_averaged_interaction(self):
v = self._interaction_strength
w = self._weights_at_q
v_sum = v.sum(axis=2).sum(axis=2)
num_band = self._primitive.get_number_of_atoms() * 3
return np.dot(w, v_sum) / num_band ** 2
def _run_c(self, g_zero=None):
import anharmonic._phono3py as phono3c
num_band = self._primitive.get_number_of_atoms() * 3
svecs, multiplicity = get_smallest_vectors(self._supercell,
self._primitive,
self._symprec)
masses = np.array(self._primitive.get_masses(), dtype='double')
p2s = self._primitive.get_primitive_to_supercell_map()
s2p = self._primitive.get_supercell_to_primitive_map()
if g_zero is None:
_g_zero = np.zeros(self._interaction_strength.shape,
dtype='byte', order='C')
else:
_g_zero = g_zero
phono3c.interaction(self._interaction_strength,
_g_zero,
self._frequencies,
self._eigenvectors,
self._triplets_at_q,
self._grid_address,
self._mesh,
self._fc3,
svecs,
multiplicity,
masses,
p2s,
s2p,
self._band_indices,
self._symmetrize_fc3_q,
self._cutoff_frequency)
self._interaction_strength *= self._unit_conversion
def _set_phonon_c(self, grid_points):
set_phonon_c(self._dm,
self._frequencies,
self._eigenvectors,
self._phonon_done,
grid_points,
self._grid_address,
self._mesh,
self._frequency_factor_to_THz,
self._nac_q_direction,
self._lapack_zheev_uplo)
def _run_py(self):
r2r = RealToReciprocal(self._fc3,
self._supercell,
self._primitive,
self._mesh,
symprec=self._symprec)
r2n = ReciprocalToNormal(self._primitive,
self._frequencies,
self._eigenvectors,
self._band_indices,
cutoff_frequency=self._cutoff_frequency)
for i, grid_triplet in enumerate(self._triplets_at_q):
print("%d / %d" % (i + 1, len(self._triplets_at_q)))
r2r.run(self._grid_address[grid_triplet])
fc3_reciprocal = r2r.get_fc3_reciprocal()
for gp in grid_triplet:
self._set_phonon_py(gp)
r2n.run(fc3_reciprocal, grid_triplet)
self._interaction_strength[i] = np.abs(
r2n.get_reciprocal_to_normal()) ** 2 * self._unit_conversion
def _set_phonon_py(self, grid_point):
set_phonon_py(grid_point,
self._phonon_done,
self._frequencies,
self._eigenvectors,
self._grid_address,
self._mesh,
self._dm,
self._frequency_factor_to_THz,
self._lapack_zheev_uplo)
def _allocate_phonon(self):
primitive_lattice = np.linalg.inv(self._primitive.get_cell())
self._grid_address, self._bz_map = get_bz_grid_address(
self._mesh, primitive_lattice, with_boundary=True)
num_band = self._primitive.get_number_of_atoms() * 3
num_grid = len(self._grid_address)
self._phonon_done = np.zeros(num_grid, dtype='byte')
self._frequencies = np.zeros((num_grid, num_band), dtype='double')
itemsize = self._frequencies.itemsize
self._eigenvectors = np.zeros((num_grid, num_band, num_band),
dtype=("c%d" % (itemsize * 2)))

View File

@ -1,290 +0,0 @@
import sys
import numpy as np
from phonopy.structure.symmetry import Symmetry
from phonopy.units import VaspToTHz
from anharmonic.phonon3.triplets import (get_triplets_at_q,
get_nosym_triplets_at_q,
get_tetrahedra_vertices,
get_triplets_integration_weights,
occupation)
from anharmonic.phonon3.interaction import set_phonon_c
from anharmonic.phonon3.imag_self_energy import get_frequency_points
from phonopy.harmonic.dynamical_matrix import get_dynamical_matrix
from phonopy.structure.tetrahedron_method import TetrahedronMethod
class JointDos(object):
def __init__(self,
mesh,
primitive,
supercell,
fc2,
nac_params=None,
nac_q_direction=None,
sigma=None,
cutoff_frequency=None,
frequency_step=None,
num_frequency_points=None,
temperatures=None,
frequency_factor_to_THz=VaspToTHz,
frequency_scale_factor=1.0,
is_mesh_symmetry=True,
symprec=1e-5,
filename=None,
log_level=False,
lapack_zheev_uplo='L'):
self._grid_point = None
self._mesh = np.array(mesh, dtype='intc')
self._primitive = primitive
self._supercell = supercell
self._fc2 = fc2
self._nac_params = nac_params
self._nac_q_direction = None
self.set_nac_q_direction(nac_q_direction)
self._sigma = None
self.set_sigma(sigma)
if cutoff_frequency is None:
self._cutoff_frequency = 0
else:
self._cutoff_frequency = cutoff_frequency
self._frequency_step = frequency_step
self._num_frequency_points = num_frequency_points
self._temperatures = temperatures
self._frequency_factor_to_THz = frequency_factor_to_THz
self._frequency_scale_factor = frequency_scale_factor
self._is_mesh_symmetry = is_mesh_symmetry
self._symprec = symprec
self._filename = filename
self._log_level = log_level
self._lapack_zheev_uplo = lapack_zheev_uplo
self._num_band = self._primitive.get_number_of_atoms() * 3
self._reciprocal_lattice = np.linalg.inv(self._primitive.get_cell())
self._set_dynamical_matrix()
self._symmetry = Symmetry(primitive, symprec)
self._tetrahedron_method = None
self._phonon_done = None
self._frequencies = None
self._eigenvectors = None
self._joint_dos = None
self._frequency_points = None
def run(self):
try:
import anharmonic._phono3py as phono3c
self._run_c()
except ImportError:
print("Joint density of states in python is not implemented.")
return None, None
def get_joint_dos(self):
return self._joint_dos
def get_frequency_points(self):
return self._frequency_points
def get_phonons(self):
return self._frequencies, self._eigenvectors, self._phonon_done
def get_primitive(self):
return self._primitive
def get_mesh_numbers(self):
return self._mesh
def set_nac_q_direction(self, nac_q_direction=None):
if nac_q_direction is not None:
self._nac_q_direction = np.array(nac_q_direction, dtype='double')
def set_sigma(self, sigma):
if sigma is None:
self._sigma = None
else:
self._sigma = float(sigma)
def set_grid_point(self, grid_point):
self._grid_point = grid_point
self._set_triplets()
num_grid = np.prod(len(self._grid_address))
num_band = self._num_band
if self._phonon_done is None:
self._phonon_done = np.zeros(num_grid, dtype='byte')
self._frequencies = np.zeros((num_grid, num_band), dtype='double')
itemsize = self._frequencies.itemsize
self._eigenvectors = np.zeros((num_grid, num_band, num_band),
dtype=("c%d" % (itemsize * 2)))
self._joint_dos = None
self._frequency_points = None
self.set_phonons(np.array([grid_point], dtype='intc'))
def get_triplets_at_q(self):
return self._triplets_at_q, self._weights_at_q
def get_grid_address(self):
return self._grid_address
def get_bz_map(self):
return self._bz_map
def _run_c(self, lang='C'):
if self._sigma is None:
if lang == 'C':
self._run_c_with_g()
else:
if self._temperatures is not None:
print("JDOS with phonon occupation numbers doesn't work "
"in this option.")
self._run_py_tetrahedron_method()
else:
self._run_c_with_g()
def _run_c_with_g(self):
self.set_phonons(self._triplets_at_q.ravel())
if self._sigma is None:
f_max = np.max(self._frequencies) * 2
else:
f_max = np.max(self._frequencies) * 2 + self._sigma * 4
f_max *= 1.005
f_min = 0
self._set_uniform_frequency_points(f_min, f_max)
num_freq_points = len(self._frequency_points)
num_mesh = np.prod(self._mesh)
if self._temperatures is None:
jdos = np.zeros((num_freq_points, 2), dtype='double')
else:
num_temps = len(self._temperatures)
jdos = np.zeros((num_temps, num_freq_points, 2), dtype='double')
occ_phonons = []
for t in self._temperatures:
freqs = self._frequencies[self._triplets_at_q[:, 1:]]
occ_phonons.append(np.where(freqs > self._cutoff_frequency,
occupation(freqs, t), 0))
for i, freq_point in enumerate(self._frequency_points):
g, _ = get_triplets_integration_weights(
self,
np.array([freq_point], dtype='double'),
self._sigma,
is_collision_matrix=True,
neighboring_phonons=(i == 0))
if self._temperatures is None:
jdos[i, 1] = np.sum(
np.tensordot(g[0, :, 0], self._weights_at_q, axes=(0, 0)))
gx = g[2] - g[0]
jdos[i, 0] = np.sum(
np.tensordot(gx[:, 0], self._weights_at_q, axes=(0, 0)))
else:
for j, n in enumerate(occ_phonons):
for k, l in list(np.ndindex(g.shape[3:])):
jdos[j, i, 1] += np.dot(
(n[:, 0, k] + n[:, 1, l] + 1) *
g[0, :, 0, k, l], self._weights_at_q)
jdos[j, i, 0] += np.dot((n[:, 0, k] - n[:, 1, l]) *
g[1, :, 0, k, l],
self._weights_at_q)
self._joint_dos = jdos / num_mesh
def _run_py_tetrahedron_method(self):
thm = TetrahedronMethod(self._reciprocal_lattice, mesh=self._mesh)
self._vertices = get_tetrahedra_vertices(
thm.get_tetrahedra(),
self._mesh,
self._triplets_at_q,
self._grid_address,
self._bz_map)
self.set_phonons(self._vertices.ravel())
f_max = np.max(self._frequencies) * 2
f_max *= 1.005
f_min = 0
self._set_uniform_frequency_points(f_min, f_max)
num_freq_points = len(self._frequency_points)
jdos = np.zeros((num_freq_points, 2), dtype='double')
for vertices, w in zip(self._vertices, self._weights_at_q):
for i, j in list(np.ndindex(self._num_band, self._num_band)):
f1 = self._frequencies[vertices[0], i]
f2 = self._frequencies[vertices[1], j]
thm.set_tetrahedra_omegas(f1 + f2)
thm.run(self._frequency_points)
iw = thm.get_integration_weight()
jdos[:, 1] += iw * w
thm.set_tetrahedra_omegas(f1 - f2)
thm.run(self._frequency_points)
iw = thm.get_integration_weight()
jdos[:, 0] += iw * w
thm.set_tetrahedra_omegas(-f1 + f2)
thm.run(self._frequency_points)
iw = thm.get_integration_weight()
jdos[:, 0] += iw * w
self._joint_dos = jdos / np.prod(self._mesh)
def _set_dynamical_matrix(self):
self._dm = get_dynamical_matrix(
self._fc2,
self._supercell,
self._primitive,
nac_params=self._nac_params,
frequency_scale_factor=self._frequency_scale_factor,
symprec=self._symprec)
def _set_triplets(self):
if not self._is_mesh_symmetry:
if self._log_level:
print("Triplets at q without considering symmetry")
sys.stdout.flush()
(self._triplets_at_q,
self._weights_at_q,
self._grid_address,
self._bz_map,
map_triplets,
map_q) = get_nosym_triplets_at_q(
self._grid_point,
self._mesh,
self._reciprocal_lattice,
with_bz_map=True)
else:
(self._triplets_at_q,
self._weights_at_q,
self._grid_address,
self._bz_map,
map_triplets,
map_q) = get_triplets_at_q(
self._grid_point,
self._mesh,
self._symmetry.get_pointgroup_operations(),
self._reciprocal_lattice)
def set_phonons(self, grid_points):
set_phonon_c(self._dm,
self._frequencies,
self._eigenvectors,
self._phonon_done,
grid_points,
self._grid_address,
self._mesh,
self._frequency_factor_to_THz,
self._nac_q_direction,
self._lapack_zheev_uplo)
def set_frequency_points(self, frequency_points):
self._frequency_points = np.array(frequency_points, dtype='double')
def _set_uniform_frequency_points(self, f_min, f_max):
if self._frequency_points is None:
self._frequency_points = get_frequency_points(
f_min,
f_max,
frequency_step=self._frequency_step,
num_frequency_points=self._num_frequency_points)

View File

@ -1,80 +0,0 @@
import numpy as np
from phonopy.harmonic.dynamical_matrix import get_smallest_vectors
class RealToReciprocal(object):
def __init__(self,
fc3,
supercell,
primitive,
mesh,
symprec=1e-5):
self._fc3 = fc3
self._supercell = supercell
self._primitive = primitive
self._mesh = mesh
self._symprec = symprec
num_satom = supercell.get_number_of_atoms()
self._p2s_map = primitive.get_primitive_to_supercell_map()
self._s2p_map = primitive.get_supercell_to_primitive_map()
# Reduce supercell atom index to primitive index
(self._smallest_vectors,
self._multiplicity) = get_smallest_vectors(supercell,
primitive,
symprec)
self._fc3_reciprocal = None
def run(self, triplet):
self._triplet = triplet
num_patom = self._primitive.get_number_of_atoms()
self._fc3_reciprocal = np.zeros(
(num_patom, num_patom, num_patom, 3, 3, 3), dtype='complex128')
self._real_to_reciprocal()
def get_fc3_reciprocal(self):
return self._fc3_reciprocal
def _real_to_reciprocal(self):
num_patom = self._primitive.get_number_of_atoms()
sum_triplets = np.where(
np.all(self._triplet != 0, axis=0), self._triplet.sum(axis=0), 0)
sum_q = sum_triplets.astype('double') / self._mesh
for i in range(num_patom):
for j in range(num_patom):
for k in range(num_patom):
self._fc3_reciprocal[
i, j, k] = self._real_to_reciprocal_elements((i, j, k))
prephase = self._get_prephase(sum_q, i)
self._fc3_reciprocal[i] *= prephase
def _real_to_reciprocal_elements(self, patom_indices):
num_satom = self._supercell.get_number_of_atoms()
pi = patom_indices
i = self._p2s_map[pi[0]]
fc3_reciprocal = np.zeros((3, 3, 3), dtype='complex128')
for j in range(num_satom):
if self._s2p_map[j] != self._p2s_map[pi[1]]:
continue
for k in range(num_satom):
if self._s2p_map[k] != self._p2s_map[pi[2]]:
continue
phase = self._get_phase((j, k), pi[0])
fc3_reciprocal += self._fc3[i, j, k] * phase
return fc3_reciprocal
def _get_prephase(self, sum_q, patom_index):
r = self._primitive.get_scaled_positions()[patom_index]
return np.exp(2j * np.pi * np.dot(sum_q, r))
def _get_phase(self, satom_indices, patom0_index):
si = satom_indices
p0 = patom0_index
phase = 1+0j
for i in (0, 1):
vs = self._smallest_vectors[si[i], p0,
:self._multiplicity[si[i], p0]]
phase *= (np.exp(2j * np.pi * np.dot(
vs, self._triplet[i + 1].astype('double') /
self._mesh)).sum() / self._multiplicity[si[i], p0])
return phase

View File

@ -1,60 +0,0 @@
import numpy as np
class ReciprocalToNormal(object):
def __init__(self,
primitive,
frequencies,
eigenvectors,
band_indices,
cutoff_frequency=0):
self._primitive = primitive
self._frequencies = frequencies
self._eigenvectors = eigenvectors
self._band_indices = band_indices
self._cutoff_frequency = cutoff_frequency
self._masses = self._primitive.get_masses()
self._fc3_normal = None
self._fc3_reciprocal = None
def run(self, fc3_reciprocal, grid_triplet):
num_band = self._primitive.get_number_of_atoms() * 3
self._fc3_reciprocal = fc3_reciprocal
self._fc3_normal = np.zeros(
(len(self._band_indices), num_band, num_band), dtype='complex128')
self._reciprocal_to_normal(grid_triplet)
def get_reciprocal_to_normal(self):
return self._fc3_normal
def _reciprocal_to_normal(self, grid_triplet):
e1, e2, e3 = self._eigenvectors[grid_triplet]
f1, f2, f3 = self._frequencies[grid_triplet]
num_band = len(f1)
cutoff = self._cutoff_frequency
for (i, j, k) in list(np.ndindex(
len(self._band_indices), num_band, num_band)):
bi = self._band_indices[i]
if f1[bi] > cutoff and f2[j] > cutoff and f3[k] > cutoff:
fc3_elem = self._sum_in_atoms((bi, j, k), (e1, e2, e3))
fff = np.sqrt(f1[bi] * f2[j] * f3[k])
self._fc3_normal[i, j, k] = fc3_elem / fff
def _sum_in_atoms(self, band_indices, eigvecs):
num_atom = self._primitive.get_number_of_atoms()
(e1, e2, e3) = eigvecs
(b1, b2, b3) = band_indices
sum_fc3 = 0j
for (i, j, k) in list(np.ndindex((num_atom,) * 3)):
sum_fc3_cart = 0
for (l, m, n) in list(np.ndindex((3, 3, 3))):
sum_fc3_cart += (e1[i * 3 + l, b1] *
e2[j * 3 + m, b2] *
e3[k * 3 + n, b3] *
self._fc3_reciprocal[i, j, k, l, m, n])
mass_sqrt = np.sqrt(np.prod(self._masses[[i, j, k]]))
sum_fc3 += sum_fc3_cart / mass_sqrt
return sum_fc3

View File

@ -1,544 +0,0 @@
import numpy as np
from phonopy.units import THzToEv, Kb
import phonopy.structure.spglib as spg
from phonopy.structure.symmetry import Symmetry
from phonopy.structure.tetrahedron_method import TetrahedronMethod
from phonopy.structure.grid_points import extract_ir_grid_points
def gaussian(x, sigma):
return 1.0 / np.sqrt(2 * np.pi) / sigma * np.exp(-x**2 / 2 / sigma**2)
def occupation(x, t):
return 1.0 / (np.exp(THzToEv * x / (Kb * t)) - 1)
def get_triplets_at_q(grid_point,
mesh,
point_group, # real space point group of space group
primitive_lattice, # column vectors
is_time_reversal=True,
stores_triplets_map=False):
map_triplets, map_q, grid_address = _get_triplets_reciprocal_mesh_at_q(
grid_point,
mesh,
point_group,
is_time_reversal=is_time_reversal)
bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address,
mesh,
primitive_lattice)
triplets_at_q, weights = _get_BZ_triplets_at_q(
grid_point,
bz_grid_address,
bz_map,
map_triplets,
mesh)
assert np.prod(mesh) == weights.sum(), \
"Num grid points %d, sum of weight %d" % (
np.prod(mesh), weights.sum())
# These maps are required for collision matrix calculation.
if not stores_triplets_map:
map_triplets = None
map_q = None
return triplets_at_q, weights, bz_grid_address, bz_map, map_triplets, map_q
def get_triplets_third_q_list(grid_point,
bz_grid_address,
bz_map,
mesh):
triplets_at_q, weights = _get_BZ_triplets_at_q(
grid_point,
bz_grid_address,
bz_map,
np.arange(len(bz_grid_address), dtype='intc'),
mesh)
return np.array(triplets_at_q[:, 2], dtype='intc')
def get_nosym_triplets_at_q(grid_point,
mesh,
primitive_lattice,
stores_triplets_map=False):
grid_address = get_grid_address(mesh)
map_triplets = np.arange(len(grid_address), dtype='intc')
bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address,
mesh,
primitive_lattice)
triplets_at_q, weights = _get_BZ_triplets_at_q(
grid_point,
bz_grid_address,
bz_map,
map_triplets,
mesh)
if not stores_triplets_map:
map_triplets = None
map_q = None
else:
map_q = map_triplets.copy()
return triplets_at_q, weights, bz_grid_address, bz_map, map_triplets, map_q
def get_grid_address(mesh):
grid_mapping_table, grid_address = spg.get_stabilized_reciprocal_mesh(
mesh,
[[[1, 0, 0], [0, 1, 0], [0, 0, 1]]],
is_time_reversal=False)
return grid_address
def get_bz_grid_address(mesh, primitive_lattice, with_boundary=False):
grid_address = get_grid_address(mesh)
bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address,
mesh,
primitive_lattice)
if with_boundary:
return bz_grid_address, bz_map
else:
return bz_grid_address[:np.prod(mesh)]
def get_grid_point_from_address_py(address, mesh):
# X runs first in XYZ
# (*In spglib, Z first is possible with MACRO setting.)
m = mesh
return (address[0] % m[0] +
(address[1] % m[1]) * m[0] +
(address[2] % m[2]) * m[0] * m[1])
def get_grid_point_from_address(address, mesh):
return spg.get_grid_point_from_address(address, mesh)
def get_bz_grid_point_from_address(address, mesh, bz_map):
# X runs first in XYZ
# (*In spglib, Z first is possible with MACRO setting.)
# 2m is defined in kpoint.c of spglib.
m = 2 * np.array(mesh, dtype='intc')
return bz_map[get_grid_point_from_address(address, m)]
def invert_grid_point(grid_point, mesh, grid_address, bz_map):
# gp --> [address] --> [-address] --> inv_gp
address = grid_address[grid_point]
return get_bz_grid_point_from_address(-address, mesh, bz_map)
def get_ir_grid_points(mesh, rotations, mesh_shifts=None):
if mesh_shifts is None:
mesh_shifts = [False, False, False]
grid_mapping_table, grid_address = spg.get_stabilized_reciprocal_mesh(
mesh,
rotations,
is_shift=np.where(mesh_shifts, 1, 0))
(ir_grid_points,
ir_grid_weights) = extract_ir_grid_points(grid_mapping_table)
return ir_grid_points, ir_grid_weights, grid_address, grid_mapping_table
def get_grid_points_by_rotations(grid_point,
reciprocal_rotations,
mesh,
mesh_shifts=None):
if mesh_shifts is None:
mesh_shifts = [False, False, False]
return spg.get_grid_points_by_rotations(
grid_point,
reciprocal_rotations,
mesh,
is_shift=np.where(mesh_shifts, 1, 0))
def get_BZ_grid_points_by_rotations(grid_point,
reciprocal_rotations,
mesh,
bz_map,
mesh_shifts=None):
if mesh_shifts is None:
mesh_shifts = [False, False, False]
return spg.get_BZ_grid_points_by_rotations(
grid_point,
reciprocal_rotations,
mesh,
bz_map,
is_shift=np.where(mesh_shifts, 1, 0))
def reduce_grid_points(mesh_divisors,
grid_address,
dense_grid_points,
dense_grid_weights=None,
coarse_mesh_shifts=None):
divisors = np.array(mesh_divisors, dtype='intc')
if (divisors == 1).all():
coarse_grid_points = np.array(dense_grid_points, dtype='intc')
if dense_grid_weights is not None:
coarse_grid_weights = np.array(dense_grid_weights, dtype='intc')
else:
grid_weights = []
if coarse_mesh_shifts is None:
shift = [0, 0, 0]
else:
shift = np.where(coarse_mesh_shifts, divisors // 2, [0, 0, 0])
modulo = grid_address[dense_grid_points] % divisors
condition = (modulo == shift).all(axis=1)
coarse_grid_points = np.extract(condition, dense_grid_points)
if dense_grid_weights is not None:
coarse_grid_weights = np.extract(condition, dense_grid_weights)
if dense_grid_weights is None:
return coarse_grid_points
else:
return coarse_grid_points, coarse_grid_weights
def from_coarse_to_dense_grid_points(dense_mesh,
mesh_divisors,
coarse_grid_points,
coarse_grid_address,
coarse_mesh_shifts=None):
if coarse_mesh_shifts is None:
coarse_mesh_shifts = [False, False, False]
shifts = np.where(coarse_mesh_shifts, 1, 0)
dense_grid_points = []
for cga in coarse_grid_address[coarse_grid_points]:
dense_address = cga * mesh_divisors + shifts * (mesh_divisors // 2)
dense_grid_points.append(get_grid_point_from_address(dense_address,
dense_mesh))
return np.array(dense_grid_points, dtype='intc')
def get_coarse_ir_grid_points(primitive,
mesh,
mesh_divisors,
coarse_mesh_shifts,
is_kappa_star=True,
symprec=1e-5):
mesh = np.array(mesh, dtype='intc')
symmetry = Symmetry(primitive, symprec)
point_group = symmetry.get_pointgroup_operations()
if mesh_divisors is None:
(ir_grid_points,
ir_grid_weights,
grid_address,
grid_mapping_table) = get_ir_grid_points(mesh, point_group)
else:
mesh_divs = np.array(mesh_divisors, dtype='intc')
coarse_mesh = mesh // mesh_divs
if coarse_mesh_shifts is None:
coarse_mesh_shifts = [False, False, False]
if not is_kappa_star:
coarse_grid_address = get_grid_address(coarse_mesh)
coarse_grid_points = np.arange(np.prod(coarse_mesh), dtype='intc')
coarse_grid_weights = np.ones(len(coarse_grid_points), dtype='intc')
else:
(coarse_ir_grid_points,
coarse_ir_grid_weights,
coarse_grid_address,
coarse_grid_mapping_table) = get_ir_grid_points(
coarse_mesh,
point_group,
mesh_shifts=coarse_mesh_shifts)
ir_grid_points = from_coarse_to_dense_grid_points(
mesh,
mesh_divs,
coarse_grid_points,
coarse_grid_address,
coarse_mesh_shifts=coarse_mesh_shifts)
grid_address = get_grid_address(mesh)
ir_grid_weights = ir_grid_weights
primitive_lattice = np.linalg.inv(primitive.get_cell())
bz_grid_address, bz_map = spg.relocate_BZ_grid_address(grid_address,
mesh,
primitive_lattice)
return (ir_grid_points,
ir_grid_weights,
bz_grid_address,
grid_mapping_table)
def get_number_of_triplets(primitive,
mesh,
grid_point,
symprec=1e-5):
mesh = np.array(mesh, dtype='intc')
symmetry = Symmetry(primitive, symprec)
point_group = symmetry.get_pointgroup_operations()
primitive_lattice = np.linalg.inv(primitive.get_cell())
triplets_at_q, _, _, _, _, _ = get_triplets_at_q(
grid_point,
mesh,
point_group,
primitive_lattice)
return len(triplets_at_q)
def get_grid_points_in_Brillouin_zone(primitive_vectors, # column vectors
mesh,
grid_address,
grid_points,
with_boundary=False):
gbz = GridBrillouinZone(primitive_vectors,
mesh,
grid_address,
with_boundary=with_boundary)
gbz.run(grid_points)
return gbz.get_shortest_addresses()
def get_triplets_integration_weights(interaction,
frequency_points,
sigma,
is_collision_matrix=False,
neighboring_phonons=True,
lang='C'):
triplets = interaction.get_triplets_at_q()[0]
frequencies = interaction.get_phonons()[0]
num_band = frequencies.shape[1]
g_zero = None
if is_collision_matrix:
g = np.zeros(
(3, len(triplets), len(frequency_points), num_band, num_band),
dtype='double', order='C')
else:
g = np.zeros(
(2, len(triplets), len(frequency_points), num_band, num_band),
dtype='double', order='C')
if sigma:
if lang == 'C':
import anharmonic._phono3py as phono3c
phono3c.triplets_integration_weights_with_sigma(
g,
frequency_points,
triplets,
frequencies,
sigma)
else:
for i, tp in enumerate(triplets):
f1s = frequencies[tp[1]]
f2s = frequencies[tp[2]]
for j, k in list(np.ndindex((num_band, num_band))):
f1 = f1s[j]
f2 = f2s[k]
g0 = gaussian(frequency_points - f1 - f2, sigma)
g[0, i, :, j, k] = g0
g1 = gaussian(frequency_points + f1 - f2, sigma)
g2 = gaussian(frequency_points - f1 + f2, sigma)
g[1, i, :, j, k] = g1 - g2
if len(g) == 3:
g[2, i, :, j, k] = g0 + g1 + g2
else:
if lang == 'C':
g_zero = _set_triplets_integration_weights_c(
g,
interaction,
frequency_points,
neighboring_phonons=neighboring_phonons)
else:
_set_triplets_integration_weights_py(
g, interaction, frequency_points)
return g, g_zero
def get_tetrahedra_vertices(relative_address,
mesh,
triplets_at_q,
bz_grid_address,
bz_map):
bzmesh = mesh * 2
grid_order = [1, mesh[0], mesh[0] * mesh[1]]
bz_grid_order = [1, bzmesh[0], bzmesh[0] * bzmesh[1]]
num_triplets = len(triplets_at_q)
vertices = np.zeros((num_triplets, 2, 24, 4), dtype='intc')
for i, tp in enumerate(triplets_at_q):
for j, adrs_shift in enumerate(
(relative_address, -relative_address)):
adrs = bz_grid_address[tp[j + 1]] + adrs_shift
bz_gp = np.dot(adrs % bzmesh, bz_grid_order)
gp = np.dot(adrs % mesh, grid_order)
vgp = bz_map[bz_gp]
vertices[i, j] = vgp + (vgp == -1) * (gp + 1)
return vertices
def _get_triplets_reciprocal_mesh_at_q(fixed_grid_number,
mesh,
rotations,
is_time_reversal=True):
import anharmonic._phono3py as phono3c
map_triplets = np.zeros(np.prod(mesh), dtype='intc')
map_q = np.zeros(np.prod(mesh), dtype='intc')
mesh_points = np.zeros((np.prod(mesh), 3), dtype='intc')
phono3c.triplets_reciprocal_mesh_at_q(
map_triplets,
map_q,
mesh_points,
fixed_grid_number,
np.array(mesh, dtype='intc'),
is_time_reversal * 1,
np.array(rotations, dtype='intc', order='C'))
return map_triplets, map_q, mesh_points
def _get_BZ_triplets_at_q(grid_point,
bz_grid_address,
bz_map,
map_triplets,
mesh):
"""grid_address is overwritten."""
import anharmonic._phono3py as phono3c
weights = np.zeros_like(map_triplets)
for g in map_triplets:
weights[g] += 1
ir_weights = np.extract(weights > 0, weights)
triplets = np.zeros((len(ir_weights), 3), dtype='intc')
num_ir_ret = phono3c.BZ_triplets_at_q(triplets,
grid_point,
bz_grid_address,
bz_map,
map_triplets,
np.array(mesh, dtype='intc'))
return triplets, ir_weights
def _set_triplets_integration_weights_c(g,
interaction,
frequency_points,
neighboring_phonons=True):
import anharmonic._phono3py as phono3c
reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
mesh = interaction.get_mesh_numbers()
thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
grid_address = interaction.get_grid_address()
bz_map = interaction.get_bz_map()
triplets_at_q = interaction.get_triplets_at_q()[0]
if neighboring_phonons:
unique_vertices = thm.get_unique_tetrahedra_vertices()
for i, j in zip((1, 2), (1, -1)):
neighboring_grid_points = np.zeros(
len(unique_vertices) * len(triplets_at_q), dtype='intc')
phono3c.neighboring_grid_points(
neighboring_grid_points,
triplets_at_q[:, i].flatten(),
j * unique_vertices,
mesh,
grid_address,
bz_map)
interaction.set_phonons(np.unique(neighboring_grid_points))
g_zero = np.zeros(g.shape[1:], dtype='byte', order='C')
phono3c.triplets_integration_weights(
g,
g_zero,
frequency_points,
thm.get_tetrahedra(),
mesh,
triplets_at_q,
interaction.get_phonons()[0],
grid_address,
bz_map)
return g_zero
def _set_triplets_integration_weights_py(g, interaction, frequency_points):
reciprocal_lattice = np.linalg.inv(interaction.get_primitive().get_cell())
mesh = interaction.get_mesh_numbers()
thm = TetrahedronMethod(reciprocal_lattice, mesh=mesh)
grid_address = interaction.get_grid_address()
bz_map = interaction.get_bz_map()
triplets_at_q = interaction.get_triplets_at_q()[0]
unique_vertices = thm.get_unique_tetrahedra_vertices()
tetrahedra_vertices = get_tetrahedra_vertices(
thm.get_tetrahedra(),
mesh,
triplets_at_q,
grid_address,
bz_map)
interaction.set_phonons(np.unique(tetrahedra_vertices))
frequencies = interaction.get_phonons()[0]
num_band = frequencies.shape[1]
for i, vertices in enumerate(tetrahedra_vertices):
for j, k in list(np.ndindex((num_band, num_band))):
f1_v = frequencies[vertices[0], j]
f2_v = frequencies[vertices[1], k]
thm.set_tetrahedra_omegas(f1_v + f2_v)
thm.run(frequency_points)
g0 = thm.get_integration_weight()
g[0, i, :, j, k] = g0
thm.set_tetrahedra_omegas(-f1_v + f2_v)
thm.run(frequency_points)
g1 = thm.get_integration_weight()
thm.set_tetrahedra_omegas(f1_v - f2_v)
thm.run(frequency_points)
g2 = thm.get_integration_weight()
g[1, i, :, j, k] = g1 - g2
if len(g) == 3:
g[2, i, :, j, k] = g0 + g1 + g2
class GridBrillouinZone(object):
search_space = np.array([
[0, 0, 0],
[0, 0, 1],
[0, 1, -1],
[0, 1, 0],
[0, 1, 1],
[1, -1, -1],
[1, -1, 0],
[1, -1, 1],
[1, 0, -1],
[1, 0, 0],
[1, 0, 1],
[1, 1, -1],
[1, 1, 0],
[1, 1, 1],
[-1, -1, -1],
[-1, -1, 0],
[-1, -1, 1],
[-1, 0, -1],
[-1, 0, 0],
[-1, 0, 1],
[-1, 1, -1],
[-1, 1, 0],
[-1, 1, 1],
[0, -1, -1],
[0, -1, 0],
[0, -1, 1],
[0, 0, -1]], dtype='intc', order='C')
def __init__(self,
primitive_vectors,
mesh,
grid_address,
with_boundary=False): # extended grid if True
self._primitive_vectors = np.array(primitive_vectors) # column vectors
self._mesh = mesh
self._grid_address = grid_address
self._with_boundary = with_boundary
self._tolerance = min(np.sum(self._primitive_vectors ** 2, axis=0)) / 10
self._primitive_vectors_inv = np.linalg.inv(self._primitive_vectors)
self._search_space = search_space * mesh
self._shortest_addresses = None
def run(self, grid_points):
self._shortest_addresses = []
for address in self._grid_address[grid_points]:
distances = np.array(
[(np.dot(self._primitive_vectors, address + g) ** 2).sum()
for g in self._search_space], dtype='double')
min_dist = min(distances)
shortest_indices = [i for i, d in enumerate(distances - min_dist)
if abs(d) < self._tolerance]
self._shortest_addresses.append(
self._search_space[shortest_indices] + address)
def get_shortest_addresses(self):
return self._shortest_addresses

File diff suppressed because it is too large Load Diff

View File

@ -1,95 +0,0 @@
/* Copyright (C) 2015 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. */
#include "flame_wrapper.h"
#include "FLAME.h"
#include "math.h"
int phonopy_pinv_libflame(double *matrix,
double *eigvals,
const int size,
const double cutoff)
{
FLA_Obj A, B, l;
/* FLA_Obj C; */
double *inv_eigvals;
int i;
inv_eigvals = (double*)malloc(sizeof(double) * size);
FLA_Init();
FLA_Obj_create_without_buffer(FLA_DOUBLE, size, size, &A);
FLA_Obj_attach_buffer(matrix, 0, 0, &A);
FLA_Obj_create_without_buffer(FLA_DOUBLE, size, 1, &l);
FLA_Obj_attach_buffer(eigvals, 0, 0, &l);
/* Eigensolver */
FLA_Obj_create_copy_of(FLA_NO_TRANSPOSE, A, &B);
FLA_Hevd(FLA_EVD_WITH_VECTORS, FLA_LOWER_TRIANGULAR, B, l);
/* SVD */
/* FLA_Obj_create(FLA_DOUBLE, size, size, 0, 0, &B); */
/* use U */
/* FLA_Svd(FLA_SVD_VECTORS_ALL, FLA_SVD_VECTORS_NONE, A, l, B, C); */
/* use V */
/* FLA_Svd(FLA_SVD_VECTORS_NONE, FLA_SVD_VECTORS_ALL, A, l, C, B); */
FLA_Obj_free_without_buffer(&l);
for (i = 0; i < size; i++) {
if (eigvals[i] < cutoff) {
inv_eigvals[i] = 0;
} else {
inv_eigvals[i] = 1.0 / sqrt(eigvals[i]);
}
}
FLA_Obj_create_without_buffer(FLA_DOUBLE, size, 1, &l);
FLA_Obj_attach_buffer(inv_eigvals, 0, 0, &l);
FLA_Apply_diag_matrix(FLA_RIGHT, FLA_NO_CONJUGATE, l, B);
FLA_Syrk(FLA_LOWER_TRIANGULAR, FLA_NO_TRANSPOSE, FLA_ONE, B, FLA_ZERO, A);
FLA_Symmetrize(FLA_LOWER_TRIANGULAR, A);
FLA_Obj_free_without_buffer(&A);
FLA_Obj_free_without_buffer(&l);
FLA_Obj_free(&B);
FLA_Finalize();
free(inv_eigvals);
return 0;
}

View File

@ -1,226 +0,0 @@
/* Copyright (C) 2015 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. */
#include <stdlib.h>
#include <lapacke.h>
#include <phonoc_const.h>
#include <phonoc_utils.h>
void get_isotope_scattering_strength(double *gamma,
const int grid_point,
const double *mass_variances,
const double *frequencies,
const lapack_complex_double *eigenvectors,
const int num_grid_points,
const int *band_indices,
const int num_band,
const int num_band0,
const double sigma,
const double cutoff_frequency)
{
int i, j, k, l, m;
double *e0_r, *e0_i, e1_r, e1_i, a, b, f, *f0, dist, sum_g, sum_g_k;
e0_r = (double*)malloc(sizeof(double) * num_band * num_band0);
e0_i = (double*)malloc(sizeof(double) * num_band * num_band0);
f0 = (double*)malloc(sizeof(double) * num_band0);
for (i = 0; i < num_band0; i++) {
f0[i] = frequencies[grid_point * num_band + band_indices[i]];
for (j = 0; j < num_band; j++) {
e0_r[i * num_band + j] = lapack_complex_double_real
(eigenvectors[grid_point * num_band * num_band +
j * num_band + band_indices[i]]);
e0_i[i * num_band + j] = lapack_complex_double_imag
(eigenvectors[grid_point * num_band * num_band +
j * num_band + band_indices[i]]);
}
}
for (i = 0; i < num_band0; i++) {
gamma[i] = 0;
}
for (i = 0; i < num_band0; i++) { /* band index0 */
if (f0[i] < cutoff_frequency) {
continue;
}
sum_g = 0;
#pragma omp parallel for private(k, l, m, f, e1_r, e1_i, a, b, dist, sum_g_k) reduction(+:sum_g)
for (j = 0; j < num_grid_points; j++) {
sum_g_k = 0;
for (k = 0; k < num_band; k++) { /* band index */
f = frequencies[j * num_band + k];
if (f < cutoff_frequency) {
continue;
}
dist = gaussian(f - f0[i], sigma);
for (l = 0; l < num_band / 3; l++) { /* elements */
a = 0;
b = 0;
for (m = 0; m < 3; m++) {
e1_r = lapack_complex_double_real
(eigenvectors[j * num_band * num_band +
(l * 3 + m) * num_band + k]);
e1_i = lapack_complex_double_imag
(eigenvectors[j * num_band * num_band +
(l * 3 + m) * num_band + k]);
a += (e0_r[i * num_band + l * 3 + m] * e1_r +
e0_i[i * num_band + l * 3 + m] * e1_i);
b += (e0_i[i * num_band + l * 3 + m] * e1_r -
e0_r[i * num_band + l * 3 + m] * e1_i);
}
sum_g_k += (a * a + b * b) * mass_variances[l] * dist;
}
}
sum_g += sum_g_k;
}
gamma[i] = sum_g;
}
for (i = 0; i < num_band0; i++) {
/* Frequency unit to ang-freq: *(2pi)**2/(2pi) */
/* Ang-freq to freq unit (for lifetime): /2pi */
/* gamma = 1/2t */
gamma[i] *= M_2PI / 4 * f0[i] * f0[i] / 2;
}
free(f0);
free(e0_r);
free(e0_i);
}
void
get_thm_isotope_scattering_strength(double *gamma,
const int grid_point,
const int *ir_grid_points,
const int *weights,
const double *mass_variances,
const double *frequencies,
const lapack_complex_double *eigenvectors,
const int num_grid_points,
const int *band_indices,
const int num_band,
const int num_band0,
const double *integration_weights,
const double cutoff_frequency)
{
int i, j, k, l, m, gp;
double *e0_r, *e0_i, *f0, *gamma_ij;
double e1_r, e1_i, a, b, f, dist, sum_g_k;
e0_r = (double*)malloc(sizeof(double) * num_band * num_band0);
e0_i = (double*)malloc(sizeof(double) * num_band * num_band0);
f0 = (double*)malloc(sizeof(double) * num_band0);
for (i = 0; i < num_band0; i++) {
f0[i] = frequencies[grid_point * num_band + band_indices[i]];
for (j = 0; j < num_band; j++) {
e0_r[i * num_band + j] = lapack_complex_double_real
(eigenvectors[grid_point * num_band * num_band +
j * num_band + band_indices[i]]);
e0_i[i * num_band + j] = lapack_complex_double_imag
(eigenvectors[grid_point * num_band * num_band +
j * num_band + band_indices[i]]);
}
}
gamma_ij = (double*)malloc(sizeof(double) * num_grid_points * num_band0);
#pragma omp parallel for
for (i = 0; i < num_grid_points * num_band0; i++) {
gamma_ij[i] = 0;
}
#pragma omp parallel for private(j, k, l, m, f, gp, e1_r, e1_i, a, b, dist, sum_g_k)
for (i = 0; i < num_grid_points; i++) {
gp = ir_grid_points[i];
for (j = 0; j < num_band0; j++) { /* band index0 */
if (f0[j] < cutoff_frequency) {
continue;
}
sum_g_k = 0;
for (k = 0; k < num_band; k++) { /* band index */
f = frequencies[gp * num_band + k];
if (f < cutoff_frequency) {
continue;
}
dist = integration_weights[gp * num_band0 * num_band +
j * num_band + k];
for (l = 0; l < num_band / 3; l++) { /* elements */
a = 0;
b = 0;
for (m = 0; m < 3; m++) {
e1_r = lapack_complex_double_real
(eigenvectors
[gp * num_band * num_band + (l * 3 + m) * num_band + k]);
e1_i = lapack_complex_double_imag
(eigenvectors
[gp * num_band * num_band + (l * 3 + m) * num_band + k]);
a += (e0_r[j * num_band + l * 3 + m] * e1_r +
e0_i[j * num_band + l * 3 + m] * e1_i);
b += (e0_i[j * num_band + l * 3 + m] * e1_r -
e0_r[j * num_band + l * 3 + m] * e1_i);
}
sum_g_k += (a * a + b * b) * mass_variances[l] * dist;
}
}
gamma_ij[gp * num_band0 + j] = sum_g_k * weights[gp];
}
}
for (i = 0; i < num_band0; i++) {
gamma[i] = 0;
}
for (i = 0; i < num_grid_points; i++) {
gp = ir_grid_points[i];
for (j = 0; j < num_band0; j++) {
gamma[j] += gamma_ij[gp * num_band0 + j];
}
}
for (i = 0; i < num_band0; i++) {
/* Frequency unit to ang-freq: *(2pi)**2/(2pi) */
/* Ang-freq to freq unit (for lifetime): /2pi */
/* gamma = 1/2t */
gamma[i] *= M_2PI / 4 * f0[i] * f0[i] / 2;
}
free(gamma_ij);
free(f0);
free(e0_r);
free(e0_i);
}

View File

@ -1,262 +0,0 @@
/* Copyright (C) 2015 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. */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <phonoc_array.h>
#include <phonoc_utils.h>
#include <phonon3_h/collision_matrix.h>
static int get_inv_sinh(double *inv_sinh,
const int gp,
const int temperature,
const double *frequencies,
const int *triplets,
const Iarray *triplets_map,
const int *stabilized_gp_map,
const int *gp2tp_map,
const int num_band,
const double cutoff_frequency);
static int *create_gp2tp_map(const Iarray *triplets);
void get_collision_matrix(double *collision_matrix,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const Iarray *triplets_map,
const int *stabilized_gp_map,
const int *ir_grid_points,
const Iarray *rotated_grid_points,
const double *rotations_cartesian,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, j, k, l, m, n, ti, r_gp, num_triplets, num_band, num_ir_gp, num_gp, num_rot, multi;
int *gp2tp_map;
double collision;
double *inv_sinh;
num_triplets = fc3_normal_squared->dims[0];
num_band = fc3_normal_squared->dims[2];
num_ir_gp = rotated_grid_points->dims[0];
num_rot = rotated_grid_points->dims[1];
num_gp = triplets_map->dims[0];
gp2tp_map = create_gp2tp_map(triplets_map);
#pragma omp parallel for private(j, k, l, m, n, ti, r_gp, collision, inv_sinh, multi)
for (i = 0; i < num_ir_gp; i++) {
inv_sinh = (double*)malloc(sizeof(double) * num_band);
multi = 0;
for (j = 0; j < num_rot; j++) {
if (rotated_grid_points->data[i * num_rot + j] < num_gp) {
multi++;
}
}
multi = num_rot / multi;
for (j = 0; j < num_rot; j++) {
r_gp = rotated_grid_points->data[i * num_rot + j];
if (r_gp > num_gp - 1) {
continue;
}
ti = get_inv_sinh(inv_sinh,
r_gp,
temperature,
frequencies,
triplets,
triplets_map,
stabilized_gp_map,
gp2tp_map,
num_band,
cutoff_frequency);
for (k = 0; k < num_band; k++) {
for (l = 0; l < num_band; l++) {
collision = 0;
for (m = 0; m < num_band; m++) {
collision +=
fc3_normal_squared->data[ti * num_band * num_band * num_band +
k * num_band * num_band +
l * num_band + m] *
g[2 * num_triplets * num_band * num_band * num_band +
ti * num_band * num_band * num_band +
k * num_band * num_band +
l * num_band + m] *
inv_sinh[m] * unit_conversion_factor;
}
collision *= multi;
for (m = 0; m < 3; m++) {
for (n = 0; n < 3; n++) {
collision_matrix[k * 3 * num_ir_gp * num_band * 3 +
m * num_ir_gp * num_band * 3 +
i * num_band * 3 + l * 3 + n] +=
collision * rotations_cartesian[j * 9 + m * 3 + n];
}
}
}
}
}
free(inv_sinh);
inv_sinh = NULL;
}
free(gp2tp_map);
gp2tp_map = NULL;
}
void get_reducible_collision_matrix(double *collision_matrix,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const Iarray *triplets_map,
const int *stabilized_gp_map,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, j, k, l, ti, num_triplets, num_band, num_gp;
int *gp2tp_map;
double collision;
double *inv_sinh;
num_triplets = fc3_normal_squared->dims[0];
num_band = fc3_normal_squared->dims[2];
num_gp = triplets_map->dims[0];
gp2tp_map = create_gp2tp_map(triplets_map);
#pragma omp parallel for private(j, k, l, ti, collision, inv_sinh)
for (i = 0; i < num_gp; i++) {
inv_sinh = (double*)malloc(sizeof(double) * num_band);
ti = get_inv_sinh(inv_sinh,
i,
temperature,
frequencies,
triplets,
triplets_map,
stabilized_gp_map,
gp2tp_map,
num_band,
cutoff_frequency);
for (j = 0; j < num_band; j++) {
for (k = 0; k < num_band; k++) {
collision = 0;
for (l = 0; l < num_band; l++) {
collision +=
fc3_normal_squared->data[ti * num_band * num_band * num_band +
j * num_band * num_band +
k * num_band + l] *
g[2 * num_triplets * num_band * num_band * num_band +
ti * num_band * num_band * num_band +
j * num_band * num_band +
k * num_band + l] *
inv_sinh[l] * unit_conversion_factor;
}
collision_matrix[j * num_gp * num_band + i * num_band + k] += collision;
}
}
free(inv_sinh);
inv_sinh = NULL;
}
free(gp2tp_map);
gp2tp_map = NULL;
}
static int get_inv_sinh(double *inv_sinh,
const int gp,
const int temperature,
const double *frequencies,
const int *triplets,
const Iarray *triplets_map,
const int *stabilized_gp_map,
const int *gp2tp_map,
const int num_band,
const double cutoff_frequency)
{
int i, ti, gp2;
double f;
ti = gp2tp_map[triplets_map->data[gp]];
if (triplets_map->data[gp] == stabilized_gp_map[gp]) {
gp2 = triplets[ti * 3 + 2];
} else {
gp2 = triplets[ti * 3 + 1];
}
for (i = 0; i < num_band; i++) {
f = frequencies[gp2 * num_band + i];
if (f > cutoff_frequency) {
inv_sinh[i] = inv_sinh_occupation(f, temperature);
} else {
inv_sinh[i] = 0;
}
}
return ti;
}
static int *create_gp2tp_map(const Iarray *triplets_map)
{
int i, max_i, count;
int *gp2tp_map;
max_i = 0;
for (i = 0; i < triplets_map->dims[0]; i++) {
if (max_i < triplets_map->data[i]) {
max_i = triplets_map->data[i];
}
}
gp2tp_map = (int*)malloc(sizeof(int) * (max_i + 1));
for (i = 0; i < max_i + 1; i++) {
gp2tp_map[i] = 0;
}
count = 0;
for (i = 0; i < triplets_map->dims[0]; i++) {
if (triplets_map->data[i] == i) {
gp2tp_map[i] = count;
count++;
}
}
return gp2tp_map;
}

View File

@ -1,204 +0,0 @@
/* Copyright (C) 2015 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. */
#include <phonon3_h/fc3.h>
static double tensor3_rotation_elem(const double *tensor,
const double *r,
const int pos);
static void copy_permutation_symmetry_fc3_elem(double *fc3,
const double fc3_elem[27],
const int a,
const int b,
const int c,
const int num_atom);
static void set_permutation_symmetry_fc3_elem(double *fc3_elem,
const double *fc3,
const int a,
const int b,
const int c,
const int num_atom);
void distribute_fc3(double *fc3_copy,
const double *fc3,
const int third_atom,
const int *atom_mapping,
const int num_atom,
const double *rot_cart)
{
int i, j;
for (i = 0; i < num_atom; i++) {
for (j = 0; j < num_atom; j++) {
tensor3_rotation(fc3_copy +
27 * num_atom * num_atom * third_atom +
27 * num_atom * i +
27 * j,
fc3 +
27 * num_atom * num_atom * atom_mapping[third_atom] +
27 * num_atom * atom_mapping[i] +
27 * atom_mapping[j],
rot_cart);
}
}
}
void tensor3_rotation(double *rot_tensor,
const double *tensor,
const double *rot_cartesian)
{
int l;
for (l = 0; l < 27; l++) {
rot_tensor[l] = tensor3_rotation_elem(tensor, rot_cartesian, l);
}
}
void set_permutation_symmetry_fc3(double *fc3, const int num_atom)
{
double fc3_elem[27];
int i, j, k;
#pragma omp parallel for private(j, k, fc3_elem)
for (i = 0; i < num_atom; i++) {
for (j = i; j < num_atom; j++) {
for (k = j; k < num_atom; k++) {
set_permutation_symmetry_fc3_elem(fc3_elem, fc3, i, j, k, num_atom);
copy_permutation_symmetry_fc3_elem(fc3, fc3_elem,
i, j, k, num_atom);
}
}
}
}
static double tensor3_rotation_elem(const double *tensor,
const double *r,
const int pos)
{
int i, j, k, l, m, n;
double sum;
l = pos / 9;
m = (pos % 9) / 3;
n = pos % 3;
sum = 0.0;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
for (k = 0; k < 3; k++) {
sum += r[l * 3 + i] * r[m * 3 + j] * r[n * 3 + k] *
tensor[i * 9 + j * 3 + k];
}
}
}
return sum;
}
static void copy_permutation_symmetry_fc3_elem(double *fc3,
const double fc3_elem[27],
const int a,
const int b,
const int c,
const int num_atom)
{
int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
for (k = 0; k < 3; k++) {
fc3[a * num_atom * num_atom * 27 +
b * num_atom * 27 +
c * 27 + i * 9 + j * 3 + k] =
fc3_elem[i * 9 + j * 3 + k];
fc3[a * num_atom * num_atom * 27 +
c * num_atom * 27 +
b * 27 + i * 9 + k * 3 + j] =
fc3_elem[i * 9 + j * 3 + k];
fc3[b * num_atom * num_atom * 27 +
a * num_atom * 27 +
c * 27 + j * 9 + i * 3 + k] =
fc3_elem[i * 9 + j * 3 + k];
fc3[b * num_atom * num_atom * 27 +
c * num_atom * 27 +
a * 27 + j * 9 + k * 3 + i] =
fc3_elem[i * 9 + j * 3 + k];
fc3[c * num_atom * num_atom * 27 +
a * num_atom * 27 +
b * 27 + k * 9 + i * 3 + j] =
fc3_elem[i * 9 + j * 3 + k];
fc3[c * num_atom * num_atom * 27 +
b * num_atom * 27 +
a * 27 + k * 9 + j * 3 + i] =
fc3_elem[i * 9 + j * 3 + k];
}
}
}
}
static void set_permutation_symmetry_fc3_elem(double *fc3_elem,
const double *fc3,
const int a,
const int b,
const int c,
const int num_atom)
{
int i, j, k;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
for (k = 0; k < 3; k++) {
fc3_elem[i * 9 + j * 3 + k] =
(fc3[a * num_atom * num_atom * 27 +
b * num_atom * 27 +
c * 27 + i * 9 + j * 3 + k] +
fc3[a * num_atom * num_atom * 27 +
c * num_atom * 27 +
b * 27 + i * 9 + k * 3 + j] +
fc3[b * num_atom * num_atom * 27 +
a * num_atom * 27 +
c * 27 + j * 9 + i * 3 + k] +
fc3[b * num_atom * num_atom * 27 +
c * num_atom * 27 +
a * 27 + j * 9 + k * 3 + i] +
fc3[c * num_atom * num_atom * 27 +
a * num_atom * 27 +
b * 27 + k * 9 + i * 3 + j] +
fc3[c * num_atom * num_atom * 27 +
b * num_atom * 27 +
a * 27 + k * 9 + j * 3 + i]) / 6;
}
}
}
}

View File

@ -1,234 +0,0 @@
/* Copyright (C) 2015 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. */
#include <lapacke.h>
#include <stdlib.h>
#include <math.h>
#include <phonoc_array.h>
#include <phonoc_utils.h>
#include <phonon3_h/frequency_shift.h>
#include <phonon3_h/real_to_reciprocal.h>
static double get_frequency_shift_at_band(const int band_index,
const Darray *fc3_normal_squared,
const double fpoint,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double epsilon,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
static double sum_frequency_shift_at_band(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double epsilon,
const double temperature,
const double cutoff_frequency);
static double sum_frequency_shift_at_band_0K(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double epsilon,
const double cutoff_frequency);
void get_frequency_shift_at_bands(double *frequency_shift,
const Darray *fc3_normal_squared,
const int *band_indices,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double epsilon,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, num_band0, num_band, gp0;
double fpoint;
num_band0 = fc3_normal_squared->dims[1];
num_band = fc3_normal_squared->dims[2];
gp0 = grid_point_triplets[0];
/* num_band0 and num_band_indices have to be same. */
for (i = 0; i < num_band0; i++) {
fpoint = frequencies[gp0 * num_band + band_indices[i]];
frequency_shift[i] =
get_frequency_shift_at_band(i,
fc3_normal_squared,
fpoint,
frequencies,
grid_point_triplets,
triplet_weights,
epsilon,
temperature,
unit_conversion_factor,
cutoff_frequency);
}
}
static double get_frequency_shift_at_band(const int band_index,
const Darray *fc3_normal_squared,
const double fpoint,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double epsilon,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, num_triplets, num_band0, num_band, gp1, gp2;
double shift;
num_triplets = fc3_normal_squared->dims[0];
num_band0 = fc3_normal_squared->dims[1];
num_band = fc3_normal_squared->dims[2];
shift = 0;
#pragma omp parallel for private(gp1, gp2) reduction(+:shift)
for (i = 0; i < num_triplets; i++) {
gp1 = grid_point_triplets[i * 3 + 1];
gp2 = grid_point_triplets[i * 3 + 2];
if (temperature > 0) {
shift +=
sum_frequency_shift_at_band(num_band,
fc3_normal_squared->data +
i * num_band0 * num_band * num_band +
band_index * num_band * num_band,
fpoint,
frequencies + gp1 * num_band,
frequencies + gp2 * num_band,
epsilon,
temperature,
cutoff_frequency) *
triplet_weights[i] * unit_conversion_factor;
} else {
shift +=
sum_frequency_shift_at_band_0K(num_band,
fc3_normal_squared->data +
i * num_band0 * num_band * num_band +
band_index * num_band * num_band,
fpoint,
frequencies + gp1 * num_band,
frequencies + gp2 * num_band,
epsilon,
cutoff_frequency) *
triplet_weights[i] * unit_conversion_factor;
}
}
return shift;
}
static double sum_frequency_shift_at_band(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double epsilon,
const double temperature,
const double cutoff_frequency)
{
int i, j;
double n2, n3, f1, f2, f3, f4, shift;
/* double sum; */
shift = 0;
for (i = 0; i < num_band; i++) {
if (freqs0[i] > cutoff_frequency) {
n2 = bose_einstein(freqs0[i], temperature);
for (j = 0; j < num_band; j++) {
if (freqs1[j] > cutoff_frequency) {
n3 = bose_einstein(freqs1[j], temperature);
f1 = fpoint + freqs0[i] + freqs1[j];
f2 = fpoint - freqs0[i] - freqs1[j];
f3 = fpoint - freqs0[i] + freqs1[j];
f4 = fpoint + freqs0[i] - freqs1[j];
/* sum = 0; */
/* if (fabs(f1) > epsilon) { */
/* sum -= (n2 + n3 + 1) / f1; */
/* } */
/* if (fabs(f2) > epsilon) { */
/* sum += (n2 + n3 + 1) / f2; */
/* } */
/* if (fabs(f3) > epsilon) { */
/* sum -= (n2 - n3) / f3; */
/* } */
/* if (fabs(f4) > epsilon) { */
/* sum += (n2 - n3) / f4; */
/* } */
/* shift += sum * fc3_normal_squared[i * num_band + j]; */
shift += (- (n2 + n3 + 1) * f1 / (f1 * f1 + epsilon * epsilon)
+ (n2 + n3 + 1) * f2 / (f2 * f2 + epsilon * epsilon)
- (n2 - n3) * f3 / (f3 * f3 + epsilon * epsilon)
+ (n2 - n3) * f4 / (f4 * f4 + epsilon * epsilon)) *
fc3_normal_squared[i * num_band + j];
}
}
}
}
return shift;
}
static double sum_frequency_shift_at_band_0K(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double epsilon,
const double cutoff_frequency)
{
int i, j;
double f1, f2, shift;
shift = 0;
for (i = 0; i < num_band; i++) {
if (freqs0[i] > cutoff_frequency) {
for (j = 0; j < num_band; j++) {
if (freqs1[j] > cutoff_frequency) {
f1 = fpoint + freqs0[i] + freqs1[j];
f2 = fpoint - freqs0[i] - freqs1[j];
shift += (- 1 * f1 / (f1 * f1 + epsilon * epsilon)
+ 1 * f2 / (f2 * f2 + epsilon * epsilon)) *
fc3_normal_squared[i * num_band + j];
}
}
}
}
return shift;
}

View File

@ -1,242 +0,0 @@
/* Copyright (C) 2015 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. */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <phonoc_array.h>
#include <phonoc_utils.h>
#include <phonon3_h/imag_self_energy.h>
static double get_imag_self_energy_at_band(const int band_index,
const Darray *fc3_normal_squared,
const double fpoint,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double sigma,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
static double sum_imag_self_energy_at_band(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double sigma,
const double temperature,
const double cutoff_frequency);
static double sum_imag_self_energy_at_band_0K(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double sigma,
const double cutoff_frequency);
/* imag_self_energy[num_band0] */
/* fc3_normal_squared[num_triplets, num_band0, num_band, num_band] */
void get_imag_self_energy(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double fpoint,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double sigma,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, num_band0;
num_band0 = fc3_normal_squared->dims[1];
for (i = 0; i < num_band0; i++) {
imag_self_energy[i] =
get_imag_self_energy_at_band(i,
fc3_normal_squared,
fpoint,
frequencies,
grid_point_triplets,
triplet_weights,
sigma,
temperature,
unit_conversion_factor,
cutoff_frequency);
}
}
void get_imag_self_energy_at_bands(double *imag_self_energy,
const Darray *fc3_normal_squared,
const int *band_indices,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double sigma,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, num_band0, num_band, gp0;
double fpoint;
num_band0 = fc3_normal_squared->dims[1];
num_band = fc3_normal_squared->dims[2];
gp0 = grid_point_triplets[0];
/* num_band0 and num_band_indices have to be same. */
for (i = 0; i < num_band0; i++) {
fpoint = frequencies[gp0 * num_band + band_indices[i]];
imag_self_energy[i] =
get_imag_self_energy_at_band(i,
fc3_normal_squared,
fpoint,
frequencies,
grid_point_triplets,
triplet_weights,
sigma,
temperature,
unit_conversion_factor,
cutoff_frequency);
}
}
static double get_imag_self_energy_at_band(const int band_index,
const Darray *fc3_normal_squared,
const double fpoint,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double sigma,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, num_triplets, num_band0, num_band, gp1, gp2;
double sum_g;
num_triplets = fc3_normal_squared->dims[0];
num_band0 = fc3_normal_squared->dims[1];
num_band = fc3_normal_squared->dims[2];
sum_g = 0;
#pragma omp parallel for private(gp1, gp2) reduction(+:sum_g)
for (i = 0; i < num_triplets; i++) {
gp1 = grid_point_triplets[i * 3 + 1];
gp2 = grid_point_triplets[i * 3 + 2];
if (temperature > 0) {
sum_g +=
sum_imag_self_energy_at_band(num_band,
fc3_normal_squared->data +
i * num_band0 * num_band * num_band +
band_index * num_band * num_band,
fpoint,
frequencies + gp1 * num_band,
frequencies + gp2 * num_band,
sigma,
temperature,
cutoff_frequency) *
triplet_weights[i] * unit_conversion_factor;
} else {
sum_g +=
sum_imag_self_energy_at_band_0K(num_band,
fc3_normal_squared->data +
i * num_band0 * num_band * num_band +
band_index * num_band * num_band,
fpoint,
frequencies + gp1 * num_band,
frequencies + gp2 * num_band,
sigma,
cutoff_frequency) *
triplet_weights[i] * unit_conversion_factor;
}
}
return sum_g;
}
static double sum_imag_self_energy_at_band(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double sigma,
const double temperature,
const double cutoff_frequency)
{
int i, j;
double n2, n3, g1, g2, g3, sum_g;
sum_g = 0;
for (i = 0; i < num_band; i++) {
if (freqs0[i] > cutoff_frequency) {
n2 = bose_einstein(freqs0[i], temperature);
for (j = 0; j < num_band; j++) {
if (freqs1[j] > cutoff_frequency) {
n3 = bose_einstein(freqs1[j], temperature);
g1 = gaussian(fpoint - freqs0[i] - freqs1[j], sigma);
g2 = gaussian(fpoint + freqs0[i] - freqs1[j], sigma);
g3 = gaussian(fpoint - freqs0[i] + freqs1[j], sigma);
sum_g += ((n2 + n3 + 1) * g1 + (n2 - n3) * (g2 - g3)) *
fc3_normal_squared[i * num_band + j];
}
}
}
}
return sum_g;
}
static double sum_imag_self_energy_at_band_0K(const int num_band,
const double *fc3_normal_squared,
const double fpoint,
const double *freqs0,
const double *freqs1,
const double sigma,
const double cutoff_frequency)
{
int i, j;
double g1, sum_g;
sum_g = 0;
for (i = 0; i < num_band; i++) {
if (freqs0[i] > cutoff_frequency) {
for (j = 0; j < num_band; j++) {
if (freqs1[j] > cutoff_frequency) {
g1 = gaussian(fpoint - freqs0[i] - freqs1[j], sigma);
sum_g += g1 * fc3_normal_squared[i * num_band + j];
}
}
}
}
return sum_g;
}

View File

@ -1,388 +0,0 @@
/* Copyright (C) 2015 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. */
#include <stdio.h>
#include <stdlib.h>
#include <phonoc_array.h>
#include <phonoc_utils.h>
#include <phonon3_h/imag_self_energy_with_g.h>
static void imag_self_energy_at_bands(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const double *g,
const char *g_zero,
const double temperature,
const double cutoff_frequency);
static double sum_imag_self_energy_at_band(const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g1,
const double *g2_3,
const char *g_zero);
static double sum_imag_self_energy_at_band_0K(const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g,
const char *g_zero);
static void
detailed_imag_self_energy_at_bands(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
static void
collect_detailed_imag_self_energy(double *imag_self_energy,
const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g1,
const double *g2_3,
const double unit_conversion_factor);
static void
collect_detailed_imag_self_energy_0K(double *imag_self_energy,
const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g,
const double unit_conversion_factor);
void get_imag_self_energy_at_bands_with_g(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const int *weights,
const double *g,
const char *g_zero,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, j, num_triplets, num_band0;
double *ise;
num_triplets = fc3_normal_squared->dims[0];
num_band0 = fc3_normal_squared->dims[1];
ise = (double*)malloc(sizeof(double) * num_triplets * num_band0);
imag_self_energy_at_bands(ise,
fc3_normal_squared,
frequencies,
triplets,
g,
g_zero,
temperature,
cutoff_frequency);
for (i = 0; i < num_band0; i++) {
imag_self_energy[i] = 0;
for (j = 0; j < num_triplets; j++) {
imag_self_energy[i] += ise[j * num_band0 + i] * weights[j];
}
imag_self_energy[i] *= unit_conversion_factor;
}
free(ise);
}
void get_detailed_imag_self_energy_at_bands_with_g
(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
detailed_imag_self_energy_at_bands(imag_self_energy,
fc3_normal_squared,
frequencies,
triplets,
g,
temperature,
unit_conversion_factor,
cutoff_frequency);
}
static void imag_self_energy_at_bands(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const double *g,
const char *g_zero,
const double temperature,
const double cutoff_frequency)
{
int i, j, num_triplets, num_band0, num_band, gp1, gp2, adrs_shift;
double f1, f2;
double *n1, *n2;
num_triplets = fc3_normal_squared->dims[0];
num_band0 = fc3_normal_squared->dims[1];
num_band = fc3_normal_squared->dims[2];
#pragma omp parallel for private(j, gp1, gp2, n1, n2, f1, f2, adrs_shift)
for (i = 0; i < num_triplets; i++) {
gp1 = triplets[i * 3 + 1];
gp2 = triplets[i * 3 + 2];
n1 = (double*)malloc(sizeof(double) * num_band);
n2 = (double*)malloc(sizeof(double) * num_band);
for (j = 0; j < num_band; j++) {
f1 = frequencies[gp1 * num_band + j];
f2 = frequencies[gp2 * num_band + j];
if (f1 > cutoff_frequency) {
n1[j] = bose_einstein(f1, temperature);
} else {
n1[j] = -1;
}
if (f2 > cutoff_frequency) {
n2[j] = bose_einstein(f2, temperature);
} else {
n2[j] = -1;
}
}
for (j = 0; j < num_band0; j++) {
adrs_shift = i * num_band0 * num_band * num_band + j * num_band * num_band;
if (temperature > 0) {
imag_self_energy[i * num_band0 + j] =
sum_imag_self_energy_at_band
(num_band,
fc3_normal_squared->data + adrs_shift,
n1,
n2,
g + adrs_shift,
g + (i + num_triplets) * num_band0 * num_band * num_band +
j * num_band * num_band,
g_zero + adrs_shift);
} else {
imag_self_energy[i * num_band0 + j] =
sum_imag_self_energy_at_band_0K
(num_band,
fc3_normal_squared->data + adrs_shift,
n1,
n2,
g + adrs_shift,
g_zero + adrs_shift);
}
}
free(n1);
free(n2);
}
}
static double sum_imag_self_energy_at_band(const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g1,
const double *g2_3,
const char *g_zero)
{
int ij, i, j;
double sum_g;
sum_g = 0;
for (ij = 0; ij < num_band * num_band; ij++) {
if (g_zero[ij]) {continue;}
i = ij / num_band;
j = ij % num_band;
if (n1[i] < 0 || n2[j] < 0) {continue;}
sum_g += ((n1[i] + n2[j] + 1) * g1[ij] +
(n1[i] - n2[j]) * g2_3[ij]) * fc3_normal_squared[ij];
}
return sum_g;
}
static double sum_imag_self_energy_at_band_0K(const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g1,
const char *g_zero)
{
int ij, i, j;
double sum_g;
sum_g = 0;
for (ij = 0; ij < num_band * num_band; ij++) {
if (g_zero[ij]) {continue;}
i = ij / num_band;
j = ij % num_band;
if (n1[i] < 0 || n2[j] < 0) {continue;}
sum_g += g1[ij] * fc3_normal_squared[ij];
}
return sum_g;
}
static void
detailed_imag_self_energy_at_bands(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency)
{
int i, j, num_triplets, num_band0, num_band, gp1, gp2, offset;
double f1, f2;
double *n1, *n2;
num_triplets = fc3_normal_squared->dims[0];
num_band0 = fc3_normal_squared->dims[1];
num_band = fc3_normal_squared->dims[2];
#pragma omp parallel for private(j, gp1, gp2, n1, n2, f1, f2, offset)
for (i = 0; i < num_triplets; i++) {
gp1 = triplets[i * 3 + 1];
gp2 = triplets[i * 3 + 2];
n1 = (double*)malloc(sizeof(double) * num_band);
n2 = (double*)malloc(sizeof(double) * num_band);
for (j = 0; j < num_band; j++) {
f1 = frequencies[gp1 * num_band + j];
f2 = frequencies[gp2 * num_band + j];
if (f1 > cutoff_frequency) {
n1[j] = bose_einstein(f1, temperature);
} else {
n1[j] = -1;
}
if (f2 > cutoff_frequency) {
n2[j] = bose_einstein(f2, temperature);
} else {
n2[j] = -1;
}
}
for (j = 0; j < num_band0; j++) {
offset = i * num_band0 * num_band * num_band + j * num_band * num_band;
if (temperature > 0) {
collect_detailed_imag_self_energy
(imag_self_energy + offset,
num_band,
fc3_normal_squared->data + offset,
n1,
n2,
g + offset,
g + num_triplets * num_band0 * num_band * num_band + offset,
unit_conversion_factor);
} else {
collect_detailed_imag_self_energy_0K
(imag_self_energy + offset,
num_band,
fc3_normal_squared->data + offset,
n1,
n2,
g + offset,
unit_conversion_factor);
}
}
free(n1);
free(n2);
}
}
static void
collect_detailed_imag_self_energy(double *imag_self_energy,
const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g1,
const double *g2_3,
const double unit_conversion_factor)
{
int i, j, adrs;
for (i = 0; i < num_band; i++) {
if (n1[i] < 0) {
for (j = 0; j < num_band; j++) {
imag_self_energy[i * num_band + j] = 0;
}
continue;
}
for (j = 0; j < num_band; j++) {
adrs = i * num_band + j;
if (n2[j] < 0) {
imag_self_energy[adrs] = 0;
continue;
}
imag_self_energy[adrs] =
((n1[i] + n2[j] + 1) * g1[adrs] + (n1[i] - n2[j]) * g2_3[adrs]) *
fc3_normal_squared[adrs] * unit_conversion_factor;
}
}
}
static void
collect_detailed_imag_self_energy_0K(double *imag_self_energy,
const int num_band,
const double *fc3_normal_squared,
const double *n1,
const double *n2,
const double *g1,
const double unit_conversion_factor)
{
int i, j, adrs;
for (i = 0; i < num_band; i++) {
if (n1[i] < 0) {
for (j = 0; j < num_band; j++) {
imag_self_energy[i * num_band + j] = 0;
}
continue;
}
for (j = 0; j < num_band; j++) {
adrs = i * num_band + j;
if (n2[j] < 0) {
imag_self_energy[adrs] = 0;
continue;
}
imag_self_energy[adrs] =
g1[adrs] * fc3_normal_squared[adrs] * unit_conversion_factor;
}
}
}

View File

@ -1,425 +0,0 @@
/* Copyright (C) 2015 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. */
#include <stdio.h>
#include <stdlib.h>
#include <lapacke.h>
#include <phonoc_array.h>
#include <phonoc_const.h>
#include <phonoc_utils.h>
#include <phonon3_h/interaction.h>
#include <phonon3_h/real_to_reciprocal.h>
#include <phonon3_h/reciprocal_to_normal.h>
static const int index_exchange[6][3] = {{0, 1, 2},
{2, 0, 1},
{1, 2, 0},
{2, 1, 0},
{0, 2, 1},
{1, 0, 2}};
static void get_interaction_at_triplet(Darray *fc3_normal_squared,
const int i,
const char *g_zero,
const Darray *frequencies,
const Carray *eigenvectors,
const Iarray *triplets,
const int *grid_address,
const int *mesh,
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int symmetrize_fc3_q,
const double cutoff_frequency,
const int num_triplets,
const int openmp_at_bands);
static void real_to_normal(double *fc3_normal_squared,
const char *g_zero,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const Darray *fc3,
const double q[9], /* q0, q1, q2 */
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency,
const int triplet_index,
const int num_triplets,
const int openmp_at_bands);
static void real_to_normal_sym_q(double *fc3_normal_squared,
const char *g_zero,
PHPYCONST double *freqs[3],
PHPYCONST lapack_complex_double *eigvecs[3],
const Darray *fc3,
const double q[9], /* q0, q1, q2 */
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency,
const int triplet_index,
const int num_triplets,
const int openmp_at_bands);
/* fc3_normal_squared[num_triplets, num_band0, num_band, num_band] */
void get_interaction(Darray *fc3_normal_squared,
const char *g_zero,
const Darray *frequencies,
const Carray *eigenvectors,
const Iarray *triplets,
const int *grid_address,
const int *mesh,
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int symmetrize_fc3_q,
const double cutoff_frequency)
{
int i, num_band;
num_band = frequencies->dims[1];
if (triplets->dims[0] > num_band * num_band) {
#pragma omp parallel for
for (i = 0; i < triplets->dims[0]; i++) {
get_interaction_at_triplet(fc3_normal_squared,
i,
g_zero,
frequencies,
eigenvectors,
triplets,
grid_address,
mesh,
fc3,
shortest_vectors,
multiplicity,
masses,
p2s_map,
s2p_map,
band_indices,
symmetrize_fc3_q,
cutoff_frequency,
triplets->dims[0],
0);
}
} else {
for (i = 0; i < triplets->dims[0]; i++) {
get_interaction_at_triplet(fc3_normal_squared,
i,
g_zero,
frequencies,
eigenvectors,
triplets,
grid_address,
mesh,
fc3,
shortest_vectors,
multiplicity,
masses,
p2s_map,
s2p_map,
band_indices,
symmetrize_fc3_q,
cutoff_frequency,
triplets->dims[0],
1);
}
}
}
static void get_interaction_at_triplet(Darray *fc3_normal_squared,
const int i,
const char *g_zero,
const Darray *frequencies,
const Carray *eigenvectors,
const Iarray *triplets,
const int *grid_address,
const int *mesh,
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int symmetrize_fc3_q,
const double cutoff_frequency,
const int num_triplets,
const int openmp_at_bands)
{
int j, k, gp, num_band, num_band0;
double *freqs[3];
lapack_complex_double *eigvecs[3];
double q[9];
num_band = frequencies->dims[1];
num_band0 = fc3_normal_squared->dims[1];
for (j = 0; j < 3; j++) {
gp = triplets->data[i * 3 + j];
for (k = 0; k < 3; k++) {
q[j * 3 + k] = ((double)grid_address[gp * 3 + k]) / mesh[k];
}
freqs[j] = frequencies->data + gp * num_band;
eigvecs[j] = eigenvectors->data + gp * num_band * num_band;
}
if (symmetrize_fc3_q) {
real_to_normal_sym_q((fc3_normal_squared->data +
i * num_band0 * num_band * num_band),
g_zero + i * num_band0 * num_band * num_band,
freqs,
eigvecs,
fc3,
q, /* q0, q1, q2 */
shortest_vectors,
multiplicity,
masses,
p2s_map,
s2p_map,
band_indices,
num_band0,
num_band,
cutoff_frequency,
i,
num_triplets,
openmp_at_bands);
} else {
real_to_normal((fc3_normal_squared->data +
i * num_band0 * num_band * num_band),
g_zero + i * num_band0 * num_band * num_band,
freqs[0],
freqs[1],
freqs[2],
eigvecs[0],
eigvecs[1],
eigvecs[2],
fc3,
q, /* q0, q1, q2 */
shortest_vectors,
multiplicity,
masses,
p2s_map,
s2p_map,
band_indices,
num_band0,
num_band,
cutoff_frequency,
i,
num_triplets,
openmp_at_bands);
}
}
static void real_to_normal(double *fc3_normal_squared,
const char* g_zero,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const Darray *fc3,
const double q[9], /* q0, q1, q2 */
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency,
const int triplet_index,
const int num_triplets,
const int openmp_at_bands)
{
int num_patom;
lapack_complex_double *fc3_reciprocal;
num_patom = num_band / 3;
fc3_reciprocal =
(lapack_complex_double*)malloc(sizeof(lapack_complex_double) *
num_patom * num_patom * num_patom * 27);
real_to_reciprocal(fc3_reciprocal,
q,
fc3,
shortest_vectors,
multiplicity,
p2s_map,
s2p_map,
openmp_at_bands);
if (openmp_at_bands) {
#ifdef MEASURE_R2N
printf("At triplet %d/%d (# of bands=%d):\n",
triplet_index, num_triplets, num_band0);
#endif
reciprocal_to_normal_squared_openmp(fc3_normal_squared,
g_zero,
fc3_reciprocal,
freqs0,
freqs1,
freqs2,
eigvecs0,
eigvecs1,
eigvecs2,
masses,
band_indices,
num_band0,
num_band,
cutoff_frequency);
} else {
reciprocal_to_normal_squared(fc3_normal_squared,
g_zero,
fc3_reciprocal,
freqs0,
freqs1,
freqs2,
eigvecs0,
eigvecs1,
eigvecs2,
masses,
band_indices,
num_band0,
num_band,
cutoff_frequency);
}
free(fc3_reciprocal);
}
static void real_to_normal_sym_q(double *fc3_normal_squared,
const char *g_zero,
double *freqs[3],
lapack_complex_double *eigvecs[3],
const Darray *fc3,
const double q[9], /* q0, q1, q2 */
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency,
const int triplet_index,
const int num_triplets,
const int openmp_at_bands)
{
int i, j, k, l;
int band_ex[3];
double q_ex[9];
double *fc3_normal_squared_ex;
fc3_normal_squared_ex =
(double*)malloc(sizeof(double) * num_band * num_band * num_band);
for (i = 0; i < num_band0 * num_band * num_band; i++) {
fc3_normal_squared[i] = 0;
}
for (i = 0; i < 6; i++) {
for (j = 0; j < 3; j ++) {
for (k = 0; k < 3; k ++) {
q_ex[j * 3 + k] = q[index_exchange[i][j] * 3 + k];
}
}
real_to_normal(fc3_normal_squared_ex,
g_zero,
freqs[index_exchange[i][0]],
freqs[index_exchange[i][1]],
freqs[index_exchange[i][2]],
eigvecs[index_exchange[i][0]],
eigvecs[index_exchange[i][1]],
eigvecs[index_exchange[i][2]],
fc3,
q_ex, /* q0, q1, q2 */
shortest_vectors,
multiplicity,
masses,
p2s_map,
s2p_map,
band_indices,
num_band,
num_band,
cutoff_frequency,
triplet_index,
num_triplets,
openmp_at_bands);
for (j = 0; j < num_band0; j++) {
for (k = 0; k < num_band; k++) {
for (l = 0; l < num_band; l++) {
band_ex[0] = band_indices[j];
band_ex[1] = k;
band_ex[2] = l;
fc3_normal_squared[j * num_band * num_band +
k * num_band +
l] +=
fc3_normal_squared_ex[band_ex[index_exchange[i][0]] *
num_band * num_band +
band_ex[index_exchange[i][1]] * num_band +
band_ex[index_exchange[i][2]]] / 6;
}
}
}
}
free(fc3_normal_squared_ex);
}

View File

@ -1,181 +0,0 @@
/* Copyright (C) 2015 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. */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <lapacke.h>
#include <phonoc_array.h>
#include <phonoc_const.h>
#include <phonoc_utils.h>
#include <phonon3_h/real_to_reciprocal.h>
static void real_to_reciprocal_elements(lapack_complex_double *fc3_rec_elem,
const double q[9],
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const int *p2s,
const int *s2p,
const int pi0,
const int pi1,
const int pi2);
/* fc3_reciprocal[num_patom, num_patom, num_patom, 3, 3, 3] */
void real_to_reciprocal(lapack_complex_double *fc3_reciprocal,
const double q[9],
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const int *p2s_map,
const int *s2p_map,
const int openmp_at_bands)
{
int i, j, k, jk, num_patom;
double pre_phase;
lapack_complex_double pre_phase_factor;
num_patom = multiplicity->dims[1];
for (i = 0; i < num_patom; i++) {
if (openmp_at_bands) {
#pragma omp parallel for private(j, k)
for (jk = 0; jk < num_patom * num_patom; jk++) {
j = jk / num_patom;
k = jk % num_patom;
real_to_reciprocal_elements(fc3_reciprocal +
i * 27 * num_patom * num_patom +
j * 27 * num_patom +
k * 27,
q,
fc3,
shortest_vectors,
multiplicity,
p2s_map,
s2p_map,
i, j, k);
}
} else {
for (j = 0; j < num_patom; j++) {
for (k = 0; k < num_patom; k++) {
real_to_reciprocal_elements(fc3_reciprocal +
i * 27 * num_patom * num_patom +
j * 27 * num_patom +
k * 27,
q,
fc3,
shortest_vectors,
multiplicity,
p2s_map,
s2p_map,
i, j, k);
}
}
}
pre_phase = 0;
for (j = 0; j < 3; j++) {
pre_phase += shortest_vectors->data
[p2s_map[i] * shortest_vectors->dims[1] *
shortest_vectors->dims[2] * 3 + j] * (q[j] + q[3 + j] + q[6 + j]);
}
pre_phase_factor = lapack_make_complex_double(cos(M_2PI * pre_phase),
sin(M_2PI * pre_phase));
for (j = 0; j < num_patom * num_patom * 27; j++) {
fc3_reciprocal[i * num_patom * num_patom * 27 + j] =
phonoc_complex_prod(fc3_reciprocal[i * num_patom * num_patom * 27 + j],
pre_phase_factor);
}
}
}
static void real_to_reciprocal_elements(lapack_complex_double *fc3_rec_elem,
const double q[9],
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const int *p2s,
const int *s2p,
const int pi0,
const int pi1,
const int pi2)
{
int i, j, k, l, num_satom;
lapack_complex_double phase_factor, phase_factor1, phase_factor2;
double fc3_rec_real[27], fc3_rec_imag[27];
double *fc3_elem;
for (i = 0; i < 27; i++) {
fc3_rec_real[i] = 0;
fc3_rec_imag[i] = 0;
}
num_satom = multiplicity->dims[0];
i = p2s[pi0];
for (j = 0; j < num_satom; j++) {
if (s2p[j] != p2s[pi1]) {
continue;
}
phase_factor1 =
get_phase_factor(q, shortest_vectors, multiplicity, pi0, j, 1);
for (k = 0; k < num_satom; k++) {
if (s2p[k] != p2s[pi2]) {
continue;
}
phase_factor2 =
get_phase_factor(q, shortest_vectors, multiplicity, pi0, k, 2);
fc3_elem = fc3->data + (i * 27 * num_satom * num_satom +
j * 27 * num_satom +
k * 27);
phase_factor = phonoc_complex_prod(phase_factor1, phase_factor2);
for (l = 0; l < 27; l++) {
fc3_rec_real[l] +=
lapack_complex_double_real(phase_factor) * fc3_elem[l];
fc3_rec_imag[l] +=
lapack_complex_double_imag(phase_factor) * fc3_elem[l];
}
}
}
for (i = 0; i < 27; i++) {
fc3_rec_elem[i] =
lapack_make_complex_double(fc3_rec_real[i], fc3_rec_imag[i]);
}
}

View File

@ -1,283 +0,0 @@
/* Copyright (C) 2015 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. */
#include <stdlib.h>
#include <lapacke.h>
#include <math.h>
#include <phonoc_utils.h>
#include <phonoc_array.h>
#include <phonon3_h/reciprocal_to_normal.h>
#ifdef MEASURE_R2N
#include <time.h>
#endif
static lapack_complex_double fc3_sum_in_reciprocal_to_normal
(const int bi0,
const int bi1,
const int bi2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const lapack_complex_double *fc3_reciprocal,
const double *masses,
const int num_atom);
static double get_fc3_sum
(const int i,
const int j,
const int k,
const int bi,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const lapack_complex_double *fc3_reciprocal,
const double *masses,
const int num_atom,
const int num_band,
const double cutoff_frequency);
void reciprocal_to_normal_squared
(double *fc3_normal_squared,
const char *g_zero,
const lapack_complex_double *fc3_reciprocal,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const double *masses,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency)
{
int i, j, k, bi, num_atom;
num_atom = num_band / 3;
for (i = 0; i < num_band0; i++) {
bi = band_indices[i];
if (freqs0[bi] > cutoff_frequency) {
for (j = 0; j < num_band; j++) {
for (k = 0; k < num_band; k++) {
if (g_zero[i * num_band * num_band + j * num_band + k]) {
fc3_normal_squared[i * num_band * num_band + j * num_band + k] = 0;
continue;
}
fc3_normal_squared[i * num_band * num_band + j * num_band + k] =
get_fc3_sum(i, j, k, bi,
freqs0, freqs1, freqs2,
eigvecs0, eigvecs1, eigvecs2,
fc3_reciprocal,
masses,
num_atom,
num_band,
cutoff_frequency);
}
}
} else {
for (j = 0; j < num_band * num_band; j++) {
fc3_normal_squared[i * num_band * num_band + j] = 0;
}
}
}
}
void reciprocal_to_normal_squared_openmp
(double *fc3_normal_squared,
const char *g_zero,
const lapack_complex_double *fc3_reciprocal,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const double *masses,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency)
{
int i, j, k, l, ijk, jk, bi, num_atom, count;
int *n;
#ifdef MEASURE_R2N
double loopTotalCPUTime, loopTotalWallTime;
time_t loopStartWallTime;
clock_t loopStartCPUTime;
#endif
num_atom = num_band / 3;
n = (int*)malloc(sizeof(int) * num_band0 * num_band * num_band);
count = 0;
for (ijk = 0; ijk < num_band0 * num_band * num_band; ijk++) {
if (g_zero[ijk]) {
fc3_normal_squared[ijk] = 0;
} else {
n[count] = ijk;
count++;
}
}
#ifdef MEASURE_R2N
loopStartWallTime = time(NULL);
loopStartCPUTime = clock();
#endif
#pragma omp parallel for private(ijk, i, j, k, jk, bi)
for (l = 0; l < count; l++) {
ijk = n[l];
i = ijk / (num_band * num_band);
jk = ijk % (num_band * num_band);
j = jk / num_band;
k = jk % num_band;
bi = band_indices[i];
if (freqs0[bi] > cutoff_frequency) {
fc3_normal_squared[n[l]] = get_fc3_sum(i, j, k, bi,
freqs0, freqs1, freqs2,
eigvecs0, eigvecs1, eigvecs2,
fc3_reciprocal,
masses,
num_atom,
num_band,
cutoff_frequency);
} else {
fc3_normal_squared[n[l]] = 0;
}
}
#ifdef MEASURE_R2N
loopTotalCPUTime = (double)(clock() - loopStartCPUTime) / CLOCKS_PER_SEC;
loopTotalWallTime = difftime(time(NULL), loopStartWallTime);
printf(" %1.3fs (%1.3fs CPU)\n", loopTotalWallTime, loopTotalCPUTime);
#endif
free(n);
}
static double get_fc3_sum
(const int i,
const int j,
const int k,
const int bi,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const lapack_complex_double *fc3_reciprocal,
const double *masses,
const int num_atom,
const int num_band,
const double cutoff_frequency)
{
double fff, sum_real, sum_imag;
lapack_complex_double fc3_sum;
if (freqs1[j] > cutoff_frequency && freqs2[k] > cutoff_frequency) {
fff = freqs0[bi] * freqs1[j] * freqs2[k];
fc3_sum = fc3_sum_in_reciprocal_to_normal
(bi, j, k,
eigvecs0, eigvecs1, eigvecs2,
fc3_reciprocal,
masses,
num_atom);
sum_real = lapack_complex_double_real(fc3_sum);
sum_imag = lapack_complex_double_imag(fc3_sum);
return (sum_real * sum_real + sum_imag * sum_imag) / fff;
} else {
return 0;
}
}
static lapack_complex_double fc3_sum_in_reciprocal_to_normal
(const int bi0,
const int bi1,
const int bi2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const lapack_complex_double *fc3_reciprocal,
const double *masses,
const int num_atom)
{
int i, j, k, l, m, n, index_l, index_lm, baseIndex;
double sum_real, sum_imag, mmm, mass_l, mass_lm;
lapack_complex_double eig_prod, eig_prod1;
sum_real = 0;
sum_imag = 0;
for (l = 0; l < num_atom; l++) {
mass_l = masses[l];
index_l = l * num_atom * num_atom * 27;
for (m = 0; m < num_atom; m++) {
mass_lm = mass_l * masses[m];
index_lm = index_l + m * num_atom * 27;
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
eig_prod1 = phonoc_complex_prod
(eigvecs0[(l * 3 + i) * num_atom * 3 + bi0],
eigvecs1[(m * 3 + j) * num_atom * 3 + bi1]);
for (n = 0; n < num_atom; n++) {
mmm = 1.0 / sqrt(mass_lm * masses[n]);
baseIndex = index_lm + n * 27 + i * 9 + j * 3;
for (k = 0; k < 3; k++) {
eig_prod = phonoc_complex_prod
(eig_prod1, eigvecs2[(n * 3 + k) * num_atom * 3 + bi2]);
eig_prod = phonoc_complex_prod
(eig_prod, fc3_reciprocal[baseIndex + k]);
sum_real += lapack_complex_double_real(eig_prod) * mmm;
sum_imag += lapack_complex_double_imag(eig_prod) * mmm;
}
}
}
}
}
}
return lapack_make_complex_double(sum_real, sum_imag);
}

View File

@ -1,146 +0,0 @@
/* Copyright (C) 2015 Atsushi Togo */
/* All rights reserved. */
/* These codes were originally parts of spglib, but only develped */
/* and used for phono3py. Therefore these were moved from spglib to */
/* phono3py. 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. */
#include <mathfunc.h>
#include <triplet_h/triplet.h>
#include <triplet_h/triplet_kpoint.h>
#include <triplet_h/triplet_iw.h>
#include <phonoc_const.h>
static int get_triplets_reciprocal_mesh_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const int is_time_reversal,
const int num_rot,
PHPYCONST int rotations[][3][3]);
int tpl_get_BZ_triplets_at_q(int triplets[][3],
const int grid_point,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const int map_triplets[],
const int num_map_triplets,
const int mesh[3])
{
return tpk_get_BZ_triplets_at_q(triplets,
grid_point,
bz_grid_address,
bz_map,
map_triplets,
num_map_triplets,
mesh);
}
int tpl_get_triplets_reciprocal_mesh_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const int is_time_reversal,
const int num_rot,
PHPYCONST int rotations[][3][3])
{
return get_triplets_reciprocal_mesh_at_q(map_triplets,
map_q,
grid_address,
grid_point,
mesh,
is_time_reversal,
num_rot,
rotations);
}
int tpl_get_integration_weight(double *iw,
char *iw_zero,
const double frequency_points[],
const int num_band0,
PHPYCONST int relative_grid_address[24][4][3],
const int mesh[3],
PHPYCONST int triplets[][3],
const int num_triplets,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const double frequencies[],
const int num_band,
const int num_iw)
{
return tpi_get_integration_weight(iw,
iw_zero,
frequency_points,
num_band0,
relative_grid_address,
mesh,
triplets,
num_triplets,
bz_grid_address,
bz_map,
frequencies,
num_band,
num_iw);
}
static int get_triplets_reciprocal_mesh_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const int is_time_reversal,
const int num_rot,
PHPYCONST int rotations[][3][3])
{
MatINT *rot_real;
int i, num_ir;
rot_real = mat_alloc_MatINT(num_rot);
for (i = 0; i < num_rot; i++) {
mat_copy_matrix_i3(rot_real->mat[i], rotations[i]);
}
num_ir = tpk_get_ir_triplets_at_q(map_triplets,
map_q,
grid_address,
grid_point,
mesh,
is_time_reversal,
rot_real);
mat_free_MatINT(rot_real);
return num_ir;
}

View File

@ -1,220 +0,0 @@
/* Copyright (C) 2016 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. */
#include <triplet_h/triplet_iw.h>
#include <phonoc_const.h>
#include <tetrahedron_method.h>
static void set_freq_vertices(double freq_vertices[3][24][4],
const double frequencies[],
PHPYCONST int vertices[2][24][4],
const int num_band,
const int b1,
const int b2);
static int set_g(double g[3],
const double f0,
PHPYCONST double freq_vertices[3][24][4]);
static int in_tetrahedra(const double f0, PHPYCONST double freq_vertices[24][4]);
static void get_triplet_tetrahedra_vertices
(int vertices[2][24][4],
PHPYCONST int relative_grid_address[2][24][4][3],
const int mesh[3],
const int triplet[3],
PHPYCONST int bz_grid_address[][3],
const int bz_map[]);
int tpi_get_integration_weight(double *iw,
char *iw_zero,
const double frequency_points[],
const int num_band0,
PHPYCONST int relative_grid_address[24][4][3],
const int mesh[3],
PHPYCONST int triplets[][3],
const int num_triplets,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const double frequencies[],
const int num_band,
const int num_iw)
{
int i, j, k, l, b1, b2, sign;
int tp_relative_grid_address[2][24][4][3];
int vertices[2][24][4];
int adrs_shift;
double g[3];
double freq_vertices[3][24][4];
for (i = 0; i < 2; i++) {
sign = 1 - i * 2;
for (j = 0; j < 24; j++) {
for (k = 0; k < 4; k++) {
for (l = 0; l < 3; l++) {
tp_relative_grid_address[i][j][k][l] =
relative_grid_address[j][k][l] * sign;
}
}
}
}
#pragma omp parallel for private(j, b1, b2, vertices, adrs_shift, g, freq_vertices)
for (i = 0; i < num_triplets; i++) {
get_triplet_tetrahedra_vertices(vertices,
tp_relative_grid_address,
mesh,
triplets[i],
bz_grid_address,
bz_map);
for (b1 = 0; b1 < num_band; b1++) {
for (b2 = 0; b2 < num_band; b2++) {
set_freq_vertices
(freq_vertices, frequencies, vertices, num_band, b1, b2);
for (j = 0; j < num_band0; j++) {
adrs_shift = i * num_band0 * num_band * num_band +
j * num_band * num_band + b1 * num_band + b2;
iw_zero[adrs_shift] = set_g(g, frequency_points[j], freq_vertices);
iw[adrs_shift] = g[0];
adrs_shift += num_triplets * num_band0 * num_band * num_band;
iw[adrs_shift] = g[1] - g[2];
if (num_iw == 3) {
adrs_shift += num_triplets * num_band0 * num_band * num_band;
iw[adrs_shift] = g[0] + g[1] + g[2];
}
}
}
}
}
return 0;
}
static void set_freq_vertices(double freq_vertices[3][24][4],
const double frequencies[],
PHPYCONST int vertices[2][24][4],
const int num_band,
const int b1,
const int b2)
{
int i, j;
double f1, f2;
for (i = 0; i < 24; i++) {
for (j = 0; j < 4; j++) {
f1 = frequencies[vertices[0][i][j] * num_band + b1];
f2 = frequencies[vertices[1][i][j] * num_band + b2];
freq_vertices[0][i][j] = f1 + f2;
freq_vertices[1][i][j] = -f1 + f2;
freq_vertices[2][i][j] = f1 - f2;
}
}
}
static int set_g(double g[3],
const double f0,
PHPYCONST double freq_vertices[3][24][4])
{
int iw_zero;
iw_zero = 1;
if (in_tetrahedra(f0, freq_vertices[0])) {
g[0] = thm_get_integration_weight(f0, freq_vertices[0], 'I');
iw_zero = 0;
} else {
g[0] = 0;
}
if (in_tetrahedra(f0, freq_vertices[1])) {
g[1] = thm_get_integration_weight(f0, freq_vertices[1], 'I');
iw_zero = 0;
} else {
g[1] = 0;
}
if (in_tetrahedra(f0, freq_vertices[2])) {
g[2] = thm_get_integration_weight(f0, freq_vertices[2], 'I');
iw_zero = 0;
} else {
g[2] = 0;
}
return iw_zero;
}
static int in_tetrahedra(const double f0, PHPYCONST double freq_vertices[24][4])
{
int i, j;
double fmin, fmax;
fmin = freq_vertices[0][0];
fmax = freq_vertices[0][0];
for (i = 0; i < 24; i++) {
for (j = 0; j < 4; j++) {
if (fmin > freq_vertices[i][j]) {
fmin = freq_vertices[i][j];
}
if (fmax < freq_vertices[i][j]) {
fmax = freq_vertices[i][j];
}
}
}
if (fmin > f0 || fmax < f0) {
return 0;
} else {
return 1;
}
}
static void get_triplet_tetrahedra_vertices
(int vertices[2][24][4],
PHPYCONST int relative_grid_address[2][24][4][3],
const int mesh[3],
const int triplet[3],
PHPYCONST int bz_grid_address[][3],
const int bz_map[])
{
int i, j;
for (i = 0; i < 2; i++) {
for (j = 0; j < 24; j++) {
thm_get_neighboring_grid_points(vertices[i][j],
triplet[i + 1],
relative_grid_address[i][j],
4,
mesh,
bz_grid_address,
bz_map);
}
}
}

View File

@ -1,343 +0,0 @@
/* Copyright (C) 2015 Atsushi Togo */
/* All rights reserved. */
/* These codes were originally parts of spglib, but only develped */
/* and used for phono3py. Therefore these were moved from spglib to */
/* phono3py. 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. */
#include <stdlib.h>
#include <mathfunc.h>
#include <kpoint.h>
#include <kgrid.h>
#include <phonoc_const.h>
#include <triplet_h/triplet_kpoint.h>
static void grid_point_to_address_double(int address_double[3],
const int grid_point,
const int mesh[3],
const int is_shift[3]);
static int get_ir_triplets_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const MatINT * rot_reciprocal);
static int get_BZ_triplets_at_q(int triplets[][3],
const int grid_point,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const int map_triplets[],
const int num_map_triplets,
const int mesh[3]);
static int get_third_q_of_triplets_at_q(int bz_address[3][3],
const int q_index,
const int bz_map[],
const int mesh[3],
const int bzmesh[3]);
static void modulo_i3(int v[3], const int m[3]);
int tpk_get_ir_triplets_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const int is_time_reversal,
const MatINT * rotations)
{
int num_ir;
MatINT *rot_reciprocal;
rot_reciprocal = kpt_get_point_group_reciprocal(rotations, is_time_reversal);
num_ir = get_ir_triplets_at_q(map_triplets,
map_q,
grid_address,
grid_point,
mesh,
rot_reciprocal);
mat_free_MatINT(rot_reciprocal);
return num_ir;
}
int tpk_get_BZ_triplets_at_q(int triplets[][3],
const int grid_point,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const int map_triplets[],
const int num_map_triplets,
const int mesh[3])
{
return get_BZ_triplets_at_q(triplets,
grid_point,
bz_grid_address,
bz_map,
map_triplets,
num_map_triplets,
mesh);
}
static int get_ir_triplets_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const MatINT * rot_reciprocal)
{
int i, j, num_grid, q_2, num_ir_q, num_ir_triplets, ir_grid_point;
int mesh_double[3], is_shift[3];
int address_double0[3], address_double1[3], address_double2[3];
int *ir_grid_points, *third_q;
double tolerance;
double stabilizer_q[1][3];
MatINT *rot_reciprocal_q;
tolerance = 0.01 / (mesh[0] + mesh[1] + mesh[2]);
num_grid = mesh[0] * mesh[1] * mesh[2];
for (i = 0; i < 3; i++) {
/* Only consider the gamma-point */
is_shift[i] = 0;
mesh_double[i] = mesh[i] * 2;
}
/* Search irreducible q-points (map_q) with a stabilizer */
/* q */
grid_point_to_address_double(address_double0, grid_point, mesh, is_shift);
for (i = 0; i < 3; i++) {
stabilizer_q[0][i] =
(double)address_double0[i] / mesh_double[i] - (address_double0[i] > mesh[i]);
}
rot_reciprocal_q = kpt_get_point_group_reciprocal_with_q(rot_reciprocal,
tolerance,
1,
stabilizer_q);
num_ir_q = kpt_get_irreducible_reciprocal_mesh(grid_address,
map_q,
mesh,
is_shift,
rot_reciprocal_q);
mat_free_MatINT(rot_reciprocal_q);
third_q = (int*) malloc(sizeof(int) * num_ir_q);
ir_grid_points = (int*) malloc(sizeof(int) * num_ir_q);
num_ir_q = 0;
for (i = 0; i < num_grid; i++) {
if (map_q[i] == i) {
ir_grid_points[num_ir_q] = i;
num_ir_q++;
}
map_triplets[i] = -1;
}
#pragma omp parallel for private(j, address_double1, address_double2)
for (i = 0; i < num_ir_q; i++) {
grid_point_to_address_double(address_double1,
ir_grid_points[i],
mesh,
is_shift); /* q' */
for (j = 0; j < 3; j++) { /* q'' */
address_double2[j] = - address_double0[j] - address_double1[j];
}
third_q[i] = kgd_get_grid_point_double_mesh(address_double2, mesh);
}
num_ir_triplets = 0;
for (i = 0; i < num_ir_q; i++) {
ir_grid_point = ir_grid_points[i];
q_2 = third_q[i];
if (map_triplets[map_q[q_2]] > -1) {
map_triplets[ir_grid_point] = map_q[q_2];
} else {
map_triplets[ir_grid_point] = ir_grid_point;
num_ir_triplets++;
}
}
#pragma omp parallel for
for (i = 0; i < num_grid; i++) {
map_triplets[i] = map_triplets[map_q[i]];
}
free(third_q);
third_q = NULL;
free(ir_grid_points);
ir_grid_points = NULL;
return num_ir_triplets;
}
static int get_BZ_triplets_at_q(int triplets[][3],
const int grid_point,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const int map_triplets[],
const int num_map_triplets,
const int mesh[3])
{
int i, j, k, num_ir;
int bz_address[3][3], bz_address_double[3], bzmesh[3];
int *ir_grid_points;
for (i = 0; i < 3; i++) {
bzmesh[i] = mesh[i] * 2;
}
num_ir = 0;
ir_grid_points = (int*) malloc(sizeof(int) * num_map_triplets);
for (i = 0; i < num_map_triplets; i++) {
if (map_triplets[i] == i) {
ir_grid_points[num_ir] = i;
num_ir++;
}
}
#pragma omp parallel for private(j, k, bz_address, bz_address_double)
for (i = 0; i < num_ir; i++) {
for (j = 0; j < 3; j++) {
bz_address[0][j] = bz_grid_address[grid_point][j];
bz_address[1][j] = bz_grid_address[ir_grid_points[i]][j];
bz_address[2][j] = - bz_address[0][j] - bz_address[1][j];
}
for (j = 2; j > -1; j--) {
if (get_third_q_of_triplets_at_q(bz_address,
j,
bz_map,
mesh,
bzmesh) == 0) {
break;
}
}
for (j = 0; j < 3; j++) {
for (k = 0; k < 3; k++) {
bz_address_double[k] = bz_address[j][k] * 2;
}
triplets[i][j] =
bz_map[kgd_get_grid_point_double_mesh(bz_address_double, bzmesh)];
}
}
free(ir_grid_points);
return num_ir;
}
static int get_third_q_of_triplets_at_q(int bz_address[3][3],
const int q_index,
const int bz_map[],
const int mesh[3],
const int bzmesh[3])
{
int i, j, smallest_g, smallest_index, sum_g, delta_g[3];
int bzgp[KPT_NUM_BZ_SEARCH_SPACE], bz_address_double[3];
modulo_i3(bz_address[q_index], mesh);
for (i = 0; i < 3; i++) {
delta_g[i] = 0;
for (j = 0; j < 3; j++) {
delta_g[i] += bz_address[j][i];
}
delta_g[i] /= mesh[i];
}
for (i = 0; i < KPT_NUM_BZ_SEARCH_SPACE; i++) {
for (j = 0; j < 3; j++) {
bz_address_double[j] = (bz_address[q_index][j] +
kpt_bz_search_space[i][j] * mesh[j]) * 2;
}
bzgp[i] = bz_map[kgd_get_grid_point_double_mesh(bz_address_double, bzmesh)];
}
for (i = 0; i < KPT_NUM_BZ_SEARCH_SPACE; i++) {
if (bzgp[i] != -1) {
goto escape;
}
}
escape:
smallest_g = 4;
smallest_index = 0;
for (i = 0; i < KPT_NUM_BZ_SEARCH_SPACE; i++) {
if (bzgp[i] > -1) { /* q'' is in BZ */
sum_g = (abs(delta_g[0] + kpt_bz_search_space[i][0]) +
abs(delta_g[1] + kpt_bz_search_space[i][1]) +
abs(delta_g[2] + kpt_bz_search_space[i][2]));
if (sum_g < smallest_g) {
smallest_index = i;
smallest_g = sum_g;
}
}
}
for (i = 0; i < 3; i++) {
bz_address[q_index][i] += kpt_bz_search_space[smallest_index][i] * mesh[i];
}
return smallest_g;
}
static void grid_point_to_address_double(int address_double[3],
const int grid_point,
const int mesh[3],
const int is_shift[3])
{
int i;
int address[3];
#ifndef GRID_ORDER_XYZ
address[2] = grid_point / (mesh[0] * mesh[1]);
address[1] = (grid_point - address[2] * mesh[0] * mesh[1]) / mesh[0];
address[0] = grid_point % mesh[0];
#else
address[0] = grid_point / (mesh[1] * mesh[2]);
address[1] = (grid_point - address[0] * mesh[1] * mesh[2]) / mesh[2];
address[2] = grid_point % mesh[2];
#endif
for (i = 0; i < 3; i++) {
address_double[i] = address[i] * 2 + is_shift[i];
}
}
static void modulo_i3(int v[3], const int m[3])
{
int i;
for (i = 0; i < 3; i++) {
v[i] = v[i] % m[i];
if (v[i] < 0) {
v[i] += m[i];
}
}
}

View File

@ -1,43 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __flame_wrapper_H__
#define __flame_wrapper_H__
int phonopy_pinv_libflame(double *matrix,
double *eigvals,
const int size,
const double cutoff);
#endif

View File

@ -1,65 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __isotope_H__
#define __isotope_H__
void get_isotope_scattering_strength(double *gamma,
const int grid_point,
const double *mass_variances,
const double *frequencies,
const lapack_complex_double *eigenvectors,
const int num_grid_points,
const int *band_indices,
const int num_band,
const int num_band0,
const double sigma,
const double cutoff_frequency);
void
get_thm_isotope_scattering_strength(double *gamma,
const int grid_point,
const int *ir_grid_points,
const int *weights,
const double *mass_variances,
const double *frequencies,
const lapack_complex_double *eigenvectors,
const int num_grid_points,
const int *band_indices,
const int num_band,
const int num_band0,
const double *integration_weights,
const double cutoff_frequency);
#endif

View File

@ -1,64 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __collision_matrix_H__
#define __collision_matrix_H__
#include <phonoc_array.h>
void get_collision_matrix(double *collision_matrix,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const Iarray *triplets_map,
const int *stabilized_gp_map,
const int *ir_grid_points,
const Iarray *rotated_grid_points,
const double *rotations_cartesian,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
void get_reducible_collision_matrix(double *collision_matrix,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const Iarray *triplets_map,
const int *stabilized_gp_map,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
#endif

View File

@ -1,49 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __fc3_H__
#define __fc3_H__
void distribute_fc3(double *fc3_copy,
const double *fc3,
const int third_atom,
const int *atom_mapping,
const int num_atom,
const double *rot_cart);
void tensor3_rotation(double *rot_tensor,
const double *tensor,
const double *rot_cartesian);
void set_permutation_symmetry_fc3(double *fc3, const int num_atom);
#endif

View File

@ -1,51 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __frequency_shift3_H__
#define __frequency_shift3_H__
#include <phonoc_array.h>
#endif
void get_frequency_shift_at_bands(double *frequency_shift,
const Darray *fc3_normal_squared,
const int *band_indices,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double epsilon,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);

View File

@ -1,69 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __imag_self_energy_H__
#define __imag_self_energy_H__
#include <phonoc_array.h>
void get_imag_self_energy(double *gamma,
const Darray *fc3_normal_squared,
const double fpoint,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double sigma,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
void get_imag_self_energy_at_bands(double *imag_self_energy,
const Darray *fc3_normal_squared,
const int *band_indices,
const double *frequencies,
const int *grid_point_triplets,
const int *triplet_weights,
const double sigma,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
int get_jointDOS(double *jdos,
const int num_fpoints,
const int num_triplet,
const int num_band,
const double *frequency_points,
const double *frequencies,
const int *triplets,
const int *weights,
const double sigma);
#endif

View File

@ -1,60 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __imag_self_energy_with_g_H__
#define __imag_self_energy_with_g_H__
#include <phonoc_array.h>
void get_imag_self_energy_at_bands_with_g(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const int *weights,
const double *g,
const char *g_zero,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
void get_detailed_imag_self_energy_at_bands_with_g
(double *imag_self_energy,
const Darray *fc3_normal_squared,
const double *frequencies,
const int *triplets,
const double *g,
const double temperature,
const double unit_conversion_factor,
const double cutoff_frequency);
#endif

View File

@ -1,56 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __interaction_H__
#define __interaction_H__
#include <phonoc_array.h>
void get_interaction(Darray *fc3_normal_squared,
const char *g_zero,
const Darray *frequencies,
const Carray *eigenvectors,
const Iarray *triplets,
const int *grid_address,
const int *mesh,
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const double *masses,
const int *p2s_map,
const int *s2p_map,
const int *band_indices,
const int is_sym_q,
const double cutoff_frequency);
#endif

View File

@ -1,50 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __real_to_reciprocal_H__
#define __real_to_reciprocal_H__
#include <lapacke.h>
#include <phonoc_array.h>
void real_to_reciprocal(lapack_complex_double *fc3_reciprocal,
const double q[9],
const Darray *fc3,
const Darray *shortest_vectors,
const Iarray *multiplicity,
const int *p2s_map,
const int *s2p_map,
const int openmp_at_bands);
#endif

View File

@ -1,73 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __reciprocal_to_normal_H__
#define __reciprocal_to_normal_H__
#include <lapacke.h>
#include <phonoc_array.h>
void reciprocal_to_normal_squared
(double *fc3_normal_squared,
const char *g_zero,
const lapack_complex_double *fc3_reciprocal,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const double *masses,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency);
void reciprocal_to_normal_squared_openmp
(double *fc3_normal_squared,
const char *g_zero,
const lapack_complex_double *fc3_reciprocal,
const double *freqs0,
const double *freqs1,
const double *freqs2,
const lapack_complex_double *eigvecs0,
const lapack_complex_double *eigvecs1,
const lapack_complex_double *eigvecs2,
const double *masses,
const int *band_indices,
const int num_band0,
const int num_band,
const double cutoff_frequency);
#endif

View File

@ -1,86 +0,0 @@
/* Copyright (C) 2015 Atsushi Togo */
/* All rights reserved. */
/* Some of these codes were originally parts of spglib, but only develped */
/* and used for phono3py. Therefore these were moved from spglib to */
/* phono3py. 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. */
#ifndef __triplet_H__
#define __triplet_H__
#include <phonoc_const.h>
/* Irreducible triplets of k-points are searched under conservation of */
/* :math:``\mathbf{k}_1 + \mathbf{k}_2 + \mathbf{k}_3 = \mathbf{G}``. */
/* Memory spaces of grid_address[prod(mesh)][3], map_triplets[prod(mesh)] */
/* and map_q[prod(mesh)] are required. rotations are point-group- */
/* operations in real space for which duplicate operations are allowed */
/* in the input. */
int tpl_get_triplets_reciprocal_mesh_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const int is_time_reversal,
const int num_rot,
PHPYCONST int rotations[][3][3]);
/* Irreducible grid-point-triplets in BZ are stored. */
/* triplets are recovered from grid_point and triplet_weights. */
/* BZ boundary is considered in this recovery. Therefore grid addresses */
/* are given not by grid_address, but by bz_grid_address. */
/* triplets[num_ir_triplets][3] = number of non-zero triplets weights*/
/* Number of ir-triplets is returned. */
int tpl_get_BZ_triplets_at_q(int triplets[][3],
const int grid_point,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const int map_triplets[],
const int num_map_triplets,
const int mesh[3]);
int tpl_get_integration_weight(double *iw,
char *iw_zero,
const double frequency_points[],
const int num_band0,
PHPYCONST int relative_grid_address[24][4][3],
const int mesh[3],
PHPYCONST int triplets[][3],
const int num_triplets,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const double frequencies[],
const int num_band,
const int num_iw);
#endif

View File

@ -1,54 +0,0 @@
/* Copyright (C) 2016 Atsushi Togo */
/* All rights reserved. */
/* phono3py. 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. */
#ifndef __triplet_iw_H__
#define __triplet_iw_H__
#include <phonoc_const.h>
int tpi_get_integration_weight(double *iw,
char *iw_zero,
const double frequency_points[],
const int num_band0,
PHPYCONST int relative_grid_address[24][4][3],
const int mesh[3],
PHPYCONST int triplets[][3],
const int num_triplets,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const double frequencies[],
const int num_band,
const int num_iw);
#endif

View File

@ -1,58 +0,0 @@
/* Copyright (C) 2015 Atsushi Togo */
/* All rights reserved. */
/* These codes were originally parts of spglib, but only develped */
/* and used for phono3py. Therefore these were moved from spglib to */
/* phono3py. 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. */
#ifndef __triplet_kpoint_H__
#define __triplet_kpoint_H__
#include <phonoc_const.h>
#include <mathfunc.h>
int tpk_get_ir_triplets_at_q(int map_triplets[],
int map_q[],
int grid_address[][3],
const int grid_point,
const int mesh[3],
const int is_time_reversal,
const MatINT * rotations);
int tpk_get_BZ_triplets_at_q(int triplets[][3],
const int grid_point,
PHPYCONST int bz_grid_address[][3],
const int bz_map[],
const int map_triplets[],
const int num_map_triplets,
const int mesh[3]);
#endif

View File

@ -1,189 +0,0 @@
/* Copyright (C) 2015 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. */
#include <lapack_wrapper.h>
#include <lapacke.h>
#define min(a,b) ((a)>(b)?(b):(a))
int phonopy_zheev(double *w,
lapack_complex_double *a,
const int n,
const char uplo)
{
lapack_int info;
info = LAPACKE_zheev(LAPACK_ROW_MAJOR,'V', uplo,
(lapack_int)n, a, (lapack_int)n, w);
return (int)info;
}
int phonopy_pinv(double *data_out,
const double *data_in,
const int m,
const int n,
const double cutoff)
{
int i, j, k;
lapack_int info;
double *s, *a, *u, *vt, *superb;
a = (double*)malloc(sizeof(double) * m * n);
s = (double*)malloc(sizeof(double) * min(m,n));
u = (double*)malloc(sizeof(double) * m * m);
vt = (double*)malloc(sizeof(double) * n * n);
superb = (double*)malloc(sizeof(double) * (min(m,n) - 1));
for (i = 0; i < m * n; i++) {
a[i] = data_in[i];
}
info = LAPACKE_dgesvd(LAPACK_ROW_MAJOR,
'A',
'A',
(lapack_int)m,
(lapack_int)n,
a,
(lapack_int)n,
s,
u,
(lapack_int)m,
vt,
(lapack_int)n,
superb);
for (i = 0; i < n * m; i++) {
data_out[i] = 0;
}
for (i = 0; i < m; i++) {
for (j = 0; j < n; j++) {
for (k = 0; k < min(m,n); k++) {
if (s[k] > cutoff) {
data_out[j * m + i] += u[i * m + k] / s[k] * vt[k * n + j];
}
}
}
}
free(a);
free(s);
free(u);
free(vt);
free(superb);
return (int)info;
}
void phonopy_pinv_mt(double *data_out,
int *info_out,
const double *data_in,
const int num_thread,
const int *row_nums,
const int max_row_num,
const int column_num,
const double cutoff)
{
int i;
#pragma omp parallel for
for (i = 0; i < num_thread; i++) {
info_out[i] = phonopy_pinv(data_out + i * max_row_num * column_num,
data_in + i * max_row_num * column_num,
row_nums[i],
column_num,
cutoff);
}
}
int phonopy_pinv_dsyev(double *data,
double *eigvals,
const int size,
const double cutoff)
{
int i, j, k;
lapack_int info;
double *tmp_data;
tmp_data = (double*)malloc(sizeof(double) * size * size);
#pragma omp parallel for
for (i = 0; i < size * size; i++) {
tmp_data[i] = data[i];
data[i] = 0;
}
info = LAPACKE_dsyev(LAPACK_ROW_MAJOR,
'V',
'U',
(lapack_int)size,
tmp_data,
(lapack_int)size,
eigvals);
#pragma omp parallel for private(j, k)
for (i = 0; i < size; i++) {
for (j = 0; j < size; j++) {
for (k = 0; k < size; k++) {
if (eigvals[k] > cutoff) {
data[i * size + j] +=
tmp_data[i * size + k] / eigvals[k] * tmp_data[j * size + k];
}
}
}
}
/* info = LAPACKE_dsyev(LAPACK_COL_MAJOR, */
/* 'V', */
/* 'U', */
/* (lapack_int)size, */
/* tmp_data, */
/* (lapack_int)size, */
/* w); */
/* #pragma omp parallel for private(j, k) */
/* for (i = 0; i < size; i++) { */
/* for (j = 0; j < size; j++) { */
/* for (k = 0; k < size; k++) { */
/* if (w[k] > cutoff) { */
/* data[i * size + j] += */
/* tmp_data[k * size + i] / w[k] * tmp_data[k * size + j]; */
/* } */
/* } */
/* } */
/* } */
free(tmp_data);
return (int)info;
}

View File

@ -1,77 +0,0 @@
/* Copyright (C) 2015 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. */
#include <Python.h>
#include <numpy/arrayobject.h>
#include <lapacke.h>
#include <phonoc_array.h>
Iarray* convert_to_iarray(const PyArrayObject* npyary)
{
int i;
Iarray *ary;
ary = (Iarray*) malloc(sizeof(Iarray));
for (i = 0; i < PyArray_NDIM(npyary); i++) {
ary->dims[i] = PyArray_DIMS(npyary)[i];
}
ary->data = (int*)PyArray_DATA(npyary);
return ary;
}
Darray* convert_to_darray(const PyArrayObject* npyary)
{
int i;
Darray *ary;
ary = (Darray*) malloc(sizeof(Darray));
for (i = 0; i < PyArray_NDIM(npyary); i++) {
ary->dims[i] = PyArray_DIMS(npyary)[i];
}
ary->data = (double*)PyArray_DATA(npyary);
return ary;
}
Carray* convert_to_carray(const PyArrayObject* npyary)
{
int i;
Carray *ary;
ary = (Carray*) malloc(sizeof(Carray));
for (i = 0; i < PyArray_NDIM(npyary); i++) {
ary->dims[i] = PyArray_DIMS(npyary)[i];
}
ary->data = (lapack_complex_double*)PyArray_DATA(npyary);
return ary;
}

View File

@ -1,104 +0,0 @@
/* Copyright (C) 2015 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. */
#include <lapacke.h>
#include <math.h>
#include <dynmat.h>
#include <phonoc_array.h>
#include <phonoc_const.h>
#include <phonoc_utils.h>
#include <lapack_wrapper.h>
#define THZTOEVPARKB 47.992398658977166
#define INVSQRT2PI 0.3989422804014327
lapack_complex_double get_phase_factor(const double q[],
const Darray *shortest_vectors,
const Iarray *multiplicity,
const int pi0,
const int si,
const int qi)
{
int i, j, multi;
double *svecs;
double sum_real, sum_imag, phase;
svecs = shortest_vectors->data + (si * shortest_vectors->dims[1] *
shortest_vectors->dims[2] * 3 +
pi0 * shortest_vectors->dims[2] * 3);
multi = multiplicity->data[si * multiplicity->dims[1] + pi0];
sum_real = 0;
sum_imag = 0;
for (i = 0; i < multi; i++) {
phase = 0;
for (j = 0; j < 3; j++) {
phase += q[qi * 3 + j] * svecs[i * 3 + j];
}
sum_real += cos(M_2PI * phase);
sum_imag += sin(M_2PI * phase);
}
sum_real /= multi;
sum_imag /= multi;
return lapack_make_complex_double(sum_real, sum_imag);
}
double bose_einstein(const double x, const double t)
{
return 1.0 / (exp(THZTOEVPARKB * x / t) - 1);
}
double gaussian(const double x, const double sigma)
{
return INVSQRT2PI / sigma * exp(-x * x / 2 / sigma / sigma);
}
double inv_sinh_occupation(const double x, const double t)
{
return 1.0 / sinh(x * THZTOEVPARKB / 2 / t);
}
lapack_complex_double
phonoc_complex_prod(const lapack_complex_double a,
const lapack_complex_double b)
{
lapack_complex_double c;
c = lapack_make_complex_double
(lapack_complex_double_real(a) * lapack_complex_double_real(b) -
lapack_complex_double_imag(a) * lapack_complex_double_imag(b),
lapack_complex_double_imag(a) * lapack_complex_double_real(b) +
lapack_complex_double_real(a) * lapack_complex_double_imag(b));
return c;
}

View File

@ -1,282 +0,0 @@
/* Copyright (C) 2015 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. */
#include <lapacke.h>
#include <math.h>
#include <dynmat.h>
#include <phonoc_array.h>
#include <phonon.h>
#include <lapack_wrapper.h>
static int collect_undone_grid_points(int *undone,
char *phonon_done,
const int num_grid_points,
const int *grid_points);
void set_phonons_at_gridpoints(Darray *frequencies,
Carray *eigenvectors,
char *phonon_done,
const Iarray *grid_points,
const int *grid_address,
const int *mesh,
const Darray *fc2,
const Darray *svecs_fc2,
const Iarray *multi_fc2,
const double *masses_fc2,
const int *p2s_fc2,
const int *s2p_fc2,
const double unit_conversion_factor,
const double *born,
const double *dielectric,
const double *reciprocal_lattice,
const double *q_direction,
const double nac_factor,
const char uplo)
{
int num_undone;
int *undone;
undone = (int*)malloc(sizeof(int) * frequencies->dims[0]);
num_undone = collect_undone_grid_points(undone,
phonon_done,
grid_points->dims[0],
grid_points->data);
get_undone_phonons(frequencies,
eigenvectors,
undone,
num_undone,
grid_address,
mesh,
fc2,
svecs_fc2,
multi_fc2,
masses_fc2,
p2s_fc2,
s2p_fc2,
unit_conversion_factor,
born,
dielectric,
reciprocal_lattice,
q_direction,
nac_factor,
uplo);
free(undone);
}
void get_undone_phonons(Darray *frequencies,
Carray *eigenvectors,
const int *undone_grid_points,
const int num_undone_grid_points,
const int *grid_address,
const int *mesh,
const Darray *fc2,
const Darray *svecs_fc2,
const Iarray *multi_fc2,
const double *masses_fc2,
const int *p2s_fc2,
const int *s2p_fc2,
const double unit_conversion_factor,
const double *born,
const double *dielectric,
const double *reciprocal_lattice,
const double *q_direction,
const double nac_factor,
const char uplo)
{
int i, j, gp, num_band;
double q[3];
num_band = frequencies->dims[1];
#pragma omp parallel for private(j, q, gp)
for (i = 0; i < num_undone_grid_points; i++) {
gp = undone_grid_points[i];
for (j = 0; j < 3; j++) {
q[j] = ((double)grid_address[gp * 3 + j]) / mesh[j];
}
if (gp == 0) {
get_phonons(eigenvectors->data + num_band * num_band * gp,
frequencies->data + num_band * gp,
q,
fc2,
masses_fc2,
p2s_fc2,
s2p_fc2,
multi_fc2,
svecs_fc2,
born,
dielectric,
reciprocal_lattice,
q_direction,
nac_factor,
unit_conversion_factor,
uplo);
} else {
get_phonons(eigenvectors->data + num_band * num_band * gp,
frequencies->data + num_band * gp,
q,
fc2,
masses_fc2,
p2s_fc2,
s2p_fc2,
multi_fc2,
svecs_fc2,
born,
dielectric,
reciprocal_lattice,
NULL,
nac_factor,
unit_conversion_factor,
uplo);
}
}
}
int get_phonons(lapack_complex_double *a,
double *w,
const double q[3],
const Darray *fc2,
const double *masses,
const int *p2s,
const int *s2p,
const Iarray *multi,
const Darray *svecs,
const double *born,
const double *dielectric,
const double *reciprocal_lattice,
const double *q_direction,
const double nac_factor,
const double unit_conversion_factor,
const char uplo)
{
int i, j, num_patom, num_satom, info;
double q_cart[3];
double *charge_sum;
double inv_dielectric_factor, dielectric_factor, tmp_val;
num_patom = multi->dims[1];
num_satom = multi->dims[0];
if (born) {
if (fabs(q[0]) < 1e-10 && fabs(q[1]) < 1e-10 && fabs(q[2]) < 1e-10 &&
(!q_direction)) {
charge_sum = NULL;
} else {
charge_sum = (double*) malloc(sizeof(double) * num_patom * num_patom * 9);
if (q_direction) {
for (i = 0; i < 3; i++) {
q_cart[i] = 0.0;
for (j = 0; j < 3; j++) {
q_cart[i] += reciprocal_lattice[i * 3 + j] * q_direction[j];
}
}
} else {
for (i = 0; i < 3; i++) {
q_cart[i] = 0.0;
for (j = 0; j < 3; j++) {
q_cart[i] += reciprocal_lattice[i * 3 + j] * q[j];
}
}
}
inv_dielectric_factor = 0.0;
for (i = 0; i < 3; i++) {
tmp_val = 0.0;
for (j = 0; j < 3; j++) {
tmp_val += dielectric[i * 3 + j] * q_cart[j];
}
inv_dielectric_factor += tmp_val * q_cart[i];
}
/* N = num_satom / num_patom = number of prim-cell in supercell */
/* N is used for Wang's method. */
dielectric_factor = nac_factor /
inv_dielectric_factor / num_satom * num_patom;
get_charge_sum(charge_sum,
num_patom,
dielectric_factor,
q_cart,
born);
}
} else {
charge_sum = NULL;
}
get_dynamical_matrix_at_q((double*)a,
num_patom,
num_satom,
fc2->data,
q,
svecs->data,
multi->data,
masses,
s2p,
p2s,
charge_sum,
0);
if (born) {
free(charge_sum);
}
info = phonopy_zheev(w, a, num_patom * 3, uplo);
for (i = 0; i < num_patom * 3; i++) {
w[i] =
sqrt(fabs(w[i])) * ((w[i] > 0) - (w[i] < 0)) * unit_conversion_factor;
}
return info;
}
static int collect_undone_grid_points(int *undone,
char *phonon_done,
const int num_grid_points,
const int *grid_points)
{
int i, gp, num_undone;
num_undone = 0;
for (i = 0; i < num_grid_points; i++) {
gp = grid_points[i];
if (phonon_done[gp] == 0) {
undone[num_undone] = gp;
num_undone++;
phonon_done[gp] = 1;
}
}
return num_undone;
}

View File

@ -1,61 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __lapack_wrapper_H__
#define __lapack_wrapper_H__
#include <lapacke.h>
int phonopy_zheev(double *w,
lapack_complex_double *a,
const int n,
const char uplo);
int phonopy_pinv(double *data_out,
const double *data_in,
const int m,
const int n,
const double cutoff);
void phonopy_pinv_mt(double *data_out,
int *info_out,
const double *data_in,
const int num_thread,
const int *row_nums,
const int max_row_num,
const int column_num,
const double cutoff);
int phonopy_pinv_dsyev(double *data,
double *eigvals,
const int size,
const double cutoff);
#endif

View File

@ -1,63 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __phonoc_array_H__
#define __phonoc_array_H__
#include <Python.h>
#include <numpy/arrayobject.h>
#include <lapacke.h>
#define MAX_NUM_DIM 20
/* It is assumed that number of dimensions is known for each array. */
typedef struct {
int dims[MAX_NUM_DIM];
int *data;
} Iarray;
typedef struct {
int dims[MAX_NUM_DIM];
double *data;
} Darray;
typedef struct {
int dims[MAX_NUM_DIM];
lapack_complex_double *data;
} Carray;
Iarray* convert_to_iarray(const PyArrayObject* npyary);
Darray* convert_to_darray(const PyArrayObject* npyary);
Carray* convert_to_carray(const PyArrayObject* npyary);
#endif

View File

@ -1,54 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __phonoc_utils_H__
#define __phonoc_utils_H__
#include <lapacke.h>
#include <phonoc_array.h>
lapack_complex_double get_phase_factor(const double q[],
const Darray *shortest_vectors,
const Iarray *multiplicity,
const int pi0,
const int si,
const int qi);
double bose_einstein(const double x, const double t);
double gaussian(const double x, const double sigma);
double inv_sinh_occupation(const double x, const double t);
lapack_complex_double
phonoc_complex_prod(const lapack_complex_double a,
const lapack_complex_double b);
#endif

View File

@ -1,96 +0,0 @@
/* Copyright (C) 2015 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. */
#ifndef __phonon_H__
#define __phonon_H__
#include <lapacke.h>
#include <phonoc_array.h>
void set_phonons_at_gridpoints(Darray *frequencies,
Carray *eigenvectors,
char *phonon_done,
const Iarray *grid_points,
const int *grid_address,
const int *mesh,
const Darray *fc2,
const Darray *svecs_fc2,
const Iarray *multi_fc2,
const double *masses_fc2,
const int *p2s_fc2,
const int *s2p_fc2,
const double unit_conversion_factor,
const double *born,
const double *dielectric,
const double *reciprocal_lattice,
const double *q_direction,
const double nac_factor,
const char uplo);
void get_undone_phonons(Darray *frequencies,
Carray *eigenvectors,
const int *undone_grid_points,
const int num_undone_grid_points,
const int *grid_address,
const int *mesh,
const Darray *fc2,
const Darray *svecs_fc2,
const Iarray *multi_fc2,
const double *masses_fc2,
const int *p2s_fc2,
const int *s2p_fc2,
const double unit_conversion_factor,
const double *born,
const double *dielectric,
const double *reciprocal_lattice,
const double *q_direction,
const double nac_factor,
const char uplo);
int get_phonons(lapack_complex_double *a,
double *w,
const double q[3],
const Darray *fc2,
const double *masses,
const int *p2s,
const int *s2p,
const Iarray *multi,
const Darray *svecs,
const double *born,
const double *dielectric,
const double *reciprocal_lattice,
const double *q_direction,
const double nac_factor,
const double unit_conversion_factor,
const char uplo);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -1,11 +0,0 @@
This is the example of silicon calculation. The supercell is 2x2x2 of the conventinal unit cell. The pwscf calculation was made to obtain forces with 50 Ry, 2x2x2 k-point mesh for the supercell, PBE, and the lattice parameters in Si.in. Silicon crystal is F-centre, so there is the transformation matrix from the conventinal unit cell to the primitive cell.
To create fc3.hdf5 and fc2.hdf5,
% phono3py --pwscf -c Si.in --dim="2 2 2" --sym_fc3r --sym_fc2 --tsym
Using 11x11x11 sampling mesh, lattice thermal conductivity is calculated by
% phono3py --pwscf -c Si.in --dim="2 2 2" --pa="0 1/2 1/2 1/2 0 1/2 1/2 1/2 0" --mesh="11 11 11" --fc3 --fc2 --br
kappa-m111111.hdf5 is written as the result. The lattice thermal conductivity is calculated as 101.9 W/m-K at 300 K. This becomes, with 19x19x19 sampling mesh, 130.0 W/m-K.

View File

@ -1,34 +0,0 @@
&control
calculation = 'scf'
pseudo_dir = '/home/togo/espresso/pseudo/'
/
&system
ibrav = 0
nat = 8
ntyp = 1
occupations = 'smearing'
smearing = 'gaussian'
degauss = 0.01
ecutwfc = 50.0
/
&electrons
diagonalization = 'david'
conv_thr = 1.0d-9
/
ATOMIC_SPECIES
Si 28.086 Si.pbe-n-kjpaw_psl.0.1.UPF
ATOMIC_POSITIONS crystal
Si 0.8750000000000000 0.8750000000000000 0.8750000000000000
Si 0.8750000000000000 0.3750000000000000 0.3750000000000000
Si 0.3750000000000000 0.8750000000000000 0.3750000000000000
Si 0.3750000000000000 0.3750000000000000 0.8750000000000000
Si 0.1250000000000000 0.1250000000000000 0.1250000000000000
Si 0.1250000000000000 0.6250000000000000 0.6250000000000000
Si 0.6250000000000000 0.1250000000000000 0.6250000000000000
Si 0.6250000000000000 0.6250000000000000 0.1250000000000000
CELL_PARAMETERS angstrom
5.4661639157319968 0 0
0 5.4661639157319968 0
0 0 5.4661639157319968
K_POINTS automatic
4 4 4 1 1 1

View File

@ -1,330 +0,0 @@
natom: 64
num_first_displacements: 1
num_second_displacements: 110
num_displacements_created: 111
first_atoms:
- number: 1
displacement:
[ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00001
second_atoms:
- number: 1
distance: 0.000000
displacements:
- [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00002
- [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00003
- number: 2
distance: 10.329553
displacements:
- [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00004
- [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00005
- number: 3
distance: 10.329553
displacements:
- [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00006
- [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00007
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00008
- number: 4
distance: 14.608194
displacements:
- [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00009
- [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00010
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00011
- number: 7
distance: 14.608194
displacements:
- [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00012
- [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00013
- number: 8
distance: 17.891310
displacements:
- [ 0.0424264068711929, 0.0424264068711929, 0.0000000000000000 ] # 00014
- [ -0.0424264068711929, -0.0424264068711929, 0.0000000000000000 ] # 00015
- number: 9
distance: 7.304097
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00016
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00017
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00018
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00019
- number: 10
distance: 12.651067
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00020
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00021
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00022
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00023
- number: 11
distance: 7.304097
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00024
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00025
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00026
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00027
- number: 12
distance: 12.651067
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00028
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00029
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00030
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00031
- number: 17
distance: 7.304097
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00032
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00033
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00034
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00035
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00036
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00037
- number: 18
distance: 7.304097
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00038
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00039
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00040
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00041
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00042
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00043
- number: 19
distance: 12.651067
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00044
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00045
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00046
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00047
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00048
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00049
- number: 20
distance: 12.651067
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00050
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00051
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00052
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00053
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00054
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00055
- number: 33
distance: 13.418483
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00056
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00057
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00058
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00059
- number: 34
distance: 11.256369
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00060
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00061
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00062
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00063
- number: 35
distance: 11.256369
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00064
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00065
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00066
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00067
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00068
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00069
- number: 36
distance: 8.564813
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00070
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00071
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00072
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00073
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00074
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00075
- number: 39
distance: 8.564813
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00076
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00077
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00078
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00079
- number: 40
distance: 4.472828
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00080
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00081
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00082
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00083
- number: 49
distance: 8.564813
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00084
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00085
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00086
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00087
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00088
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00089
- number: 50
distance: 11.256369
displacements:
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00090
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00091
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00092
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00093
- [ 0.0000000000000000, 0.0000000000000000, 0.0600000000000000 ] # 00094
- [ 0.0000000000000000, 0.0000000000000000, -0.0600000000000000 ] # 00095
- number: 51
distance: 4.472828
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00096
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00097
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00098
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00099
- number: 52
distance: 8.564813
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00100
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00101
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00102
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00103
- number: 53
distance: 11.256369
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00104
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00105
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00106
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00107
- number: 54
distance: 13.418483
displacements:
- [ 0.0000000000000000, 0.0600000000000000, 0.0000000000000000 ] # 00108
- [ 0.0000000000000000, -0.0600000000000000, 0.0000000000000000 ] # 00109
- [ 0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00110
- [ -0.0600000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00111
lattice:
- [ 20.659105641913271, 0.000000000000000, 0.000000000000000 ]
- [ 0.000000000000000, 20.659105641913271, 0.000000000000000 ]
- [ 0.000000000000000, 0.000000000000000, 20.659105641913271 ]
atoms:
- symbol: Si # 1
position: [ 0.43750000000000, 0.43750000000000, 0.43750000000000 ]
- symbol: Si # 2
position: [ 0.93750000000000, 0.43750000000000, 0.43750000000000 ]
- symbol: Si # 3
position: [ 0.43750000000000, 0.93750000000000, 0.43750000000000 ]
- symbol: Si # 4
position: [ 0.93750000000000, 0.93750000000000, 0.43750000000000 ]
- symbol: Si # 5
position: [ 0.43750000000000, 0.43750000000000, 0.93750000000000 ]
- symbol: Si # 6
position: [ 0.93750000000000, 0.43750000000000, 0.93750000000000 ]
- symbol: Si # 7
position: [ 0.43750000000000, 0.93750000000000, 0.93750000000000 ]
- symbol: Si # 8
position: [ 0.93750000000000, 0.93750000000000, 0.93750000000000 ]
- symbol: Si # 9
position: [ 0.43750000000000, 0.18750000000000, 0.18750000000000 ]
- symbol: Si # 10
position: [ 0.93750000000000, 0.18750000000000, 0.18750000000000 ]
- symbol: Si # 11
position: [ 0.43750000000000, 0.68750000000000, 0.18750000000000 ]
- symbol: Si # 12
position: [ 0.93750000000000, 0.68750000000000, 0.18750000000000 ]
- symbol: Si # 13
position: [ 0.43750000000000, 0.18750000000000, 0.68750000000000 ]
- symbol: Si # 14
position: [ 0.93750000000000, 0.18750000000000, 0.68750000000000 ]
- symbol: Si # 15
position: [ 0.43750000000000, 0.68750000000000, 0.68750000000000 ]
- symbol: Si # 16
position: [ 0.93750000000000, 0.68750000000000, 0.68750000000000 ]
- symbol: Si # 17
position: [ 0.18750000000000, 0.43750000000000, 0.18750000000000 ]
- symbol: Si # 18
position: [ 0.68750000000000, 0.43750000000000, 0.18750000000000 ]
- symbol: Si # 19
position: [ 0.18750000000000, 0.93750000000000, 0.18750000000000 ]
- symbol: Si # 20
position: [ 0.68750000000000, 0.93750000000000, 0.18750000000000 ]
- symbol: Si # 21
position: [ 0.18750000000000, 0.43750000000000, 0.68750000000000 ]
- symbol: Si # 22
position: [ 0.68750000000000, 0.43750000000000, 0.68750000000000 ]
- symbol: Si # 23
position: [ 0.18750000000000, 0.93750000000000, 0.68750000000000 ]
- symbol: Si # 24
position: [ 0.68750000000000, 0.93750000000000, 0.68750000000000 ]
- symbol: Si # 25
position: [ 0.18750000000000, 0.18750000000000, 0.43750000000000 ]
- symbol: Si # 26
position: [ 0.68750000000000, 0.18750000000000, 0.43750000000000 ]
- symbol: Si # 27
position: [ 0.18750000000000, 0.68750000000000, 0.43750000000000 ]
- symbol: Si # 28
position: [ 0.68750000000000, 0.68750000000000, 0.43750000000000 ]
- symbol: Si # 29
position: [ 0.18750000000000, 0.18750000000000, 0.93750000000000 ]
- symbol: Si # 30
position: [ 0.68750000000000, 0.18750000000000, 0.93750000000000 ]
- symbol: Si # 31
position: [ 0.18750000000000, 0.68750000000000, 0.93750000000000 ]
- symbol: Si # 32
position: [ 0.68750000000000, 0.68750000000000, 0.93750000000000 ]
- symbol: Si # 33
position: [ 0.06250000000000, 0.06250000000000, 0.06250000000000 ]
- symbol: Si # 34
position: [ 0.56250000000000, 0.06250000000000, 0.06250000000000 ]
- symbol: Si # 35
position: [ 0.06250000000000, 0.56250000000000, 0.06250000000000 ]
- symbol: Si # 36
position: [ 0.56250000000000, 0.56250000000000, 0.06250000000000 ]
- symbol: Si # 37
position: [ 0.06250000000000, 0.06250000000000, 0.56250000000000 ]
- symbol: Si # 38
position: [ 0.56250000000000, 0.06250000000000, 0.56250000000000 ]
- symbol: Si # 39
position: [ 0.06250000000000, 0.56250000000000, 0.56250000000000 ]
- symbol: Si # 40
position: [ 0.56250000000000, 0.56250000000000, 0.56250000000000 ]
- symbol: Si # 41
position: [ 0.06250000000000, 0.31250000000000, 0.31250000000000 ]
- symbol: Si # 42
position: [ 0.56250000000000, 0.31250000000000, 0.31250000000000 ]
- symbol: Si # 43
position: [ 0.06250000000000, 0.81250000000000, 0.31250000000000 ]
- symbol: Si # 44
position: [ 0.56250000000000, 0.81250000000000, 0.31250000000000 ]
- symbol: Si # 45
position: [ 0.06250000000000, 0.31250000000000, 0.81250000000000 ]
- symbol: Si # 46
position: [ 0.56250000000000, 0.31250000000000, 0.81250000000000 ]
- symbol: Si # 47
position: [ 0.06250000000000, 0.81250000000000, 0.81250000000000 ]
- symbol: Si # 48
position: [ 0.56250000000000, 0.81250000000000, 0.81250000000000 ]
- symbol: Si # 49
position: [ 0.31250000000000, 0.06250000000000, 0.31250000000000 ]
- symbol: Si # 50
position: [ 0.81250000000000, 0.06250000000000, 0.31250000000000 ]
- symbol: Si # 51
position: [ 0.31250000000000, 0.56250000000000, 0.31250000000000 ]
- symbol: Si # 52
position: [ 0.81250000000000, 0.56250000000000, 0.31250000000000 ]
- symbol: Si # 53
position: [ 0.31250000000000, 0.06250000000000, 0.81250000000000 ]
- symbol: Si # 54
position: [ 0.81250000000000, 0.06250000000000, 0.81250000000000 ]
- symbol: Si # 55
position: [ 0.31250000000000, 0.56250000000000, 0.81250000000000 ]
- symbol: Si # 56
position: [ 0.81250000000000, 0.56250000000000, 0.81250000000000 ]
- symbol: Si # 57
position: [ 0.31250000000000, 0.31250000000000, 0.06250000000000 ]
- symbol: Si # 58
position: [ 0.81250000000000, 0.31250000000000, 0.06250000000000 ]
- symbol: Si # 59
position: [ 0.31250000000000, 0.81250000000000, 0.06250000000000 ]
- symbol: Si # 60
position: [ 0.81250000000000, 0.81250000000000, 0.06250000000000 ]
- symbol: Si # 61
position: [ 0.31250000000000, 0.31250000000000, 0.56250000000000 ]
- symbol: Si # 62
position: [ 0.81250000000000, 0.31250000000000, 0.56250000000000 ]
- symbol: Si # 63
position: [ 0.31250000000000, 0.81250000000000, 0.56250000000000 ]
- symbol: Si # 64
position: [ 0.81250000000000, 0.81250000000000, 0.56250000000000 ]

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +0,0 @@
Si
1.0
5.4335600309153529 0.0000000000000000 0.0000000000000000
0.0000000000000000 5.4335600309153529 0.0000000000000000
0.0000000000000000 0.0000000000000000 5.4335600309153529
Si
8
Direct
0.8750000000000000 0.8750000000000000 0.8750000000000000
0.8750000000000000 0.3750000000000000 0.3750000000000000
0.3750000000000000 0.8750000000000000 0.3750000000000000
0.3750000000000000 0.3750000000000000 0.8750000000000000
0.1250000000000000 0.1250000000000000 0.1250000000000000
0.1250000000000000 0.6250000000000000 0.6250000000000000
0.6250000000000000 0.1250000000000000 0.6250000000000000
0.6250000000000000 0.6250000000000000 0.1250000000000000

View File

@ -1,24 +0,0 @@
This is the example of silicon calculation. The supercell is 2x2x2 of the conventinal unit cell. The VASP calculation was made for force calculations with 300 eV, 2x2x2 k-point mesh for the supercell, and PBE-sol. Silicon crystal is F-centre, so there is the transformation matrix from the conventinal unit cell to the primitive cell.
To create fc3.hdf5 and fc2.hdf5,
% phono3py --dim="2 2 2" --sym_fc3r --sym_fc2 --tsym -c POSCAR-unitcell
Using 11x11x11 sampling mesh, lattice thermal conductivity is calculated by
% phono3py --dim="2 2 2" --pa="0 1/2 1/2 1/2 0 1/2 1/2 1/2 0" -c POSCAR-unitcell --mesh="11 11 11" --fc3 --fc2 --br
kappa-m111111.hdf5 is written as the result. The lattice thermal conductivity is calculated as 108.9 W/m-K at 300 K. This becomes, with 19x19x19 sampling mesh, 123.2 W/m-K.
Accumulated lattice thermal conductivity is calculated using 'kaccum' script.
% kaccum --mesh="11 11 11" --pa="0 1/2 1/2 1/2 0 1/2 1/2 1/2 0" POSCAR-unitcell kappa-m111111.hdf5 |tee kaccum.dat
The plot of this result is shown in Si-kaccum.png. It is found that most of the lattice thermal conductivity owes the phonon modes below 6 THz.
fc2.hdf5 can be read by harmonic phonopy to rename it to force_constants.hdf5. The phonon band structure and DOS are watched by
% cp fc2.hdf5 force_constants.hdf5
% phonopy --dim="2 2 2" --pa="0 1/2 1/2 1/2 0 1/2 1/2 1/2 0" -c POSCAR-unitcell --mesh="19 19 19" --band="1/2 1/2 0 0 0 0 1/2 1/2 1/2" --hdf5 --readfc --thm -p
Si-band-DOS.png shows this plot. The shape of phonon DOS below 6 THz is similar to the derivative of the accumulated lattice thermal conductivity, i.e., the heat is conductied by the low frequency longitudinal-acoustic-like modes.

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

View File

@ -1,68 +0,0 @@
#!/usr/bin/env python
import numpy as np
from phonopy.interface.vasp import read_vasp
from phonopy.file_IO import parse_BORN
from phonopy.units import Bohr, Hartree
from phonopy.harmonic.force_constants import show_drift_force_constants
from anharmonic.phonon3.fc3 import show_drift_fc3
from anharmonic.phonon3 import Phono3py
from anharmonic.file_IO import (parse_disp_fc3_yaml,
parse_disp_fc2_yaml,
parse_FORCES_FC2,
parse_FORCES_FC3,
read_fc3_from_hdf5,
read_fc2_from_hdf5)
cell = read_vasp("POSCAR-unitcell")
mesh = [11, 11, 11]
phono3py = Phono3py(cell,
np.diag([2, 2, 2]),
primitive_matrix=[[0, 0.5, 0.5],
[0.5, 0, 0.5],
[0.5, 0.5, 0]],
mesh=mesh,
log_level=1) # log_level=0 make phono3py quiet
# Create fc3 and fc2 from disp_fc3.yaml and FORCES_FC3
disp_dataset = parse_disp_fc3_yaml(filename="disp_fc3.yaml")
forces_fc3 = parse_FORCES_FC3(disp_dataset, filename="FORCES_FC3")
phono3py.produce_fc3(
forces_fc3,
displacement_dataset=disp_dataset,
is_translational_symmetry=True,
is_permutation_symmetry=True,
is_permutation_symmetry_fc2=True)
fc3 = phono3py.get_fc3()
fc2 = phono3py.get_fc2()
# # Create fc2 from disp_fc2.yaml and FORCES_FC2
# disp_dataset2 = parse_disp_fc2_yaml(filename="disp_fc2.yaml")
# forces_fc2 = parse_FORCES_FC2(disp_dataset2, filename="FORCES_FC2")
# phono3py.produce_fc2(
# forces_fc2,
# displacement_dataset=disp_dataset2,
# is_translational_symmetry=True,
# is_permutation_symmetry=True)
# # Read fc3 and fc2 from c3.hdf5 and fc2.hdf5
# fc3 = read_fc3_from_hdf5(filename="fc3.hdf5")
# fc2 = read_fc2_from_hdf5(filename="fc2.hdf5")
# phono3py.set_fc3(fc3)
# phono3py.set_fc2(fc2)
show_drift_fc3(fc3)
show_drift_force_constants(fc2, name='fc2')
# # For special cases like NAC
# primitive = phono3py.get_phonon_primitive()
# nac_params = parse_BORN(primitive, filename="BORN")
# nac_params['factor'] = Hartree * Bohr
# phono3py.set_phph_interaction(nac_params=nac_params)
phono3py.run_thermal_conductivity(temperatures=range(0, 1001, 10),
write_kappa=True)
# Conductivity_RTA object (https://git.io/vVRUW)
cond_rta = phono3py.get_thermal_conductivity()

View File

@ -1,330 +0,0 @@
natom: 64
num_first_displacements: 1
num_second_displacements: 110
num_displacements_created: 111
first_atoms:
- number: 1
displacement:
[ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00001
second_atoms:
- number: 1
distance: 0.000000
displacements:
- [ 0.0212132034355964, 0.0212132034355964, 0.0000000000000000 ] # 00002
- [ -0.0212132034355964, -0.0212132034355964, 0.0000000000000000 ] # 00003
- number: 2
distance: 5.433560
displacements:
- [ 0.0212132034355964, 0.0212132034355964, 0.0000000000000000 ] # 00004
- [ -0.0212132034355964, -0.0212132034355964, 0.0000000000000000 ] # 00005
- number: 3
distance: 5.433560
displacements:
- [ 0.0212132034355964, 0.0212132034355964, 0.0000000000000000 ] # 00006
- [ -0.0212132034355964, -0.0212132034355964, 0.0000000000000000 ] # 00007
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00008
- number: 4
distance: 7.684214
displacements:
- [ 0.0212132034355964, 0.0212132034355964, 0.0000000000000000 ] # 00009
- [ -0.0212132034355964, -0.0212132034355964, 0.0000000000000000 ] # 00010
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00011
- number: 7
distance: 7.684214
displacements:
- [ 0.0212132034355964, 0.0212132034355964, 0.0000000000000000 ] # 00012
- [ -0.0212132034355964, -0.0212132034355964, 0.0000000000000000 ] # 00013
- number: 8
distance: 9.411202
displacements:
- [ 0.0212132034355964, 0.0212132034355964, 0.0000000000000000 ] # 00014
- [ -0.0212132034355964, -0.0212132034355964, 0.0000000000000000 ] # 00015
- number: 9
distance: 3.842107
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00016
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00017
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00018
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00019
- number: 10
distance: 6.654725
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00020
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00021
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00022
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00023
- number: 11
distance: 3.842107
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00024
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00025
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00026
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00027
- number: 12
distance: 6.654725
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00028
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00029
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00030
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00031
- number: 17
distance: 3.842107
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00032
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00033
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00034
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00035
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00036
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00037
- number: 18
distance: 3.842107
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00038
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00039
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00040
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00041
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00042
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00043
- number: 19
distance: 6.654725
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00044
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00045
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00046
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00047
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00048
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00049
- number: 20
distance: 6.654725
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00050
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00051
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00052
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00053
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00054
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00055
- number: 33
distance: 7.058402
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00056
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00057
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00058
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00059
- number: 34
distance: 5.921085
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00060
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00061
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00062
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00063
- number: 35
distance: 5.921085
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00064
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00065
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00066
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00067
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00068
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00069
- number: 36
distance: 4.505270
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00070
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00071
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00072
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00073
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00074
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00075
- number: 39
distance: 4.505270
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00076
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00077
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00078
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00079
- number: 40
distance: 2.352801
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00080
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00081
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00082
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00083
- number: 49
distance: 4.505270
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00084
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00085
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00086
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00087
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00088
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00089
- number: 50
distance: 5.921085
displacements:
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00090
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00091
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00092
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00093
- [ 0.0000000000000000, 0.0000000000000000, 0.0300000000000000 ] # 00094
- [ 0.0000000000000000, 0.0000000000000000, -0.0300000000000000 ] # 00095
- number: 51
distance: 2.352801
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00096
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00097
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00098
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00099
- number: 52
distance: 4.505270
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00100
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00101
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00102
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00103
- number: 53
distance: 5.921085
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00104
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00105
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00106
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00107
- number: 54
distance: 7.058402
displacements:
- [ 0.0000000000000000, 0.0300000000000000, 0.0000000000000000 ] # 00108
- [ 0.0000000000000000, -0.0300000000000000, 0.0000000000000000 ] # 00109
- [ 0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00110
- [ -0.0300000000000000, 0.0000000000000000, 0.0000000000000000 ] # 00111
lattice:
- [ 10.867120061830706, 0.000000000000000, 0.000000000000000 ]
- [ 0.000000000000000, 10.867120061830706, 0.000000000000000 ]
- [ 0.000000000000000, 0.000000000000000, 10.867120061830706 ]
atoms:
- symbol: Si # 1
position: [ 0.43750000000000, 0.43750000000000, 0.43750000000000 ]
- symbol: Si # 2
position: [ 0.93750000000000, 0.43750000000000, 0.43750000000000 ]
- symbol: Si # 3
position: [ 0.43750000000000, 0.93750000000000, 0.43750000000000 ]
- symbol: Si # 4
position: [ 0.93750000000000, 0.93750000000000, 0.43750000000000 ]
- symbol: Si # 5
position: [ 0.43750000000000, 0.43750000000000, 0.93750000000000 ]
- symbol: Si # 6
position: [ 0.93750000000000, 0.43750000000000, 0.93750000000000 ]
- symbol: Si # 7
position: [ 0.43750000000000, 0.93750000000000, 0.93750000000000 ]
- symbol: Si # 8
position: [ 0.93750000000000, 0.93750000000000, 0.93750000000000 ]
- symbol: Si # 9
position: [ 0.43750000000000, 0.18750000000000, 0.18750000000000 ]
- symbol: Si # 10
position: [ 0.93750000000000, 0.18750000000000, 0.18750000000000 ]
- symbol: Si # 11
position: [ 0.43750000000000, 0.68750000000000, 0.18750000000000 ]
- symbol: Si # 12
position: [ 0.93750000000000, 0.68750000000000, 0.18750000000000 ]
- symbol: Si # 13
position: [ 0.43750000000000, 0.18750000000000, 0.68750000000000 ]
- symbol: Si # 14
position: [ 0.93750000000000, 0.18750000000000, 0.68750000000000 ]
- symbol: Si # 15
position: [ 0.43750000000000, 0.68750000000000, 0.68750000000000 ]
- symbol: Si # 16
position: [ 0.93750000000000, 0.68750000000000, 0.68750000000000 ]
- symbol: Si # 17
position: [ 0.18750000000000, 0.43750000000000, 0.18750000000000 ]
- symbol: Si # 18
position: [ 0.68750000000000, 0.43750000000000, 0.18750000000000 ]
- symbol: Si # 19
position: [ 0.18750000000000, 0.93750000000000, 0.18750000000000 ]
- symbol: Si # 20
position: [ 0.68750000000000, 0.93750000000000, 0.18750000000000 ]
- symbol: Si # 21
position: [ 0.18750000000000, 0.43750000000000, 0.68750000000000 ]
- symbol: Si # 22
position: [ 0.68750000000000, 0.43750000000000, 0.68750000000000 ]
- symbol: Si # 23
position: [ 0.18750000000000, 0.93750000000000, 0.68750000000000 ]
- symbol: Si # 24
position: [ 0.68750000000000, 0.93750000000000, 0.68750000000000 ]
- symbol: Si # 25
position: [ 0.18750000000000, 0.18750000000000, 0.43750000000000 ]
- symbol: Si # 26
position: [ 0.68750000000000, 0.18750000000000, 0.43750000000000 ]
- symbol: Si # 27
position: [ 0.18750000000000, 0.68750000000000, 0.43750000000000 ]
- symbol: Si # 28
position: [ 0.68750000000000, 0.68750000000000, 0.43750000000000 ]
- symbol: Si # 29
position: [ 0.18750000000000, 0.18750000000000, 0.93750000000000 ]
- symbol: Si # 30
position: [ 0.68750000000000, 0.18750000000000, 0.93750000000000 ]
- symbol: Si # 31
position: [ 0.18750000000000, 0.68750000000000, 0.93750000000000 ]
- symbol: Si # 32
position: [ 0.68750000000000, 0.68750000000000, 0.93750000000000 ]
- symbol: Si # 33
position: [ 0.06250000000000, 0.06250000000000, 0.06250000000000 ]
- symbol: Si # 34
position: [ 0.56250000000000, 0.06250000000000, 0.06250000000000 ]
- symbol: Si # 35
position: [ 0.06250000000000, 0.56250000000000, 0.06250000000000 ]
- symbol: Si # 36
position: [ 0.56250000000000, 0.56250000000000, 0.06250000000000 ]
- symbol: Si # 37
position: [ 0.06250000000000, 0.06250000000000, 0.56250000000000 ]
- symbol: Si # 38
position: [ 0.56250000000000, 0.06250000000000, 0.56250000000000 ]
- symbol: Si # 39
position: [ 0.06250000000000, 0.56250000000000, 0.56250000000000 ]
- symbol: Si # 40
position: [ 0.56250000000000, 0.56250000000000, 0.56250000000000 ]
- symbol: Si # 41
position: [ 0.06250000000000, 0.31250000000000, 0.31250000000000 ]
- symbol: Si # 42
position: [ 0.56250000000000, 0.31250000000000, 0.31250000000000 ]
- symbol: Si # 43
position: [ 0.06250000000000, 0.81250000000000, 0.31250000000000 ]
- symbol: Si # 44
position: [ 0.56250000000000, 0.81250000000000, 0.31250000000000 ]
- symbol: Si # 45
position: [ 0.06250000000000, 0.31250000000000, 0.81250000000000 ]
- symbol: Si # 46
position: [ 0.56250000000000, 0.31250000000000, 0.81250000000000 ]
- symbol: Si # 47
position: [ 0.06250000000000, 0.81250000000000, 0.81250000000000 ]
- symbol: Si # 48
position: [ 0.56250000000000, 0.81250000000000, 0.81250000000000 ]
- symbol: Si # 49
position: [ 0.31250000000000, 0.06250000000000, 0.31250000000000 ]
- symbol: Si # 50
position: [ 0.81250000000000, 0.06250000000000, 0.31250000000000 ]
- symbol: Si # 51
position: [ 0.31250000000000, 0.56250000000000, 0.31250000000000 ]
- symbol: Si # 52
position: [ 0.81250000000000, 0.56250000000000, 0.31250000000000 ]
- symbol: Si # 53
position: [ 0.31250000000000, 0.06250000000000, 0.81250000000000 ]
- symbol: Si # 54
position: [ 0.81250000000000, 0.06250000000000, 0.81250000000000 ]
- symbol: Si # 55
position: [ 0.31250000000000, 0.56250000000000, 0.81250000000000 ]
- symbol: Si # 56
position: [ 0.81250000000000, 0.56250000000000, 0.81250000000000 ]
- symbol: Si # 57
position: [ 0.31250000000000, 0.31250000000000, 0.06250000000000 ]
- symbol: Si # 58
position: [ 0.81250000000000, 0.31250000000000, 0.06250000000000 ]
- symbol: Si # 59
position: [ 0.31250000000000, 0.81250000000000, 0.06250000000000 ]
- symbol: Si # 60
position: [ 0.81250000000000, 0.81250000000000, 0.06250000000000 ]
- symbol: Si # 61
position: [ 0.31250000000000, 0.31250000000000, 0.56250000000000 ]
- symbol: Si # 62
position: [ 0.81250000000000, 0.31250000000000, 0.56250000000000 ]
- symbol: Si # 63
position: [ 0.31250000000000, 0.81250000000000, 0.56250000000000 ]
- symbol: Si # 64
position: [ 0.81250000000000, 0.81250000000000, 0.56250000000000 ]

View File

@ -183,7 +183,7 @@ class Mesh(object):
(num_qpoints, num_band, num_band,), dtype='complex128')
if self._use_lapack_solver:
from phonopy.phonon.solver import get_phonons_at_qpoints
from anharmonic.phonon.solver import get_phonons_at_qpoints
get_phonons_at_qpoints(self._frequencies,
self._eigenvectors,
self._dynamical_matrix,

189
setup3.py
View File

@ -1,189 +0,0 @@
import numpy
from setup import (extension_spglib, extension_phonopy,
packages_phonopy, scripts_phonopy)
import platform
import os
# For making source distribution package:
# 1. cp MANIFEST-phono3py.in MANIFEST.in
# 2. python setup3.py sdist
# 3. git checkout -- MANIFEST.in
try:
from setuptools import setup, Extension
use_setuptools = True
print("setuptools is used.")
except ImportError:
from distutils.core import setup, Extension
use_setuptools = False
print("distutils is used.")
include_dirs_numpy = [numpy.get_include()]
extra_link_args = []
cc = None
if 'CC' in os.environ:
if 'clang' in os.environ['CC']:
cc = 'clang'
if 'gcc' in os.environ['CC']:
cc = 'gcc'
if cc == 'gcc' or cc is None:
extra_link_args.append('-lgomp')
# Workaround Python issue 21121
import sysconfig
config_var = sysconfig.get_config_var("CFLAGS")
if config_var is not None and "-Werror=declaration-after-statement" in config_var:
os.environ['CFLAGS'] = config_var.replace(
"-Werror=declaration-after-statement", "")
sources = ['c/_phono3py.c',
'c/harmonic/dynmat.c',
'c/harmonic/lapack_wrapper.c',
'c/harmonic/phonoc_array.c',
'c/harmonic/phonoc_utils.c',
'c/anharmonic/phonon3/fc3.c',
'c/anharmonic/phonon3/frequency_shift.c',
'c/anharmonic/phonon3/interaction.c',
'c/anharmonic/phonon3/real_to_reciprocal.c',
'c/anharmonic/phonon3/reciprocal_to_normal.c',
'c/anharmonic/phonon3/imag_self_energy.c',
'c/anharmonic/phonon3/imag_self_energy_with_g.c',
'c/anharmonic/phonon3/collision_matrix.c',
'c/anharmonic/other/isotope.c',
'c/anharmonic/triplet/triplet.c',
'c/anharmonic/triplet/triplet_kpoint.c',
'c/anharmonic/triplet/triplet_iw.c',
'c/spglib/mathfunc.c',
'c/spglib/kpoint.c',
'c/kspclib/kgrid.c',
'c/kspclib/tetrahedron_method.c']
extra_link_args += ['-llapacke', # this is when lapacke is installed on system
'-llapack',
'-lblas']
extra_compile_args = ['-fopenmp',]
include_dirs = (['c/harmonic_h',
'c/anharmonic_h',
'c/spglib_h',
'c/kspclib_h'] +
include_dirs_numpy)
define_macros = []
##
## Modify include_dirs and extra_link_args if lapacke is prepared in a special
## location
#
if platform.system() == 'Darwin':
# phono3py is compiled with gcc5 from MacPorts. (export CC=gcc)
# port install gcc5
# port select --set gcc mp-gcc5
# With OpenBLAS in MacPorts
# port install OpenBLAS +gcc5
# port install py27-numpy +gcc5 +openblas
include_dirs += ['/opt/local/include']
extra_link_args = ['/opt/local/lib/libopenblas.a']
# # With lapack compiled manually
# include_dirs += ['../lapack-3.5.0/lapacke/include']
# extra_link_args = ['../lapack-3.5.0/liblapacke.a']
## Uncomment below to measure reciprocal_to_normal_squared_openmp performance
# define_macros = [('MEASURE_R2N', None)]
##
## This is for the test of libflame
##
# use_libflame = False
# if use_libflame:
# sources.append('c/anharmonic/flame_wrapper.c')
# extra_link_args.append('../libflame-bin/lib/libflame.a')
# include_dirs_libflame = ['../libflame-bin/include']
# include_dirs += include_dirs_libflame
extension_phono3py = Extension(
'anharmonic._phono3py',
include_dirs=include_dirs,
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,
define_macros=define_macros,
sources=sources)
packages_phono3py = ['anharmonic',
'anharmonic.other',
'anharmonic.phonon3',
'anharmonic.cui']
scripts_phono3py = ['scripts/phono3py',
'scripts/kaccum',
'scripts/gaccum']
########################
# _lapackepy extension #
########################
include_dirs_lapackepy = ['c/harmonic_h',] + include_dirs_numpy
sources_lapackepy = ['c/_lapackepy.c',
'c/harmonic/dynmat.c',
'c/harmonic/phonon.c',
'c/harmonic/phonoc_array.c',
'c/harmonic/phonoc_utils.c',
'c/harmonic/lapack_wrapper.c']
extension_lapackepy = Extension(
'phonopy._lapackepy',
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,
include_dirs=include_dirs,
sources=sources_lapackepy)
if __name__ == '__main__':
version_nums = [None, None, None]
with open("phonopy/version.py") as w:
for line in w:
if "__version__" in line:
for i, num in enumerate(line.split()[2].strip('\"').split('.')):
version_nums[i] = int(num)
# To deploy to pypi by travis-CI
if os.path.isfile("__nanoversion__.txt"):
with open('__nanoversion__.txt') as nv:
try :
for line in nv:
nanoversion = int(line.strip())
break
except ValueError :
nanoversion = 0
if nanoversion:
version_nums.append(nanoversion)
if None in version_nums:
print("Failed to get version number in setup.py.")
raise
version_number = ".".join(["%d" % n for n in version_nums])
if use_setuptools:
setup(name='phono3py',
version=version_number,
description='This is the phono3py module.',
author='Atsushi Togo',
author_email='atz.togo@gmail.com',
url='http://phonopy.sourceforge.net/',
packages=(packages_phonopy + packages_phono3py),
requires=['numpy', 'PyYAML', 'matplotlib', 'h5py'],
provides=['phonopy'],
scripts=(scripts_phonopy + scripts_phono3py),
ext_modules=[extension_spglib,
extension_lapackepy,
extension_phonopy,
extension_phono3py])
else:
setup(name='phono3py',
version=version_number,
description='This is the phono3py module.',
author='Atsushi Togo',
author_email='atz.togo@gmail.com',
url='http://phonopy.sourceforge.net/',
packages=(packages_phonopy + packages_phono3py),
requires=['numpy', 'PyYAML', 'matplotlib', 'h5py'],
provides=['phonopy'],
scripts=(scripts_phonopy + scripts_phono3py),
ext_modules=[extension_spglib,
extension_lapackepy,
extension_phonopy,
extension_phono3py])

View File

@ -1,294 +0,0 @@
lattice:
- [ 9.8130133395493626, 0.0000000000000000, 0.0000000000000000 ] # a
- [ 0.0000000000000000, 12.9607729652407464, 0.0000000000000000 ] # b
- [ 0.0000000000000000, 0.0000000000000000, 9.9776294309342557 ] # c
points:
- symbol: N # 1 -> 1
coordinates: [ 0.0010190549685383, 0.2500000000000000, 0.1952475607335603 ]
- symbol: N # 2 -> 2
coordinates: [ 0.3333333333333333, 0.2500000000000000, 0.1952475607335603 ]
- symbol: N # 3 -> 3
coordinates: [ 0.6666666666666666, 0.2500000000000000, 0.1952475607335603 ]
- symbol: N # 4 -> 4
coordinates: [ 0.0000000000000000, 0.7500000000000000, 0.1952475607335603 ]
- symbol: N # 5 -> 5
coordinates: [ 0.3333333333333333, 0.7500000000000000, 0.1952475607335603 ]
- symbol: N # 6 -> 6
coordinates: [ 0.6666666666666666, 0.7500000000000000, 0.1952475607335603 ]
- symbol: N # 7 -> 7
coordinates: [ 0.0000000000000000, 0.2500000000000000, 0.6952475607335603 ]
- symbol: N # 8 -> 8
coordinates: [ 0.3333333333333333, 0.2500000000000000, 0.6952475607335603 ]
- symbol: N # 9 -> 9
coordinates: [ 0.6666666666666666, 0.2500000000000000, 0.6952475607335603 ]
- symbol: N # 10 -> 10
coordinates: [ 0.0000000000000000, 0.7500000000000000, 0.6952475607335603 ]
- symbol: N # 11 -> 11
coordinates: [ 0.3333333333333333, 0.7500000000000000, 0.6952475607335603 ]
- symbol: N # 12 -> 12
coordinates: [ 0.6666666666666666, 0.7500000000000000, 0.6952475607335603 ]
- symbol: O # 13 -> 25
coordinates: [ 0.0000000000000000, 0.3318936741729317, 0.2635067655175194 ]
- symbol: O # 14 -> 26
coordinates: [ 0.3333333333333333, 0.3318936741729317, 0.2635067655175194 ]
- symbol: O # 15 -> 27
coordinates: [ 0.6666666666666666, 0.3318936741729317, 0.2635067655175194 ]
- symbol: O # 16 -> 28
coordinates: [ 0.0000000000000000, 0.8318936741729317, 0.2635067655175194 ]
- symbol: O # 17 -> 29
coordinates: [ 0.3333333333333333, 0.8318936741729317, 0.2635067655175194 ]
- symbol: O # 18 -> 30
coordinates: [ 0.6666666666666666, 0.8318936741729317, 0.2635067655175194 ]
- symbol: O # 19 -> 31
coordinates: [ 0.0000000000000000, 0.3318936741729317, 0.7635067655175194 ]
- symbol: O # 20 -> 32
coordinates: [ 0.3333333333333333, 0.3318936741729317, 0.7635067655175194 ]
- symbol: O # 21 -> 33
coordinates: [ 0.6666666666666666, 0.3318936741729317, 0.7635067655175194 ]
- symbol: O # 22 -> 34
coordinates: [ 0.0000000000000000, 0.8318936741729317, 0.7635067655175194 ]
- symbol: O # 23 -> 35
coordinates: [ 0.3333333333333333, 0.8318936741729317, 0.7635067655175194 ]
- symbol: O # 24 -> 36
coordinates: [ 0.6666666666666666, 0.8318936741729317, 0.7635067655175194 ]
- symbol: O # 25 -> 37
coordinates: [ 0.0000000000000000, 0.1681063258270684, 0.2635067655175194 ]
- symbol: O # 26 -> 38
coordinates: [ 0.3333333333333333, 0.1681063258270684, 0.2635067655175194 ]
- symbol: O # 27 -> 39
coordinates: [ 0.6666666666666666, 0.1681063258270684, 0.2635067655175194 ]
- symbol: O # 28 -> 40
coordinates: [ 0.0000000000000000, 0.6681063258270684, 0.2635067655175194 ]
- symbol: O # 29 -> 41
coordinates: [ 0.3333333333333333, 0.6681063258270684, 0.2635067655175194 ]
- symbol: O # 30 -> 42
coordinates: [ 0.6666666666666666, 0.6681063258270684, 0.2635067655175194 ]
- symbol: O # 31 -> 43
coordinates: [ 0.0000000000000000, 0.1681063258270684, 0.7635067655175194 ]
- symbol: O # 32 -> 44
coordinates: [ 0.3333333333333333, 0.1681063258270684, 0.7635067655175194 ]
- symbol: O # 33 -> 45
coordinates: [ 0.6666666666666666, 0.1681063258270684, 0.7635067655175194 ]
- symbol: O # 34 -> 46
coordinates: [ 0.0000000000000000, 0.6681063258270684, 0.7635067655175194 ]
- symbol: O # 35 -> 47
coordinates: [ 0.3333333333333333, 0.6681063258270684, 0.7635067655175194 ]
- symbol: O # 36 -> 48
coordinates: [ 0.6666666666666666, 0.6681063258270684, 0.7635067655175194 ]
- symbol: Ag # 37 -> 73
coordinates: [ 0.0000000000000000, 0.2500000000000000, 0.4777389082314037 ]
- symbol: Ag # 38 -> 74
coordinates: [ 0.3333333333333333, 0.2500000000000000, 0.4777389082314037 ]
- symbol: Ag # 39 -> 75
coordinates: [ 0.6666666666666666, 0.2500000000000000, 0.4777389082314037 ]
- symbol: Ag # 40 -> 76
coordinates: [ 0.0000000000000000, 0.7500000000000000, 0.4777389082314037 ]
- symbol: Ag # 41 -> 77
coordinates: [ 0.3333333333333333, 0.7500000000000000, 0.4777389082314037 ]
- symbol: Ag # 42 -> 78
coordinates: [ 0.6666666666666666, 0.7500000000000000, 0.4777389082314037 ]
- symbol: Ag # 43 -> 79
coordinates: [ 0.0000000000000000, 0.2500000000000000, 0.9777389082314037 ]
- symbol: Ag # 44 -> 80
coordinates: [ 0.3333333333333333, 0.2500000000000000, 0.9777389082314037 ]
- symbol: Ag # 45 -> 81
coordinates: [ 0.6666666666666666, 0.2500000000000000, 0.9777389082314037 ]
- symbol: Ag # 46 -> 82
coordinates: [ 0.0000000000000000, 0.7500000000000000, 0.9777389082314037 ]
- symbol: Ag # 47 -> 83
coordinates: [ 0.3333333333333333, 0.7500000000000000, 0.9777389082314037 ]
- symbol: Ag # 48 -> 84
coordinates: [ 0.6666666666666666, 0.7500000000000000, 0.9777389082314037 ]
- symbol: N # 49 -> 13
coordinates: [ 0.1666666666666667, 0.0000000000000000, 0.4452475607335603 ]
- symbol: N # 50 -> 14
coordinates: [ 0.5000000000000000, 0.0000000000000000, 0.4452475607335603 ]
- symbol: N # 51 -> 15
coordinates: [ 0.8333333333333334, 0.0000000000000000, 0.4452475607335603 ]
- symbol: N # 52 -> 16
coordinates: [ 0.1666666666666667, 0.5000000000000000, 0.4452475607335603 ]
- symbol: N # 53 -> 17
coordinates: [ 0.5000000000000000, 0.5000000000000000, 0.4452475607335603 ]
- symbol: N # 54 -> 18
coordinates: [ 0.8333333333333334, 0.5000000000000000, 0.4452475607335603 ]
- symbol: N # 55 -> 19
coordinates: [ 0.1666666666666667, 0.0000000000000000, 0.9452475607335603 ]
- symbol: N # 56 -> 20
coordinates: [ 0.5000000000000000, 0.0000000000000000, 0.9452475607335603 ]
- symbol: N # 57 -> 21
coordinates: [ 0.8333333333333334, 0.0000000000000000, 0.9452475607335603 ]
- symbol: N # 58 -> 22
coordinates: [ 0.1666666666666667, 0.5000000000000000, 0.9452475607335603 ]
- symbol: N # 59 -> 23
coordinates: [ 0.5000000000000000, 0.5000000000000000, 0.9452475607335603 ]
- symbol: N # 60 -> 24
coordinates: [ 0.8333333333333334, 0.5000000000000000, 0.9452475607335603 ]
- symbol: O # 61 -> 49
coordinates: [ 0.1666666666666667, 0.0818936741729317, 0.0135067655175194 ]
- symbol: O # 62 -> 50
coordinates: [ 0.5000000000000000, 0.0818936741729317, 0.0135067655175194 ]
- symbol: O # 63 -> 51
coordinates: [ 0.8333333333333334, 0.0818936741729317, 0.0135067655175194 ]
- symbol: O # 64 -> 52
coordinates: [ 0.1666666666666667, 0.5818936741729317, 0.0135067655175194 ]
- symbol: O # 65 -> 53
coordinates: [ 0.5000000000000000, 0.5818936741729317, 0.0135067655175194 ]
- symbol: O # 66 -> 54
coordinates: [ 0.8333333333333334, 0.5818936741729317, 0.0135067655175194 ]
- symbol: O # 67 -> 55
coordinates: [ 0.1666666666666667, 0.0818936741729317, 0.5135067655175194 ]
- symbol: O # 68 -> 56
coordinates: [ 0.5000000000000000, 0.0818936741729317, 0.5135067655175194 ]
- symbol: O # 69 -> 57
coordinates: [ 0.8333333333333334, 0.0818936741729317, 0.5135067655175194 ]
- symbol: O # 70 -> 58
coordinates: [ 0.1666666666666667, 0.5818936741729317, 0.5135067655175194 ]
- symbol: O # 71 -> 59
coordinates: [ 0.5000000000000000, 0.5818936741729317, 0.5135067655175194 ]
- symbol: O # 72 -> 60
coordinates: [ 0.8333333333333334, 0.5818936741729317, 0.5135067655175194 ]
- symbol: O # 73 -> 61
coordinates: [ 0.1666666666666667, 0.4181063258270684, 0.0135067655175194 ]
- symbol: O # 74 -> 62
coordinates: [ 0.5000000000000000, 0.4181063258270684, 0.0135067655175194 ]
- symbol: O # 75 -> 63
coordinates: [ 0.8333333333333334, 0.4181063258270684, 0.0135067655175194 ]
- symbol: O # 76 -> 64
coordinates: [ 0.1666666666666667, 0.9181063258270683, 0.0135067655175194 ]
- symbol: O # 77 -> 65
coordinates: [ 0.5000000000000000, 0.9181063258270683, 0.0135067655175194 ]
- symbol: O # 78 -> 66
coordinates: [ 0.8333333333333334, 0.9181063258270683, 0.0135067655175194 ]
- symbol: O # 79 -> 67
coordinates: [ 0.1666666666666667, 0.4181063258270684, 0.5135067655175194 ]
- symbol: O # 80 -> 68
coordinates: [ 0.5000000000000000, 0.4181063258270684, 0.5135067655175194 ]
- symbol: O # 81 -> 69
coordinates: [ 0.8333333333333334, 0.4181063258270684, 0.5135067655175194 ]
- symbol: O # 82 -> 70
coordinates: [ 0.1666666666666667, 0.9181063258270683, 0.5135067655175194 ]
- symbol: O # 83 -> 71
coordinates: [ 0.5000000000000000, 0.9181063258270683, 0.5135067655175194 ]
- symbol: O # 84 -> 72
coordinates: [ 0.8333333333333334, 0.9181063258270683, 0.5135067655175194 ]
- symbol: Ag # 85 -> 85
coordinates: [ 0.1666666666666667, 0.0000000000000000, 0.2277389082314037 ]
- symbol: Ag # 86 -> 86
coordinates: [ 0.5000000000000000, 0.0000000000000000, 0.2277389082314037 ]
- symbol: Ag # 87 -> 87
coordinates: [ 0.8333333333333334, 0.0000000000000000, 0.2277389082314037 ]
- symbol: Ag # 88 -> 88
coordinates: [ 0.1666666666666667, 0.5000000000000000, 0.2277389082314037 ]
- symbol: Ag # 89 -> 89
coordinates: [ 0.5000000000000000, 0.5000000000000000, 0.2277389082314037 ]
- symbol: Ag # 90 -> 90
coordinates: [ 0.8333333333333334, 0.5000000000000000, 0.2277389082314037 ]
- symbol: Ag # 91 -> 91
coordinates: [ 0.1666666666666667, 0.0000000000000000, 0.7277389082314037 ]
- symbol: Ag # 92 -> 92
coordinates: [ 0.5000000000000000, 0.0000000000000000, 0.7277389082314037 ]
- symbol: Ag # 93 -> 93
coordinates: [ 0.8333333333333334, 0.0000000000000000, 0.7277389082314037 ]
- symbol: Ag # 94 -> 94
coordinates: [ 0.1666666666666667, 0.5000000000000000, 0.7277389082314037 ]
- symbol: Ag # 95 -> 95
coordinates: [ 0.5000000000000000, 0.5000000000000000, 0.7277389082314037 ]
- symbol: Ag # 96 -> 96
coordinates: [ 0.8333333333333334, 0.5000000000000000, 0.7277389082314037 ]
poscar_order:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96

View File

@ -1,30 +0,0 @@
import unittest
import numpy as np
from phonopy.interface.phonopy_yaml import get_unitcell_from_phonopy_yaml
from anharmonic.phonon3.triplets import (get_grid_point_from_address,
get_grid_point_from_address_py)
class TestTriplets(unittest.TestCase):
def setUp(self):
filename = "POSCAR.yaml"
self._cell = get_unitcell_from_phonopy_yaml(filename)
def tearDown(self):
pass
def test_get_grid_point_from_address(self):
self._mesh = (10, 10, 10)
print("Compare get_grid_point_from_address from spglib and that "
"written in python")
print("with mesh numbers [%d %d %d]" % self._mesh)
for address in list(np.ndindex(self._mesh)):
gp_spglib = get_grid_point_from_address(address, self._mesh)
gp_py = get_grid_point_from_address_py(address, self._mesh)
# print("%s %d %d" % (address, gp_spglib, gp_py))
self.assertEqual(gp_spglib, gp_py)
if __name__ == '__main__':
unittest.main()