3
0
mirror of https://github.com/triqs/dft_tools synced 2024-06-29 08:24:54 +02:00

block_structure: introduce space parameter

in methods convert_gf, create_gf, check_gf
This commit is contained in:
Gernot J. Kraberger 2018-08-30 21:55:59 +02:00
parent ef979199af
commit d8a2693123
3 changed files with 96 additions and 40 deletions

View File

@ -349,8 +349,11 @@ class BlockStructure(object):
self.sumk_to_solver[ish]=su2so self.sumk_to_solver[ish]=su2so
self.solver_to_sumk_block[ish]=so2su_block self.solver_to_sumk_block[ish]=so2su_block
def create_gf(self,ish=0,gf_function=GfImFreq,**kwargs): def create_gf(self, ish=0, gf_function=GfImFreq, space='solver', **kwargs):
""" Create a zero BlockGf having the gf_struct_solver structure. """ Create a zero BlockGf having the correct structure.
For ``space='solver'``, the structure is according to
``gf_struct_solver``, else according to ``gf_struct_sumk``.
When using GfImFreq as gf_function, typically you have to When using GfImFreq as gf_function, typically you have to
supply beta as keyword argument. supply beta as keyword argument.
@ -359,27 +362,40 @@ class BlockStructure(object):
---------- ----------
ish : int ish : int
shell index shell index
If ``space='solver', the index of the of the inequivalent correlated shell,
if ``space='sumk'`, the index of the correlated shell
gf_function : constructor gf_function : constructor
function used to construct the Gf objects constituting the function used to construct the Gf objects constituting the
individual blocks; default: GfImFreq individual blocks; default: GfImFreq
space : 'solver' or 'sumk'
which space the structure should correspond to
**kwargs : **kwargs :
options passed on to the Gf constructor for the individual options passed on to the Gf constructor for the individual
blocks blocks
""" """
names = self.gf_struct_solver[ish].keys() if space == 'solver':
blocks=[] gf_struct = self.gf_struct_solver
elif space == 'sumk':
gf_struct = self.gf_struct_sumk_dict
else:
raise Exception(
"Argument space has to be either 'solver' or 'sumk'.")
names = gf_struct[ish].keys()
blocks = []
for n in names: for n in names:
G = gf_function(indices=self.gf_struct_solver[ish][n],**kwargs) G = gf_function(indices=gf_struct[ish][n], **kwargs)
blocks.append(G) blocks.append(G)
G = BlockGf(name_list = names, block_list = blocks) G = BlockGf(name_list=names, block_list=blocks)
return G return G
def check_gf(self, G, ish=None): def check_gf(self, G, ish=None, space='solver'):
""" check whether the Green's function G has the right structure """ check whether the Green's function G has the right structure
This throws an error if the structure of G is not the same This throws an error if the structure of G is not the same
as ``gf_struct_solver``. as ``gf_struct_solver`` (for ``space=solver``) or
``gf_struct_sumk`` (for ``space=sumk``)..
Parameters Parameters
---------- ----------
@ -392,34 +408,44 @@ class BlockStructure(object):
shell index shell index
default: 0 if G is just one Green's function is given, default: 0 if G is just one Green's function is given,
check all if list of Green's functions is given check all if list of Green's functions is given
space : 'solver' or 'sumk'
which space the structure should correspond to
""" """
if space == 'solver':
gf_struct = self.gf_struct_solver
elif space == 'sumk':
gf_struct = self.gf_struct_sumk_dict
else:
raise Exception(
"Argument space has to be either 'solver' or 'sumk'.")
if isinstance(G, list): if isinstance(G, list):
assert len(G) == len(self.gf_struct_solver),\ assert len(G) == len(gf_struct),\
"list of G does not have the correct length" "list of G does not have the correct length"
if ish is None: if ish is None:
ishs = range(len(self.gf_struct_solver)) ishs = range(len(gf_struct))
else: else:
ishs = [ish] ishs = [ish]
for ish in ishs: for ish in ishs:
self.check_gf(G[ish], ish=ish) self.check_gf(G[ish], ish=ish, space=space)
return return
if ish is None: if ish is None:
ish = 0 ish = 0
for block in self.gf_struct_solver[ish]: for block in gf_struct[ish]:
assert block in G.indices,\ assert block in G.indices,\
"block " + block + " not in G (shell {})".format(ish) "block " + block + " not in G (shell {})".format(ish)
for block, gf in G: for block, gf in G:
assert block in self.gf_struct_solver[ish],\ assert block in gf_struct[ish],\
"block " + block + " not in struct (shell {})".format(ish) "block " + block + " not in struct (shell {})".format(ish)
assert list(gf.indices) == 2 * [map(str, self.gf_struct_solver[ish][block])],\ assert list(gf.indices) == 2 * [map(str, gf_struct[ish][block])],\
"block " + block + " has wrong indices (shell {})".format(ish) "block " + block + " has wrong indices (shell {})".format(ish)
def convert_gf(self, G, G_struct, ish=0, show_warnings=True, def convert_gf(self, G, G_struct, ish_from=0, ish_to=None, show_warnings=True,
G_out=None, **kwargs): G_out=None, space_from='solver', space_to='solver', ish=None, **kwargs):
""" Convert BlockGf from its structure to this (solver) structure. """ Convert BlockGf from its structure to this structure.
.. warning:: .. warning::
@ -432,10 +458,13 @@ class BlockStructure(object):
G : BlockGf G : BlockGf
the Gf that should be converted the Gf that should be converted
G_struct : BlockStructure or str G_struct : BlockStructure or str
the structure of that G or 'sumk' (then, the structure of the structure of that G or None (then, this structure
the sumk Green's function of this BlockStructure is used) is used)
ish : int ish_from : int
shell index shell index of the input structure
ish_to : int
shell index of the output structure; if None (the default),
it is the same as ish_from
show_warnings : bool or float show_warnings : bool or float
whether to show warnings when elements of the Green's whether to show warnings when elements of the Green's
function get thrown away function get thrown away
@ -445,41 +474,67 @@ class BlockStructure(object):
G_out : BlockGf G_out : BlockGf
the output Green's function (if not given, a new one is the output Green's function (if not given, a new one is
created) created)
space_from : 'solver' or 'sumk'
whether the Green's function ``G`` corresponds to the
solver or sumk structure of ``G_struct``
space_to : 'solver' or 'sumk'
whether the output Green's function should be according to
the solver of sumk structure of this structure
**kwargs : **kwargs :
options passed to the constructor for the new Gf options passed to the constructor for the new Gf
""" """
if ish is not None:
warn(
'The parameter ish in convert_gf is deprecated. Use ish_from and ish_to instead.')
ish_from = ish
ish_to = ish
if ish_to is None:
ish_to = ish_from
warning_threshold = 1.e-10 warning_threshold = 1.e-10
if isinstance(show_warnings, float): if isinstance(show_warnings, float):
warning_threshold = show_warnings warning_threshold = show_warnings
show_warnings = True show_warnings = True
# we offer the possibility to convert to convert from sumk_dft if G_struct is None:
from_sumk = False G_struct = self
if isinstance(G_struct, str) and G_struct == 'sumk':
gf_struct_in = self.gf_struct_sumk_dict[ish] if space_from == 'solver':
from_sumk = True gf_struct_in = G_struct.gf_struct_solver[ish_from]
elif space_from == 'sumk':
gf_struct_in = G_struct.gf_struct_sumk_dict[ish_from]
else: else:
gf_struct_in = G_struct.gf_struct_solver[ish] raise Exception(
"Argument space_from has to be either 'solver' or 'sumk'.")
# create a Green's function to hold the result # create a Green's function to hold the result
if G_out is None: if G_out is None:
G_out = self.create_gf(ish=ish, **kwargs) G_out = self.create_gf(ish=ish_to, space=space_to, **kwargs)
else: else:
self.check_gf(G_out, ish=ish) self.check_gf(G_out, ish=ish_to, space=space_to)
for block in gf_struct_in.keys(): for block in gf_struct_in.keys():
for i1 in gf_struct_in[block]: for i1 in gf_struct_in[block]:
for i2 in gf_struct_in[block]: for i2 in gf_struct_in[block]:
if from_sumk: if space_from == 'sumk':
i1_sumk = (block, i1) i1_sumk = (block, i1)
i2_sumk = (block, i2) i2_sumk = (block, i2)
else: elif space_from == 'solver':
i1_sumk = G_struct.solver_to_sumk[ish][(block, i1)] i1_sumk = G_struct.solver_to_sumk[ish_from][(block, i1)]
i2_sumk = G_struct.solver_to_sumk[ish][(block, i2)] i2_sumk = G_struct.solver_to_sumk[ish_from][(block, i2)]
if space_to == 'sumk':
i1_sol = i1_sumk
i2_sol = i2_sumk
elif space_to == 'solver':
i1_sol = self.sumk_to_solver[ish_to][i1_sumk]
i2_sol = self.sumk_to_solver[ish_to][i2_sumk]
else:
raise Exception(
"Argument space_to has to be either 'solver' or 'sumk'.")
i1_sol = self.sumk_to_solver[ish][i1_sumk]
i2_sol = self.sumk_to_solver[ish][i2_sumk]
if i1_sol[0] is None or i2_sol[0] is None: if i1_sol[0] is None or i2_sol[0] is None:
if show_warnings: if show_warnings:
if mpi.is_master_node(): if mpi.is_master_node():

View File

@ -743,8 +743,7 @@ class SumkDFT(object):
G_out G_out
""" """
if G_out is None: if G_out is None:
G_out = [BlockGf(mesh=G_loc[0].mesh, G_out = [self.block_structure.create_gf(ish=ish, mesh=G_loc[self.inequiv_to_corr[ish]].mesh)
gf_struct=[(k, v) for k, v in self.gf_struct_solver[ish].iteritems()])
for ish in range(self.n_inequiv_shells)] for ish in range(self.n_inequiv_shells)]
else: else:
for ish in range(self.n_inequiv_shells): for ish in range(self.n_inequiv_shells):
@ -754,8 +753,10 @@ class SumkDFT(object):
for ish in range(self.n_inequiv_shells): for ish in range(self.n_inequiv_shells):
self.block_structure.convert_gf( self.block_structure.convert_gf(
G=G_loc[self.inequiv_to_corr[ish]], G=G_loc[self.inequiv_to_corr[ish]],
G_struct='sumk', G_struct=None,
ish=ish, ish_from=self.inequiv_to_corr[ish],
ish_to=ish,
space_from='sumk',
G_out=G_out[ish]) G_out=G_out[ish])
# return only the inequivalent shells: # return only the inequivalent shells:

View File

@ -61,7 +61,7 @@ G_sumk = BlockGf(mesh=G1.mesh, gf_struct=original_bs.gf_struct_sumk[0])
for i in range(3): for i in range(3):
G_sumk['up'][i, i] << SemiCircular(1 if i < 2 else 2) G_sumk['up'][i, i] << SemiCircular(1 if i < 2 else 2)
G_sumk['down'][i, i] << SemiCircular(4 if i < 2 else 3) G_sumk['down'][i, i] << SemiCircular(4 if i < 2 else 3)
G3 = original_bs.convert_gf(G_sumk, 'sumk', beta=40, n_points=3) G3 = original_bs.convert_gf(G_sumk, None, space_from='sumk', beta=40, n_points=3)
assert_block_gfs_are_close(G1, G3) assert_block_gfs_are_close(G1, G3)
assert original_bs.gf_struct_sumk_list ==\ assert original_bs.gf_struct_sumk_list ==\