TABLE OF CONTENTS
::pwtk::supercell3D
USAGE
supercell3D unitvec supercell ?unitKmesh?
ARGUMENTS
- unitvec --- unitcell lattice vectors (a 3x3 matrix in any form accepted by ::pwtk::matricize), e.g., either {{xa ya za} {xb yb zb} {xc yc zc}} or {xa ya za xb yb zb xc yc zc} ...
- supercell --- a 3x3 expansion matrix, in any form accepted by ::pwtk::matricize, i.e., either NxMxL, x1.y1.z1_x2.y2.z2_x3.y3.z3, {{x1 y1 z1} {x2 y2 z2} {x3 y3 z3}}, or {x1 y1 z1 x2 y2 z2 x3 y3 z3}
- unitKmesh --- (optional) K-mesh for the unitcell in the K1xK2xK3 or "K1 K2 K3" form; if specified, the k-mesh for the supercell is generated.
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 }