[Pw_forum] band and dos input files in xcrysden
O. Baris Malcioglu
baris.malcioglu at gmail.com
Thu Feb 26 11:09:08 CET 2009
Dear Paolo,
I, being a script-happy person, like the "seperate steps" approach of
pw.x very very much. Although not as high level as a python one,
please find a script written in TCL which I use for preparing DOS and
PDOS plots.
Use this at your own risk! Being a script I modify it constantly for
my needs, and I am not sure this is the "most corrected" version.
Basically you use it like this :
makedosgraph.tcl "pw.x input file" "pw.x output file for latest
coordinates or -- to use coordinates in input file" -i "mpi related
things + directory"
run the script without parameters to see available options.
some examples:
Prepare the pdos showing atoms 1 3 5 with a degauss of 0.002 from a pwscf result
makedosgraph.tcl in.grapheneO -- -i "/home/obm/Progs/pwscf/bin/"
-plot_dg 0.002 -fermi_at_zero -atoms "1 3 5"
Prepare a nscf file using the latest coordinates from a output file of
a relaxation run
makedosgraph.tcl in.grapheneO out.grapheneO -s 1
Prepare gnuplot files for an already run projwfc.x/dos.x
makedosgraph.tcl in.grapheneO -- -s 4 -fermi_at_zero -atoms "1 3 5"
(I also remember having something for bands and workfunctions somewhere)
Best,
Baris Malcioglu
SISSA .
makedosgraph.tcl
#!/bin/sh
# the next line restarts using tclsh \
exec tclsh8.4 "$0" "$@"
###########################
# this script will
# 1) read an input file for prefix and outdir
# 2) read an output file for latest coordinates
# 2) do a nscf calculation according to above data
# 3) do a dos.x calculation according to above data
# 4) do a projwfc.x calculation according to above data
# 5) prepare gnuplot files
#
# Osman Baris Malcioglu 2007 v.1 alpha
#
##########################
proc ::main {argc argv} {
global pw_input_file
global pw_output_file
global plot_dg
global stag
global spref
global plotlist
global nspin
set plot_dg 0
set stag 0
set spref ""
set plotlist ""
get_commandline $argc $argv
do_calcs
}
##########################
#A procedure to read commandline
##########################
proc ::get_commandline {argc argv} {
global pw_input_file
global pw_output_file
global plot_dg
global stag
global spref
global plotlist
global fatzero
set fatzero 0
if { $argc < 2} {
puts stderr "Usage: makedosgraph <input file> <otput
file>\[parameters\]"
puts stderr "Parameters:"
puts stderr "-s : set calculation stage "
puts stderr " 1 : prepare nscf files and exit"
puts stderr " 2 : use present files and run nscf, and quit"
puts stderr " 3 : prepare for and run dos.x and projwfc.x"
puts stderr " 4 : prepare gnuplot baches for pdos output only"
puts stderr "-plot_dg <float> : set the plotting degauss in dos.x"
puts stderr "-i <\"prefix to pwscf\"> : the prefix to be appended to runs"
puts stderr "-atoms <\"space seperated list of atoms\">: will draw
these atoms only"
puts stderr "-fermi_at_zero move the graphs such that
Ef is at 0"
exit 1
}
if { $argc > 0 } {
set state first
foreach arg $argv {
switch -- $state {
first {
set state second
#check if the infile exists
set pw_input_file $arg
if { [file exists $pw_input_file] } {
puts "using input file $pw_input_file"
} else {
puts stderr "Input file $pw_input_file does not exits"
exit 1
}
}
second {
set state flag
#check if the outfile exists
set pw_output_file $arg
if { [file exists $pw_output_file] || $pw_output_file == "--"} {
puts "using output file $pw_output_file"
} else {
puts stderr "Output file $pw_output_file does not exist"
exit 1
}
}
flag {
switch -glob -- $arg {
-plot_dg {
set state p_dg
}
-s {
set state sstag
}
-i { set state sspref }
-atoms {set state splotlist}
-fermi_at_zero {set fatzero 1}
default {
puts stderr "unknown flag $arg"
exit 2
}
}
}
p_dg {
if { [ regexp -- {-?[0-9]+\.?[0-9]*} $arg plot_dg ] } {
puts "using plot degauss = $plot_dg"
set state flag
} else {
puts stderr " I didn't understand $arg after -plot_dg "
exit 2
}
}
sstag {
if { [ regexp -- {[1-4]} $arg stag ] } {
puts "Calculation stage set to $stag"
set state flag
} else {
puts stderr " I didn't understand $arg after -s "
exit 2
}
}
sspref {
set spref $arg
puts "run prefix is $spref"
set state flag
}
splotlist {
set plotlist $arg
puts "Plotlist is $plotlist"
set state flag
}
}
}
}
if {![file exists [file join $spref "pw.x"]]} {
puts "Warning: I can not find [file join $spref pw.x ]"
}
if {![file exists [file join $spref "dos.x"]]} {
puts "Warning: I can not find [file join $spref dos.x ]"
}
if {![file exists [file join $spref "projwfc.x"]]} {
puts "Warning: I can not find [file join $spref projwfc.x ]"
}
}
#######################
#This procedure reads the input file, prepares input files for nscf
dos.x projwfc.x
#and runs them
######################
proc ::do_calcs {} {
global pw_input_file
global pw_output_file
global pw_outdir
global n_at
global pw_prefix
global lc_pos
global lc_posin
global stag
global spref
global nspin
global e_fermi
global plotlist
global plot_dg
global fatzero
if [catch {open $pw_input_file r} fileId] {
puts stderr "Cannot open $pw_input_file: $fileId"
exit 1
}
set tmpfile [read $fileId]
close $fileId
if { ! [regexp -linestop -- {outdir\s*=\s*'?"?(.*?)[!',]*} $tmpfile
match pw_outdir] } {
puts stderr "outdir not found !"
exit 1
} else {
puts "The outdir is : $pw_outdir"
}
if { ! [regexp -linestop -- {prefix\s*=\s*'?"?(.*?)[!',]*} $tmpfile
match pw_prefix] } {
puts stderr "prefix not found !"
exit 1
} else {
puts "The prefix is : $pw_prefix"
}
# read number of atoms
if {![regexp -linestop -- {nat\s*=\s*([0-9]+)} $tmpfile match n_at]} {
puts "Error reading n_at, exiting"
exit 2
}
puts "nat=$n_at"
# read nspin
if {![regexp -linestop -- {nspin\s*=\s*([1-2])} $tmpfile match nspin]} {
puts "no nspin line found, setting nspin to 1"
set nspin 1
}
puts "nspin=$nspin"
# do this only if stage is 0 or 1
if {$stag<2} {
regsub -nocase -linestop -- {calculation.*} $tmpfile
{calculation = 'nscf'} tmpfile2
regsub -nocase -linestop -- {restart_mode.*} $tmpfile2 {} tmpfile2
if { $pw_output_file != "--" } {
if [catch {open $pw_output_file r} fileId] {
puts stderr "Cannot open $pw_output_file: $fileId"
exit 1
}
set tmpoutfile [read $fileId]
close $fileId
if {[regexp -all -indices -nocase --
{ATOMIC_POSITIONS\s*\([a-z]+\)\s*} $tmpoutfile lc_pos] == 0 } {
puts stderr "Error locating latest coordinates in $pw_output_file "
exit 1
}
set lc_pos [lindex [split $lc_pos] 1]
puts "Latest coordinates at index:$lc_pos in output file"
if {[regexp -all -indices -nocase --
{ATOMIC_POSITIONS\s*\{?\(?[a-z]+\)?\}?\s*} $tmpfile2 lc_posin] == 0 }
{
puts stderr "Error locating latest coordinates in $pw_input_file "
exit 1
}
set lc_posin [lindex [split $lc_posin] 1]
puts "Coordinates at index:$lc_posin in input file"
for {set i 0} {$i<$n_at} {incr i 1} {
set search "regexp -start $lc_pos -linestop -nocase --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*}
\$tmpoutfile match"
#puts "$search"
eval $search
set search "regexp -start $lc_posin -linestop -nocase --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*}
\$tmpfile2 match2"
#puts "$search"
eval $search
puts "replacing $match2 with $match"
puts "[regsub -linestop "$match2" $tmpfile2 "$match" tmpfile2]
replacements was made"
set search "regexp -start $lc_pos -linestop -nocase -indices --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s*}
\$tmpoutfile match"
#puts $search
eval $search
set lc_pos [lindex [split $match] 1]
set search "regexp -start $lc_posin -linestop -nocase -indices --
{\[a-z\]+\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s+-?\[0-9\]+\\.?\[0-9\]*\\s*}
\$tmpfile2 match2"
#puts $search
eval $search
set lc_posin [lindex [split $match2] 1]
}
unset tmpoutfile
} else {
puts "using input coordinates"
}
if {![regexp -nocase -linestop -- {diagonalization} $tmpfile2]} {
puts "The diagonalization method is now set to cg"
regsub -- {\&electrons} $tmpfile2 "\\&electrons\n
diagonalization='cg'" tmpfile2
}
puts "Preparing nscf input in.$pw_prefix.nscf"
if [catch {open in.$pw_prefix.nscf w} fileId] {
puts stderr "Cannot open in.$pw_prefix.nscf: $fileId"
exit 1
}
puts $fileId $tmpfile2
close $fileId
}
# do this only if stage is 2 or 0
if {$stag == 2 || $stag == 0} {
puts "Running nscf calculation"
exec [file join $spref pw.x ] < in.$pw_prefix.nscf > out.$pw_prefix.nscf
}
#do this if stage is anyhing but 4
if {$stag < 4 } {
puts "preparing DOS input : in.$pw_prefix.dosx"
if [catch {open in.$pw_prefix.dosx w} fileId] {
puts stderr "Cannot open in.$pw_prefix.dosx: $fileId"
exit 1
}
puts $fileId "&inputpp"
puts $fileId " outdir='$pw_outdir'"
puts $fileId " prefix='$pw_prefix'"
if {$plot_dg > 0} {
puts $fileId " degauss = $plot_dg"
}
puts $fileId "/"
close $fileId
puts "Running Dos.x"
exec [file join $spref dos.x ] <in.$pw_prefix.dosx >out.$pw_prefix.dosx
puts "Preparing gnuplot batch for DOS: $pw_prefix.dosx.gnu"
if [catch {open $pw_prefix.dosx.gnu w} gnufile] {
puts stderr "Cannot open in.$pw_prefix.dosx: $gnufile"
exit 1
}
puts $gnufile "set term jpeg size 1024,768"
puts $gnufile "set output '$pw_prefix-dos.jpg'"
puts $gnufile "set key below"
puts $gnufile "set title '$pw_prefix'"
puts $gnufile "set xlabel 'Energy in (eV)'"
puts $gnufile "set ylabel 'DOS'"
if {$nspin == 2} {
puts $gnufile "plot '$pw_prefix.dos' using 1:2 w l title 'Spin
up','$pw_prefix.dos' using 1:3 w l title 'Spin down'"
} else {
puts $gnufile "unset key"
puts $gnufile "plot '$pw_prefix.dos' using 1:2 w l "
}
close $gnufile
puts "Running PDOS"
exec [file join $spref projwfc.x ] <in.$pw_prefix.dosx >out.$pw_prefix.pdosx
}
# do anyhow, preparation for further stages
if {$stag < 5 } {
puts "preparing gnuplot file for pdos : $pw_prefix-pdos.gnu"
if [catch {open out.$pw_prefix.nscf r} fileId] {
puts "Warning : Cannot open out.$pw_prefix.nscf:
$fileId , setting Fermi Energy to zero"
set e_fermi 0
} else {
set tmpoutfile [read $fileId]
close $fileId
if {[regexp -linestop -- {the Fermi energy is\s+(-?[0-9]+\.?[0-9]*)}
$tmpoutfile match e_fermi]} {
puts "NSCF calculation yields an Efermi of $e_fermi"
} else {
puts "Error reading E_fermi, set to 0"
set e_fermi 0
}
}
if [catch {open $pw_prefix-pdos.gnu w} gnufile] {
puts stderr "Cannot open in.$pw_prefix.dosx: $gnufile"
exit 1
}
puts $gnufile "set term jpeg size 1024,768"
puts $gnufile "set output '$pw_prefix-pdos.jpg'"
puts $gnufile "set key below"
puts $gnufile "set title '$pw_prefix'"
puts $gnufile "set xlabel 'Energy in (eV)'"
puts $gnufile "unset ylabel"
puts $gnufile "unset ytics"
puts $gnufile "set yrange \[0:[expr {[llength $plotlist]*1.5 + 2}]\]"
if {[llength $plotlist]==0} {
if {$nspin == 2} {
puts $gnufile "plot '$pw_prefix.pdos_tot' using 1:4 w l title 'Spin
up','$pw_prefix.pdos_tot' using 1:5 w l title 'Spin down'"
} else {
puts $gnufile "unset key"
puts $gnufile "plot '$pw_prefix.pdos_tot' using 1:3 w l "
}
} else {
puts $gnufile "unset key"
if {$nspin == 2} {
if { $fatzero == 0 } {
puts $gnufile "set label \"Ef=$e_fermi\" at [expr
{$e_fermi+0.2}],0.6 front rotate"
} else {
puts $gnufile "set label \"Ef\" at 0.2,0.6
front rotate"
}
puts $gnufile "set label \"S\" at graph 0,1.02 point lt 1"
puts $gnufile "set label \"Pz\" at graph 0.1,1.02 point lt 2"
puts $gnufile "set label \"Px\" at graph 0.2,1.02 point lt 3"
puts $gnufile "set label \"Py\" at graph 0.3,1.02 point lt 4"
set plot_incr 0
foreach atom_no $plotlist {
puts $gnufile "set label \"Atom $atom_no\" at graph -0.01,first
[expr {$plot_incr+0.6}] rotate"
set plot_incr [ expr {$plot_incr + 1.5} ]
}
puts $gnufile "set label \"Tot Pdos\" at graph -0.01, first [expr
{[llength $plotlist]*1.5 + 0.7}] rotate"
puts -nonewline $gnufile "plot "
set plot_incr 0
foreach atom_no $plotlist {
foreach file [glob -nocomplain $pw_prefix.pdos_atm#$atom_no* ] {
if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#1\\(s\\)"
$file match]} {
if { $fatzero == 0 } {
puts -nonewline $gnufile "'$match' using 1:($plot_incr+\$4) w l lt 1,"
} else {
puts -nonewline $gnufile "'$match' using
(\$1-$e_fermi):($plot_incr+\$4) w l lt 1,"
}
}
if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#2\\(p\\)"
$file match]} {
if { $fatzero == 0 } {
puts -nonewline $gnufile "'$match' u
1:($plot_incr+\$4) w l lt 2,'$match' u 1:($plot_incr+\$6) w l lt
3,'$match' u 1:($plot_incr+\$8) w l lt 4,"
} else {
puts -nonewline $gnufile "'$match' u
(\$1-$e_fermi):($plot_incr+\$4) w l lt 2,'$match' u
(\$1-$e_fermi):($plot_incr+\$6) w l lt 3,'$match' u
(\$1-$e_fermi):($plot_incr+\$8) w l lt 4,"
}
}
}
set plot_incr [expr {$plot_incr + 1.5}]
}
if { $fatzero == 0 } {
puts $gnufile "'$pw_prefix.pdos_tot' using 1:(\$2/4+$plot_incr) w
l lt 1,'-' w l lt 8"
puts $gnufile "$e_fermi 0"
puts $gnufile "$e_fermi [expr {$plot_incr+10}]"
puts $gnufile "e"
} else {
puts $gnufile "'$pw_prefix.pdos_tot' using
(\$1-$e_fermi):(\$2/4+$plot_incr) w l lt 1,'-' w l lt 8"
puts $gnufile "0 0"
puts $gnufile "0 [expr {$plot_incr+10}]"
puts $gnufile "e"
}
} else {
if { $fatzero == 0 } {
puts $gnufile "set label \"Ef=$e_fermi\" at [expr
{$e_fermi+0.2}],0.6 front rotate"
} else {
puts $gnufile "set label \"Ef\" at 0.2,0.6
front rotate"
}
puts $gnufile "set label \"S\" at graph 0,1.02 point lt 1"
puts $gnufile "set label \"Pz\" at graph 0.1,1.02 point lt 2"
puts $gnufile "set label \"Px\" at graph 0.2,1.02 point lt 3"
puts $gnufile "set label \"Py\" at graph 0.3,1.02 point lt 4"
set plot_incr 0
foreach atom_no $plotlist {
puts $gnufile "set label \"Atom $atom_no\" at graph -0.01,first
[expr {$plot_incr+0.6}] rotate"
set plot_incr [ expr {$plot_incr + 1.5} ]
}
puts $gnufile "set label \"Tot Pdos\" at graph -0.01, first [expr
{[llength $plotlist]*1.5 + 0.7}] rotate"
puts -nonewline $gnufile "plot "
set plot_incr 0
foreach atom_no $plotlist {
foreach file [glob -nocomplain $pw_prefix.pdos_atm#$atom_no* ] {
if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#1\\(s\\)"
$file match]} {
if { $fatzero == 0 } {
puts -nonewline $gnufile "'$match' using 1:($plot_incr+\$3) w l lt 1,"
} else {
puts -nonewline $gnufile "'$match' using
(\$1-$e_fermi):($plot_incr+\$3) w l lt 1,"
}
}
if {[regexp "$pw_prefix.pdos_atm#$atom_no\\(.+?\\)_wfc#2\\(p\\)"
$file match]} {
if { $fatzero == 0 } {
puts -nonewline $gnufile "'$match'
u 1:($plot_incr+\$3) w l lt 2,'$match' u 1:($plot_incr+\$4) w l lt
3,'$match' u 1:($plot_incr+\$5) w l lt 4,"
} else {
puts -nonewline $gnufile "'$match' u
(\$1-$e_fermi):($plot_incr+\$3) w l lt 2,'$match' u
(\$1-$e_fermi):($plot_incr+\$4) w l lt 3,'$match' u
(\$1-$e_fermi):($plot_incr+\$5) w l lt 4,"
}
}
}
set plot_incr [expr {$plot_incr + 1.5}]
}
if { $fatzero == 0 } {
puts $gnufile "'$pw_prefix.pdos_tot' using 1:(\$2/4+$plot_incr) w
l lt 1,'-' w l lt 8"
puts $gnufile "$e_fermi 0"
puts $gnufile "$e_fermi [expr {$plot_incr+10}]"
puts $gnufile "e"
} else {
puts $gnufile "'$pw_prefix.pdos_tot' using
(\$1-$e_fermi):(\$2/4+$plot_incr) w l lt 1,'-' w l lt 8"
puts $gnufile "0 0"
puts $gnufile "0 [expr {$plot_incr+10}]"
puts $gnufile "e"
}
}
}
close $gnufile
}
}
main $argc $argv
On Thu, Feb 26, 2009 at 10:34 AM, Paolo Giannozzi
<giannozz at democritos.it> wrote:
>
> On Feb 21, 2009, at 17:05 , Eduardo Ariel Menendez Proupin wrote:
>
>> Let me remind how is the process to obtain the DOS. It has three
>> calculations
>> and 3 input files
>>
>> pw.x < si.scf.in > si.scf.out # self consistent
>> pw.x <si.dos.in > si.dos.out # non selfconsistent dense k-points
>> mesh and a few options
>> dos.x <si.dos2.in > si.dos2.out # postprocessing
>
> Hi Eduardo, the issue you raise is a serious one and requires some
> though.
> Right now several standard calculations in q-e are clumsy because they
> require separate steps. While I think that it is a good idea to keep
> separate
> steps separate, I also think that at least the most common
> calculations might
> be streamlined. I am not convinced that the PWGui is the right tool
> for this,
> though, at least not in the present form (a tool to produce input data).
> The ideal solution would be the usage of a high-level scripting
> language like
> python to "glue" the various pieces together, but this is highly
> nontrivial
> (at least for me and for 99% of q-e users).
> A simpler option could be to collapse some calculations into the same
> executable:
> for instance
> - add a call to dos after a nscf calculation in pw.x,
> add a call to bands after a bands calculation in pw.x
> or
> - prepend a nscf calculation to dos.x,
> prepend a band calculation to bands.x
> Suggestions are welcome
>
> Paolo
> ---
> Paolo Giannozzi, Democritos and University of Udine, Italy
>
>
> _______________________________________________
> Pw_forum mailing list
> Pw_forum at pwscf.org
> http://www.democritos.it/mailman/listinfo/pw_forum
>
More information about the users
mailing list