# perturbation

All subroutines in `*.irp.f` starting with `pt2_` in the current directory are perturbation computed using the routine `i_H_psi`. Other cases are not allowed. The arguments of the `pt2_` are always:

    subroutine pt2_...(                                          &
        psi_ref,                                                 &
        psi_ref_coefs,                                           &
        E_refs,                                                  &
        det_pert,                                                &
        c_pert,                                                  &
        e_2_pert,                                                &
        H_pert_diag,                                             &
        Nint,                                                    &
        Ndet,                                                    &
        N_st )

    integer          , intent(in)  :: Nint,Ndet,N_st
    integer(bit_kind), intent(in)  :: psi_ref(Nint,2,Ndet)
    double precision , intent(in)  :: psi_ref_coefs(Ndet,N_st)
    double precision , intent(in)  :: E_refs(N_st)
    integer(bit_kind), intent(in)  :: det_pert(Nint,2)
    double precision , intent(out) :: c_pert(N_st),e_2_pert(N_st),H_pert_diag

`psi_ref`
  bitstring of the determinants present in the various `N_st` states
`psi_ref_coefs`
  coefficients of the determinants on the various `N_st` states
`E_refs`
  Energy of the various `N_st` states
`det_pert`
  Perturber determinant
`c_pert`
  Perturbative coefficients for the various states
`e_2_pert`
  Perturbative energetic contribution for the various states
`H_pert_diag`
  Diagonal \(\hat H\) matrix element of the perturber
`Nint`
  Should be equal to `N_int`
`Ndet`
  Number of determinants `i` in \(|\Psi \rangle\) on which we apply <det_pert | \(\hat H\) | `i`>
`N_st`
  Number of states

## EZFIO parameters

`do_pt2```

  If `True`, compute the PT2 contribution

  Default: True

`pt2_max```

  The selection process stops when the largest PT2 (for all the state) is lower

  than `pt2_max` in absolute value

  Default: 0.0001

`pt2_relative_error```

  Stop stochastic PT2 when the relative error is smaller than `PT2_relative_error`

  Default: 0.002

`correlation_energy_ratio_max```

  The selection process stops at a fixed correlation ratio (useful for getting same accuracy between molecules).

  Defined as \({E_{CI}-E_{HF}}/{E_{CI}+E_{PT2} - E_{HF}}\).

  Default: 1.00

## Providers

`fill_h_apply_buffer_selection:`()

  > File : `perturbation/selection.irp.f`

  >     subroutine fill_H_apply_buffer_selection(n_selected,det_buffer,e_2_pert_buffer,coef_pert_buffer, &

  N_st,Nint,iproc,select_max_out)

  > Fill the H_apply buffer with determiants for the selection

  > Needs:

  > `selection_criterion` `h_apply_buffer_allocated` | `n_det` | `n_int`

  > Calls:

  > `omp_set_lock()` | `omp_unset_lock()` | `resize_h_apply_buffer()`

`h0_type`

  File : `perturbation/h0_type.irp.f`

      character*32    :: h0_type

  Type of zeroth-order Hamiltonian

  Needs:

  `s2_eig` |  |

  Needed by:

  `pt2_e0_denominator` |  |

`max_exc_pert`

  File : `perturbation/exc_max.irp.f`

      integer :: max_exc_pert

`selection_criterion`

  File : `perturbation/selection.irp.f`

      double precision        :: selection_criterion
      double precision        :: selection_criterion_min
      double precision        :: selection_criterion_factor

  Threshold to select determinants. Set by selection routines.

`selection_criterion_factor`

  File : `perturbation/selection.irp.f`

      double precision        :: selection_criterion
      double precision        :: selection_criterion_min
      double precision        :: selection_criterion_factor

  Threshold to select determinants. Set by selection routines.

`selection_criterion_min`

  File : `perturbation/selection.irp.f`

      double precision        :: selection_criterion
      double precision        :: selection_criterion_min
      double precision        :: selection_criterion_factor

  Threshold to select determinants. Set by selection routines.

