mirror of https://github.com/phonopy/phonopy.git
228 lines
7.8 KiB
Python
Executable File
228 lines
7.8 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
# Copyright (C) 2011 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.
|
|
|
|
# Displacement manager ( dispmanager )
|
|
#
|
|
# Usage:
|
|
# dispmanager disp.yaml
|
|
|
|
import sys, os
|
|
import numpy as np
|
|
from phonopy.structure.atoms import PhonopyAtoms as Atoms
|
|
from phonopy.interface.vasp import write_vasp
|
|
import phonopy.file_IO as file_IO
|
|
|
|
try:
|
|
import yaml
|
|
except ImportError:
|
|
print("You need to install python-yaml.")
|
|
exit(1)
|
|
|
|
try:
|
|
from yaml import CLoader as Loader
|
|
from yaml import CDumper as Dumper
|
|
except ImportError:
|
|
from yaml import Loader, Dumper
|
|
|
|
# Parse options
|
|
from optparse import OptionParser
|
|
parser = OptionParser()
|
|
parser.set_defaults(output_filename=None,
|
|
is_overwrite=False,
|
|
is_create_structure_file=False,
|
|
is_compatibility=False,
|
|
is_d2d=False,
|
|
add_disp=None,
|
|
select_disp=None,
|
|
amplitude=0.01)
|
|
parser.add_option("-o", "--output", dest="output_filename",
|
|
action="store", type="string",
|
|
help="Output filename")
|
|
parser.add_option("--overwrite", dest="is_overwrite",
|
|
action="store_true", help="Overwrite input file")
|
|
parser.add_option("-w", dest="is_create_structure_file",
|
|
action="store_true", help="Create structure files")
|
|
parser.add_option("-a", "--add", dest="add_disp",
|
|
action="store", type="string",
|
|
help="Direction of added displacement")
|
|
parser.add_option("-s", "--select", dest="select_disp",
|
|
action="store", type="string",
|
|
help="Select displacements and write input file")
|
|
parser.add_option("--amplitude", dest="amplitude", type="float",
|
|
help="Amplitude of displacement")
|
|
parser.add_option("--compatibility", dest="is_compatibility",
|
|
action="store_true", help="Check if disp.yaml is equivalent to old DISP")
|
|
parser.add_option("--d2d", dest="is_d2d",
|
|
action="store_true", help="Show the order of calculated files for disp.yaml")
|
|
(options, args) = parser.parse_args()
|
|
|
|
if len(args) > 0:
|
|
filename = args[0]
|
|
else:
|
|
filename = 'disp.yaml'
|
|
|
|
if os.path.exists(filename):
|
|
disp = yaml.load(open(filename).read(), Loader=Loader)
|
|
else:
|
|
print("%s could not be found." % filename)
|
|
sys.exit(1)
|
|
|
|
natom = disp['natom']
|
|
displacements = []
|
|
directions = []
|
|
for x in disp['displacements']:
|
|
atom = x['atom'] - 1
|
|
d = x['displacement']
|
|
displacements.append([atom, d[0], d[1], d[2]])
|
|
d = x['direction']
|
|
directions.append([atom, d[0], d[1], d[2]])
|
|
lattice = disp['lattice']
|
|
positions = [x['position'] for x in disp['atoms']]
|
|
symbols = [x['symbol'] for x in disp['atoms']]
|
|
cell = Atoms(cell=lattice,
|
|
scaled_positions=positions,
|
|
symbols=symbols,
|
|
pbc=True)
|
|
|
|
######################
|
|
# Create DPOSCAR-xxx #
|
|
######################
|
|
if options.is_create_structure_file:
|
|
for i, disp in enumerate(displacements):
|
|
positions = cell.get_positions()
|
|
positions[disp[0]] += disp[1:4]
|
|
write_vasp("%s-%03d" % ("DPOSCAR", i + 1),
|
|
Atoms(numbers=cell.get_atomic_numbers(),
|
|
masses=cell.get_masses(),
|
|
positions=positions,
|
|
cell=cell.get_cell(),
|
|
pbc=True), direct=True)
|
|
sys.exit(0)
|
|
|
|
######################
|
|
# Check DISP #
|
|
######################
|
|
if options.is_compatibility:
|
|
directions_DISP = file_IO.parse_DISP()
|
|
if len(directions_DISP) != len(directions):
|
|
print("disp.yaml and DISP are inconsistent.")
|
|
sys.exit(1)
|
|
print(" DISP disp.yaml")
|
|
for d_DISP, d in zip(directions_DISP, directions):
|
|
if d_DISP[0] != d[0]:
|
|
print("disp.yaml and DISP are inconsistent.")
|
|
sys.exit(1)
|
|
if (abs(np.array(d_DISP[1:4]) - np.array(d[1:4])) < 0.0001).all():
|
|
print d_DISP, d
|
|
else:
|
|
print("disp.yaml and DISP are inconsistent.")
|
|
sys.exit(1)
|
|
print("diap.yaml and DISP are equivalent!")
|
|
sys.exit(0)
|
|
|
|
#######################################
|
|
# Arrange order in DISP for disp.yaml #
|
|
#######################################
|
|
if options.is_d2d:
|
|
numbers = ""
|
|
count = 0
|
|
directions_DISP = file_IO.parse_DISP()
|
|
for i, d in enumerate(directions):
|
|
is_found = False
|
|
for j, d_DISP in enumerate(directions_DISP):
|
|
if (d_DISP[0] == d[0] and
|
|
(abs(np.array(d_DISP[1:4]) - np.array(d[1:4])) < 0.0001).all()):
|
|
numbers += "%03d," % (j + 1)
|
|
count += 1
|
|
is_found = True
|
|
break
|
|
if not is_found:
|
|
print("disp.yaml and DISP are inconsistent.")
|
|
sys.exit(1)
|
|
|
|
print("%s" % numbers)
|
|
print("%d" % count)
|
|
sys.exit(0)
|
|
|
|
####################
|
|
# Modify disp.yaml #
|
|
####################
|
|
if options.is_overwrite:
|
|
output_filename = filename
|
|
else:
|
|
output_filename = options.output_filename
|
|
|
|
# Add displacements
|
|
if options.add_disp is not None:
|
|
|
|
if output_filename is None:
|
|
print("Output filename (-o or --overwrite) is required.")
|
|
sys.exit(1)
|
|
|
|
print("%s" % options.add_disp.split()[1:4])
|
|
v = np.array([float(x) for x in options.add_disp.split()[1:4]])
|
|
v = np.dot(v, cell.get_cell())
|
|
v = v / np.linalg.norm(v) * options.amplitude
|
|
d = [int(options.add_disp.split()[0]) - 1, v[0], v[1], v[2]]
|
|
displacements.append(d)
|
|
directions.append([float(x) for x in options.add_disp.split()])
|
|
|
|
file_IO.write_disp_yaml(displacements,
|
|
cell,
|
|
directions=directions,
|
|
filename=output_filename)
|
|
sys.exit(0)
|
|
|
|
# Select displacements
|
|
if options.select_disp is not None:
|
|
|
|
if output_filename is None:
|
|
print("Output filename (-o or --overwrite) is required.")
|
|
sys.exit(1)
|
|
|
|
disp_selected = []
|
|
direction_selected = []
|
|
for x in options.select_disp.split():
|
|
disp_selected.append(displacements[int(x) - 1])
|
|
direction_selected.append(directions[int(x) - 1])
|
|
file_IO.write_disp_yaml(disp_selected,
|
|
cell,
|
|
directions=direction_selected,
|
|
filename=output_filename)
|
|
sys.exit(0)
|
|
|
|
print("Nothing has been done.")
|