mirror of
https://github.com/triqs/dft_tools
synced 2024-12-21 20:03:41 +01:00
Added transformation matrices to ProjectorShell
Matrices parsed by the config-parser are interpreted as transformation matrices for each ion in the shell. If only one matrix is defined (by TRANSFORM) it is copied for every ion. Whether a matrix is real or complex is derived from its dimensions consistently with other parameters of the shell (such as 'nm = 2*l + 1'). Transformation matrices are stored as complex in any case.
This commit is contained in:
parent
cefaf9dda4
commit
5ec3e881cd
@ -11,6 +11,14 @@ try:
|
||||
except ImportError:
|
||||
import json
|
||||
|
||||
def issue_warning(message):
|
||||
"""
|
||||
Issues a warning.
|
||||
"""
|
||||
print
|
||||
print " !!! WARNING !!!: " + message
|
||||
print
|
||||
|
||||
class Projector:
|
||||
"""
|
||||
Class describing a local-orbital projector.
|
||||
@ -302,19 +310,21 @@ class ProjectorShell:
|
||||
self.lorb = sh_pars['lshell']
|
||||
self.ion_list = sh_pars['ion_list']
|
||||
self.user_index = sh_pars['user_index']
|
||||
try:
|
||||
self.tmatrix = sh_pars['tmatrix']
|
||||
except KeyError:
|
||||
self.tmatrix = None
|
||||
# try:
|
||||
# self.tmatrix = sh_pars['tmatrix']
|
||||
# except KeyError:
|
||||
# self.tmatrix = None
|
||||
|
||||
self.lm1 = self.lorb**2
|
||||
self.lm2 = (self.lorb+1)**2
|
||||
|
||||
if self.tmatrix is None:
|
||||
self.ndim = self.lm2 - self.lm1
|
||||
else:
|
||||
# TODO: generalize this to a tmatrix for every ion
|
||||
self.ndim = self.tmatrix.shape[0]
|
||||
self.ndim = self.extract_tmatrices(sh_pars)
|
||||
print " Dimension of subspace:", self.ndim
|
||||
# if self.tmatrix is None:
|
||||
# self.ndim = self.lm2 - self.lm1
|
||||
# else:
|
||||
## TODO: generalize this to a tmatrix for every ion
|
||||
# self.ndim = self.tmatrix.shape[0]
|
||||
|
||||
# Pre-select a subset of projectors (this should be an array view => no memory is wasted)
|
||||
# !!! This sucks but I have to change the order of 'ib' and 'ilm' indices here
|
||||
@ -341,6 +351,108 @@ class ProjectorShell:
|
||||
|
||||
# self.proj_arr = proj_raw[iproj_l, :, :, :].transpose((1, 2, 0, 3))
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# extract_tmatrices
|
||||
#
|
||||
################################################################################
|
||||
def extract_tmatrices(self, sh_pars):
|
||||
"""
|
||||
Extracts and interprets transformation matrices provided by the
|
||||
config-parser.
|
||||
There are two relevant options in 'sh_pars':
|
||||
|
||||
'tmatrix' : a transformation matrix applied to all ions in the shell
|
||||
'tmatrices': interpreted as a set of transformation matrices for each ion.
|
||||
|
||||
If both of the options are present a warning is issued and 'tmatrices'
|
||||
supersedes 'tmatrix'.
|
||||
"""
|
||||
nion = len(self.ion_list)
|
||||
nm = self.lm2 - self.lm1
|
||||
|
||||
if 'tmatrices' in sh_pars:
|
||||
if 'tmatrix' in sh_pars:
|
||||
mess = "Both TRANSFORM and TRANSFILE are specified, TRANSFORM will be ignored."
|
||||
issue_warning(mess)
|
||||
|
||||
raw_matrices = sh_pars['tmatrices']
|
||||
nrow, ncol = raw_matrices.shape
|
||||
|
||||
assert nrow%nion == 0, "Number of rows in TRANSFILE must be divisible by the number of ions"
|
||||
assert ncol%nm == 0, "Number of columns in TRANSFILE must be divisible by the number of orbitals 2*l + 1"
|
||||
|
||||
nr = nrow / nion
|
||||
nsize = ncol / nm
|
||||
assert nsize in (1, 2, 4), "Number of columns in TRANSFILE must be divisible by either 1, 2, or 4"
|
||||
#
|
||||
# Determine the spin-dimension and whether the matrices are real or complex
|
||||
#
|
||||
# if nsize == 1 or nsize == 2:
|
||||
# Matrices (either real or complex) are spin-independent
|
||||
# nls_dim = nm
|
||||
# if msize == 2:
|
||||
# is_complex = True
|
||||
# else:
|
||||
# is_complex = False
|
||||
# elif nsize = 4:
|
||||
# Matrices are complex and spin-dependent
|
||||
# nls_dim = 2 * nm
|
||||
# is_complex = True
|
||||
#
|
||||
is_complex = nsize > 1
|
||||
ns_dim = max(1, nsize / 2)
|
||||
|
||||
# Dimension of the orbital subspace
|
||||
assert nr%ns_dim == 0, "Number of rows in TRANSFILE is not compatible with the spin dimension"
|
||||
ndim = nr / ns_dim
|
||||
|
||||
self.tmatrices = np.zeros((nion, nr, nm * ns_dim), dtype=np.complex128)
|
||||
|
||||
if is_complex:
|
||||
raw_matrices = raw_matrices[:, ::2] + raw_matrices[:, 1::2] * 1j
|
||||
|
||||
for io in xrange(nion):
|
||||
i1 = io * nr
|
||||
i2 = (io + 1) * nr
|
||||
self.tmatrices[io, :, :] = raw_matrices[i1:i2, :]
|
||||
|
||||
return ndim
|
||||
|
||||
if 'tmatrix' in sh_pars:
|
||||
raw_matrix = sh_pars['tmatrix']
|
||||
nrow, ncol = raw_matrix.shape
|
||||
|
||||
assert ncol%nm == 0, "Number of columns in TRANSFORM must be divisible by the number of orbitals 2*l + 1"
|
||||
|
||||
# Only spin-independent matrices are expected here
|
||||
nsize = ncol / nm
|
||||
assert nsize in (1, 2), "Number of columns in TRANSFORM must be divisible by either 1 or 2"
|
||||
|
||||
is_complex = nsize > 1
|
||||
if is_complex:
|
||||
matrix = raw_matrix[:, ::2] + raw_matrix[:, 1::2] * 1j
|
||||
else:
|
||||
matrix = raw_matrix
|
||||
|
||||
ndim = nrow
|
||||
|
||||
self.tmatrices = np.zeros((nion, nrow, nm), dtype=np.complex128)
|
||||
for io in xrange(nion):
|
||||
self.tmatrices[io, :, :] = raw_matrix
|
||||
|
||||
return ndim
|
||||
|
||||
# If no transformation matrices are provided define a default one
|
||||
ns_dim = 2 if self.nc_flag else 1
|
||||
ndim = nm * ns_dim
|
||||
|
||||
self.tmatrices = np.zeros((nion, ndim, ndim), dtype=np.complex128)
|
||||
for io in xrange(nion):
|
||||
self.tmatrices[io, :, :] = np.identity(ndim, dtype=np.complex128)
|
||||
|
||||
return ndim
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# select_projectors
|
||||
|
Loading…
Reference in New Issue
Block a user