TABLE OF CONTENTS
::pwtk::pwi::supercell_slab
SYNOPSIS
proc ::pwtk::pwi::supercell_slab {args} {
USAGE
::pwtk::pwi::supercell_slab ?-unit alat|angs|bohr? ?-unitvec UNITVEC? ?-kshift "S1 S2 S2"? ?-slabz THICKNESS_BOHR? ?-vacuum VACUUM_SPECS? supercell ?unitKmesh?
PURPOSE
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.
OPTIONS
- -unit UNIT --- the length unit for unitvec (default = bohr, allowed values = alat, angs*, bohr)
- -unitvec UNITVEC --- 2D or 3D unitcell Bravais lattice vectors in any form accepted by ::pwtk::matricize. If not set, the unitcell vectors from the CELL_PARAMETERS card are used.
- -kshift "S1 S2 S2" --- a list of k-mesh offsets, e.g., "1 1 1" or "0 0 0" or ... (default taken from K_POINTS; if the K_POINTS card does not exist, the "1 1 1" k-mesh is assumed)
- -slabz THICKNESS_BOHR --- thickness of the slab along the surface normal Z direction (in Bohr)
- -vacuum VACUUM_SPECS --- either a single value (default = 16.0) or a list of three values as {vac1st diplayer vac2nd}; either possibility is in the Bohr units
Further explanation of the "-vacuum VACUUM_SPECS" option:
- if "VACUUM_SPECS" is a single number, e.g., -vacuum 16.0, it corresponds to the vacuum thickness (in Bohr). In this case, no dipole correction is activated;
- if "VACUUM_SPECS" is a list with 3 numbers, e.g., -vacuum {15.0 2.0 16.0}, it corresponds to "vac1st diplayer vac2nd" (see ::pwtk::pwi::dipoleCorr). In this case, dipole correction is activated. If any of vac1st, diplayer, or vac2nd is an empty string, the corresponding default value is used.
ARGUMENTS
- supercell --- 2x2 (or 3x3) supercell expansion matrix (in any form accepted by ::pwtk::matricize)
- unitKmesh --- (optional) K-mesh for the unitcell in the K1xK2xK3, K1xK2, "K1 K2 K3", or "K1 K2" form; if specified, the K_POINTS card for the supercell is generated.
SOURCE
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::parseOpt_ ::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 supercellCommonOpts_ # -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] Supercell: 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_ }