`var_pt2_ratio`

  File : `perturbation/var_pt2_ratio_provider.irp.f`

      double precision        :: var_pt2_ratio

  The selection process stops when the energy ratio variational/(variational+PT2) is equal to var_pt2_ratio

  Needs:

  `correlation_energy_ratio_max` |  |

## Subroutines / functions

`perturb_buffer_by_mono_dummy:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_by_mono_dummy(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``dummy`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `mo_num` `psi_selectors` | `n_det` `n_det_selectors` | `n_det_generators` `psi_det_generators`

  Calls:

  `create_minilist()` | `create_minilist_find_previous()` | `pt2_dummy()`

`perturb_buffer_by_mono_epstein_nesbet:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_by_mono_epstein_nesbet(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``epstein_nesbet`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `mo_num` `psi_selectors` | `n_det` `n_det_selectors` | `n_det_generators` `psi_det_generators`

  Calls:

  `create_minilist()` | `create_minilist_find_previous()` | `pt2_epstein_nesbet()`

`perturb_buffer_by_mono_epstein_nesbet_2x2:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_by_mono_epstein_nesbet_2x2(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``epstein_nesbet_2x2`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `mo_num` `psi_selectors` | `n_det` `n_det_selectors` | `n_det_generators` `psi_det_generators`

  Calls:

  `create_minilist()` | `create_minilist_find_previous()` | `pt2_epstein_nesbet_2x2()`

`perturb_buffer_by_mono_epstein_nesbet_2x2_no_ci_diag:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_by_mono_epstein_nesbet_2x2_no_ci_diag(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``epstein_nesbet_2x2_no_ci_diag`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `mo_num` `psi_selectors` | `n_det` `n_det_selectors` | `n_det_generators` `psi_det_generators`

  Calls:

  `create_minilist()` | `create_minilist_find_previous()` | `pt2_epstein_nesbet_2x2_no_ci_diag()`

`perturb_buffer_by_mono_moller_plesset:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_by_mono_moller_plesset(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``moller_plesset`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `mo_num` `psi_selectors` | `n_det` `n_det_selectors` | `n_det_generators` `psi_det_generators`

  Calls:

  `create_minilist()` | `create_minilist_find_previous()` | `pt2_moller_plesset()`

`perturb_buffer_by_mono_qdpt:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_by_mono_qdpt(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``qdpt`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `mo_num` `psi_selectors` | `n_det` `n_det_selectors` | `n_det_generators` `psi_det_generators`

  Calls:

  `create_minilist()` | `create_minilist_find_previous()` | `pt2_qdpt()`

`perturb_buffer_dummy:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_dummy(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``dummy`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `n_det_selectors` `n_det_generators` | `psi_selectors` `psi_det_generators` | `mo_num`

  Calls:

  `create_microlist()` `create_minilist()` | `create_minilist_find_previous()` `getmobiles()` | `pt2_dummy()`

`perturb_buffer_epstein_nesbet:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_epstein_nesbet(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``epstein_nesbet`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `n_det_selectors` `n_det_generators` | `psi_selectors` `psi_det_generators` | `mo_num`

  Calls:

  `create_microlist()` `create_minilist()` | `create_minilist_find_previous()` `getmobiles()` | `pt2_epstein_nesbet()`

`perturb_buffer_epstein_nesbet_2x2:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_epstein_nesbet_2x2(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``epstein_nesbet_2x2`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `n_det_selectors` `n_det_generators` | `psi_selectors` `psi_det_generators` | `mo_num`

  Calls:

  `create_microlist()` `create_minilist()` | `create_minilist_find_previous()` `getmobiles()` | `pt2_epstein_nesbet_2x2()`

