# mo_two_e_ints

Here, all two-electron integrals (\(1/r_{12}\)) are computed. As they have 4 indices and many are zero, they are stored in a map, as defined in `Utils/map_module.f90`.

To fetch an AO integral, use the `get_ao_two_e_integral(i,j,k,l,ao_integrals_map)` function, and to fetch an MO integral, use `get_two_e_integral(i,j,k,l,mo_integrals_map)` or `mo_two_e_integral(i,j,k,l)`.

The conventions are:

- For AO integrals : (ik|jl) = (11|22)
- For MO integrals : <ij|kl> = <12|12>

## EZFIO parameters

`io_mo_two_e_integrals```

  Read/Write MO integrals from/to disk [ Write | Read | None ]

  Default: None

`mo_integrals_threshold```

  If | <ij|kl> | < `mo_integrals_threshold` then <ij|kl> is zero

  Default: 1.e-15

`no_vvvv_integrals```

  If `True`, computes all integrals except for the integrals having 4 virtual indices

  Default: False

`no_ivvv_integrals```

  Can be switched on only if `no_vvvv_integrals` is `True`, then does not compute the integrals with 3 virtual indices and 1 belonging to the core inactive active orbitals

  Default: False

`no_vvv_integrals```

  Can be switched on only if `no_vvvv_integrals` is `True`, then does not compute the integrals with 3 virtual orbitals

  Default: False

## Providers

`big_array_coulomb_integrals`

  File : `mo_two_e_ints/integrals_3_index.irp.f`

      double precision, allocatable   :: big_array_coulomb_integrals  (mo_num,mo_num,mo_num)
      double precision, allocatable   :: big_array_exchange_integrals (mo_num,mo_num,mo_num)

  big_array_coulomb_integrals(i,j) = <ij|ij> = (ii|jj)

  big_array_exchange_integrals(i,j) = <ij|ji> = (ij|ij)

  Needs:

  `mo_integrals_cache` `mo_integrals_cache_min` | `mo_integrals_map` `mo_num` | `mo_two_e_integrals_in_map`

  Needed by:

  `coef_hf_selector` | `h_matrix_all_dets` | `h_matrix_cas`

`big_array_exchange_integrals`

  File : `mo_two_e_ints/integrals_3_index.irp.f`

      double precision, allocatable   :: big_array_coulomb_integrals  (mo_num,mo_num,mo_num)
      double precision, allocatable   :: big_array_exchange_integrals (mo_num,mo_num,mo_num)

  big_array_coulomb_integrals(i,j) = <ij|ij> = (ii|jj)

  big_array_exchange_integrals(i,j) = <ij|ji> = (ij|ij)

  Needs:

  `mo_integrals_cache` `mo_integrals_cache_min` | `mo_integrals_map` `mo_num` | `mo_two_e_integrals_in_map`

  Needed by:

  `coef_hf_selector` | `h_matrix_all_dets` | `h_matrix_cas`

`core_energy`

  File : `mo_two_e_ints/core_quantities.irp.f`

      double precision        :: core_energy

  energy from the core : contains all core-core contributions

  Needs:

  `list_inact` `mo_one_e_integrals` | `mo_two_e_integrals_jj` `n_core_orb` | `nuclear_repulsion`

`core_fock_operator`

  File : `mo_two_e_ints/core_quantities.irp.f`

      double precision, allocatable   :: core_fock_operator   (mo_num,mo_num)

  this is the contribution to the Fock operator from the core electrons

  Needs:

  `list_inact` `mo_integrals_cache` `mo_integrals_cache_min` | `mo_integrals_map` `mo_num` | `mo_two_e_integrals_in_map` `n_core_orb`

