From 1deb3b242360ff5a31b0a1164393ef214cd61f72 Mon Sep 17 00:00:00 2001 From: Antonio Manesco <am@antoniomanesco.org> Date: Tue, 19 Dec 2023 22:48:03 +0100 Subject: [PATCH] add real-space solver --- codes/hf.py | 83 +++++++++++++++++++++++++---------------------------- 1 file changed, 39 insertions(+), 44 deletions(-) diff --git a/codes/hf.py b/codes/hf.py index 254f1fb..4e4fb62 100644 --- a/codes/hf.py +++ b/codes/hf.py @@ -2,7 +2,7 @@ from scipy.ndimage import convolve import numpy as np import codes.utils as utils from functools import partial -from scipy.optimize import anderson, minimize +from scipy import optimize def density_matrix(vals, vecs, E_F): """ @@ -158,7 +158,7 @@ def updated_matrices(mf_k, model): rho = density_matrix(vals=vals, vecs=vecs, E_F=E_F) return rho, compute_mf(rho=rho, H_int=model.H_int) - E_F * np.eye(model.hamiltonians_0.shape[-1]) -def default_cost(mf, model): +def rspace_solver(model, optimizer, optimizer_kwargs): """ Default cost function. @@ -177,29 +177,36 @@ def default_cost(mf, model): * Non-hermitian part of the mean-field correction. * The commutator between the mean-field Hamiltonian and density matrix. """ - mf_dict = {} - for i, key in enumerate(model.guess.keys()): - mf_dict[key] = mf[i] - mf = utils.kgrid_hamiltonian( - nk=model.nk, - hk=utils.model2hk(mf_dict), - dim=model.dim, - hermitian=False + model.kgrid_evaluation(nk=model.nk) + mf = np.array([*model.guess.values()]) + shape = mf.shape + + def cost_function(mf): + mf = utils.flat_to_matrix(utils.real_to_complex(mf), shape) + mf_dict = {} + for i, key in enumerate(model.guess.keys()): + mf_dict[key] = mf[i] + mf = utils.kgrid_hamiltonian( + nk=model.nk, + hk=utils.model2hk(mf_dict), + dim=model.dim, + hermitian=False + ) + model.rho, model.mf_k = updated_matrices(mf_k=mf, model=model) + model.energy = total_energy(h=model.hamiltonians_0 + model.mf_k, rho=model.rho) + delta_mf = model.mf_k - mf + delta_mf = utils.hk2tb_model(delta_mf, model.vectors, model.ks) + delta_mf = np.array([*delta_mf.values()]) + return utils.matrix_to_flat(utils.complex_to_real(delta_mf)) + + _ = optimizer( + cost_function, + utils.matrix_to_flat(utils.complex_to_real(mf)), + **optimizer_kwargs ) - model.rho, model.mf_k = updated_matrices(mf_k=mf, model=model) - model.energy = total_energy(h=model.hamiltonians_0 + model.mf_k, rho=model.rho) - h = model.hamiltonians_0 + model.mf_k - commutator = (h@model.rho - model.rho@h) - n_herm = (mf - np.moveaxis(mf, -1, -2).conj())/2 - delta_mf = model.mf_k - mf - n_herm = [*utils.hk2tb_model(n_herm, model.vectors, model.ks).values()] - commutator = [*utils.hk2tb_model(commutator, model.vectors, model.ks).values()] - delta_mf = [*utils.hk2tb_model(delta_mf, model.vectors, model.ks).values()] - quantities = np.array([commutator, delta_mf, n_herm]) - idx_max = np.argmax(np.linalg.norm(quantities.reshape(3, -1), axis=-1)) - return quantities[idx_max] - -def kspace_solver(model, nk, optimizer, optimizer_kwargs): + + +def kspace_solver(model, optimizer, optimizer_kwargs): """ Default cost function. @@ -218,7 +225,7 @@ def kspace_solver(model, nk, optimizer, optimizer_kwargs): * Non-hermitian part of the mean-field correction. * The commutator between the mean-field Hamiltonian and density matrix. """ - model.kgrid_evaluation(nk=nk) + model.kgrid_evaluation(nk=model.nk) def cost_function(mf): mf = utils.flat_to_matrix(utils.real_to_complex(mf), model.mf_k.shape) model.rho, model.mf_k = updated_matrices(mf_k=mf, model=model) @@ -226,25 +233,12 @@ def kspace_solver(model, nk, optimizer, optimizer_kwargs): delta_mf = model.mf_k - mf return utils.matrix_to_flat(utils.complex_to_real(delta_mf)) - mf = optimizer( + _ = optimizer( cost_function, utils.matrix_to_flat(utils.complex_to_real(model.mf_k)), **optimizer_kwargs ) - mf = utils.flat_to_matrix(utils.real_to_complex(mf), model.mf_k.shape) - h = model.hamiltonians_0 + model.mf_k - commutator = (h@model.rho - model.rho@h) - while np.invert(np.isclose(commutator, 0, atol=1e-15)).all(): - model.random_guess(model.vectors) - model.kgrid_evaluation(nk=nk) - mf = optimizer( - cost_function, - utils.matrix_to_flat(utils.complex_to_real(model.mf_k)), - **optimizer_kwargs - ) - mf = utils.flat_to_matrix(utils.real_to_complex(mf), model.mf_k.shape) - h = model.hamiltonians_0 + mf - commutator = (h@model.rho - model.rho@h) + def find_groundstate_ham( @@ -253,8 +247,8 @@ def find_groundstate_ham( filling, nk=10, solver=kspace_solver, - optimizer=anderson, - optimizer_kwargs={'M':0}, + optimizer=optimize.anderson, + optimizer_kwargs={'verbose': False}, ): """ Self-consistent loop to find groundstate Hamiltonian. @@ -280,9 +274,10 @@ def find_groundstate_ham( model.nk=nk model.filling=filling vectors = utils.generate_vectors(cutoff_Vk, model.dim) - model.vectors=[*vectors, *model.tb_model.keys()] + model.vectors=[*model.int_model.keys()] if model.guess is None: model.random_guess(model.vectors) - solver(model, nk, optimizer, optimizer_kwargs) + solver(model, optimizer, optimizer_kwargs) + model.vectors=[*model.int_model, *model.tb_model.keys()] assert np.allclose((model.mf_k - np.moveaxis(model.mf_k, -1, -2).conj())/2, 0, atol=1e-15) return utils.hk2tb_model(model.hamiltonians_0 + model.mf_k, model.vectors, model.ks) -- GitLab