2016-02-01 14:06:41 +01:00
|
|
|
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# TRIQS: a Toolbox for Research in Interacting Quantum Systems
|
|
|
|
#
|
|
|
|
# Copyright (C) 2011 by M. Ferrero, O. Parcollet
|
|
|
|
#
|
|
|
|
# DFT tools: Copyright (C) 2011 by M. Aichhorn, L. Pourovskii, V. Vildosola
|
|
|
|
#
|
|
|
|
# PLOVasp: Copyright (C) 2015 by O. E. Peil
|
|
|
|
#
|
|
|
|
# TRIQS is free software: you can redistribute it and/or modify it under the
|
|
|
|
# terms of the GNU General Public License as published by the Free Software
|
|
|
|
# Foundation, either version 3 of the License, or (at your option) any later
|
|
|
|
# version.
|
|
|
|
#
|
|
|
|
# TRIQS is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
|
|
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
|
|
# details.
|
|
|
|
#
|
|
|
|
# You should have received a copy of the GNU General Public License along with
|
|
|
|
# TRIQS. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
#
|
|
|
|
################################################################################
|
2015-11-20 18:54:51 +01:00
|
|
|
r"""
|
|
|
|
vasp.plotools
|
|
|
|
=============
|
2015-02-13 21:58:42 +01:00
|
|
|
|
2015-11-20 18:54:51 +01:00
|
|
|
Set of routines for processing and outputting PLOs.
|
|
|
|
|
|
|
|
This is the main module containing routines responsible for checking
|
|
|
|
the consistency of the input data, generation of projected localized
|
|
|
|
orbitals (PLOs) out of raw VASP projectors, and outputting data
|
|
|
|
required by DFTTools.
|
|
|
|
"""
|
2015-02-19 21:22:51 +01:00
|
|
|
import itertools as it
|
2015-02-13 21:58:42 +01:00
|
|
|
import numpy as np
|
2015-11-13 19:09:25 +01:00
|
|
|
from proj_group import ProjectorGroup
|
|
|
|
from proj_shell import ProjectorShell
|
2019-06-27 15:21:07 +02:00
|
|
|
from proj_shell import ComplementShell
|
2015-02-13 21:58:42 +01:00
|
|
|
|
2015-10-16 18:10:48 +02:00
|
|
|
np.set_printoptions(suppress=True)
|
|
|
|
|
2015-08-10 13:52:29 +02:00
|
|
|
# 'simplejson' is supposed to be faster than 'json' in stdlib.
|
2015-09-21 11:59:04 +02:00
|
|
|
try:
|
|
|
|
import simplejson as json
|
|
|
|
except ImportError:
|
|
|
|
import json
|
2015-08-10 13:52:29 +02:00
|
|
|
|
2015-11-11 12:43:51 +01:00
|
|
|
def issue_warning(message):
|
|
|
|
"""
|
|
|
|
Issues a warning.
|
|
|
|
"""
|
|
|
|
print
|
|
|
|
print " !!! WARNING !!!: " + message
|
|
|
|
print
|
|
|
|
|
2015-02-13 21:58:42 +01:00
|
|
|
################################################################################
|
2015-03-01 11:42:18 +01:00
|
|
|
# check_data_consistency()
|
2015-02-13 21:58:42 +01:00
|
|
|
################################################################################
|
2015-03-01 11:42:18 +01:00
|
|
|
def check_data_consistency(pars, el_struct):
|
2015-02-13 21:58:42 +01:00
|
|
|
"""
|
|
|
|
Check the consistency of the VASP data.
|
|
|
|
"""
|
2015-09-16 11:40:01 +02:00
|
|
|
# Check that ions inside each shell are of the same sort
|
|
|
|
for sh in pars.shells:
|
2018-05-04 16:08:46 +02:00
|
|
|
max_ion_index = max([max(gr) for gr in sh['ions']['ion_list']])
|
|
|
|
assert max_ion_index < el_struct.natom, "Site index in the projected shell exceeds the number of ions in the structure"
|
|
|
|
ion_list = list(it.chain(*sh['ions']['ion_list']))
|
|
|
|
|
|
|
|
sorts = set([el_struct.type_of_ion[io] for io in ion_list])
|
2015-09-16 11:40:01 +02:00
|
|
|
assert len(sorts) == 1, "Each projected shell must contain only ions of the same sort"
|
2015-02-13 21:58:42 +01:00
|
|
|
|
2015-10-14 19:32:12 +02:00
|
|
|
# Check that ion and orbital lists in shells match those of projectors
|
|
|
|
lshell = sh['lshell']
|
|
|
|
for ion in ion_list:
|
|
|
|
for par in el_struct.proj_params:
|
|
|
|
if par['isite'] - 1 == ion and par['l'] == lshell:
|
|
|
|
break
|
|
|
|
else:
|
|
|
|
errmsg = "Projector for isite = %s, l = %s does not match PROJCAR"%(ion + 1, lshell)
|
|
|
|
raise Exception(errmsg)
|
|
|
|
|
2015-03-01 13:09:31 +01:00
|
|
|
################################################################################
|
|
|
|
#
|
2015-03-03 10:53:46 +01:00
|
|
|
# generate_plo()
|
2015-03-01 13:09:31 +01:00
|
|
|
#
|
|
|
|
################################################################################
|
2015-03-03 10:27:52 +01:00
|
|
|
def generate_plo(conf_pars, el_struct):
|
2015-02-13 21:58:42 +01:00
|
|
|
"""
|
|
|
|
Parameters
|
|
|
|
----------
|
|
|
|
|
|
|
|
conf_pars (dict) : dictionary of input parameters (from conf-file)
|
2015-03-01 11:42:18 +01:00
|
|
|
el_struct : ElectronicStructure object
|
2015-02-13 21:58:42 +01:00
|
|
|
"""
|
|
|
|
|
2015-03-01 11:42:18 +01:00
|
|
|
check_data_consistency(conf_pars, el_struct)
|
2015-02-13 21:58:42 +01:00
|
|
|
|
2015-03-01 11:42:18 +01:00
|
|
|
proj_raw = el_struct.proj_raw
|
2015-02-17 19:42:34 +01:00
|
|
|
try:
|
|
|
|
efermi = conf_pars.general['efermi']
|
2015-03-01 11:42:18 +01:00
|
|
|
except (KeyError, AttributeError):
|
|
|
|
efermi = el_struct.efermi
|
2015-02-17 19:42:34 +01:00
|
|
|
|
2015-02-13 21:58:42 +01:00
|
|
|
# eigvals(nktot, nband, ispin) are defined with respect to the Fermi level
|
2015-10-14 19:32:12 +02:00
|
|
|
eigvals = el_struct.eigvals - efermi
|
2015-02-13 21:58:42 +01:00
|
|
|
|
2015-11-10 12:24:14 +01:00
|
|
|
nshell = len(conf_pars.shells)
|
|
|
|
print
|
|
|
|
print " Generating %i shell%s..."%(nshell, '' if nshell == 1 else 's')
|
2015-03-01 11:42:18 +01:00
|
|
|
pshells = []
|
2015-02-17 19:42:34 +01:00
|
|
|
for sh_par in conf_pars.shells:
|
2016-09-13 11:47:13 +02:00
|
|
|
pshell = ProjectorShell(sh_par, proj_raw, el_struct.proj_params, el_struct.kmesh, el_struct.structure, el_struct.nc_flag)
|
2015-11-10 12:24:14 +01:00
|
|
|
print
|
|
|
|
print " Shell : %s"%(pshell.user_index)
|
|
|
|
print " Orbital l : %i"%(pshell.lorb)
|
2018-05-04 16:08:46 +02:00
|
|
|
print " Number of ions: %i"%(pshell.nion)
|
2015-11-11 18:58:38 +01:00
|
|
|
print " Dimension : %i"%(pshell.ndim)
|
2019-06-27 09:04:22 +02:00
|
|
|
print " Correlated : %r"%(pshell.corr)
|
2015-11-10 12:24:14 +01:00
|
|
|
pshells.append(pshell)
|
2015-02-17 19:42:34 +01:00
|
|
|
|
2015-03-01 11:42:18 +01:00
|
|
|
pgroups = []
|
2015-02-17 21:12:57 +01:00
|
|
|
for gr_par in conf_pars.groups:
|
2015-11-19 16:01:05 +01:00
|
|
|
pgroup = ProjectorGroup(gr_par, pshells, eigvals)
|
2015-10-20 17:37:17 +02:00
|
|
|
pgroup.orthogonalize()
|
2019-06-27 15:21:07 +02:00
|
|
|
if gr_par['complement']:
|
|
|
|
pgroup.complement(eigvals)
|
|
|
|
if conf_pars.general['hk']:
|
|
|
|
pgroup.calc_hk(eigvals)
|
2015-11-20 18:54:51 +01:00
|
|
|
# DEBUG output
|
2015-10-16 18:10:48 +02:00
|
|
|
print "Density matrix:"
|
2015-11-20 16:58:36 +01:00
|
|
|
nimp = 0.0
|
2019-06-27 09:04:22 +02:00
|
|
|
ov_all = []
|
|
|
|
for ish in pgroup.ishells:
|
2019-06-27 15:21:07 +02:00
|
|
|
if not isinstance(pshells[pgroup.ishells[ish]],ComplementShell):
|
|
|
|
print " Shell %i"%(ish + 1)
|
|
|
|
dm_all, ov_all_ = pshells[ish].density_matrix(el_struct)
|
|
|
|
ov_all.append(ov_all_[0])
|
|
|
|
spin_fac = 2 if dm_all.shape[0] == 1 else 1
|
|
|
|
for io in xrange(dm_all.shape[1]):
|
|
|
|
print " Site %i"%(io + 1)
|
|
|
|
dm = spin_fac * dm_all[:, io, : ,:].sum(0)
|
|
|
|
for row in dm:
|
|
|
|
print ''.join(map("{0:14.7f}".format, row))
|
|
|
|
ndm = dm.trace()
|
|
|
|
if pshells[ish].corr:
|
|
|
|
nimp += ndm
|
|
|
|
print " trace: ", ndm
|
2015-11-20 16:58:36 +01:00
|
|
|
print
|
|
|
|
print " Impurity density:", nimp
|
2015-10-16 18:10:48 +02:00
|
|
|
print
|
|
|
|
print "Overlap:"
|
2019-06-27 09:04:22 +02:00
|
|
|
for io, ov in enumerate(ov_all):
|
2015-11-20 16:58:36 +01:00
|
|
|
print " Site %i"%(io + 1)
|
2019-06-27 09:04:22 +02:00
|
|
|
print ov[0,...]
|
2016-02-09 13:48:39 +01:00
|
|
|
print
|
|
|
|
print "Local Hamiltonian:"
|
2019-06-27 09:04:22 +02:00
|
|
|
for ish in pgroup.ishells:
|
2019-06-27 15:21:07 +02:00
|
|
|
if not isinstance(pshells[pgroup.ishells[ish]],ComplementShell):
|
|
|
|
print " Shell %i"%(ish + 1)
|
|
|
|
loc_ham = pshells[pgroup.ishells[ish]].local_hamiltonian(el_struct)
|
|
|
|
for io in xrange(loc_ham.shape[1]):
|
|
|
|
print " Site %i"%(io + 1)
|
|
|
|
for row in loc_ham[:, io, :, :].sum(0):
|
|
|
|
print ''.join(map("{0:14.7f}".format, row))
|
2015-11-20 18:54:51 +01:00
|
|
|
# END DEBUG output
|
2015-11-10 16:40:46 +01:00
|
|
|
if 'dosmesh' in conf_pars.general:
|
|
|
|
print
|
|
|
|
print "Evaluating DOS..."
|
|
|
|
mesh_pars = conf_pars.general['dosmesh']
|
|
|
|
if np.isnan(mesh_pars['emin']):
|
|
|
|
dos_emin = pgroup.emin
|
|
|
|
dos_emax = pgroup.emax
|
|
|
|
else:
|
|
|
|
dos_emin = mesh_pars['emin']
|
|
|
|
dos_emax = mesh_pars['emax']
|
|
|
|
n_points = mesh_pars['n_points']
|
|
|
|
|
|
|
|
emesh = np.linspace(dos_emin, dos_emax, n_points)
|
2019-06-27 09:04:22 +02:00
|
|
|
for ish in pgroup.ishells:
|
2019-06-27 15:21:07 +02:00
|
|
|
if not isinstance(pshells[pgroup.ishells[ish]],ComplementShell):
|
|
|
|
print " Shell %i"%(ish + 1)
|
|
|
|
dos = pshells[pgroup.ishells[ish]].density_of_states(el_struct, emesh)
|
|
|
|
de = emesh[1] - emesh[0]
|
|
|
|
ntot = (dos[1:,...] + dos[:-1,...]).sum(0) / 2 * de
|
|
|
|
print " Total number of states:", ntot
|
|
|
|
for io in xrange(dos.shape[2]):
|
|
|
|
np.savetxt('pdos_%i_%i.dat'%(ish,io), np.vstack((emesh.T, dos[:, 0, io, :].T)).T)
|
2015-11-10 16:40:46 +01:00
|
|
|
|
2015-03-01 11:42:18 +01:00
|
|
|
pgroups.append(pgroup)
|
2015-02-17 21:12:57 +01:00
|
|
|
|
2015-03-01 11:42:18 +01:00
|
|
|
return pshells, pgroups
|
2015-02-13 21:58:42 +01:00
|
|
|
|
2015-11-20 18:54:51 +01:00
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# output_as_text
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
def output_as_text(pars, el_struct, pshells, pgroups):
|
|
|
|
"""
|
|
|
|
Output all information necessary for the converter as text files.
|
|
|
|
"""
|
|
|
|
ctrl_output(pars, el_struct, len(pgroups))
|
|
|
|
plo_output(pars, el_struct, pshells, pgroups)
|
2019-06-27 15:21:07 +02:00
|
|
|
if pars.general['hk']:
|
2019-06-27 16:26:22 +02:00
|
|
|
hk_output(pars, el_struct, pgroups)
|
2015-11-20 18:54:51 +01:00
|
|
|
|
2015-03-01 13:09:31 +01:00
|
|
|
|
2015-03-03 10:53:46 +01:00
|
|
|
# TODO: k-points with weights should be stored once and for all
|
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# kpoints_output
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
def kpoints_output(basename, el_struct):
|
|
|
|
"""
|
|
|
|
Outputs k-point data into a text file.
|
|
|
|
"""
|
|
|
|
kmesh = el_struct.kmesh
|
|
|
|
fname = basename + '.kpoints'
|
|
|
|
with open(fname, 'wt') as f:
|
|
|
|
f.write("# Number of k-points: nktot\n")
|
|
|
|
nktot = kmesh['nktot']
|
|
|
|
f.write("%i\n"%(nktot))
|
|
|
|
# TODO: add the output of reciprocal lattice vectors
|
|
|
|
f.write("# List of k-points with weights\n")
|
|
|
|
for ik in xrange(nktot):
|
|
|
|
kx, ky, kz = kmesh['kpoints'][ik, :]
|
|
|
|
kwght = kmesh['kweights'][ik]
|
|
|
|
f.write("%15.10f%15.10f%15.10f%20.10f\n"%(kx, ky, kz, kwght))
|
|
|
|
|
|
|
|
# Check if there are tetrahedra defined and if they are, output them
|
|
|
|
try:
|
|
|
|
ntet = kmesh['ntet']
|
|
|
|
volt = kmesh['volt']
|
|
|
|
f.write("\n# Number of tetrahedra and volume: ntet, volt\n")
|
|
|
|
f.write("%i %s\n"%(ntet, volt))
|
|
|
|
f.write("# List of tetrahedra: imult, ik1, ..., ik4\n")
|
|
|
|
for it in xrange(ntet):
|
|
|
|
f.write(' '.join(map("{0:d}".format, *kmesh['itet'][it, :])) + '\n')
|
|
|
|
except KeyError:
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
2015-08-12 17:09:30 +02:00
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# ctrl_output
|
|
|
|
#
|
|
|
|
################################################################################
|
|
|
|
def ctrl_output(conf_pars, el_struct, ng):
|
|
|
|
"""
|
|
|
|
Outputs a ctrl-file.
|
|
|
|
"""
|
|
|
|
ctrl_fname = conf_pars.general['basename'] + '.ctrl'
|
|
|
|
head_dict = {}
|
|
|
|
|
2015-08-13 11:50:49 +02:00
|
|
|
# TODO: Add output of tetrahedra
|
2015-08-12 17:09:30 +02:00
|
|
|
# Construct the header dictionary
|
|
|
|
head_dict['ngroups'] = ng
|
|
|
|
head_dict['nk'] = el_struct.kmesh['nktot']
|
|
|
|
head_dict['ns'] = el_struct.nspin
|
|
|
|
head_dict['nc_flag'] = 1 if el_struct.nc_flag else 0
|
|
|
|
# head_dict['efermi'] = conf_pars.general['efermi'] # We probably don't need Efermi
|
|
|
|
|
|
|
|
header = json.dumps(head_dict, indent=4, separators=(',', ': '))
|
|
|
|
|
2015-08-13 10:59:32 +02:00
|
|
|
print " Storing ctrl-file..."
|
2015-08-12 17:09:30 +02:00
|
|
|
with open(ctrl_fname, 'wt') as f:
|
2015-08-13 10:59:32 +02:00
|
|
|
f.write(header + "\n")
|
|
|
|
f.write("#END OF HEADER\n")
|
|
|
|
|
|
|
|
f.write("# k-points and weights\n")
|
|
|
|
labels = ['kx', 'ky', 'kz', 'kweight']
|
2015-10-15 13:26:48 +02:00
|
|
|
out = "".join(map(lambda s: s.center(15), labels))
|
2015-08-13 10:59:32 +02:00
|
|
|
f.write("#" + out + "\n")
|
|
|
|
for ik, kp in enumerate(el_struct.kmesh['kpoints']):
|
|
|
|
tmp1 = "".join(map("{0:15.10f}".format, kp))
|
|
|
|
out = tmp1 + "{0:16.10f}".format(el_struct.kmesh['kweights'][ik])
|
|
|
|
f.write(out + "\n")
|
|
|
|
|
2015-08-12 17:09:30 +02:00
|
|
|
|
2015-03-01 13:09:31 +01:00
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# plo_output
|
|
|
|
#
|
|
|
|
################################################################################
|
2015-08-12 17:09:30 +02:00
|
|
|
def plo_output(conf_pars, el_struct, pshells, pgroups):
|
2015-03-01 13:09:31 +01:00
|
|
|
"""
|
|
|
|
Outputs PLO groups into text files.
|
|
|
|
|
|
|
|
Filenames are defined by <basename> that is passed from config-file.
|
|
|
|
All necessary general parameters are stored in a file '<basename>.ctrl'.
|
|
|
|
|
|
|
|
Each group is stored in a '<basename>.plog<Ng>' file. The format is the
|
|
|
|
following:
|
|
|
|
|
|
|
|
# Energy window: emin, emax
|
|
|
|
ib_min, ib_max
|
2015-03-02 21:29:54 +01:00
|
|
|
nelect
|
2015-03-01 13:09:31 +01:00
|
|
|
# Eigenvalues
|
2015-03-02 21:29:54 +01:00
|
|
|
isp, ik1, kx, ky, kz, kweight
|
2015-03-01 13:09:31 +01:00
|
|
|
ib1, ib2
|
|
|
|
eig1
|
|
|
|
eig2
|
|
|
|
...
|
|
|
|
eigN
|
|
|
|
ik2, kx, ky, kz, kweight
|
|
|
|
...
|
|
|
|
|
|
|
|
# Projected shells
|
|
|
|
Nshells
|
|
|
|
# Shells: <shell indices>
|
2015-08-10 13:52:29 +02:00
|
|
|
# Shell <1>
|
2015-03-01 13:09:31 +01:00
|
|
|
Shell 1
|
|
|
|
ndim
|
|
|
|
# complex arrays: plo(ns, nion, ndim, nb)
|
|
|
|
...
|
|
|
|
# Shells: <shell indices>
|
2015-08-10 13:52:29 +02:00
|
|
|
# Shell <2>
|
2015-03-01 13:09:31 +01:00
|
|
|
Shell 2
|
|
|
|
...
|
|
|
|
|
|
|
|
"""
|
2015-08-13 12:29:41 +02:00
|
|
|
for ig, pgroup in enumerate(pgroups):
|
|
|
|
plo_fname = conf_pars.general['basename'] + '.pg%i'%(ig + 1)
|
|
|
|
print " Storing PLO-group file '%s'..."%(plo_fname)
|
|
|
|
head_dict = {}
|
|
|
|
|
|
|
|
head_dict['ewindow'] = (pgroup.emin, pgroup.emax)
|
|
|
|
head_dict['nb_max'] = pgroup.nb_max
|
|
|
|
|
2015-09-17 12:40:55 +02:00
|
|
|
# Number of electrons within the window
|
|
|
|
head_dict['nelect'] = pgroup.nelect_window(el_struct)
|
2015-10-15 13:26:48 +02:00
|
|
|
print " Density within window:", head_dict['nelect']
|
2015-09-17 12:40:55 +02:00
|
|
|
|
2015-08-13 12:29:41 +02:00
|
|
|
head_shells = []
|
2015-08-18 11:36:08 +02:00
|
|
|
for ish in pgroup.ishells:
|
|
|
|
shell = pgroup.shells[ish]
|
2015-08-13 12:29:41 +02:00
|
|
|
sh_dict = {}
|
2015-08-18 11:36:08 +02:00
|
|
|
sh_dict['shell_index'] = ish
|
2015-08-13 12:29:41 +02:00
|
|
|
sh_dict['lorb'] = shell.lorb
|
|
|
|
sh_dict['ndim'] = shell.ndim
|
2019-06-27 09:04:22 +02:00
|
|
|
sh_dict['corr'] = shell.corr
|
2015-08-13 12:29:41 +02:00
|
|
|
# Convert ion indices from the internal representation (starting from 0)
|
|
|
|
# to conventional VASP representation (starting from 1)
|
|
|
|
ion_output = [io + 1 for io in shell.ion_list]
|
2018-05-04 16:08:46 +02:00
|
|
|
# Derive sorts from equivalence classes
|
2015-08-13 12:29:41 +02:00
|
|
|
sh_dict['ion_list'] = ion_output
|
2018-05-04 16:08:46 +02:00
|
|
|
sh_dict['ion_sort'] = shell.ion_sort
|
2015-09-16 11:56:54 +02:00
|
|
|
|
2015-08-13 12:29:41 +02:00
|
|
|
# TODO: add the output of transformation matrices
|
|
|
|
|
|
|
|
head_shells.append(sh_dict)
|
|
|
|
|
|
|
|
head_dict['shells'] = head_shells
|
|
|
|
|
|
|
|
header = json.dumps(head_dict, indent=4, separators=(',', ': '))
|
|
|
|
|
|
|
|
with open(plo_fname, 'wt') as f:
|
|
|
|
f.write(header + "\n")
|
2015-08-18 11:36:08 +02:00
|
|
|
f.write("#END OF HEADER\n")
|
2015-08-13 12:29:41 +02:00
|
|
|
|
2015-08-18 11:36:08 +02:00
|
|
|
# Eigenvalues within the window
|
|
|
|
f.write("# Eigenvalues within the energy window: %s, %s\n"%(pgroup.emin, pgroup.emax))
|
|
|
|
nk, nband, ns_band = el_struct.eigvals.shape
|
2015-03-02 21:29:54 +01:00
|
|
|
for isp in xrange(ns_band):
|
2015-08-18 11:36:08 +02:00
|
|
|
f.write("# is = %i\n"%(isp + 1))
|
2015-03-02 21:29:54 +01:00
|
|
|
for ik in xrange(nk):
|
2015-08-18 11:36:08 +02:00
|
|
|
ib1, ib2 = pgroup.ib_win[ik, isp, 0], pgroup.ib_win[ik, isp, 1]
|
2015-12-04 19:55:37 +01:00
|
|
|
# Output band indices in Fortran convention!
|
|
|
|
f.write(" %i %i\n"%(ib1 + 1, ib2 + 1))
|
2015-08-18 11:36:08 +02:00
|
|
|
for ib in xrange(ib1, ib2 + 1):
|
2015-10-20 12:02:46 +02:00
|
|
|
eigv_ef = el_struct.eigvals[ik, ib, isp] - el_struct.efermi
|
2015-11-19 16:06:25 +01:00
|
|
|
f_weight = el_struct.ferw[isp, ik, ib]
|
|
|
|
f.write("%13.8f %12.7f\n"%(eigv_ef, f_weight))
|
2015-08-18 11:36:08 +02:00
|
|
|
|
|
|
|
# Projected shells
|
|
|
|
f.write("# Projected shells\n")
|
|
|
|
f.write("# Shells: %s\n"%(pgroup.ishells))
|
|
|
|
for ish in pgroup.ishells:
|
|
|
|
shell = pgroup.shells[ish]
|
|
|
|
f.write("# Shell %i\n"%(ish))
|
|
|
|
|
|
|
|
nion, ns, nk, nlm, nb = shell.proj_win.shape
|
|
|
|
for isp in xrange(ns):
|
|
|
|
f.write("# is = %i\n"%(isp + 1))
|
|
|
|
for ik in xrange(nk):
|
|
|
|
f.write("# ik = %i\n"%(ik + 1))
|
2015-03-02 21:29:54 +01:00
|
|
|
for ion in xrange(nion):
|
2015-08-18 11:36:08 +02:00
|
|
|
for ilm in xrange(nlm):
|
|
|
|
ib1, ib2 = pgroup.ib_win[ik, isp, 0], pgroup.ib_win[ik, isp, 1]
|
2015-10-20 17:37:17 +02:00
|
|
|
ib_win = ib2 - ib1 + 1
|
|
|
|
for ib in xrange(ib_win):
|
2015-08-18 11:36:08 +02:00
|
|
|
p = shell.proj_win[ion, isp, ik, ilm, ib]
|
|
|
|
f.write("{0:16.10f}{1:16.10f}\n".format(p.real, p.imag))
|
2015-03-02 21:29:54 +01:00
|
|
|
f.write("\n")
|
2015-08-18 11:36:08 +02:00
|
|
|
|
2019-06-27 15:21:07 +02:00
|
|
|
################################################################################
|
|
|
|
#
|
|
|
|
# plo_output
|
|
|
|
#
|
|
|
|
################################################################################
|
2019-06-27 16:26:22 +02:00
|
|
|
def hk_output(conf_pars, el_struct, pgroups):
|
2019-06-27 15:21:07 +02:00
|
|
|
"""
|
|
|
|
Outputs HK into text file.
|
|
|
|
|
|
|
|
Filename is defined by <basename> that is passed from config-file.
|
|
|
|
|
2019-06-27 16:26:22 +02:00
|
|
|
The Hk for each groups is stored in a '<basename>.hk<Ng>' file. The format is
|
|
|
|
as defined in the Hk dft_tools format
|
|
|
|
|
|
|
|
nk # number of k-points
|
|
|
|
n_el # electron density
|
|
|
|
n_sh # number of total atomic shells
|
|
|
|
at sort l dim # atom, sort, l, dim
|
|
|
|
at sort l dim # atom, sort, l, dim
|
|
|
|
n_cr_sh # number of correlated shells
|
|
|
|
at sort l dim SO irep # atom, sort, l, dim, SO, irep
|
|
|
|
n_irrep dim_irrep # number of ireps, dim of irep
|
|
|
|
|
|
|
|
After these header lines, the file has to contain the Hamiltonian matrix
|
|
|
|
in orbital space. The standard convention is that you give for each k-point
|
|
|
|
first the matrix of the real part, then the matrix of the imaginary part,
|
|
|
|
and then move on to the next k-point.
|
|
|
|
|
2019-06-27 15:21:07 +02:00
|
|
|
"""
|
|
|
|
|
2019-06-27 16:26:22 +02:00
|
|
|
|
2019-06-27 15:21:07 +02:00
|
|
|
for ig, pgroup in enumerate(pgroups):
|
2019-06-27 16:26:22 +02:00
|
|
|
|
2019-06-27 15:21:07 +02:00
|
|
|
hk_fname = conf_pars.general['basename'] + '.hk%i'%(ig + 1)
|
2019-06-27 16:26:22 +02:00
|
|
|
print " Storing HK-group file '%s'..."%(hk_fname)
|
2019-06-27 15:21:07 +02:00
|
|
|
|
|
|
|
head_corr_shells = []
|
|
|
|
head_shells = []
|
|
|
|
for ish in pgroup.ishells:
|
|
|
|
|
|
|
|
shell = pgroup.shells[ish]
|
|
|
|
|
|
|
|
sh_dict = {}
|
|
|
|
sh_dict['shell_index'] = ish
|
|
|
|
sh_dict['lorb'] = shell.lorb
|
|
|
|
sh_dict['ndim'] = shell.ndim
|
|
|
|
# Convert ion indices from the internal representation (starting from 0)
|
|
|
|
# to conventional VASP representation (starting from 1)
|
|
|
|
ion_output = [io + 1 for io in shell.ion_list]
|
|
|
|
# Derive sorts from equivalence classes
|
|
|
|
sh_dict['ion_list'] = ion_output
|
|
|
|
sh_dict['ion_sort'] = shell.ion_sort
|
|
|
|
|
|
|
|
|
|
|
|
head_shells.append(sh_dict)
|
|
|
|
if shell.corr:
|
|
|
|
head_corr_shells.append(sh_dict)
|
|
|
|
|
|
|
|
|
|
|
|
with open(hk_fname, 'wt') as f:
|
2019-06-27 16:26:22 +02:00
|
|
|
# Eigenvalues within the window
|
2019-06-27 15:21:07 +02:00
|
|
|
nk, nband, ns_band = el_struct.eigvals.shape
|
2019-06-27 16:26:22 +02:00
|
|
|
f.write('%i # number of kpoints\n'%nk)
|
|
|
|
f.write('{0:0.4f} # electron density\n'.format(pgroup.nelect_window(el_struct)))
|
|
|
|
f.write('%i # number of shells\n'%len(head_shells))
|
2019-06-27 15:21:07 +02:00
|
|
|
for head in head_shells:
|
2019-06-27 16:26:22 +02:00
|
|
|
f.write('%i %i %i %i # atom sort l dim\n'%(head['ion_list'][0],head['ion_sort'][0],head['lorb'],head['ndim']))
|
|
|
|
f.write('%i # number of correlated shells\n'%len(head_corr_shells))
|
2019-06-27 15:21:07 +02:00
|
|
|
for head in head_corr_shells:
|
2019-06-27 16:26:22 +02:00
|
|
|
f.write('%i %i %i %i 0 0 # atom sort l dim SO irrep\n'%(head['ion_list'][0],head['ion_sort'][0],head['lorb'],head['ndim']))
|
|
|
|
f.write('1 5 # number of ireps, dim of irep\n')
|
2019-06-27 15:21:07 +02:00
|
|
|
norbs = pgroup.hk.shape[2]
|
|
|
|
for isp in xrange(ns_band):
|
|
|
|
for ik in xrange(nk):
|
|
|
|
for io in xrange(norbs):
|
|
|
|
for iop in xrange(norbs):
|
|
|
|
f.write(" {0:14.10f}".format(pgroup.hk[isp,ik,io,iop].real))
|
|
|
|
f.write("\n")
|
|
|
|
for io in xrange(norbs):
|
|
|
|
for iop in xrange(norbs):
|
|
|
|
f.write(" {0:14.10f}".format(pgroup.hk[isp,ik,io,iop].imag))
|
|
|
|
f.write("\n")
|