Skip to content

Commit 89998a9

Browse files
committed
[feat] add Pade Sigma analytic continuation and refine tests
1 parent f512cdc commit 89998a9

5 files changed

Lines changed: 164 additions & 23 deletions

File tree

python/solid_dmft/dmft_tools/initial_self_energies.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ def determine_dc_and_initial_sigma(general_params, advanced_params, sum_k,
498498

499499
# Updates the sum_k object with the Matsubara self-energy
500500
sum_k.put_Sigma([solvers[icrsh].Sigma_freq for icrsh in range(sum_k.n_inequiv_shells)])
501-
501+
502502
# load sigma as first guess in the hartree solver if applicable
503503
if general_params['solver_type'] == 'hartree':
504504
# TODO:

python/solid_dmft/postprocessing/maxent_sigma.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,8 @@ def main(external_path, iteration=None, continuator_type='inversion_sigmainf', m
257257
Main function that reads the Matsubara self-energy from h5, analytically continues it,
258258
writes the results back to the h5 archive and also returns the results.
259259
260+
Function parallelizes using MPI over impurities and blocks.
261+
260262
Parameters
261263
----------
262264
external_path : string
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# pyright: reportUnusedExpression=false
2+
3+
import numpy as np
4+
5+
from triqs.utility import mpi
6+
from h5 import HDFArchive
7+
from triqs.gf import Gf, MeshReFreq, BlockGf
8+
9+
from solid_dmft.postprocessing.maxent_sigma import _read_h5
10+
11+
def _write_sigma_omega_to_h5(sigma_w, external_path, iteration):
12+
""" Writes real-frequency self energy to h5 archive. """
13+
h5_internal_path = 'DMFT_results/' + ('last_iter' if iteration is None
14+
else f'it_{iteration}')
15+
16+
with HDFArchive(external_path, 'a') as archive:
17+
for i, sigma_imp in enumerate(sigma_w):
18+
archive[h5_internal_path][f'Sigma_Refreq_{i}'] = sigma_imp
19+
20+
def _run_pade(sigma_iw_list, n_w, w_min, w_max, n_iw, eta):
21+
"""
22+
Run pade in parallel. Call via main function.
23+
"""
24+
mpi.report('Continuing impurities with blocks:')
25+
26+
imps_blocks = []
27+
sigma_iw_flat_list = []
28+
29+
# create flattened list of self-energies
30+
for i, sigma_iw in enumerate(sigma_iw_list):
31+
blocks = list(sigma_iw.indices)
32+
mpi.report('- Imp {}: {}'.format(i, blocks))
33+
for block in blocks:
34+
imps_blocks.append((i, block))
35+
sigma_iw_flat_list.append(sigma_iw[block])
36+
37+
sigma_w_flat_list = []
38+
wmesh = MeshReFreq(w_min=w_min,w_max=w_max,n_w=n_w)
39+
imps_blocks_indices = np.arange(len(imps_blocks))
40+
for i in imps_blocks_indices:
41+
sigma_w_flat_list.append(Gf(mesh=wmesh, target_shape=sigma_iw_flat_list[i].target_shape))
42+
43+
# Runs Pade while parallelizing over impurities and blocks
44+
for i in mpi.slice_array(imps_blocks_indices):
45+
print(f'Rank {mpi.rank} continuing Σ {i}/{len(imps_blocks)}')
46+
sigma_w_flat_list[i].set_from_pade(sigma_iw_flat_list[i],n_points=n_iw, freq_offset=eta)
47+
48+
# sync Pade data
49+
for i in imps_blocks_indices:
50+
sigma_w_flat_list[i] = mpi.all_reduce(sigma_w_flat_list[i])
51+
52+
# Create list of BlockGf
53+
sigma_w_list = []
54+
for i, sigma_iw in enumerate(sigma_iw_list):
55+
block_list = []
56+
for block in sigma_iw.indices:
57+
block_list.append(sigma_w_flat_list.pop(0))
58+
sigma_w_list.append(BlockGf(name_list=list(sigma_iw.indices), block_list=block_list, make_copies=True))
59+
60+
return sigma_w_list
61+
62+
def main(external_path, n_w, w_min, w_max, n_iw, iteration=None, eta=0.0):
63+
"""
64+
Main function that reads the Matsubara self-energy from h5, analytically continues it,
65+
writes the results back to the h5 archive and also returns the results.
66+
67+
Function parallelizes using MPI over impurities and blocks.
68+
69+
Parameters
70+
----------
71+
external_path : string
72+
Path to the h5 archive to read from and write to
73+
n_w : int
74+
number of real frequencies of the final self-energies returned
75+
w_min : float
76+
Lower end of range where Sigma is being continued.
77+
w_max : float
78+
Upper end of range where Sigma is being continued.
79+
n_iw : int
80+
number of Matsubara frequencies to consider for the Pade approximant
81+
iteration : int/string
82+
Iteration to read from and write to. Default to last_iter
83+
eta : float
84+
frequency offset within Pade
85+
86+
Returns
87+
-------
88+
sigma_w : list of triqs.gf.BlockGf
89+
Sigma(omega) per inequivalent shell
90+
"""
91+
92+
sigma_iw = None
93+
if mpi.is_master_node():
94+
sigma_iw, _, _, _ = _read_h5(external_path, iteration)
95+
sigma_iw = mpi.bcast(sigma_iw)
96+
97+
# run pade in parallel
98+
sigma_w = _run_pade(sigma_iw, n_w, w_min, w_max, n_iw, eta)
99+
100+
mpi.report('Writing results to h5 archive now.')
101+
if mpi.is_master_node():
102+
_write_sigma_omega_to_h5(sigma_w, external_path, iteration)
103+
mpi.report('Finished writing Σ(ω) to archive.')
104+
105+
return sigma_w
106+

test/python/CMakeLists.txt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,29 @@
11
# all pytest unittests
2-
set (all_pytests
3-
test_afm_mapping
4-
test_interaction_hamiltonian
5-
test_manipulate_chemical_potential.py
6-
test_observables.py
7-
test_read_config.py
8-
test_update_dmft_config.py
2+
set (all_pytests
3+
test_afm_mapping
4+
test_interaction_hamiltonian
5+
test_manipulate_chemical_potential.py
6+
test_observables.py
7+
test_read_config.py
8+
test_update_dmft_config.py
99
test_update_results_h5.py
1010
)
1111

1212
foreach(test ${all_pytests})
1313
get_filename_component(test_name ${test} NAME_WE)
1414
get_filename_component(test_dir ${test} DIRECTORY)
15-
16-
add_test(NAME ${test_name}
17-
COMMAND ${TRIQS_PYTHON_EXECUTABLE} -m pytest -vv ${CMAKE_CURRENT_SOURCE_DIR}/${test_dir}/${test_name}.py
15+
16+
add_test(NAME ${test_name}
17+
COMMAND ${TRIQS_PYTHON_EXECUTABLE} -m pytest -vv ${CMAKE_CURRENT_SOURCE_DIR}/${test_dir}/${test_name}.py
1818
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${test_dir})
19-
19+
2020
set_property(TEST ${test_name} APPEND PROPERTY ENVIRONMENT PYTHONPATH=${PROJECT_BINARY_DIR}/python:$ENV{PYTHONPATH})
2121
endforeach()
2222

2323
# ------------------------------#
2424

2525
# all other tests
26-
set(all_tests
26+
set(all_tests
2727
test_convergence
2828
test_matheval
2929
test_plot_correlated_bands
@@ -38,7 +38,7 @@ set(all_tests
3838

3939
# copy reference data for PCB test
4040
FILE(COPY test_pcb_ref.h5 DESTINATION ${test_dir})
41-
41+
4242
# copy reference data for respack test
4343
FILE(COPY respack_sfo_data DESTINATION ${test_dir})
4444

@@ -52,7 +52,7 @@ endforeach()
5252
# ------------------------------#
5353

5454
# integration tests
55-
set (integration_tests
55+
set (integration_tests
5656
svo_hubbardI_basic
5757
svo_hartree
5858
lno_hubbardI_mag
@@ -65,17 +65,17 @@ FILE(COPY UIJKL DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
6565

6666
foreach(test ${integration_tests})
6767
set (test_dir ${CMAKE_CURRENT_BINARY_DIR}/${test})
68-
68+
6969
foreach(file dmft_config.ini inp.h5 ref.h5 test.py)
7070
FILE(COPY ${test}/${file} DESTINATION ${test_dir})
7171
endforeach()
72-
73-
add_test(NAME ${test}
72+
73+
add_test(NAME ${test}
7474
#COMMAND bash ${test}.sh
7575
COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_PREFLAGS} ${TRIQS_PYTHON_EXECUTABLE} test.py
7676
WORKING_DIRECTORY ${test_dir}
7777
)
78-
78+
7979
set_property(TEST ${test} APPEND PROPERTY ENVIRONMENT PYTHONPATH=${PROJECT_BINARY_DIR}/python:$ENV{PYTHONPATH})
8080
endforeach()
8181

test/python/test_maxent.py

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,51 @@
33

44
from helper import are_iterables_equal
55

6-
from solid_dmft.postprocessing import maxent_gf_imp, maxent_gf_latt
6+
from solid_dmft.postprocessing import maxent_gf_imp, maxent_gf_latt, maxent_sigma, pade_sigma
7+
8+
# Note: no unit tests here because lack of MPI support
79

810
# Runs maxent on lattice Green function and compares afterwards
9-
maxent_gf_latt.main('svo_hubbardI_basic/out/inp.h5', sum_spins=True, n_points_maxent=100, n_points_alpha=25, omega_min=-20, omega_max=20)
11+
mpi.report('#########\nTesting lattice Gf Maxent\n#########')
12+
maxent_gf_latt.main('svo_hubbardI_basic/out/inp.h5',
13+
sum_spins=True,
14+
n_points_maxent=100,
15+
n_points_alpha=25,
16+
omega_min=-20,
17+
omega_max=20)
1018

1119
# Runs maxent on the impurity Green function
1220
# No comparison to reference because the spectral function would be too "spiky"
1321
# because of HubbardI so that numerical differences can dominate the comparison
22+
mpi.report('#########\nTesting impurity Gf Maxent\n#########')
1423
maxent_gf_imp.main('svo_hubbardI_basic/out/inp.h5', sum_spins=True,
1524
n_points_maxent=50, n_points_alpha=20)
1625

1726
if mpi.is_master_node():
1827
print('Comparing Alatt_maxent')
19-
with HDFArchive('svo_hubbardI_basic/out/inp.h5', 'r')['DMFT_results']['last_iter'] as out, HDFArchive('svo_hubbardI_basic/ref.h5', 'r')['DMFT_results']['last_iter'] as ref:
20-
assert are_iterables_equal(out['Alatt_maxent'], ref['Alatt_maxent'])
28+
with HDFArchive('svo_hubbardI_basic/out/inp.h5', 'r') as out, HDFArchive('svo_hubbardI_basic/ref.h5', 'r') as ref:
29+
assert are_iterables_equal(out['DMFT_results']['last_iter']['Alatt_maxent'], ref['DMFT_results']['last_iter']['Alatt_maxent'])
30+
31+
# Run sigma maxent
32+
mpi.report('#########\nTesting Sigma Maxent\n#########')
33+
maxent_sigma.main(external_path='svo_hubbardI_basic/out/inp.h5',
34+
omega_min=-12, omega_max=12,
35+
maxent_error=0.001, iteration=None,
36+
n_points_maxent=50,
37+
n_points_alpha=10,
38+
analyzer='LineFitAnalyzer',
39+
n_points_interp=501,
40+
n_points_final=501,
41+
continuator_type='inversion_dc')[0]
42+
43+
44+
# Run sigma pade
45+
mpi.report('#########\nTesting Sigma Pade\n#########')
46+
pade_sigma.main(external_path='svo_hubbardI_basic/out/inp.h5',
47+
n_w = 4001,
48+
w_min=-4.5,
49+
w_max=4.5,
50+
n_iw=100,
51+
eta=0.0
52+
)
53+

0 commit comments

Comments
 (0)