getdensity

#!/usr/bin/env python
from sys import exit
from optparse import OptionParser
 
def getIndexedDansity(idx, calc):
  if index_error(idx, calc):
    exit()
  (nb, nk, ns) = idx
  wf = calc.GetWaveFunctionArray(band = nb, kpt = nk, spin = ns)
  density = abs(wf)*abs(wf)
  return density
 
def index_error(idx, calc):
  (nband, nkpt, nspin) = idx
  NumberOfBands = calc.GetNumberOfBands()
  NumberOfKpoints = len(calc.GetIBZKPoints())
  isSpinPolarized = calc.GetSpinPolarized()
  error = False
  if not (nband < NumberOfBands):
    print "error: nband must be less than %d" % NumberOfBands
    error = True
  if not (nkpt < NumberOfKpoints):
    print "error: nkpt must be less than %d" % NumberOfKpoints 
    error = True
  if isSpinPolarized:
    if not ((nspin == 0) or (nspin == 1)):
      print "error: nspin must be 0 or 1"
      error = True
  else:
    if not (nspin == 0):
      print "error: nspin must be 0"
      error = True
  return error
 
 
def getNumberOfSpins(calc):
  if (calc.GetSpinPolarized()):
    return 2
  else:
    return 1
 
def getRangedDansity(ewin, calc):
  (min_energy, max_energy) = ewin
  if (min_energy > max_energy):
    (min_energy, max_energy) = (max_energy, min_energy)
  NumberOfBands = calc.GetNumberOfBands()
  NumberOfKpoints = len(calc.GetIBZKPoints())
  NumberOfSpins = getNumberOfSpins(calculator)
  density = calculator.GetDensityArray()*0.0
  out_of_range = True
  min_range = 0.0
  max_range = 0.0
  for ns in range(NumberOfSpins):
    for nk in range(NumberOfKpoints):
      energies = calculator.GetEigenvalues(kpt = nk, spin = ns)
      for nb in range(NumberOfBands):
        if (energies[nb] < min_range):
          min_range = energies[nb] 
        if (energies[nb] > max_range):
          max_range = energies[nb]
        if (min_energy <= energies[nb]) and (energies[nb] <= max_energy):
          out_of_range = False
          wf = calculator.GetWaveFunctionArray(band = nb, kpt = nk, spin = ns)
          density = density + abs(wf)*abs(wf)
  if out_of_range:
    print "error: energy range should be from %f to %f" % (min_range, max_range)
    exit()
  return density
 
 
from Dacapo import Dacapo
from ASE.IO.Cube import WriteCube
 
cmd = OptionParser(usage = '%prog [-i|-e|-a] input_nc_file output_cube_file')
 
cmd.add_option('-i', '--indecies', type = 'int', nargs = 3,
               help = 'density of N-th Band, K-th Kpoint, and S-th Spin state',
               metavar = 'N K S')
 
cmd.add_option('-e', '--energy', type = 'float', nargs = 2,
               help = 'density of states with energies from E1[eV] to E2[eV]',
               metavar = 'E1 E2')
 
(opt, argv) = cmd.parse_args()
 
if len(argv) != 2:
    cmd.print_help()
    raise SystemExit
 
if (opt.indecies is not None) and (opt.energy is not None):
  print 'error: do not specify both options -i and -e'
  exit()
 
ncfile = argv[0]
cubefile = argv[1]
 
model = Dacapo.ReadAtoms(ncfile)
calculator = model.GetCalculator()
 
if opt.indecies is not None:
  density = getIndexedDansity(opt.indecies, calculator)
elif opt.energy is not None:
  density = getRangedDansity(opt.energy, calculator)
else:
  density = calculator.GetDensityArray()
WriteCube(model, density, cubefile)

Usage

usage: getdensity [-i|-e|-a] input_nc_file output_cube_file
 
options:
  -h, --help            show this help message and exit
  -iN K S, --indecies=N K S
                        density of N-th Band, K-th Kpoint, and S-th Spin state
  -eE1 E2, --energy=E1 E2
                        density of states with energies from E1[eV] to E2[eV]
script/getdensity.txt · 最終更新: 2009/02/02 15:53 by kimi
www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0