3
0
mirror of https://github.com/triqs/dft_tools synced 2024-12-23 04:43:42 +01:00

block_structure: convert_gf: add G_out, let G_struct be sumk

This commit is contained in:
Gernot J. Kraberger 2018-08-29 12:03:14 +02:00
parent 6c908e9c6e
commit 2b490d1485
2 changed files with 53 additions and 23 deletions

View File

@ -283,6 +283,7 @@ class BlockStructure(object):
def check_gf(self, G, ish=None): def check_gf(self, G, ish=None):
""" 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``.
@ -322,8 +323,9 @@ class BlockStructure(object):
assert list(gf.indices) == 2 * [map(str, self.gf_struct_solver[ish][block])],\ assert list(gf.indices) == 2 * [map(str, self.gf_struct_solver[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,**kwargs): def convert_gf(self, G, G_struct, ish=0, show_warnings=True,
""" Convert BlockGf from its structure to this structure. G_out=None, **kwargs):
""" Convert BlockGf from its structure to this (solver) structure.
.. warning:: .. warning::
@ -335,8 +337,9 @@ class BlockStructure(object):
---------- ----------
G : BlockGf G : BlockGf
the Gf that should be converted the Gf that should be converted
G_struct : GfStructure G_struct : BlockStructure or str
the structure of that G the structure of that G or 'sumk' (then, the structure of
the sumk Green's function of this BlockStructure is used)
ish : int ish : int
shell index shell index
show_warnings : bool or float show_warnings : bool or float
@ -354,30 +357,50 @@ class BlockStructure(object):
warning_threshold = show_warnings warning_threshold = show_warnings
show_warnings = True show_warnings = True
G_new = self.create_gf(ish=ish,**kwargs) # we offer the possibility to convert to convert from sumk_dft
for block in G_struct.gf_struct_solver[ish].keys(): from_sumk = False
for i1 in G_struct.gf_struct_solver[ish][block]: if isinstance(G_struct, str) and G_struct == 'sumk':
for i2 in G_struct.gf_struct_solver[ish][block]: gf_struct_in = {block: indices
i1_sumk = G_struct.solver_to_sumk[ish][(block,i1)] for block, indices in self.gf_struct_sumk[ish]}
i2_sumk = G_struct.solver_to_sumk[ish][(block,i2)] from_sumk = True
else:
gf_struct_in = G_struct.gf_struct_solver[ish]
# create a Green's function to hold the result
if G_out is None:
G_out = self.create_gf(ish=ish, **kwargs)
else:
self.check_gf(G_out, ish=ish)
for block in gf_struct_in.keys():
for i1 in gf_struct_in[block]:
for i2 in gf_struct_in[block]:
if from_sumk:
i1_sumk = (block, i1)
i2_sumk = (block, i2)
else:
i1_sumk = G_struct.solver_to_sumk[ish][(block, i1)]
i2_sumk = G_struct.solver_to_sumk[ish][(block, i2)]
i1_sol = self.sumk_to_solver[ish][i1_sumk] i1_sol = self.sumk_to_solver[ish][i1_sumk]
i2_sol = self.sumk_to_solver[ish][i2_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():
warn(('Element {},{} of block {} of G is not present '+ warn(('Element {},{} of block {} of G is not present ' +
'in the new structure').format(i1,i2,block)) 'in the new structure').format(i1, i2, block))
continue continue
if i1_sol[0]!=i2_sol[0]: if i1_sol[0] != i2_sol[0]:
if show_warnings and np.max(np.abs(G[block][i1,i2].data)) > warning_threshold: if (show_warnings and
np.max(np.abs(G[block][i1, i2].data)) > warning_threshold):
if mpi.is_master_node(): if mpi.is_master_node():
warn(('Element {},{} of block {} of G is approximated '+ warn(('Element {},{} of block {} of G is approximated ' +
'to zero to match the new structure. Max abs value: {}').format( 'to zero to match the new structure. Max abs value: {}').format(
i1,i2,block,np.max(np.abs(G[block][i1,i2].data)))) i1, i2, block, np.max(np.abs(G[block][i1, i2].data))))
continue continue
G_new[i1_sol[0]][i1_sol[1],i2_sol[1]] = \ G_out[i1_sol[0]][i1_sol[1], i2_sol[1]] = \
G[block][i1,i2] G[block][i1, i2]
return G_new return G_out
def approximate_as_diagonal(self): def approximate_as_diagonal(self):
""" Create a structure for a GF with zero off-diagonal elements. """ Create a structure for a GF with zero off-diagonal elements.

View File

@ -40,10 +40,9 @@ map1.map_gf_struct_solver(mapping)
# check create_gf # check create_gf
G1 = original_bs.create_gf(beta=40, n_points=3) G1 = original_bs.create_gf(beta=40, n_points=3)
i = 1 widths = dict(up_0=1, up_1=2, down_0=4, down_1=3)
for block, gf in G1: for block, gf in G1:
gf << SemiCircular(i) gf << SemiCircular(widths[block])
i += 1
original_bs.check_gf(G1) original_bs.check_gf(G1)
original_bs.check_gf([G1]) original_bs.check_gf([G1])
@ -58,6 +57,14 @@ G2 = map1.convert_gf(G1, original_bs, beta=40, n_points=3, show_warnings=False)
full = BlockStructure.full_structure( full = BlockStructure.full_structure(
[{'up_0': [0, 1], 'up_1': [0], 'down_1': [0], 'down_0': [0, 1]}], None) [{'up_0': [0, 1], 'up_1': [0], 'down_1': [0], 'down_0': [0, 1]}], None)
G_sumk = BlockGf(mesh=G1.mesh, gf_struct=original_bs.gf_struct_sumk[0])
for i in range(3):
G_sumk['up'][i, i] << SemiCircular(1 if i < 2 else 2)
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)
assert_block_gfs_are_close(G1, G3)
# check __eq__ # check __eq__
assert full == full, 'equality not correct (equal structures not equal)' assert full == full, 'equality not correct (equal structures not equal)'
assert pick1 == pick1, 'equality not correct (equal structures not equal)' assert pick1 == pick1, 'equality not correct (equal structures not equal)'