`insert_into_mo_integrals_map:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

        subroutine insert_into_mo_integrals_map(n_integrals,                 &
      buffer_i, buffer_values, thr)

  Create new entry into MO map, or accumulate in an existing entry

  Needs:

  `mo_integrals_map` |  |

  Called by:

  `add_integrals_to_map()` | `add_integrals_to_map_no_exit_34()` | `add_integrals_to_map_three_indices()`

  Calls:

  `map_update()` |  |

`mo_integrals_cache`

  File : `mo_two_e_ints/map_integrals.irp.f`

      double precision, allocatable   :: mo_integrals_cache   (0_8:128_8*128_8*128_8*128_8)

  Cache of MO integrals for fast access

  Needs:

  `mo_integrals_cache_min` | `mo_integrals_map` | `mo_two_e_integrals_in_map`

  Needed by:

  `big_array_coulomb_integrals` | `core_fock_operator` | `mo_two_e_integrals_jj`

`mo_integrals_cache_max`

  File : `mo_two_e_ints/map_integrals.irp.f`

      integer*4       :: mo_integrals_cache_min
      integer*4       :: mo_integrals_cache_max
      integer*8       :: mo_integrals_cache_min_8
      integer*8       :: mo_integrals_cache_max_8

  Min and max values of the MOs for which the integrals are in the cache

  Needs:

  `elec_alpha_num` | `mo_num` |

  Needed by:

  `big_array_coulomb_integrals` `core_fock_operator` | `mo_integrals_cache` | `mo_two_e_integrals_jj`

`mo_integrals_cache_max_8`

  File : `mo_two_e_ints/map_integrals.irp.f`

      integer*4       :: mo_integrals_cache_min
      integer*4       :: mo_integrals_cache_max
      integer*8       :: mo_integrals_cache_min_8
      integer*8       :: mo_integrals_cache_max_8

  Min and max values of the MOs for which the integrals are in the cache

  Needs:

  `elec_alpha_num` | `mo_num` |

  Needed by:

  `big_array_coulomb_integrals` `core_fock_operator` | `mo_integrals_cache` | `mo_two_e_integrals_jj`

`mo_integrals_cache_min`

  File : `mo_two_e_ints/map_integrals.irp.f`

      integer*4       :: mo_integrals_cache_min
      integer*4       :: mo_integrals_cache_max
      integer*8       :: mo_integrals_cache_min_8
      integer*8       :: mo_integrals_cache_max_8

  Min and max values of the MOs for which the integrals are in the cache

  Needs:

  `elec_alpha_num` | `mo_num` |

  Needed by:

  `big_array_coulomb_integrals` `core_fock_operator` | `mo_integrals_cache` | `mo_two_e_integrals_jj`

`mo_integrals_cache_min_8`

  File : `mo_two_e_ints/map_integrals.irp.f`

      integer*4       :: mo_integrals_cache_min
      integer*4       :: mo_integrals_cache_max
      integer*8       :: mo_integrals_cache_min_8
      integer*8       :: mo_integrals_cache_max_8

  Min and max values of the MOs for which the integrals are in the cache

  Needs:

  `elec_alpha_num` | `mo_num` |

  Needed by:

  `big_array_coulomb_integrals` `core_fock_operator` | `mo_integrals_cache` | `mo_two_e_integrals_jj`

`mo_integrals_map`

  File : `mo_two_e_ints/map_integrals.irp.f`

      type(map_type)  :: mo_integrals_map

  MO integrals

  Needs:

  `mo_num` |  |

  Needed by:

  `big_array_coulomb_integrals` `coef_hf_selector` `core_fock_operator` `fock_operator_closed_shell_ref_bitmask` | `fock_wee_closed_shell` `h_matrix_all_dets` `h_matrix_cas` | `mo_integrals_cache` `mo_two_e_integrals_in_map` `mo_two_e_integrals_jj`

`mo_two_e_integral_jj_from_ao`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integral_jj_from_ao (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_exchange_from_ao       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_anti_from_ao   (mo_num,mo_num)

  mo_two_e_integral_jj_from_ao(i,j) = J_ij mo_two_e_integrals_jj_exchange_from_ao(i,j) = J_ij mo_two_e_integrals_jj_anti_from_ao(i,j) = J_ij - K_ij

  Needs:

  `ao_integrals_map` `ao_integrals_threshold` `ao_num` `ao_overlap_abs` | `ao_two_e_integral_schwartz` `ao_two_e_integrals_in_map` `do_direct_integrals` | `mo_coef` `mo_coef_transp` `mo_num`

`mo_two_e_integrals_in_map`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      logical :: mo_two_e_integrals_in_map

  If True, the map of MO two-electron integrals is provided

  Needs:

  `ao_num` `ao_two_e_integrals_in_map` `core_inact_act_bitmask_4` `ezfio_filename` `full_ijkl_bitmask_4` `list_inact` | `mo_class` `mo_coef` `mo_coef_transp` `mo_integrals_map` `mo_integrals_threshold` `mo_num` | `mpi_master` `n_int` `no_ivvv_integrals` `no_vvv_integrals` `no_vvvv_integrals` `read_mo_two_e_integrals`

  Needed by:

  `big_array_coulomb_integrals` `ci_electronic_energy` `coef_hf_selector` `core_fock_operator` | `fock_operator_closed_shell_ref_bitmask` `fock_wee_closed_shell` `h_matrix_all_dets` | `h_matrix_cas` `mo_integrals_cache` `mo_two_e_integrals_jj`

`mo_two_e_integrals_jj`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integrals_jj        (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_exchange       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_anti   (mo_num,mo_num)

  mo_two_e_integrals_jj(i,j) = J_ij mo_two_e_integrals_jj_exchange(i,j) = K_ij mo_two_e_integrals_jj_anti(i,j) = J_ij - K_ij

  Needs:

  `mo_integrals_cache` `mo_integrals_cache_min` | `mo_integrals_map` `mo_num` | `mo_two_e_integrals_in_map`

  Needed by:

  `core_energy` | `ref_bitmask_energy` |

`mo_two_e_integrals_jj_anti`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integrals_jj        (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_exchange       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_anti   (mo_num,mo_num)

  mo_two_e_integrals_jj(i,j) = J_ij mo_two_e_integrals_jj_exchange(i,j) = K_ij mo_two_e_integrals_jj_anti(i,j) = J_ij - K_ij

  Needs:

  `mo_integrals_cache` `mo_integrals_cache_min` | `mo_integrals_map` `mo_num` | `mo_two_e_integrals_in_map`

  Needed by:

  `core_energy` | `ref_bitmask_energy` |

`mo_two_e_integrals_jj_anti_from_ao`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integral_jj_from_ao (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_exchange_from_ao       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_anti_from_ao   (mo_num,mo_num)

  mo_two_e_integral_jj_from_ao(i,j) = J_ij mo_two_e_integrals_jj_exchange_from_ao(i,j) = J_ij mo_two_e_integrals_jj_anti_from_ao(i,j) = J_ij - K_ij

  Needs:

  `ao_integrals_map` `ao_integrals_threshold` `ao_num` `ao_overlap_abs` | `ao_two_e_integral_schwartz` `ao_two_e_integrals_in_map` `do_direct_integrals` | `mo_coef` `mo_coef_transp` `mo_num`

`mo_two_e_integrals_jj_exchange`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integrals_jj        (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_exchange       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_anti   (mo_num,mo_num)

  mo_two_e_integrals_jj(i,j) = J_ij mo_two_e_integrals_jj_exchange(i,j) = K_ij mo_two_e_integrals_jj_anti(i,j) = J_ij - K_ij

  Needs:

  `mo_integrals_cache` `mo_integrals_cache_min` | `mo_integrals_map` `mo_num` | `mo_two_e_integrals_in_map`

  Needed by:

  `core_energy` | `ref_bitmask_energy` |

`mo_two_e_integrals_jj_exchange_from_ao`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integral_jj_from_ao (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_exchange_from_ao       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_jj_anti_from_ao   (mo_num,mo_num)

  mo_two_e_integral_jj_from_ao(i,j) = J_ij mo_two_e_integrals_jj_exchange_from_ao(i,j) = J_ij mo_two_e_integrals_jj_anti_from_ao(i,j) = J_ij - K_ij

  Needs:

  `ao_integrals_map` `ao_integrals_threshold` `ao_num` `ao_overlap_abs` | `ao_two_e_integral_schwartz` `ao_two_e_integrals_in_map` `do_direct_integrals` | `mo_coef` `mo_coef_transp` `mo_num`

`mo_two_e_integrals_vv_anti_from_ao`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integrals_vv_from_ao        (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_vv_exchange_from_ao       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_vv_anti_from_ao   (mo_num,mo_num)

  mo_two_e_integrals_vv_from_ao(i,j) = J_ij mo_two_e_integrals_vv_exchange_from_ao(i,j) = J_ij mo_two_e_integrals_vv_anti_from_ao(i,j) = J_ij - K_ij but only for the virtual orbitals

  Needs:

  `ao_integrals_map` `ao_integrals_threshold` `ao_num` `ao_overlap_abs` | `ao_two_e_integral_schwartz` `ao_two_e_integrals_in_map` `do_direct_integrals` `list_inact` | `mo_coef` `mo_coef_transp` `mo_num` `n_core_orb`

`mo_two_e_integrals_vv_exchange_from_ao`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integrals_vv_from_ao        (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_vv_exchange_from_ao       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_vv_anti_from_ao   (mo_num,mo_num)

  mo_two_e_integrals_vv_from_ao(i,j) = J_ij mo_two_e_integrals_vv_exchange_from_ao(i,j) = J_ij mo_two_e_integrals_vv_anti_from_ao(i,j) = J_ij - K_ij but only for the virtual orbitals

  Needs:

  `ao_integrals_map` `ao_integrals_threshold` `ao_num` `ao_overlap_abs` | `ao_two_e_integral_schwartz` `ao_two_e_integrals_in_map` `do_direct_integrals` `list_inact` | `mo_coef` `mo_coef_transp` `mo_num` `n_core_orb`

`mo_two_e_integrals_vv_from_ao`

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      double precision, allocatable   :: mo_two_e_integrals_vv_from_ao        (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_vv_exchange_from_ao       (mo_num,mo_num)
      double precision, allocatable   :: mo_two_e_integrals_vv_anti_from_ao   (mo_num,mo_num)

  mo_two_e_integrals_vv_from_ao(i,j) = J_ij mo_two_e_integrals_vv_exchange_from_ao(i,j) = J_ij mo_two_e_integrals_vv_anti_from_ao(i,j) = J_ij - K_ij but only for the virtual orbitals

  Needs:

  `ao_integrals_map` `ao_integrals_threshold` `ao_num` `ao_overlap_abs` | `ao_two_e_integral_schwartz` `ao_two_e_integrals_in_map` `do_direct_integrals` `list_inact` | `mo_coef` `mo_coef_transp` `mo_num` `n_core_orb`

## Subroutines / functions

`add_integrals_to_map:`()

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      subroutine add_integrals_to_map(mask_ijkl)

  Adds integrals to tha MO map according to some bitmask

  Needs:

  `mo_coef` `mo_integrals_threshold` `mo_coef_transp` | `ao_num` `mo_integrals_map` `mo_num` | `ao_two_e_integrals_in_map` `n_int`

  Called by:

  `mo_two_e_integrals_in_map` |  |

  Calls:

  `bitstring_to_list()` `bitstring_to_str()` `cpu_time()` | `get_ao_two_e_integrals()` `insert_into_mo_integrals_map()` `map_merge()` | `mo_two_e_integrals_index()` `wall_time()`

`add_integrals_to_map_no_exit_34:`()

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      subroutine add_integrals_to_map_no_exit_34(mask_ijkl)

  Adds integrals to tha MO map according to some bitmask

  Needs:

  `mo_coef` `mo_integrals_threshold` `mo_coef_transp` | `ao_num` `mo_integrals_map` `mo_num` | `ao_two_e_integrals_in_map` `n_int`

  Called by:

  `mo_two_e_integrals_in_map` |  |

  Calls:

  `bitstring_to_list()` `cpu_time()` `get_ao_two_e_integrals()` | `insert_into_mo_integrals_map()` `map_merge()` | `mo_two_e_integrals_index()` `wall_time()`

`add_integrals_to_map_three_indices:`()

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      subroutine add_integrals_to_map_three_indices(mask_ijk)

  Adds integrals to tha MO map according to some bitmask

  Needs:

  `mo_coef` `mo_integrals_threshold` `mo_coef_transp` | `ao_num` `mo_integrals_map` `mo_num` | `ao_two_e_integrals_in_map` `n_int`

  Called by:

  `mo_two_e_integrals_in_map` |  |

  Calls:

  `bitstring_to_list()` `bitstring_to_str()` `cpu_time()` | `get_ao_two_e_integrals()` `insert_into_mo_integrals_map()` `map_merge()` | `mo_two_e_integrals_index()` `wall_time()`

`clear_mo_map:`()

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      subroutine clear_mo_map

  Frees the memory of the MO map

  Needs:

  `mo_integrals_map` |  |

  Calls:

  `map_deinit()` |  |

`dump_mo_integrals:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      subroutine dump_mo_integrals(filename)

  Save to disk the MO integrals

  Needs:

  `mo_integrals_map` | `mpi_master` |

  Calls:

  `ezfio_set_work_empty()` |  |

