TABLE OF CONTENTS


::pwtk::lobster_run

SYNOPSIS

proc ::pwtk::lobster_run {args} {

USAGE

    ::pwtk::lobster_run  ?SPECIFIC-OPTIONS?  ?PLOTTING-OPTIONS?  ?STANDARD-PLOTTING-OPTIONS?  HEAD  ?LOBSTER_INPUT_DATA?

    where SPECIFIC-OPTIONS are:

       -scf
       -nscf KGRID
       -dir  DIR
       -threads OMP_NUM_THREADS

   For PLOTTING-OPTIONS, see: ::pwtk::lobster::multiplot    
   For STANDARD-PLOTTING-OPTIONS, see: ::pwtk::plot

SPECIFIC OPTIONS

ARGUMENTS

DESCRIPTION

Perform a LOBSTER analysis of chemical bonding (this command requires the LOBSTER program: http://www.cohp.de/ ). The sequence of jobs is:

      pw.x SCF (optional, requested by -scf)
       |
       |
      pw.x NSCF (optional, requested by -nscf)
       |
       |
      lobster
       |
       |
      PLOTTING       

The LOBSTER input data can be specified in three ways:

RETURN VALUE

SOURCE

    printTitle LOBSTER_RUN "Running the LOBSTER workflow"
    print "Workflow options & arguments :  $args\n"
    
    # check for lobster
    
    set lobster [getExecutable [::pwtk::getVar_ LOBSTER] lobster]
    if { $lobster eq {} } {
        ::pwtk::error "cannot find a usable \"lobster\" executable" 1
    }

    # parse command-line arguments

    addOpts_ options usage {
        {scf          "perform SCF pw.x calculation"}
        {nscf.arg {}  "perform NSCF pw.x calculation using provided KGRID"}
        {dir.arg  .   "perform calculations in specified directory"}
        {threads.arg {} "number of OpenMP threads (aka OMP_NUM_THREADS)"}
    } {
        -scf {-nscf KGRID} {-dir DIRECTORY} {-threads OMP_NUM_THREADS}
    }

    set nargmin 1
    set usage "[fmtUsage_ $usage]  ?SPECIFIC-OPTIONS?  ?PLOTTING-OPTIONS?  ?STANDARD-PLOTTING-OPTIONS?  HEAD  ?LOBSTER_INPUT_DATA?"
    parseKnownOpt_
    checkOType_ -nscf $opt(nscf) {numberlist nonnegint}  "list of non-negative integer numbers (i.e. automatic k-point grid specs)"

    set head      [lindex $args end-1]
    set lobsterin [lindex $args end]    
    if { [llength $lobsterin] == 1 } {
        set head $lobsterin
        set lobsterin {}
        set args [lrange $args 0 end-1]
    } else {
        set args [lrange $args 0 end-2]
    }
    
    # trim head from prefixes/postfixes
    set t {scf nscf relax vc-relax md vc-md} 
    set head [trim_prefix $t [trim_postfix [join $t {.in }].in $head]]
    
    # lobster input

    file mkdir $opt(dir)
    ifset lobsterin [::pwtk::input::cardGetContent LOBSTER]
    if { $lobsterin ne {} } {
        writeFile [file join $opt(dir) lobsterin] $lobsterin
    }
    if { $lobsterin eq {} && ! [file exists [file join $opt(dir) lobsterin]] } {
        ::pwtk::error "missing lobsterin input data " 1
    }

    # if *scf.in file does not exist in $opt(dir), try to create a link
    
    if { $opt(dir) ne "." && !$opt(scf) && $opt(nscf) eq {} } {
        foreach pre {pw. {}} {
            if { ! [file exists [file join $opt(dir) ${pre}$head.scf.in]] \
                     && [file exists ${pre}$head.scf.in] } {
                file link [file join $opt(dir) ${pre}$head.scf.in] ${pre}$head.scf.in            
            }
            if { ! [file exists [file join $opt(dir) ${pre}$head.nscf.in]] \
                           && [file exists ${pre}$head.nscf.in] } {
                file link [file join $opt(dir) ${pre}$head.nscf.in] ${pre}$head.nscf.in
            }

        }
        if { [glob -directory $opt(dir) -nocomplain *scf.in] eq {} } {
            ::pwtk::error "cannot find a usable pw.x input file" 1
        }
    }

    # calculations
    
    set plots {}
    eval_in_dir $opt(dir) {

        # pw.x

        input_pushpop {
            if { $opt(scf) || $opt(nscf) ne {} } {
                infoMsg "temporarily setting SYSTEM { nosym = .true. } for LOBSTER"
                CONTROL { wf_collect = .true. }
                SYSTEM  { nosym = .true. }
                SCF_NSCF_
            }
        }

        # lobster

        print LOBSTER "Performing LOBSTER calculation\n"
        
        ifexist ::env(OMP_NUM_THREADS) {
            set save_threads $::env(OMP_NUM_THREADS)
            unset ::env(OMP_NUM_THREADS)
        }
        ifnotempty opt(threads) {
            set ::env(OMP_NUM_THREADS) $opt(threads)
        }    

        try {
            execute $lobster
        } on error err {
            variable state
            ::pwtk::error "An error occured while executing lobster !!!\n\nError INFO:\n$err" $state(stopOnError)
        }

        ifexist save_threads {
            set ::env(OMP_NUM_THREADS) $save_threads
        }

        # plot i0 (e.g. total / average)

        set llist {}
        foreach car {
            DOSCAR DOSCAR.LSO COOPCAR COHPCAR COBICAR
            DOSCAR.LCFO COOPCAR.LCFO COHPCAR.LCFO COBICAR.LCFO
        } {
            if { [file exists $car.lobster] } {
                incr nplot
                array set info [::pwtk::lobster::getinfo $car]
                set nproj($car) $info(nproj)
                lappend llist [list $car i0]
            }
        }
        ifnotempty llist {
            set nx [expr { $nplot > 8 ? 5 : 4 }]            
            set nx [expr { "-nx" ni $args ? "-nx $nx" : {} }]
            lappend plots [::pwtk::lobster::multiplot {*}$args {*}$nx $llist $head-i0]
        }

        # plot projections to atoms / fragments / interactions
        
        foreach {prop cardatL} {
            DOS {
                {DOSCAR      DOSCAR.atom}
                {DOSCAR.LSO  DOSCAR.LSO.atom}
                {DOSCAR.LCFO DOSCAR.LCFO.frag}
            }
            COOP {
                COOPCAR
                COOPCAR.LCFO
            }
            COHP {
                COHPCAR
                COHPCAR.LCFO
            }
            COBI {
                COBICAR
                COBICAR.LCFO
            }
        } {
            set llist {}
            foreach cardat $cardatL {
                set car [lindex $cardat 0]
                set dat [lindex $cardat end]
                if { [file exists $dat.dat] && $nproj($car) > 1 } {
                    for {set ip 1} {$ip < $nproj($car)} {incr ip} {
                        lappend llist [list $dat i$ip]
                    }
                }
            }
            ifnotempty llist {
                lappend plots [::pwtk::lobster::multiplot {*}$args $llist $head-$prop]
            }
        }        
    }

    # list all created plot files
    
    ifnotempty plots {
        print LOBSTER "The following plot files were created:"
        foreach plot $plots {
            print "* [file join $opt(dir) $plot]"
        }
    }

    return [varvalue plots]
}