`perturb_buffer_epstein_nesbet_2x2_no_ci_diag:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_epstein_nesbet_2x2_no_ci_diag(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``epstein_nesbet_2x2_no_ci_diag`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `n_det_selectors` `n_det_generators` | `psi_selectors` `psi_det_generators` | `mo_num`

  Calls:

  `create_microlist()` `create_minilist()` | `create_minilist_find_previous()` `getmobiles()` | `pt2_epstein_nesbet_2x2_no_ci_diag()`

`perturb_buffer_moller_plesset:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_moller_plesset(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``moller_plesset`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `n_det_selectors` `n_det_generators` | `psi_selectors` `psi_det_generators` | `mo_num`

  Calls:

  `create_microlist()` `create_minilist()` | `create_minilist_find_previous()` `getmobiles()` | `pt2_moller_plesset()`

`perturb_buffer_qdpt:`()

  File : `perturbation/perturbation.irp.f_shell_13`

         subroutine perturb_buffer_qdpt(i_generator,buffer,buffer_size,e_2_pert_buffer,coef_pert_buffer,sum_e_2_pert,sum_norm_pert,sum_H_pert_diag,N_st,Nint,key_mask,fock_diag_tmp,electronic_energy)

      Applly pertubration ``qdpt`` to the buffer of determinants generated in the H_apply

  routine.

  Needs:

  `n_det_selectors` `n_det_generators` | `psi_selectors` `psi_det_generators` | `mo_num`

  Calls:

  `create_microlist()` `create_minilist()` | `create_minilist_find_previous()` `getmobiles()` | `pt2_qdpt()`

`pt2_dummy:`()

  File : `perturbation/pt2_equations.irp.f_template_305`

      subroutine pt2_dummy (electronic_energy,det_ref,det_pert,fock_diag_tmp,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st,minilist,idx_minilist,N_minilist)

  Dummy perturbation to add all connected determinants.

  Needs:

  `n_det_selectors` `selection_criterion` | `psi_selectors` `psi_selectors_size` | `mo_num`

  Called by:

  `perturb_buffer_by_mono_dummy()` | `perturb_buffer_dummy()` |

  Calls:

  `i_h_psi_minilist()` |  |

`pt2_epstein_nesbet:`()

  File : `perturbation/pt2_equations.irp.f_template_305`

      subroutine pt2_epstein_nesbet (electronic_energy,det_ref,det_pert,fock_diag_tmp,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st,minilist,idx_minilist,N_minilist)

  Compute the standard Epstein-Nesbet perturbative first order coefficient and second order energetic contribution for the various N_st states.

  `c_pert(i)` = $frac{langle i|H|alpha rangle}{ E_n - langle alpha|H|alpha rangle }$.

  `e_2_pert(i)` = $frac{langle i|H|alpha rangle^2}{ E_n - langle alpha|H|alpha rangle }$.

  Needs:

  `n_det_selectors` `selection_criterion` | `psi_selectors` `psi_selectors_size` | `mo_num`

  Called by:

  `perturb_buffer_by_mono_epstein_nesbet()` | `perturb_buffer_epstein_nesbet()` |

  Calls:

  `i_h_psi_minilist()` |  |

`pt2_epstein_nesbet_2x2:`()

  File : `perturbation/pt2_equations.irp.f_template_305`

      subroutine pt2_epstein_nesbet_2x2 (electronic_energy,det_ref,det_pert,fock_diag_tmp,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st,minilist,idx_minilist,N_minilist)

  Computes the Epstein-Nesbet 2x2 diagonalization coefficient and energetic contribution for the various N_st states.

  `e_2_pert(i)` = $frac{1}{2} ( langle alpha|H|alpha rangle - E_n) - sqrt{ (langle alpha|H|alpha rangle - E_n)^2 + 4 langle i|H|alpha rangle^2 }$.

  `c_pert(i)` = `e_2_pert(i)` $times frac{1}{ langle i|H|alpha rangle}$.

  Needs:

  `n_det_selectors` `psi_selectors` | `psi_selectors_size` | `mo_num`

  Called by:

  `perturb_buffer_by_mono_epstein_nesbet_2x2()` | `perturb_buffer_epstein_nesbet_2x2()` |

  Calls:

  `i_h_psi()` |  |

