TABLE OF CONTENTS


::pwtk::supercell3D

USAGE

   supercell3D unitvec supercell ?unitKmesh?

ARGUMENTS

PURPOSE

Generate a supercell vectors from the unitcell Bravais lattice vectors (unitvec) and the supercell expansion matrix (supercell), i.e.:

      superVecs = 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 $superVecs $supeKmesh]

SOURCE

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

    if { [shape $unitvec] ne "3 3" } {
        ::pwtk::error "wrong format of the unit-cell lattice vectors,
got \"$unitvec\" but expected a 3x3 matrix" 1
    }
    if { [shape $supercell] ne "3 3" } {
        ::pwtk::error "wrong format of the supercell expansion matrix,
got \"$supercell\"
but expected a 3x3 matrix in the form of \"{x1 y1 z1} {x2 y2 z2} {x3 y3 z3}\",
x1.y1.z1_x2.y2.z2_x3.y3.z3, or MxNxL" 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 3]
        
        # 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 k-mesh, must be \"k1 k2 k3\" but got $unitKmesh" 1
        }

        # calc inverse norm of supercell vectors
        lassign $supervec v1 v2 v3
        lassign [list [expr 1.0/[norm $v1]] [expr 1.0/[norm $v2]] [expr 1.0/[norm $v3]]] in1 in2 in3

        set nkk [::tcl::mathop::* {*}$unitKmesh]        
        set skk [expr double($nkk)/abs([det $supercell])]
        # skk = ik**3 * in1 * in2 * in3, hence:
        set ik [expr ($skk / ($in1*$in2*$in3))**(1.0/3.0)]

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

    return $result
}