TABLE OF CONTENTS


::pwtk::pwi::getPrimVec

SYNOPSIS

proc ::pwtk::pwi::getPrimVec {lenUnit} {

PURPOSE

Get the primitive lattice vectors (aka CELL_PARAMETERS) in the 'lenUnit' units from the pw.x input data in the form:

        ax  ay  az
        bx  by  bz
        cx  cy  cz

If ibrav == 0, the lattice vectors from the CELL_PARAMETERS card, converted to 'lenUnit' are returned. Otherwise, the lattice vectors are generated from the celldm(i) or A,B,C... parameters.

If lattice vectors cannot be generated from the input data (i.e. in case of insufficient data), the empty string is returned.

ARGUMENTS

RETURN VALUE

Primitive lattice vectors in requested unit or an empty string.

SOURCE

    set ibrav [ibrav]
    set alat  [alat]
    set unit [::pwtk::input::cardGetFlags CELL_PARAMETERS trim]
    set cell [::pwtk::input::cardGetContent CELL_PARAMETERS]

    # alat may not exist: in this case [alat] returns 0.0
    set notDefined 1e-8
    if { $alat < $notDefined } {
        set alat [expr 0.5*$notDefined]
    }
    
    # scaling factor to convert from bohr to $lenUnit
    switch -glob -- $lenUnit {
        angs* { set scale $::pwtk::bohr2angs }
        bohr  { set scale 1.0 }
        alat  {
            if { $alat < $notDefined } {
                # alat not defined: use bohr (see below)
                set scale 1.0
            } else {
                set scale [expr 1.0/$alat]
            }
        }
        default {
            ::pwtk::error "wrong unit $lenUnit, must be one of angstrom, bohr, or alat" 1
        }
    }

    # Rules:
    #   1. if (ibrav == 0 || ibrav eq {}) && cell ne {}, use cell
    #   2. else get lattice-vectors from one_atom_dryrunPW
    #

    if { $ibrav == 0 || $ibrav eq "" } {
        if { $cell eq "" } {
            return {}
        } else {
            if { $unit == "" } {
                # from input_pw.html:
                #   for CELL_PERAMETERS without unit: if alat is
                #   defined, it implies "CELL_PERAMETERS (alat)"
                #
                #   if neither unit nor lattice parameter are specified, 'bohr'
                #   is assumed - DEPRECATED, will no longer be allowed
                
                if { $alat < $notDefined } {
                    set unit bohr
                } else {
                    set unit alat
                }
            }
        }
        
        # convert $cell to bohr
        switch -glob -- $unit {
            angs* { set scale2 $::pwtk::angs2bohr }
            bohr  { set scale2 1.0 }
            alat  { set scale2 $alat }
            default {
                ::pwtk::error "wrong unit $unit, must be one of angstrom, bohr, or alat" 1
            }
        }
    } elseif { $cell ne {} } {
        ::pwtk::error "cell parameters are specified twice, i.e., ibrav !=0 & CELL_PARAMETERS card exists" 1
    } else {
        # ibrav != 0:  get lattice vectors (in alat) from one-atom pw.x dry-run
        set cell [::pwtk::pwo::getPrimVec [::pwtk::one_atom_dryrunPW]]
        set scale2 $alat
    }
    set cell [::pwtk::scaleVec [expr $scale*$scale2] $cell]

    return [::pwtk::CELL_PARAMETERS_math_parser $cell]
}