mirror of https://github.com/phonopy/phonopy.git
145 lines
5.7 KiB
Python
Executable File
145 lines
5.7 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# Copyright (C) 2018 Antti Karttunen (antti.j.karttunen@iki.fi)
|
|
# 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 __future__ import print_function
|
|
import sys
|
|
import numpy as np
|
|
|
|
def get_options():
|
|
# Parse options
|
|
import argparse
|
|
parser = argparse.ArgumentParser(
|
|
description="Phonopy crystal-born command-line-tool")
|
|
parser.add_argument(
|
|
"filename", nargs='*',
|
|
help="Filename: CRYSTAL output file (default: crystal.o)")
|
|
args = parser.parse_args()
|
|
return args
|
|
|
|
def read_crystal_epsilon(epscol, epslines):
|
|
# XX, XY, XZ, YY, YZ, ZZ are given (6 rows). YX = XY, ZX = XZ, ZY = YZ
|
|
# Format for CRYSTAL17 (epscol == 4):
|
|
# 0.000 XX 57.1760 0.0000 3.2117 0.0000 2.2117
|
|
# Format for CRYSTAL14 (epscol == 3):
|
|
# XX 57.1760 0.0000 3.2117 2.2117
|
|
eps = [] # Will have 9 elements 0..8
|
|
eps.append(float(epslines[0].split()[epscol])) # XX (0)
|
|
eps.append(float(epslines[1].split()[epscol])) # XY (1)
|
|
eps.append(float(epslines[2].split()[epscol])) # XZ (2)
|
|
eps.append(eps[1]) # YX = XY (3)
|
|
eps.append(float(epslines[3].split()[epscol])) # YY (4)
|
|
eps.append(float(epslines[4].split()[epscol])) # YZ (5)
|
|
eps.append(eps[2]) # ZX = XZ (6)
|
|
eps.append(eps[5]) # ZY = YZ (7)
|
|
eps.append(float(epslines[5].split()[epscol])) # ZZ (8)
|
|
return eps
|
|
|
|
def main(args):
|
|
if args.filename:
|
|
crystal_filename = args.filename[0]
|
|
else:
|
|
crystal_filename = "crystal.o"
|
|
|
|
# Read in the output file
|
|
try:
|
|
with open(crystal_filename, "r") as crystal_file:
|
|
lines = crystal_file.readlines()
|
|
except OSError:
|
|
print("CRYSTAL output file {} cannot be opened for reading".format(crystal_filename))
|
|
sys.exit(1)
|
|
|
|
# Recommended CRYSTAL calculation type:
|
|
# Gamma-point FREQCALC with INTCPHF and INTENS
|
|
# The file will include both dielectric tensor and effective Born charges
|
|
epsilon = []
|
|
zeff = []
|
|
l = 0
|
|
while l < len(lines):
|
|
line = lines[l]
|
|
# Parse the information about atoms
|
|
if 'PRIMITIVE CELL - CENTRING CODE' in line:
|
|
l += 4
|
|
# ATOMS IN THE ASYMMETRIC UNIT 2 - ATOMS IN THE UNIT CELL: 6
|
|
N_asym_atoms = int(lines[l].split()[5])
|
|
N_atoms = int(lines[l].split()[12])
|
|
l += 3
|
|
# Check for each atom if it belongs to the asymmetric unit
|
|
# 1 T 22 TI 4.721218104494E-21 3.307446203077E-21 1.413771901417E-21
|
|
is_asym = []
|
|
for atom in range(0, N_atoms):
|
|
atomdata = lines[l].split()
|
|
is_asym.append(atomdata[1])
|
|
l += 1
|
|
|
|
# Parse dielectric tensor from INTCPHF
|
|
elif 'FR.(eV) COMP. ALPHA(Re,Im) EPSILON(Re,Im)' in line:
|
|
# CRYSTAL17
|
|
epsilon = read_crystal_epsilon(4, lines[l+1:l+7])
|
|
l += 7
|
|
elif 'COMPONENT ALPHA(REAL, IMAGINARY) EPSILON CHI(1)' in line:
|
|
epsilon = read_crystal_epsilon(3, lines[l+1:l+7])
|
|
l += 7
|
|
|
|
# Parse Born charges
|
|
elif 'ATOMIC BORN CHARGE TENSOR' in line:
|
|
l += 6
|
|
for atom in range(0, N_atoms):
|
|
if is_asym[atom] == 'T':
|
|
zeffatom = []
|
|
for i in range(0, 3):
|
|
# 1 8.3860E-01 3.4861E-01 3.4861E-01
|
|
zeffatom += [float(x) for x in lines[l].split()[1:4]]
|
|
l += 1
|
|
zeff.append(zeffatom)
|
|
l += 4
|
|
else:
|
|
l += 7
|
|
l += 1 # while l < len(lines)
|
|
|
|
# Output BORN if epsilon and zeff are available
|
|
if len(epsilon) == 9 and len(zeff) == N_asym_atoms:
|
|
# Conversion factor
|
|
bornlines = ("default\n")
|
|
# Dielectric tensor
|
|
bornlines += ("%6.4f " * 9 + "\n") % tuple(epsilon)
|
|
# Effective charges
|
|
for atom in range(0, N_asym_atoms):
|
|
bornlines += ("%6.4f " * 9 + "\n") % tuple(zeff[atom])
|
|
print(bornlines, end='')
|
|
|
|
if __name__ == "__main__":
|
|
main(get_options())
|