TABLE OF CONTENTS


::pwtk::sumpdosFiles

SYNOPSIS

proc ::pwtk::sumpdosFiles {pdosFiles fileout} {

DESCRIPTION

Sum PDOSes from $pdosFiles and write the result to the $fileout file.

BEWARE that PDOSes are summed separately for each component, hence only compatible pdos_atm files can be summed, i.e., s with s, p with p, and d with d, where s,p,d are angular momenta. Otherwise, an error occurs.

ARGUMENTS

RETURN VALUE

The value of the "fileout" argument.

SOURCE

    ::pwtk::print "Summing PDOSes (all components separately) from files:"
    foreach f $pdosFiles {
        ::pwtk::print "   $f"
    }
    ::pwtk::print " "

    set outID [open $fileout w]
    
    set kresolved 0    
    set n_ik_E 8; # the length of "[ik] E" fields (ik field is optional)
    set nspin 1
    set last -1

    foreach f $pdosFiles {
        ::pwtk::fileMustExist $f "projwfc.x pdos_atm"
        set fid($f) [open $f r]

        # read the 1st line from all the files
        
        gets $fid($f) line($f)
        set len [llength $line($f)]

        # kresolved mode?
        
        if { [lindex $line($f) 1] == "ik" } {
            set kresolved 1
            set n_ik_E 14; # 8 + 5 + 1
        }

        # spin-polarized?
        if { [lindex $line($f) 3+$kresolved] == "ldosup(E)" || [lindex $line($f) 3+$kresolved] == "pdosup(E)" } {
            set nspin 2
        }

        # check that all the files have the same number of fields
        
        if { $last < 0 } {
            set last $len
            puts $outID $line($f)
        } elseif { $len != $last } {
            ::pwtk::error "pdos_atm files $pdosFiles do not contain the same number of fields; cannot sum orbital contributions" 1
        }
        set last $len
    }
    # due to "#" and "(eV)"  fields, $len == nfields+2, 
    incr len -2

    if { $kresolved } {
        ::pwtk::print "PDOSes are k-resolved"
    }
    if { $nspin > 1 } {
        ::pwtk::print "PDOSes are spin-polarized"
    }
        
    set eof 0
    while { ! $eof } {
        for {set i 1} {$i < $len} {incr i} {
            set pdos($i) 0.0
        }
        foreach f $pdosFiles {
            set ik_E [read $fid($f) $n_ik_E]
            if { [eof $fid($f)] } {
                set eof 1
                break
            }
            for {set i 1} {$i < $len} {incr i} {
                if { [catch {set pdos($i) [expr $pdos($i) + [read $fid($f) 11]]} err] } {
                    ::pwtk::error "error reading file $f\n$err" 1
                }
            }
            # read EOL 
            read $fid($f) 1
        }
        if { ! $eof } {
            puts -nonewline $outID [format %${n_ik_E}s $ik_E]
            for {set i 1} {$i < $len} {incr i} {
                puts -nonewline $outID [format %11.3E $pdos($i)]            
            }
            puts $outID ""
        }
    }
    
    # close the files
    foreach f $pdosFiles {
        close $fid($f)
    }
    close $outID

    ::pwtk::print "Summed PDOS written to :   $fileout\n"
    return $fileout
}