mirror of https://github.com/phonopy/phonopy.git
Added a siesta interface
Implemented a siesta interface. It uses regular expressions to read the siesta .fdf input file. Also added documentation and two working examples: Silicon and Graphene
This commit is contained in:
parent
8e1a3ac0de
commit
de735912ba
|
@ -114,6 +114,19 @@ input file that contains the unit cell crystal structure, e.g.,
|
|||
|
||||
% phonopy --pwscf -c NaCl.in band.conf
|
||||
|
||||
.. _siesta_mode:
|
||||
|
||||
``--siesta``
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Siesta mode is invoked with this option. Usually this option is used
|
||||
with ``--cell`` (``-c``) option or ``CELL_FILENAME`` tag to read a Siesta
|
||||
input file that contains the unit cell crystal structure, e.g.,
|
||||
|
||||
::
|
||||
|
||||
% phonopy --siesta -c Si.fdf band.conf
|
||||
|
||||
.. _elk_mode:
|
||||
|
||||
``--elk``
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
.. _siesta_interface:
|
||||
|
||||
Siesta & phonopy calculation
|
||||
=========================================
|
||||
|
||||
Supported Siesta tags
|
||||
---------------------------
|
||||
|
||||
Currently phonopy can read the siesta tags listed below.
|
||||
More tags may be supported on request.
|
||||
|
||||
::
|
||||
|
||||
AtomicCoordinatesFormat, ChemicalSpeciesLabel, AtomicCoordinatesFormat,
|
||||
AtomicCoordinatesAndAtomicSpecies, LatticeVectors
|
||||
|
||||
How to run
|
||||
----------
|
||||
|
||||
The procedure of a Siesta-phonopy calculation is the following:
|
||||
|
||||
1) Read a Siesta input file and create supercells with
|
||||
:ref:`siesta_mode` option::
|
||||
|
||||
% phonopy --siesta -d --dim="2 2 2" -c Si.fdf
|
||||
|
||||
In this example, 2x2x2 supercells are created. ``supercell.fdf`` and
|
||||
``supercell-xxx.fdf`` (``xxx`` are numbers) give the perfect
|
||||
supercell and supercells with displacements, respectively. In these
|
||||
supercell files, lines only relevant to crystal structures are
|
||||
generated. ``disp.yaml`` is also created. This file contains
|
||||
information on displacements. Perhaps the supercell files are
|
||||
stored in ``disp-xxx`` directories, then Siesta calculations are
|
||||
executed in these directories.
|
||||
|
||||
2) Calculate forces on atoms in the supercells with
|
||||
displacements. Calculation specification tags have to be added to
|
||||
``supercell-xxx.in`` files. Crystal structure is not allowed to relax
|
||||
in the force calculations, because atomic forces induced by a small
|
||||
atomic displacement are what we need for the phonon calculation.
|
||||
|
||||
3) Create ``FORCE_SETS`` by
|
||||
|
||||
::
|
||||
|
||||
% phonopy --siesta -f disp-001/si.FA ...
|
||||
|
||||
Here ``*.FA`` files are the forces files created by Siesta.
|
||||
To run this command, ``disp.yaml`` has to be
|
||||
located in the current directory because the atomic displacements are
|
||||
written into the FORCE_SETS file. An example is found in
|
||||
``example/Si-siesta``.
|
||||
|
||||
4) Run post-process of phonopy with the Siesta input file for the
|
||||
unit cell used in the step 1::
|
||||
|
||||
% phonopy --siesta -c Si.fdf -p band.conf
|
||||
|
||||
or::
|
||||
|
||||
% phonopy --siesta -c Si.fdf --dim="2 2 2" [other-OPTIONS] [setting-file]
|
||||
|
||||
.. |sflogo| image:: http://sflogo.sourceforge.net/sflogo.php?group_id=161614&type=1
|
||||
:target: http://sourceforge.net
|
||||
|
||||
|sflogo|
|
|
@ -0,0 +1,24 @@
|
|||
This is an example of the Siesta interface.
|
||||
|
||||
To create supercells with displacements:
|
||||
|
||||
% phonopy --siesta -c Gr.fdf -d --dim="3 3 1"
|
||||
|
||||
A perfect 3x3x1 supercell (supercell.fdf) and one 3x3x1 supercells
|
||||
(supercell-xxx.in) of the conventional unit cell written in Gr.fdf are
|
||||
created. In addition, disp.yaml file is created. After force
|
||||
calculation with the crystal structure in supercell-001.fdf, it is
|
||||
needed to create FORCE_SETS file by
|
||||
|
||||
% phonopy --siesta -f disp-001/Gr.FA
|
||||
|
||||
Here the .FA file contains the forces on atoms calculated by Siesta. The
|
||||
disp.yaml file has to be put in the current directory. Now you can run
|
||||
phonon calculation, e.g.,
|
||||
|
||||
% phonopy --siesta -c Gr.fdf -p --dim="3 3 1" --band="0.0 0.0 0.0 1/4 0.0 0.0 0.5 0.0 0.0 2/3 -1/3 1/2 1/3 -1/6 0.0 0.0 0.0 0.0"
|
||||
|
||||
You can run the run_example.sh bash script to perform all the above commands
|
||||
and run the Siesta calculation (need to have Siesta installed).
|
||||
Be aware that this calculation is not converged and serves only to show the workflow
|
||||
of a siesta-phonopy calculation.
|
|
@ -0,0 +1,19 @@
|
|||
18
|
||||
1 -0.160630715159 0.000022129661 -0.117029565525
|
||||
2 0.013904321133 -0.000635004254 -0.002783938893
|
||||
3 0.006033593624 0.003792892916 -0.002667666114
|
||||
4 -0.005302250740 -0.006540073197 -0.002712592628
|
||||
5 0.001335036108 0.011718467376 -0.002739454829
|
||||
6 0.006045158152 0.000010094262 0.001244723790
|
||||
7 -0.001439502916 -0.008841864821 -0.002768356138
|
||||
8 0.006045301078 0.000011377309 0.001262253735
|
||||
9 -0.002555148927 0.000516607376 -0.002682944816
|
||||
10 0.065463382106 0.024429002958 0.046814749865
|
||||
11 -0.001238341736 -0.004450110524 -0.007316931722
|
||||
12 0.055547885402 -0.018600739401 0.047546920213
|
||||
13 0.006428688965 -0.000567713058 0.003667294554
|
||||
14 -0.007710376636 0.003725418801 -0.007302628603
|
||||
15 -0.000022664889 0.000691178617 -0.007331859660
|
||||
16 -0.004329322223 0.006225815921 0.003668998234
|
||||
17 -0.003390917282 -0.005654737751 0.003665241986
|
||||
18 0.023243972747 -0.005473732963 0.047183550197
|
|
@ -0,0 +1,76 @@
|
|||
# Commands to run this example
|
||||
|
||||
head="
|
||||
PAO.EnergyShift 0.1 eV
|
||||
DM.Tolerance 0.0001
|
||||
DM.MixingWeight 0.2
|
||||
Use.New.Diagk .true.
|
||||
SystemLabel Gr
|
||||
PAO.BasisSize sz
|
||||
SolutionMethod diagon
|
||||
MaxSCFIterations 120
|
||||
SCF.MixAfterConvergence .false.
|
||||
MeshCutoff 400 Ry
|
||||
NumberOfSpecies 1
|
||||
DM.UseSaveDM False
|
||||
ElectronicTemperature 0.02 eV
|
||||
%block ChemicalSpeciesLabel
|
||||
1 6 C
|
||||
%endblock ChemicalSpeciesLabel
|
||||
"
|
||||
|
||||
kgrid_uc="
|
||||
%block kgrid_Monkhorst_Pack
|
||||
30 0 0 0.0
|
||||
0 30 0 0.0
|
||||
0 0 1 0.0
|
||||
%endblock Kgrid_Monkhorst_Pack
|
||||
"
|
||||
|
||||
kgrid_sc="
|
||||
%block kgrid_Monkhorst_Pack
|
||||
10 0 0 0.0
|
||||
0 10 0 0.0
|
||||
0 0 1 0.0
|
||||
%endblock Kgrid_Monkhorst_Pack
|
||||
"
|
||||
|
||||
atoms_uc="
|
||||
NumberOfAtoms 2
|
||||
LatticeConstant 1.000000 Ang
|
||||
AtomicCoordinatesFormat NotScaledCartesianAng
|
||||
%block LatticeVectors
|
||||
2.55000000000000 0.00000000000000 0.00000000000000
|
||||
-1.27500000000000 2.20836477965032 0.00000000000000
|
||||
0.00000000000000 0.00000000000000 30.00000000000000
|
||||
%endblock LatticeVectors
|
||||
|
||||
AtomicCoordinatesFormat NotScaledCartesianAng
|
||||
|
||||
%block AtomicCoordinatesAndAtomicSpecies
|
||||
0.00000000000000 0.00000000000000 0.00000000000000 1 12.011000
|
||||
1.27500000000000 0.73612159321677 0.00000000000000 1 12.011000
|
||||
%endblock AtomicCoordinatesAndAtomicSpecies
|
||||
"
|
||||
|
||||
echo "$head" > Gr.fdf
|
||||
echo "$kgrid_uc" >> Gr.fdf
|
||||
echo "$atoms_uc" >> Gr.fdf
|
||||
phonopy --siesta -d --dim="3 3 1" -c Gr.fdf --amplitude=0.02
|
||||
mkdir disp-001
|
||||
cp C.psf supercell-001.fdf disp-001
|
||||
cd disp-001
|
||||
echo "$head" > Gr.fdf
|
||||
echo "$kgrid_sc" >> Gr.fdf
|
||||
echo "LatticeConstant 1.0 Bohr">> Gr.fdf
|
||||
echo "%include supercell-001.fdf" >> Gr.fdf
|
||||
#siesta < Gr.fdf
|
||||
cd ..
|
||||
phonopy --siesta -f disp-001/gr.FA -c Gr.fdf
|
||||
cat > band.conf << EOF
|
||||
ATOM_NAME = C
|
||||
DIM = 3 3 1
|
||||
BAND_POINTS = 50
|
||||
BAND = 0.0 0.0 0.0 1/4 0.0 0.0 0.5 0.0 0.0 2/3 -1/3 1/2 1/3 -1/6 0.0 0.0 0.0 0.0
|
||||
EOF
|
||||
phonopy --siesta -p band.conf -c Gr.fdf
|
|
@ -0,0 +1,24 @@
|
|||
This is an example of the Siesta interface.
|
||||
|
||||
To create supercells with displacements:
|
||||
|
||||
% phonopy --siesta -c Si.fdf -d --dim="3 3 3"
|
||||
|
||||
A perfect 3x3x3 supercell (supercell.fdf) and one 3x3x3 supercells
|
||||
(supercell-xxx.in) of the conventional unit cell written in Si.fdf are
|
||||
created. In addition, disp.yaml file is created. After force
|
||||
calculation with the crystal structure in supercell-001.fdf, it is
|
||||
needed to create FORCE_SETS file by
|
||||
|
||||
% phonopy --siesta -f disp-001/Si.FA
|
||||
|
||||
Here the .FA file contains the forces on atoms calculated by Siesta. The
|
||||
disp.yaml file has to be put in the current directory. Now you can run
|
||||
phonon calculation, e.g.,
|
||||
|
||||
% phonopy --siesta -c Si.fdf -p --dim="3 3 3" --band="1/2 1/2 1/2 0.0 0.0 0.0 0.0 1/2 1/2 1.0 1.0 1.0"
|
||||
|
||||
You can run the run_example.sh bash script to perform all the above commands
|
||||
and run the Siesta calculation (need to have Siesta installed).
|
||||
Be aware that this calculation is not converged and serves only to show the workflow
|
||||
of a siesta-phonopy calculation.
|
|
@ -0,0 +1,49 @@
|
|||
|
||||
SystemName silicon
|
||||
SystemLabel Si
|
||||
|
||||
NumberOfSpecies 1
|
||||
|
||||
%block ChemicalSpeciesLabel
|
||||
1 14 Si
|
||||
%endblock ChemicalSpeciesLabel
|
||||
|
||||
PAO.BasisSize sz
|
||||
|
||||
MeshCutoff 400.0 Ry
|
||||
|
||||
MaxSCFIterations 50
|
||||
DM.MixingWeight 0.2
|
||||
DM.NumberPulay 3
|
||||
DM.Tolerance 1.d-4
|
||||
DM.UseSaveDM
|
||||
|
||||
SolutionMethod diagon
|
||||
|
||||
WriteForces .true.
|
||||
|
||||
ElectronicTemperature 100 K
|
||||
|
||||
AtomicCoordinatesFormat Fractional
|
||||
|
||||
|
||||
%block kgrid_Monkhorst_Pack
|
||||
8 0 0 0.0
|
||||
0 8 0 0.0
|
||||
0 0 8 0.0
|
||||
%endblock Kgrid_Monkhorst_Pack
|
||||
|
||||
|
||||
NumberOfAtoms 2
|
||||
LatticeConstant 5.430 Ang
|
||||
%block LatticeVectors
|
||||
0.000 0.500 0.500
|
||||
0.500 0.000 0.500
|
||||
0.500 0.500 0.000
|
||||
%endblock LatticeVectors
|
||||
|
||||
%block AtomicCoordinatesAndAtomicSpecies
|
||||
0.00 0.00 0.00 1 # Si 1
|
||||
0.25 0.25 0.25 1 # Si 2
|
||||
%endblock AtomicCoordinatesAndAtomicSpecies
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
54
|
||||
1 -0.006326846769 -0.269865757978 -0.269865757978
|
||||
2 0.005151543965 0.005583616288 0.005583616288
|
||||
3 -0.004977276653 0.005408044170 0.005408044170
|
||||
4 0.000247570675 -0.003871608212 0.000115500409
|
||||
5 0.000001013377 0.001252796001 0.001246450742
|
||||
6 -0.000339901374 0.000142066028 -0.003912286238
|
||||
7 0.005303289109 -0.008964266238 0.005165263586
|
||||
8 -0.005417684456 0.005221264143 -0.008942876228
|
||||
9 -0.000004802907 0.001236186575 0.001250282992
|
||||
10 0.000247570675 0.000115500409 -0.003871608212
|
||||
11 0.000001013377 0.001246450741 0.001252796002
|
||||
12 -0.000339901374 -0.003912286238 0.000142066027
|
||||
13 0.001456557896 -0.000217456890 -0.000217456890
|
||||
14 -0.001463339652 -0.000218830516 -0.000218830516
|
||||
15 0.000005579543 0.000662351861 0.000662351861
|
||||
16 0.000006064992 -0.000163726718 -0.000172249727
|
||||
17 -0.000000826380 0.000288991743 0.000664696621
|
||||
18 0.000003538757 0.000664820231 0.000283249392
|
||||
19 0.005303289109 0.005165263585 -0.008964266238
|
||||
20 -0.005417684456 -0.008942876228 0.005221264143
|
||||
21 -0.000004802907 0.001250282992 0.001236186575
|
||||
22 0.000006064992 -0.000172249727 -0.000163726718
|
||||
23 -0.000000826380 0.000664696621 0.000288991743
|
||||
24 0.000003538757 0.000283249392 0.000664820231
|
||||
25 0.001464046517 -0.000216057239 -0.000216057239
|
||||
26 -0.000004482501 0.000667077125 0.000667077126
|
||||
27 -0.001447261482 -0.000225400452 -0.000225400453
|
||||
28 0.112159255692 0.123631298410 0.123631298410
|
||||
29 -0.000062884187 -0.000908605845 -0.000908605845
|
||||
30 -0.103778555678 0.117717678764 0.117717678764
|
||||
31 -0.000697949960 0.005426721989 -0.000224902550
|
||||
32 0.000673585888 -0.000220947908 0.005402662507
|
||||
33 -0.000025648556 -0.001830385054 -0.001894361966
|
||||
34 0.000822366299 0.012134870078 0.013401443528
|
||||
35 0.000056973811 -0.001798431230 -0.001917308947
|
||||
36 -0.000022159979 -0.001888198576 -0.001747769998
|
||||
37 -0.000697949960 -0.000224902550 0.005426721989
|
||||
38 0.000673585888 0.005402662507 -0.000220947908
|
||||
39 -0.000025648556 -0.001894361966 -0.001830385053
|
||||
40 0.000004156964 0.000463071295 0.000463071295
|
||||
41 -0.000142294256 -0.000580061073 -0.000580061073
|
||||
42 0.000141513273 -0.000577374141 -0.000577374141
|
||||
43 -0.001939576349 0.000184375211 0.000066457615
|
||||
44 0.000002858907 -0.000439650268 -0.000434048062
|
||||
45 0.001915736809 0.000064392340 0.000201320199
|
||||
46 0.000822366299 0.013401443528 0.012134870078
|
||||
47 0.000056973811 -0.001917308947 -0.001798431230
|
||||
48 -0.000022159979 -0.001747769998 -0.001888198576
|
||||
49 -0.001939576348 0.000066457615 0.000184375211
|
||||
50 0.000002858907 -0.000434048062 -0.000439650268
|
||||
51 0.001915736808 0.000201320199 0.000064392340
|
||||
52 -0.001967316329 0.000020213564 0.000020213564
|
||||
53 0.001966976723 0.000030325332 0.000030325332
|
||||
54 -0.000003097174 -0.000531768850 -0.000531768850
|
|
@ -0,0 +1,83 @@
|
|||
#Commands to run this example:
|
||||
|
||||
head="
|
||||
SystemName silicon
|
||||
SystemLabel Si
|
||||
|
||||
NumberOfSpecies 1
|
||||
|
||||
%block ChemicalSpeciesLabel
|
||||
1 14 Si
|
||||
%endblock ChemicalSpeciesLabel
|
||||
|
||||
PAO.BasisSize sz
|
||||
|
||||
MeshCutoff 400.0 Ry
|
||||
|
||||
MaxSCFIterations 50
|
||||
DM.MixingWeight 0.2
|
||||
DM.NumberPulay 3
|
||||
DM.Tolerance 1.d-4
|
||||
DM.UseSaveDM
|
||||
|
||||
SolutionMethod diagon
|
||||
|
||||
WriteForces .true.
|
||||
|
||||
ElectronicTemperature 100 K
|
||||
|
||||
AtomicCoordinatesFormat Fractional
|
||||
"
|
||||
|
||||
kgrid_uc="
|
||||
%block kgrid_Monkhorst_Pack
|
||||
8 0 0 0.0
|
||||
0 8 0 0.0
|
||||
0 0 8 0.0
|
||||
%endblock Kgrid_Monkhorst_Pack
|
||||
"
|
||||
|
||||
kgrid_sc="
|
||||
%block kgrid_Monkhorst_Pack
|
||||
3 0 0 0.0
|
||||
0 3 0 0.0
|
||||
0 0 3 0.0
|
||||
%endblock Kgrid_Monkhorst_Pack
|
||||
"
|
||||
|
||||
atoms_uc="
|
||||
NumberOfAtoms 2
|
||||
LatticeConstant 5.430 Ang
|
||||
%block LatticeVectors
|
||||
0.000 0.500 0.500
|
||||
0.500 0.000 0.500
|
||||
0.500 0.500 0.000
|
||||
%endblock LatticeVectors
|
||||
|
||||
%block AtomicCoordinatesAndAtomicSpecies
|
||||
0.00 0.00 0.00 1 # Si 1
|
||||
0.25 0.25 0.25 1 # Si 2
|
||||
%endblock AtomicCoordinatesAndAtomicSpecies
|
||||
"
|
||||
|
||||
echo "$head" > Si.fdf
|
||||
echo "$kgrid_uc" >> Si.fdf
|
||||
echo "$atoms_uc" >> Si.fdf
|
||||
phonopy --siesta -d --dim="3 3 3" -c Si.fdf --amplitude=0.04
|
||||
mkdir disp-001
|
||||
cp Si.psf supercell-001.fdf disp-001
|
||||
cd disp-001
|
||||
echo "$head" > Si.fdf
|
||||
echo "$kgrid_sc" >> Si.fdf
|
||||
echo "LatticeConstant 1.0 Bohr">> Si.fdf
|
||||
echo "%include supercell-001.fdf" >> Si.fdf
|
||||
siesta < Si.fdf
|
||||
cd ..
|
||||
phonopy --siesta -f disp-001/Si.FA -c Si.fdf
|
||||
cat > band.conf << EOF
|
||||
ATOM_NAME = Si O
|
||||
DIM = 3 3 3
|
||||
BAND_POINTS = 100
|
||||
BAND = 1/2 1/2 1/2 0.0 0.0 0.0 0.0 1/2 1/2 1.0 1.0 1.0
|
||||
EOF
|
||||
phonopy --siesta -p band.conf -c Si.fdf
|
|
@ -83,6 +83,10 @@ def read_crystal_structure(filename=None,
|
|||
unitcell, sp_filenames = read_elk(unitcell_filename)
|
||||
return unitcell, (unitcell_filename, sp_filenames)
|
||||
|
||||
if interface_mode == 'siesta':
|
||||
from phonopy.interface.siesta import read_siesta
|
||||
unitcell, atypes = read_siesta(unitcell_filename)
|
||||
return unitcell, (unitcell_filename, atypes)
|
||||
|
||||
def get_default_cell_filename(interface_mode, yaml_mode):
|
||||
if yaml_mode:
|
||||
|
@ -97,7 +101,9 @@ def get_default_cell_filename(interface_mode, yaml_mode):
|
|||
return "case.struct"
|
||||
if interface_mode == 'elk':
|
||||
return "elk.in"
|
||||
|
||||
if interface_mode == 'siesta':
|
||||
return "input.fdf"
|
||||
|
||||
def create_FORCE_SETS(interface_mode,
|
||||
force_filenames,
|
||||
options,
|
||||
|
@ -107,7 +113,8 @@ def create_FORCE_SETS(interface_mode,
|
|||
if (interface_mode == 'wien2k' or
|
||||
interface_mode == 'abinit' or
|
||||
interface_mode == 'elk' or
|
||||
interface_mode == 'pwscf'):
|
||||
interface_mode == 'pwscf' or
|
||||
interface_mode == 'siesta'):
|
||||
displacements, supercell = parse_disp_yaml(filename='disp.yaml',
|
||||
return_cell=True)
|
||||
|
||||
|
@ -173,6 +180,17 @@ def create_FORCE_SETS(interface_mode,
|
|||
force_filenames,
|
||||
supercell.get_number_of_atoms())
|
||||
|
||||
if interface_mode == 'siesta':
|
||||
from phonopy.interface.siesta import parse_set_of_forces
|
||||
print "**********************************************************"
|
||||
print "**** Siesta FORCE_SETS support is experimental. ****"
|
||||
print "**** Your feedback would be appreciated. ****"
|
||||
print "**********************************************************"
|
||||
is_parsed = parse_set_of_forces(
|
||||
displacements,
|
||||
force_filenames,
|
||||
supercell.get_number_of_atoms())
|
||||
|
||||
if is_parsed:
|
||||
write_FORCE_SETS(displacements, filename='FORCE_SETS')
|
||||
|
||||
|
|
|
@ -0,0 +1,201 @@
|
|||
# Copyright (C) 2015 Henrique Pereira Coutada Miranda
|
||||
# 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
|
||||
import re
|
||||
|
||||
from phonopy.file_IO import iter_collect_forces, get_drift_forces
|
||||
from phonopy.interface.vasp import get_scaled_positions_lines
|
||||
from phonopy.units import Bohr
|
||||
from phonopy.cui.settings import fracval
|
||||
from phonopy.structure.atoms import Atoms, symbol_map
|
||||
|
||||
def parse_set_of_forces(displacements,
|
||||
forces_filenames,
|
||||
num_atom):
|
||||
hook = ''
|
||||
for siesta_filename, disp in zip(forces_filenames,
|
||||
displacements['first_atoms']):
|
||||
siesta_forces = iter_collect_forces(siesta_filename,
|
||||
num_atom,
|
||||
hook,
|
||||
[1, 2, 3],
|
||||
word='')
|
||||
drift_force = get_drift_forces(siesta_forces)
|
||||
disp['forces'] = np.array(siesta_forces) - drift_force
|
||||
|
||||
return True
|
||||
|
||||
def read_siesta(filename):
|
||||
siesta_in = SiestaIn(open(filename).read())
|
||||
numbers = siesta_in._tags["atomicnumbers"]
|
||||
lattice = siesta_in._tags["latticevectors"]
|
||||
positions = siesta_in._tags["atomiccoordinates"]
|
||||
atypes = siesta_in._tags["chemicalspecieslabel"]
|
||||
cell = Atoms(numbers=numbers,
|
||||
cell=lattice)
|
||||
|
||||
coordformat = siesta_in._tags["atomiccoordinatesformat"]
|
||||
if coordformat == "fractional" or coordformat == "scaledbylatticevectors":
|
||||
cell.set_scaled_positions(positions)
|
||||
elif coordformat == "scaledcartesian":
|
||||
if siesta_in._tags['latticeconstant'] == 'ang':
|
||||
cell.set_positions(np.array(positions) / Bohr)#convert from angstroem to Bohr
|
||||
else:
|
||||
cell.set_positions(np.array(positions))
|
||||
elif coordformat == "notscaledcartesianang" or coordformat == "ang":
|
||||
cell.set_positions(np.array(positions) / Bohr) #convert from angstroem to Bohr
|
||||
elif coordformat == "notscaledcartesianbohr" or coordformat == "bohr":
|
||||
cell.set_positions(np.array(positions))
|
||||
else:
|
||||
print "The format %s for the AtomicCoordinatesFormat is not implemented"%coordformat
|
||||
exit()
|
||||
|
||||
return cell, atypes
|
||||
|
||||
def write_siesta(filename, cell, atypes):
|
||||
f = open(filename, 'w')
|
||||
f.write(get_siesta_structure(cell,atypes))
|
||||
|
||||
def write_supercells_with_displacements(supercell,
|
||||
cells_with_displacements,
|
||||
atypes):
|
||||
write_siesta("supercell.fdf", supercell, atypes)
|
||||
for i, cell in enumerate(cells_with_displacements):
|
||||
write_siesta("supercell-%03d.fdf" % (i + 1), cell, atypes)
|
||||
|
||||
def get_siesta_structure(cell,atypes):
|
||||
lattice = cell.get_cell()
|
||||
positions = cell.get_scaled_positions()
|
||||
masses = cell.get_masses()
|
||||
chemical_symbols = cell.get_chemical_symbols()
|
||||
|
||||
lines = ""
|
||||
|
||||
lines += "NumberOfAtoms %d\n\n"% len(positions)
|
||||
|
||||
lines += "%block LatticeVectors\n"
|
||||
lines += ((" %21.16f" * 3 + "\n") * 3) % tuple(lattice.ravel())
|
||||
lines += "%endblock LatticeVectors\n\n"
|
||||
|
||||
lines += "AtomicCoordinatesFormat Fractional\n\n"
|
||||
|
||||
lines += "LatticeConstant 1.0 Bohr\n\n"
|
||||
|
||||
lines += "%block AtomicCoordinatesAndAtomicSpecies\n"
|
||||
for pos, i in zip(positions,chemical_symbols):
|
||||
lines += ("%21.16lf"*3+" %d\n") % tuple(pos.tolist()+[atypes[i]])
|
||||
lines += "%endblock AtomicCoordinatesAndAtomicSpecies\n"
|
||||
|
||||
return lines
|
||||
|
||||
class SiestaIn:
|
||||
_num_regex = '([+-]?\d+(?:\.\d+)?(?:[eE][-+]?\d+)?)'
|
||||
_tags = { "latticeconstant": 1.0,
|
||||
"latticeconstantunit": None,
|
||||
"chemicalspecieslabel": None,
|
||||
"atomiccoordinatesformat": None,
|
||||
"atomicnumbers": None,
|
||||
"atomicspecies": None,
|
||||
"atomiccoordinates": None }
|
||||
|
||||
def __init__(self, lines):
|
||||
self._collect(lines)
|
||||
|
||||
def _collect(self, lines):
|
||||
""" This routine reads the following from the Siesta file:
|
||||
- atomic positions
|
||||
- cell_parameters
|
||||
- atomic_species
|
||||
"""
|
||||
#capture tags
|
||||
for tag,value,unit in re.findall('([\.A-Za-z]+)\s+?%s(?:[ ]+)?([A-Za-z]+)?'%self._num_regex,lines):
|
||||
tag = tag.lower()
|
||||
if tag == "latticeconstant":
|
||||
self._tags['latticeconstantunit'] = unit.lower()
|
||||
if unit == 'Ang':
|
||||
self._tags[tag] = float(value) / Bohr
|
||||
else:
|
||||
self._tags[tag] = float(value)
|
||||
|
||||
for tag,value in re.findall('([\.A-Za-z]+)[ \t]+([a-zA-Z]+)',lines):
|
||||
tag = tag.replace('_','').lower()
|
||||
if tag == "atomiccoordinatesformat":
|
||||
self._tags[tag] = value.strip().lower()
|
||||
|
||||
#check if the necessary tags are present
|
||||
self.check_present('atomiccoordinatesformat')
|
||||
acell = self._tags['latticeconstant']
|
||||
|
||||
#capture the blocks
|
||||
blocks = re.findall('%block\s+([A-Za-z_]+)\s((?:.+\n)+?(?=(?:\s+)?%endblock))',lines,re.MULTILINE)
|
||||
for tag,block in blocks:
|
||||
tag = tag.replace('_','').lower()
|
||||
if tag == "chemicalspecieslabel":
|
||||
lines = block.split('\n')[:-1]
|
||||
self._tags["atomicnumbers"] = dict([map(int,species.split()[:2]) for species in lines])
|
||||
self._tags[tag] = dict([(lambda x: (x[2],int(x[0])))(species.split()) for species in lines])
|
||||
elif tag == "latticevectors":
|
||||
self._tags[tag] = [[ float(v)*acell for v in vector.split()] for vector in block.split('\n')[:3]]
|
||||
elif tag == "atomiccoordinatesandatomicspecies":
|
||||
lines = block.split('\n')[:-1]
|
||||
self._tags["atomiccoordinates"] = [ [float(x) for x in atom.split()[:3]] for atom in lines ]
|
||||
self._tags["atomicspecies"] = [ int(atom.split()[3]) for atom in lines]
|
||||
|
||||
#check if the block are present
|
||||
self.check_present("atomicspecies")
|
||||
self.check_present("atomiccoordinates")
|
||||
self.check_present("latticevectors")
|
||||
self.check_present("chemicalspecieslabel")
|
||||
|
||||
#translate the atomicspecies to atomic numbers
|
||||
self._tags["atomicnumbers"] = [self._tags["atomicnumbers"][atype] for atype in self._tags["atomicspecies"]]
|
||||
|
||||
def check_present(self,tag):
|
||||
if not self._tags[tag]:
|
||||
print "%s not present"%tag
|
||||
exit()
|
||||
|
||||
def __str__():
|
||||
return self._tags
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from phonopy.structure.symmetry import Symmetry
|
||||
cell,atypes = read_siesta(sys.argv[1])
|
||||
symmetry = Symmetry(cell)
|
||||
print "#", symmetry.get_international_table()
|
||||
print get_siesta_structure(cell,atypes)
|
|
@ -65,4 +65,5 @@ Wien2kToTHz = sqrt(Rydberg/1000*EV/AMU)/(Bohr*1e-10)/(2*pi)/1e12 # [THz] 3.44595
|
|||
AbinitToTHz = sqrt(EV/(AMU*Bohr))/Angstrom/(2*pi)/1e12 # [THz] 21.49068
|
||||
PwscfToTHz = sqrt(Rydberg*EV/AMU)/(Bohr*1e-10)/(2*pi)/1e12 # [THz] 108.97077
|
||||
ElkToTHz = sqrt(Hartree*EV/AMU)/(Bohr*1e-10)/(2*pi)/1e12 # [THz] 154.10794
|
||||
SiestaToTHz = sqrt(EV/(AMU*Bohr))/Angstrom/(2*pi)/1e12 # [THz] 21.49068
|
||||
EVAngstromToGPa = EV * 1e21
|
||||
|
|
|
@ -207,6 +207,7 @@ parser.set_defaults(
|
|||
displacement_distance=None,
|
||||
dynamical_matrix_decimals=None,
|
||||
elk_mode=False,
|
||||
siesta_mode=False,
|
||||
factor=None,
|
||||
fc_symmetry=None,
|
||||
fc_computation_algorithm=None,
|
||||
|
@ -401,6 +402,8 @@ parser.add_option("--pt", "--projected_thermal_property",
|
|||
help="Output projected thermal properties")
|
||||
parser.add_option("--pwscf", dest="pwscf_mode",
|
||||
action="store_true", help="Invoke Pwscf mode")
|
||||
parser.add_option("--siesta", dest="siesta_mode",
|
||||
action="store_true", help="Invoke Siesta mode")
|
||||
parser.add_option("-q", "--quiet", dest="quiet",
|
||||
action="store_true",
|
||||
help="Print out smallest information")
|
||||
|
@ -489,6 +492,7 @@ if options.loglevel is not None:
|
|||
# abinit : hartree, au, AMU, eV/Angstrom
|
||||
# elk : hartree, au, AMU, hartree/au
|
||||
# pwscf : Ry, au, AMU, Ry/au
|
||||
# siesta : eV, au, AMU, eV/Angstroem
|
||||
#
|
||||
if options.wien2k_mode:
|
||||
interface_mode = 'wien2k'
|
||||
|
@ -506,6 +510,10 @@ elif options.elk_mode:
|
|||
interface_mode = 'elk'
|
||||
from phonopy.interface.elk import write_supercells_with_displacements
|
||||
factor = ElkToTHz
|
||||
elif options.siesta_mode:
|
||||
interface_mode = 'siesta'
|
||||
from phonopy.interface.siesta import write_supercells_with_displacements
|
||||
factor = SiestaToTHz
|
||||
else:
|
||||
interface_mode = 'vasp'
|
||||
from phonopy.interface.vasp import write_supercells_with_displacements
|
||||
|
@ -620,7 +628,8 @@ if settings.get_displacement_distance() is None:
|
|||
if (interface_mode == 'wien2k' or
|
||||
interface_mode == 'abinit' or
|
||||
interface_mode == 'elk' or
|
||||
interface_mode == 'pwscf'):
|
||||
interface_mode == 'pwscf' or
|
||||
interface_mode == 'siesta'):
|
||||
displacement_distance = 0.02
|
||||
else:
|
||||
displacement_distance = 0.01
|
||||
|
@ -767,6 +776,11 @@ if run_mode == 'displacements':
|
|||
write_supercells_with_displacements(supercell,
|
||||
cells_with_disps,
|
||||
sp_filenames)
|
||||
elif interface_mode == 'siesta':
|
||||
atypes = optional_structure_file_information[1]
|
||||
write_supercells_with_displacements(supercell,
|
||||
cells_with_disps,
|
||||
atypes)
|
||||
else:
|
||||
write_supercells_with_displacements(supercell, cells_with_disps)
|
||||
|
||||
|
|
Loading…
Reference in New Issue