proc ::pwtk::pwi::supercell_slab {args} {


   ::pwtk::pwi::supercell_slab  ?-unit alat|angs|bohr?  ?-unitvec UNITVEC?  ?-kshift "S1 S2 S2"?  ?-slabz THICKNESS_BOHR?  ?-vacuum VACUUM_SPECS?  supercell ?unitKmesh?


Generate CELL_PARAMETERS and, if requested, K_POINTS and dipole correction for a 2D-slab supercell.

It is assumed that the slab is oriented along the XY plane and Z is the surface normal direction.


Further explanation of the "-vacuum VACUUM_SPECS" option:



    set nargmin 1
    set nargmax 2
    set usage "?-unit alat|angs|bohr?  ?-unitvec unitvec?  ?-kshift \"s1 s2 s2\"?  ?-slabz thicknessBohr?  ?-vacuum vacuum-specsBohr?  supercell  ?unitKmesh?"
    set options {
        {unit.arg     bohr "alat of the 2D (1x1) unit cell"}
        {unitvec.arg  {}   "unitcell Bravais lattice vectors"}
        {kshift.arg   {}   "a list of k-mesh offsets"}
        {slabz.arg    0.0  "slab thickness"}
        {vacuum.arg   {}   "either vacuum thickness or \"vac1st diplayer vac2nd\" list"}
    ::pwtk::checkOType_ -kshift  $opt(kshift)  {numberlist binary}  "list of binary numbers"
    ::pwtk::checkOType_ -slabz   $opt(slabz)   {number nonnegreal}  "non-negative real number"
    ::pwtk::checkOType_ -vacuum  $opt(vacuum)  {numberlist posreal} "list of positive numbers"

    lassign $args supercell unitKmesh

    set path_ [namespace path]
    namespace path ::math::linearalgebra

    # -slabz
    # -vacuum
    if { $opt(vacuum) == {} } {
        set vacuum 16.0
    } else {
        set vlen [llength $opt(vacuum)]
        if { $vlen == 1 } {
            set vacuum $opt(vacuum)
        } elseif { $vlen == 3 } {
            lassign $opt(vacuum) vac1st diplayer vac2nd
        } else {
            ::pwtk::error "wrong value of the -vacuum option; got \"$opt(vacuum)\"
but expected either a single number or a list of 3 nunmbers" 1
    # get the size of the C vector in Bohr
    ::pwtk::ifexist vacuum {
        # "vacuum" exist only for the case of NO dipole-correction
        # (see above the parsing of the -vacuum option)
        set Z_bohr [expr $opt(slabz) + $vacuum]
    } else {
        # dipole-correction case
        set Z_bohr [dipoleCorr -vac1st $vac1st -diplayer $diplayer -vac2nd $vac2nd $opt(slabz)]

    # generate supercell & k-mesh
    if { $unitKmesh eq {} } {
        set supervec [::pwtk::supercell2D $unitvec $supercell]
    } else {
        lassign [::pwtk::supercell2D $unitvec $supercell $unitKmesh] supervec kp
    set kmesh [list {*}$kp {*}$opt(kshift)]
    # rescale the supercell vectors so that norm(v1) = 1.0 && add Z-thickness
    lassign $supervec v1
    set alat [norm $v1]    
    set supervec [::pwtk::latvec2Dto3D [scale [expr 1.0/$alat] $supervec] [expr $Z_bohr/$alat]]
    lassign $supervec v1 v2 v3

    set nb    [norm $v2]    
    set nc    [norm $v3]

    # set the pw.x input
    SYSTEM "ibrav = 0, celldm(1) = $alat, A = "
    CELL_PARAMETERS (alat) [::pwtk::m2cell $supervec]
    if { $unitKmesh != {} } {
        K_POINTS (automatic) $kmesh

    # print the basic info to stdout

    set sv2D [::pwtk::latvec3Dto2D [::pwtk::matricize $supercell]]
    set sv3D [::pwtk::latvec2Dto3D $sv2D 1.0]    
    set area [expr abs([det $sv3D])]
    ::pwtk::print ++++ "Auto-generation of the SLAB supercell..."
    if { $unitKmesh ne {} } {
        ::pwtk::print "\nUnitcell k-mesh:  [::pwtk::Kmeshize $unitKmesh 2]"
    ::pwtk::print "
2D unitcell lattice vectors (in Bohr):

[show [::pwtk::latvec3Dto2D $unitvec] %15.10f]
2D supercell expansion matrix:  
[show $sv2D %3.0f]
   alat = [format %.6f $alat] Bohr = [format %.6f [expr $alat/$unitalat]] unitcell-alat
   Size of vector A  = [format %8.4f 1.0] alat
   Size of vector B  = [format %8.4f $nb] alat
   Size of vector C  = [format %8.4f $nc] alat
   2D area of supercell = [format %8.4f $area] of the unitcell area
   Expected slab thickness = $opt(slabz) Bohr"
    ::pwtk::ifexist vacuum {
        ::pwtk::print "   Vacuum thickness        = $vacuum Bohr\n"
    } else {
        ::pwtk::print "   Vacuum thickness        = [join [::pwtk::dipcorrDefault_ $vac1st $diplayer $vac2nd] { + }] Bohr\n"
    if { $unitKmesh != {} } {
        ::pwtk::print "The following cell parameters and k-points cards were generated:\n"    
        ::pwtk::input::cardPrint CELL_PARAMETERS
        ::pwtk::input::cardPrint K_POINTS
    } else {
        ::pwtk::print "The following cell parameters were generated:\n"    
        ::pwtk::input::cardPrint CELL_PARAMETERS
    namespace path $path_