`get_mo_map_size:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      integer*8 function get_mo_map_size()

  Return the number of elements in the MO map

  Needs:

  `mo_integrals_map` |  |

`get_mo_two_e_integrals:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      subroutine get_mo_two_e_integrals(j,k,l,sze,out_val,map)

  Returns multiple integrals <ij|kl> in the MO basis, all i for j,k,l fixed.

  Needs:

  `mo_two_e_integrals_in_map` | `mo_integrals_cache` | `mo_integrals_cache_min`

  Called by:

  `get_d0()` | `get_d1()` |

  Calls:

  `map_get()` |  |

`get_mo_two_e_integrals_coulomb_ii:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      subroutine get_mo_two_e_integrals_coulomb_ii(k,l,sze,out_val,map)

  Returns multiple integrals <ki|li> k(1)i(2) 1/r12 l(1)i(2) :: out_val(i1) for k,l fixed.

  Needs:

  `mo_two_e_integrals_in_map` |  |

  Called by:

  `fock_operator_closed_shell_ref_bitmask` | `fock_wee_closed_shell` |

  Calls:

  `map_get_many()` | `two_e_integrals_index()` |

`get_mo_two_e_integrals_exch_ii:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      subroutine get_mo_two_e_integrals_exch_ii(k,l,sze,out_val,map)

  Returns multiple integrals <ki|il> k(1)i(2) 1/r12 i(1)l(2) :: out_val(i1) for k,l fixed.

  Needs:

  `mo_two_e_integrals_in_map` |  |

  Called by:

  `fock_operator_closed_shell_ref_bitmask` | `fock_wee_closed_shell` |

  Calls:

  `map_get_many()` | `two_e_integrals_index()` |

