TABLE OF CONTENTS


::pwtk::calcmol

SYNOPSIS

proc ::pwtk::calcmol {args} {

DESCRIPTION

Utility for making a fast molecule-in-a-box calculation. Orthorhombic "box" will be automatically constructed, based on the size of the molecule.

Beware that this routine requires obabel and xsf2_manipulator programs.

USAGE

calcmol [-relax|-scf] [-vacuum vacuum] [-center|-orig] [-mo] molecule SMILE

ARGUMENTS

Default options: -relax -center -vacuum 8.0

OPTIONS

List of options:

    -relax|-scf      make either a molecular structural relaxation (-relax)
                     or SCF calculation (-scf); Default = -relax

    -vacuum <size>   size of vacuum around the molecule; Default = 8 Angstroms

    -center|-orig    shift the molecule either to the center or to the
                     origin of the simulation BOX; Default = -center

    -mo              calculate signed molecular-orbital densities and write them to XSF files

    -magn <nelec>    total magnetization, i.e., number of unpaired electrons

    -smear <value>   smearing value for occupiations = 'smearing'
                     (e.g., use in case of convergency problems; 
                            usable values are in range of, say, 1e-2 to 1e-3)

SOURCE

    # check if obabel and xsf_manipulator exist

    if { [auto_execok obabel] == "" } {
        ::pwtk::error {"obabel" program does not exist} 1
    }
    if { [auto_execok xsf2_manipulator] == "" } {
        ::pwtk::error {"xsf2_manipulator" program does not exist} 1
    }

    # parse options
    
    set options {
        {relax           "make a molecular structural relaxation"}
        {scf             "make a single point SCF calculation"}
        {vacuum.arg 8.0  "size of vacuum around the molecule (the same in each direction)"}
        {center          "shift the molecule to the center of the simulation BOX"}
        {orig            "shift the molecule to the origin of the simulation BOX"}
        {mo              "calculate signed molecular-orbital densities and write them to XSF file"}
        {magn.arg   0    "total magnetization, i.e., number of unpaired electrons"}
        {smear.arg  -1   "smearing value for occupiations = 'smearing' (e.g., use in case of convergency problems;  usable values are in range of, say, 1e-2 to 1e-3)"}
    }
    set usage "
Usage:  

calcmol \[-relax|-scf] \[-vacuum value] \[-center|-orig] \[-mo] \[-magn value] \[-smear value] molecule SMILE

where:
    molecule :   name of molecule
    SMILE    :   SMILE specification of molecular structure
                 (SMILE stands for \"Simplified Molecular-Input Line-Entry\") 

options are:"    

    set args_copy $args
    array set opt [::cmdline::getoptions args $options $usage]

    # consistency-check
    
    if { $opt(relax) && $opt(scf) } {
        ::pwtk::error "incompatible -relax and -scf options specified; please specify only one of them" 1
    }
    if { $opt(center) && $opt(orig) } {
        ::pwtk::error "incompatible -center and -orig options specified; please specify only one of them" 1
    }

    #
    # SET-UP
    #
    set calc   "relax"
    set origin "0.5 0.5 0.5"
    set shift   center
    
    if { $opt(scf) } { set calc "scf" }
    if { $opt(orig) } { set origin "0.0 0.0 0.0"; set shift origin }

    set name   [lindex $args 0]
    set smile  [lindex $args 1]
    set prefix [regsub , $name .]; # get rid of ","    

    printTitle CALCMOL "Building and calculating \"$name\" molecular structure"
    
    print "Specified command-line : $args_copy\n"

    if { $smile == {} || [llength $args] != 2 } {
        puts [::cmdline::usage $options $usage]
        exit 1
    }

    #
    # GENERATE STRUCTURE from SMILE
    #
    catch {
        exec obabel -:$smile -oxyz -O /tmp/smile.xyz --gen3D --best
    }
    set xyz [::pwtk::skipEmptyLines [readFile /tmp/smile.xyz]]

    set xyzn [split $xyz \n]
    set nat  [lindex $xyzn 0]
    set coor [join [lrange $xyzn 1 end] \n]
    if { $nat == 1 } {
        set calc scf
    }    
    print "  Structure name :  $name"
    print "           SMILE :  $smile"
    print "Calculation type :  [string toupper $calc]\n"
    
    print "Summary of generated molecular structure from SMILE"
    print "Number of atoms  : $nat"
    #print "Atomic positions :\n"    
    #puts $coor

    # put molecule in a box
    
    print "
MOLECULE in a BOX SETTINGS:
   - requested vacuum size (in each direction): $opt(vacuum) Angstroms
   - molecule shifted to : box-$shift"
    
    set head "MOLECULE\nPRIMCOORD\n"
    append head $xyz\n
    append head "BOXIFY\n$opt(vacuum)\n$origin"

    writeFile /tmp/smile.xsf2 $head
    exec xsf2_manipulator /tmp/smile.xsf2 /tmp/smile.xsf2_angs    

    #
    # CALCULATE
    #
    input_pushpop {

        # pw.x
        CONTROL " calculation = '$calc', prefix = '$prefix' "
        if { $calc == "relax" } {
            IONS ""
        }
        ::pwtk::pwi::CELL_PARAMETERS_and_ATOMIC_POSITIONS_fromXSF /tmp/smile.xsf2_angs

        print "Box unit-cell vectors:"
        print [::pwtk::pwi::CELL_PARAMETERS_math_parser [::pwtk::pwi::getPrimVec]]
        print "Box atomic positions:"
        print [::pwtk::pwi::ATOMIC_POSITIONS_math_parser [::pwtk::pwi::getAtmPos]]

        # smearing ?
        if { $opt(smear) > 0.0 } {
            set smearing [::pwtk::input::namelistGetVarValue SYSTEM smearing]
            if { $smearing == {} } { set smearing 'm-p' }
            set occ "occupations = 'smearing', smearing = $smearing, degauss = $opt(smear)"
            print "\nSmearing requested :"
            print "( $occ )\n"
            SYSTEM $occ
        }

        # set the spin/magnetization setup
        set nbnd [spinSetup $opt(magn) $opt(mo)]
        
        if { $calc == "scf" } {
            printTitle SCF "making an [string toupper $calc] calculation of \"$name\" via pw.x"
        } else {
            printTitle RELAX "making a [string toupper $calc] calculation of \"$name\" via pw.x"
        }
        runPW pw.$name.$calc

        # do we want to calculate also MO ?
        
        if { $opt(mo) } {
            INPUTPP "
                filplot = 'psi2.$prefix'
                plot_num  =  7
                kpoint    =  1 
                kband(1)  =  1
                kband(2)  =  $nbnd
                lsign     =  .true.
            "
            PLOT {
                nfile     =  1,
                weight(1) =  1.0,
                iflag     =  3,
                fileout   = '.xsf'
                output_format =  5,
            }
            printTitle ORBITALS "Calculating valence signed molecular-orbital densities (up to LUMO orbital)"
            runPP pp.$name.psi2

            set last [format %03d $nbnd]
            print "Molecular orbital densities written to files :  
psi2.${prefix}_K001_B001.xsf, ..., psi2.${prefix}_K001_B$last.xsf\n"

            print "You can visualize signed molecular-obital densities as, e.g.:  xcrysden --xsf psi2.${prefix}_K001_B001.xsf\n"
            
            # delete the PP files
            #print "(deleting temporary psi2.${prefix}_K001_B??? files)"
            foreach file [glob -nocomplain psi2.${prefix}_K001_B???] {
                file delete $file
            }
        }
    }
}