|
| 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 | + |
0 commit comments