From 76a268cf77ccaada4651606ea7c49c30f12baebf Mon Sep 17 00:00:00 2001 From: Alexander Hampel Date: Fri, 26 Jan 2024 13:05:44 -0500 Subject: [PATCH] [feat] respack fit slater for p shell allow to use the respack fit slater routine for l=1 (p-shells) rename fit_slater_fulld -> fit_slater --- .../postprocessing/eval_U_cRPA_RESPACK.py | 25 ++++++++----- test/python/test_respack_sfo.py | 37 ++++++++++++------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/python/solid_dmft/postprocessing/eval_U_cRPA_RESPACK.py b/python/solid_dmft/postprocessing/eval_U_cRPA_RESPACK.py index 11efd7bd..df18d26b 100644 --- a/python/solid_dmft/postprocessing/eval_U_cRPA_RESPACK.py +++ b/python/solid_dmft/postprocessing/eval_U_cRPA_RESPACK.py @@ -219,16 +219,16 @@ def construct_Uijkl(Uijij, Uiijj): return Uijkl -def fit_slater_fulld(u_ijij_crpa, u_ijji_crpa, U_init, J_init, fixed_F4_F2=True): +def fit_slater(u_ijij_crpa, u_ijji_crpa, U_init, J_init, fixed_F4_F2=True): ''' finds best Slater parameters U, J for given Uijij and Uijji matrices using the triqs U_matrix operator routine assumes F4/F2=0.625 Parameters: ----------- - u_ijij_crpa: np.ndarray of shape (5, 5) + u_ijij_crpa: np.ndarray of shape (3,3) or (5, 5) Uijij matrix - u_ijji_crpa: np.ndarray of shape (5, 5) + u_ijji_crpa: np.ndarray of shape (3,3) or (5, 5) Uijji matrix U_init: float inital value of U for optimization @@ -248,12 +248,18 @@ def fit_slater_fulld(u_ijij_crpa, u_ijji_crpa, U_init, J_init, fixed_F4_F2=True) from scipy.optimize import minimize # input checks - assert u_ijij_crpa.shape == (5, 5), 'fit slater only implemented for full d shell (5 orbitals)' - assert u_ijji_crpa.shape == (5, 5), 'fit slater only implemented for full d shell (5 orbitals)' + if u_ijij_crpa.shape == (3,3): + l=1 + # for p shell there are only 2 parameters + fixed_F4_F2 = True + elif u_ijij_crpa.shape == (5,5): + l=2 + else: + raise ValueError('fit slater only implemented for full p or d shell') def minimizer(parameters): U_int, J_hund = parameters - Umat_full = U_matrix_slater(l=2, U_int=U_int, J_hund=J_hund, basis='spherical') + Umat_full = U_matrix_slater(l=l, U_int=U_int, J_hund=J_hund, basis='spherical') Umat_full = transform_U_matrix(Umat_full, T) Umat, u_ijij_slater = reduce_4index_to_2index(Umat_full) @@ -261,8 +267,7 @@ def minimizer(parameters): return np.sum((u_ijji_crpa - u_iijj_slater)**2 + (u_ijij_crpa - u_ijij_slater)**2) def minimizer_radial(parameters): - F0, F2, F4 = parameters - Umat_full = U_matrix_slater(l=2, radial_integrals=[F0, F2, F4], basis='spherical') + Umat_full = U_matrix_slater(l=l, radial_integrals=parameters, basis='spherical') Umat_full = transform_U_matrix(Umat_full, T) Umat, u_ijij_slater = reduce_4index_to_2index(Umat_full) @@ -270,7 +275,7 @@ def minimizer_radial(parameters): return np.sum((u_ijji_crpa - u_iijj_slater)**2 + (u_ijij_crpa - u_ijij_slater)**2) # transformation matrix from spherical to w90 basis - T = spherical_to_cubic(l=2, convention='wannier90') + T = spherical_to_cubic(l=l, convention='wannier90') if fixed_F4_F2: result = minimize(minimizer, (U_init, J_init)) @@ -284,7 +289,7 @@ def minimizer_radial(parameters): F2 = J_init * 14.0 / (1.0 + 0.63) F4 = 0.630 * F2 - initial_guess = (F0, F2, F4) + initial_guess = [F0, F2, F4] print('Initial guess: F0 = {0[0]:.3f} eV, F2 = {0[1]:.3f} eV, F4 = {0[2]:.3f} eV'.format(initial_guess)) diff --git a/test/python/test_respack_sfo.py b/test/python/test_respack_sfo.py index 19fd358a..ea76ae88 100644 --- a/test/python/test_respack_sfo.py +++ b/test/python/test_respack_sfo.py @@ -19,7 +19,7 @@ from itertools import product from h5 import HDFArchive -from solid_dmft.postprocessing.eval_U_cRPA_RESPACK import read_interaction, fit_slater_fulld +from solid_dmft.postprocessing.eval_U_cRPA_RESPACK import read_interaction, fit_slater from solid_dmft.postprocessing.eval_U_cRPA_Vasp import fit_slater_fulld as fit_slater_vasp from triqs.operators.util.U_matrix import transform_U_matrix @@ -38,10 +38,10 @@ def setUp(self): def test_U_J_fit(self): print('------------') print('Fitting screened interaction with fixed F4/F2 ratio') - U_int, J_int = fit_slater_fulld(self.res.Uijij.real, - self.res.Uijji.real, - U_init=2, J_init=1, - fixed_F4_F2=True) + U_int, J_int = fit_slater(self.res.Uijij.real, + self.res.Uijji.real, + U_init=2, J_init=1, + fixed_F4_F2=True) assert abs(U_int - 1.6087813069026353) < 1e-4 assert abs(J_int - 0.6085825226244702) < 1e-4 @@ -55,23 +55,34 @@ def test_U_J_fit(self): print('------------') print('Fitting bare interaction with fixed F4/F2 ratio') - U_int, J_int = fit_slater_fulld(self.res.Vijij.real, - self.res.Vijji.real, - U_init=1.7, J_init=0.7, - fixed_F4_F2=True) + U_int, J_int = fit_slater(self.res.Vijij.real, + self.res.Vijji.real, + U_init=1.7, J_init=0.7, + fixed_F4_F2=True) assert abs(U_int - 13.169980952573283) < 1e-4 assert abs(J_int - 0.7852793988793887) < 1e-4 return + def test_U_J_fit_p(self): + print('------------') + print('Fitting screened interaction for p-shell with fixed F4/F2 ratio') + print(self.res.Uijij.real[:3,:3]) + U_int, J_int = fit_slater(self.res.Uijij.real[:3,:3], + self.res.Uijji.real[:3,:3], + U_init=2, J_init=1, + fixed_F4_F2=True) + assert abs(U_int - 1.7803822) < 1e-4 + assert abs(J_int - 0.6158827) < 1e-4 + def test_F0_F2_F4_fit(self): print('------------') print('Fitting screened interaction to F0, F2, F4') - U_int, J_int = fit_slater_fulld(self.res.U_R[(0, 0, 0)].real, - self.res.J_R[(0, 0, 0)].real, - U_init=13, J_init=1, - fixed_F4_F2=False) + U_int, J_int = fit_slater(self.res.U_R[(0, 0, 0)].real, + self.res.J_R[(0, 0, 0)].real, + U_init=13, J_init=1, + fixed_F4_F2=False) assert abs(U_int - 1.6072376926602756) < 1e-4 assert abs(J_int - 0.6166868032423679) < 1e-4