---
# System prepended metadata

title: Fortran Developer Documentation Main Page

---

# Fortran Developer Documentation Main Page

![](https://i.imgur.com/FXzNrNN.png)

This is the homepage for the Developer Documentation of the Fortran backend of _Dice_. On this site, you will find definitions for all of the functions and subroutines that we use to run VQMC simulations on our three currently implemented problems (QHO, H2plus and H2), as well as instructions for integrating support for a new problem into the code (see below).

### Links

| Link                                                                  | Destination               |
| --------------------------------------------------------------------- | ------------------------- |
| GitHub                  | [Here](https://github.com/HetSys/PX915_2021_A) |
| Dev Documentation Main    | [Here](https://joegilkes.github.io/PX915-Docs/)                       |
| Fortran Dev Documentation | You are here                                                          |
| Python Dev Documentation  | [Here](https://joegilkes.github.io/PX915-Docs/python/docs/index.html) |

---

### Adding a new problem to Dice Quantum Monte Carlo (QMC)

This section presents what the user would need to modify in the Fortran files (.f90) to add a new problem to Dice QMC. 

The first step is to add the derived type of the new problem to `shared_data.f90`, under the section "Derived Types". Below is a sample format of how the derived type should look like.

---

```fortran 
! Sample format of new derived type for new problem
type :: New_Problem_type
        integer(int32) :: steps=100000_int32         ! Total number of steps for each MMC chain
        integer(int32) :: burn_step=1000_int32       ! Number of steps to be burnt from the start of the MMC chain
        integer(int32) :: thin_step=10_int32         ! Interval of steps by which the MMC chain is thinned
        real(real64) :: rcut=3.0_real64              ! Maximum radius of search around the atoms             
        real(real64) :: sigma=1.8_real64             ! Standard deviation in MMC transition probability
        logical :: auto_params = .TRUE.              ! True runs the automatic gradient search and false runs the grid search
        real(real64) :: parameter_for_new_problem = 0.4_real64      ! One can add more than one parameter in the same format
        real(real64), dimension(3) :: parameter_grid = (/0,1,10/)   ! Grid of parameter values, format: [min, max, grid points]
        real(real64), dimension(3) :: bond = (/1,3,10/)             ! Grid of bondlength values, format: [min, max, grid points]
    end type H2_type
```
If the user wants to add any other numerical constants then they can be added to the `constants` module in `shared_data.f90`.

The next step is to modify `quantum_solvers.f90`. Regardless of the new problem the user will need to implement a function that calculates the transition probability of the current step and the proposed step. Below is a sample format of how the transition probability function should look like.

---

```fortran 
! Sample format of transition probability function
function Trans_Prob(parameters_of_new_problem, &
current_step, next_step, other_constants) result(Prob)

        implicit none

        real(real64), intent(in) :: parameters_of new_problem 
        real(real64), dimension(3), intent(in) :: current_step, next_step
        real(real64), dimension(:), intent(in) :: other_constants 

        real(real64) :: Prob

        Prob = ...

    end function Trans_Prob
```

The other function that is also necessary to be implemented regardless of the problem is one that calculates the local energy of the problem at a given position. Below is a sample format of how the local energy function should look like.

---
```fortran 
! Sample format of local energy function 
function Local_Energy(parameters_of_new_problem, &
position) result(E_loc)

        implicit none

        real(real64), intent(in), dimension(:) :: parameters
        real(real64), intent(in), dimension(:) :: position 

        real(real64) :: E_loc

        E_loc = ...

    end function Local_Energy
```

Most problems will require the user to implement a wave function corresponding to the problem, in order to calculate the transitional probabilities and local energies. The user is free to implement this however they want, as long as the local energy and transitional probability functions have the formats presented above. Another remark for the user is that when calculating the energy, unless the derivatives can be found analytically the user will need to use some numerical method to obtain the derivatives, which they will have to implement themselves. All of the modifications to `quantum_solvers.f90` should be done after the section `H_2 Solvers`.   

The next step is to modify the `vqmc.f90` module.  The user will need to implement a new VQMC solver for the new problem in this module. The user should use one of the "VQMC_QHO", "VQMC_H_2_plus" or "VQMC_H_2" sub-routines as a template for their VQMC solver. This is because they would only need to modify the transitional probability and local energy functions in the Metropolis algorithm. Below is a sample template of how the Metropolis algorithm should look like.

---
```fortran
! Metropolis Algorithm without burning and thinning for new problem
do i = 2, N            
    ...

    ! Modify here the function for transitional probability
    log_prob_n = log(Trans_Prob(parameters, X(i-1), X_n(1)))
            
    ...
            
    ! Compare the drawn sample from the uniform distribution with the acceptance ratio 
    if (a_prob_trans >= unif_num) then 
        ...
        ! Modify here the function for local energy  
        energy_chain(i) = Local_Energy(parameters, X_n(1))
    else 
        ... 
        
        ! Modify here the function for local energy
        energy_chain(i) = Local_Energy(parameters, X(i-1))
    end if 
end do
```
If the user uses one of the "VQMC_QHO", "VQMC_H_2_plus" or "VQMC_H_2" sub-routines as a template then the burning and thinning features can be reused for the new problem. It is important to stick to one of the VQMC sub-routines so that the outputs are the same. 

The next step is to add the automatic gradient descent-based search (GDBS) to `vqmc.f90`. The user should use "Auto_H_2", "Auto_H_2_plus" sub-routines as a template and should only modify the VQMC solver being called (see below). This modification should be place after the new VQMC solver.

---
```fortran
subroutine Auto_H_2(...)
        ...
        ! Main iteration loop
        do k = cauto_start, maxiter

            ! Calculate gradient at current beta
            ! This should be modified to the VQMC
            ! solver that user created in the 
            ! last step.
            call VQMC_H_2(...)
        ...
        end do 
        
end subroutine Auto_H_2
```
If the user does not want to do a GDBS then they can ignore the previous step. Instead they can add a grid search to `vqmc.f90`. The user should use "Grid_H_2", "Grid_H_2_plus" sub-routines as a template and should only modify the VQMC solver being called (see below). This sub-routine should be placed after the new VQMC solver.

---
```fortran
subroutine Grid_H_2_plus(...)
        ...
    ! Loop over c values
    do i = cgrid_start, size(c_array)

        ! Calculate energy at current value of c
        ! This should be modified to the VQMC
        ! solver that user created in the 
        ! last step.
        call VQMC_H_2_plus(...)
        ...
    end do
    ...
end subroutine Grid_H_2_plus
```
The user can of course add both of the search methods mentioned above, but it is important that they at least add one. The final item the user has to add to `vqmc.f90` is the equilibration run subroutine. This can be based off "Equil_QHO" or "Equil_H_2" and the user should only modify the VQMC solver being used like in the previous step.  


The final step is to modify `driver.f90`. The user should add a new case with the corresponding problem to the "VQMC Loops" section. The user should use the following "Quantum Harmonic Oscillator" subsection, as a template to write their code. The code should only be modified so that the GDBS or grid search, and equilibration subroutines for the new problem are called (see below).

---
```fortran
case('New_problem')
    ...
    ! Loop over bond lengths
    do b = 1, int(H2plus%bond(3))
        ...
        ! Main VQMC callers
        if (.not. run_equil) then
            if (H2plus%auto_params) then
            ! Search for best param at this bond length
            ! This should be modified to the 
            ! GDBS sub-routine for this problem
            call Auto_H_2_plus(...)
            ...
            else

            ! Find best param in grid at this bond length
            ! This should be modified to the 
            ! Grid search routine for this problem 
            call Grid_H_2_plus(...)

            end if
        ...
        end if 
        ...
        if 
            ...
        else
            ! Run equilibrations serially on rank 0
            if (my_rank==0) then
                ! This shoud be modified to 
                ! the equilibration sub_routine 
                ! for this new problem
                call Equil_H_2_plus(...)
            ...
        end if
    ...
    end do
...        
```

After all the modifications the user should be able to run the code the same way as it is explained in the user manual. 