`get_mo_two_e_integrals_i1j1:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      subroutine get_mo_two_e_integrals_i1j1(k,l,sze,out_array,map)

  Returns multiple integrals <ik|jl> in the MO basis, all i(1)j(1) 1/r12 k(2)l(2) i, j for k,l fixed.

  Needs:

  `mo_two_e_integrals_in_map` | `mo_integrals_map` |

  Calls:

  `i2radix_sort()` `i8radix_sort()` | `iradix_sort()` `map_get_many()` | `two_e_integrals_index()`

`get_mo_two_e_integrals_ij:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      subroutine get_mo_two_e_integrals_ij(k,l,sze,out_array,map)

  Returns multiple integrals <ij|kl> in the MO basis, all i(1)j(2) 1/r12 k(1)l(2) i, j for k,l fixed.

  Needs:

  `mo_two_e_integrals_in_map` | `mo_integrals_map` |

  Calls:

  `i2radix_sort()` `i8radix_sort()` | `iradix_sort()` `map_get_many()` | `two_e_integrals_index()`

`get_two_e_integral:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      double precision function get_two_e_integral(i,j,k,l,map)

  Returns one integral <ij|kl> in the MO basis

  Needs:

  `mo_two_e_integrals_in_map` | `mo_integrals_cache` | `mo_integrals_cache_min`

  Calls:

  `map_get()` | `two_e_integrals_index()` |

`load_mo_integrals:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      integer function load_mo_integrals(filename)

  Read from disk the MO integrals

  Needs:

  `mo_integrals_map` |  |

  Calls:

  `cache_map_reallocate()` | `map_deinit()` | `map_sort()`

`mo_two_e_integral:`()

  File : `mo_two_e_ints/map_integrals.irp.f`

      double precision function mo_two_e_integral(i,j,k,l)

  Returns one integral <ij|kl> in the MO basis

  Needs:

  `mo_integrals_cache` | `mo_integrals_map` | `mo_two_e_integrals_in_map`

`mo_two_e_integrals_index:`()

  File : `mo_two_e_ints/mo_bi_integrals.irp.f`

      subroutine mo_two_e_integrals_index(i,j,k,l,i1)

  Computes an unique index for i,j,k,l integrals

  Called by:

  `add_integrals_to_map()` `add_integrals_to_map_erf()` | `add_integrals_to_map_no_exit_34()` | `add_integrals_to_map_three_indices()`