TABLE OF CONTENTS


::pwtk::supercell2D

USAGE

   supercell2D unitvec supercell ?unitKmesh?

ARGUMENTS

PURPOSE

Generate a 2D supercell vectors from the unit-cell Bravais lattice vectors (unitvec) and the supercell expansion matrix (supercell), i.e.:

      supervec = supercell x unitvec

If the unitKmesh argument (i.e., a K-mesh of the unitcell) is specified, a k-mesh for the supercell is generated, which is of compatible quality (density) to the "unitKmesh".

Note that the routine is agnostic about the units; arguments are treated as numeric matrices.

RETURN VALUE

if unitKmesh NOT specified:

      * supercell lattice vectors

else:

      * a list of supercell lattice vectors and supercell k-mesh as [list $supervec $supeKmesh]

The supercell lattice vectors are returned as a 3x3 matrix in the following form:

      {{x1 y1 0.0} {x2 y2 0.0} {0.0 0.0 1.0}}

K-mesh is returned in the following form:

      "kx  ky  1"    

SOURCE

    set path_ [namespace path]
    namespace path ::math::linearalgebra
    
    set unitvec   [latvec2Dto3D [matricize $unitvec] 1.0]
    set supercell [latvec2Dto3D [matricize $supercell] 1.0]

    if { [shape $unitvec] ne "3 3" } {
        ::pwtk::error "wrong format of the 2D unit-cell lattice vectors,
got \"$unitvec\"
but expected a 2x2 (or a 3x3) matrix" 1
    }
    if { [shape $supercell] ne "3 3" } {
        ::pwtk::error "wrong format of the 2D supercell expansion matrix,
got \"$supercell\"
but expected a 2x2 (or 3x3) matrix" 1
    }
    if { abs([det $unitvec]) < 1e-6 } {
        ::pwtk::error "singular \"unitvec\" matrix $unitvec" 1
    }
    if { abs([det $supercell]) < 1e-6 } {
        ::pwtk::error "singular \"supercell\" matrix $supercell" 1
    }

    # calculate supercell
    
    set supervec [matmul $supercell $unitvec]
    if { abs([det $supervec]) < 1e-6 } {
        ::pwtk::error "generated supercell is singular: $supervec" 1
    }

    if { $unitKmesh eq {} } {
        set result $supervec
    } else {
        set unitKmesh [Kmeshize $unitKmesh 2]
        # check that unitKmesh is a number list; a real numbers are allowed for unitKmesh as to have more accurate scaling!
        if { ! [::pwtk::type::numberlist posreal -strict $unitKmesh] } {
            ::pwtk::error "wrong format of the \"unitKmesh\" k-mesh, must be \"k1 k2 ?k3?\" but got $unitKmesh" 1
        }
        lassign $unitKmesh k1 k2
       
        # calc inverse norm of supercell vectors
        lassign $supervec v1 v2
        lassign [list [expr 1.0/[norm $v1]] [expr 1.0/[norm $v2]]] in1 in2

        set nkk [expr $k1*$k2]
        set skk [expr double($nkk)/abs([det $supercell])]
        # skk = ik**2 * in1 * in2, hence:
        set ik [expr sqrt($skk / ($in1*$in2))]

        set result [list $supervec [list [expr max(1,round($ik*$in1))] [expr max(1,round($ik*$in2))] 1] ]
    }
    
    namespace path $path_

    return $result
}