Skip to content

Latest commit

 

History

History
154 lines (121 loc) · 6.49 KB

README.md

File metadata and controls

154 lines (121 loc) · 6.49 KB

hubbard-model-ed

This repository contains an exact diagonalization implementation for the Hubbard model (in the approximation of 1D spins chain with first neigbohrs hopping terms using periodic boundary conditions) defined as $$H = H_t + H_U = -t\sum_{\langle i, j\rangle, \sigma}(c^\dagger_{i\sigma}c_{j\sigma} + h.c.) + U\sum_i n_{i\uparrow}n_{i\downarrow},$$ where $c^\dagger$ and $c$ are respectively the second quantization creation/anihilation operators and where $n$ represents the number operator from the same formalism. The code is entirely written in Rust and will eventually be parallelized using rayon Rust crate.

Rust

Build LICENSE release

Table of contents

Requirements

Rust

I recommend having a version of cargo >= 1.70.0 and Rust compiler rustc >= 1.70.0 to use this crate. If you don't know what version you have, run the following commands

cargo version && rustc --version

If you want to update them anyways, just run the command

rustup update

and it will upgrade the version of your Rust compiler, package manager, documentation and etc.

LAPACK and BLAS

Users must also have a version of LAPACK (Linear Algebra PACKage) and BLAS (Basic Linear Algebra Subprograms) on their computers. For Mac users, you can install it directly using Homebrew and the commands

brew install lapack openblas

For additionnal details on installation I suggest to check for online support such as: linux, and windows.

Installation

To use the program, users should clone this repository on their computer using the command

git clone https://github.com/BCarnaval/hubbard_model_ed

Then build the binairies using cargo by executing the command

cargo build -r

at the root of the project. This command should use the build script to find LAPACK and BLAS and then link it inside the compiler. If the build succeed, you shoud also be able to verify if the unit tests are running properly on your machine by running the command

cargo test

at the root of the project. If all the tests pass, you are ready to use the program!

Usage

Compute eigenvalues

To modify the entry parameters for the 1D spins chain, users must edit the main function inside main.rs script. It is very simple

// Main module. This is where one should create and solve the Hubbard
// model for given parameters.
mod array_utils;
mod file_utils;
mod fock_space;

use crate::fock_space::Hubbard;
use std::println;
use std::time::Instant;

fn main() {
    let now = Instant::now();
    let hubbard_model = Hubbard {
        n_sites: 7,
        t: 1.,
        u: 2.,
    };
    hubbard_model.get_eigenvalues();
    println!("Time elapsed: {:.2?}", now.elapsed());
}

The parameter named n_sites determines how many sites are considered in the chain, the parameter t the hopping amplitude for the first neighbors and u the on-site interaction amplitude. Once the parameters are setted, run the programm using

cargo run -r

to save the eigenvalues of the hamiltonian inside ./Data/eigen_values.csv data file.

Visualise blocks

To visualise the different blocks of the block diagonal hamiltonian, one can use the function build_tri_up_array from the module ./src/array_utils.rs. Simply call the function inside the module ./src/fock_space.rs when computing matrix elements of the different blocks1

/// Outputs the eigenvalues of Hubbard hamiltonian by diagonalizing all
/// of it's blocks using LAPACK 'sspevd' Fortran implementation.
///
/// The eigenvalues are saved and stored inside './Data/eigen_vals.csv'.
pub fn get_eigenvalues(&self) {
    // Data file initialization (csv)
    let data_path: String = String::from("./Data/eigen_values.csv");
    let mut eig_wtr: csv::Writer<std::fs::File> = init_file_writter(&data_path, false);

    // Vector containing the blocs of the matrix & already visited states
    let mut visited: Vec<i32> = Vec::new();
    let mut blocks: Vec<Vec<i32>> = Vec::new();

    // Main loop over Fock space states (4^(n_sites))
    for state_i in 0..(4 as i32).pow(self.n_sites) {
        // Verifying if the state was already used
        if !visited.contains(&state_i) {
            // State bank from 'state_i;
            let (sub_block, matrix_elems) = self.find_sub_block(state_i);
            
            // ADD THE FOLLOWING
            println!("{:?}\n", build_tri_up_array(&matrix_elems));
            
            let (_success, eigen_vals): (i32, Vec<f32>) = lapack_diagonalization(matrix_elems);
            
            eig_wtr.serialize(eigen_vals).unwrap();

            // Building already visited states list
            let mut filtered: Vec<i32> = sub_block.clone();
            filtered.retain(|i: &i32| !visited.contains(i));
            visited.append(&mut filtered);
            blocks.push(sub_block);
        } else {
            continue;
        }
    }
}

and it will print all the differents blocks of the hamiltonian that are diagonalized to find the eigenvalues.

Todo

  • Complete the README.md
  • Include periodic boundary conditions to hoppings operator (phase correction)
  • Save eigenvalues based on filling (hamiltonian blocks)
  • Save Hamiltonian blocks in text file
  • Include parallel computing using rayon
  • Comment the code base
  • Unit testing

Footnotes

  1. Don't forget to import the crate array_utils.rs at the top of ./src/fock_space.rs in order to call the function. Use the code line: use crate::array_utils::build_tri_up_array;.