`pt2_epstein_nesbet_2x2_no_ci_diag:`()

  File : `perturbation/pt2_equations.irp.f_template_305`

      subroutine pt2_epstein_nesbet_2x2_no_ci_diag(electronic_energy,det_ref,det_pert,fock_diag_tmp,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st,minilist,idx_minilist,N_minilist)

  compute the Epstein-Nesbet 2x2 diagonalization coefficient and energetic contribution

  for the various N_st states.

  e_2_pert(i) = 0.5 * (( <det_pert|H|det_pert> - E(i) ) - sqrt( ( <det_pert|H|det_pert> - E(i)) ^2 + 4 <psi(i)|H|det_pert>^2 )

  c_pert(i) = e_2_pert(i)/ <psi(i)|H|det_pert>

  Needs:

  `n_det_selectors` `psi_selectors` | `psi_selectors_size` `psi_energy` | `mo_num`

  Called by:

  `perturb_buffer_by_mono_epstein_nesbet_2x2_no_ci_diag()` | `perturb_buffer_epstein_nesbet_2x2_no_ci_diag()` |

  Calls:

  `i_h_psi()` |  |

`pt2_moller_plesset:`()

  File : `perturbation/pt2_equations.irp.f_template_305`

      subroutine pt2_moller_plesset (electronic_energy,det_ref,det_pert,fock_diag_tmp,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st,minilist,idx_minilist,N_minilist)

  Computes the standard Moller-Plesset perturbative first order coefficient and second order energetic contribution for the various N_st states.

  `c_pert(i)` = $frac{langle i|H|alpha rangle}{text{difference of orbital energies}}$.

  `e_2_pert(i)` = $frac{langle i|H|alpha rangle^2}{text{difference of orbital energies}}$.

  Needs:

  `ref_bitmask` `psi_selectors_size` | `psi_selectors` `mo_num` | `n_det_selectors` `fock_matrix_mo`

  Called by:

  `perturb_buffer_by_mono_moller_plesset()` | `perturb_buffer_moller_plesset()` |

  Calls:

  `decode_exc()` | `get_excitation()` | `i_h_psi_minilist()`

`pt2_qdpt:`()

  File : `perturbation/pt2_equations.irp.f_template_305`

      subroutine pt2_qdpt (electronic_energy,det_ref,det_pert,fock_diag_tmp,c_pert,e_2_pert,H_pert_diag,Nint,ndet,N_st,minilist,idx_minilist,N_minilist)

  Computes the QDPT first order coefficient and second order energetic contribution for the various N_st states.

  `c_pert(i)` = $frac{langle i|H|alpha rangle}{langle i|H|i rangle - langle alpha|H|alpha rangle}$.

  Needs:

  `n_det_selectors` `selection_criterion` | `psi_selectors` `psi_selectors_size` | `mo_num`

  Called by:

  `perturb_buffer_by_mono_qdpt()` | `perturb_buffer_qdpt()` |

  Calls:

  `get_excitation_degree()` | `i_h_j()` | `i_h_psi_minilist()`

`remove_small_contributions:`()

  File : `perturbation/selection.irp.f`

      subroutine remove_small_contributions

  Remove determinants with small contributions. N_states is assumed to be provided.

  Needs:

  `psi_coef` `selection_criterion` `n_states` `n_det` | `psi_det_size` `n_det_generators` `n_int` | `psi_det_sorted` `psi_det` `psi_det_sorted`

  Calls:

  `diagonalize_ci()` | `i_h_psi()` | `write_int()`

  Touches:

  `ci_electronic_energy` `ci_electronic_energy` `ci_energy` | `ci_electronic_energy` `n_det` | `psi_coef` `psi_det`