LCOV - code coverage report
Current view: top level - src - hfx_types.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:71c3ab0) Lines: 95.8 % 1250 1197
Test Date: 2026-07-25 06:35:44 Functions: 41.5 % 53 22

            Line data    Source code
       1              : !--------------------------------------------------------------------------------------------------!
       2              : !   CP2K: A general program to perform molecular dynamics simulations                              !
       3              : !   Copyright 2000-2026 CP2K developers group <https://cp2k.org>                                   !
       4              : !                                                                                                  !
       5              : !   SPDX-License-Identifier: GPL-2.0-or-later                                                      !
       6              : !--------------------------------------------------------------------------------------------------!
       7              : 
       8              : ! **************************************************************************************************
       9              : !> \brief Types and set/get functions for HFX
      10              : !> \par History
      11              : !>      04.2008 created [Manuel Guidon]
      12              : !>      05.2019 Moved erfc_cutoff to common/mathlib (A. Bussy)
      13              : !>      10.2025 Added gcc from basis_parameter and hfx_library option
      14              : !> \author Manuel Guidon
      15              : ! **************************************************************************************************
      16              : MODULE hfx_types
      17              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      18              :                                               get_atomic_kind,&
      19              :                                               get_atomic_kind_set
      20              :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      21              :                                               gto_basis_set_p_type,&
      22              :                                               gto_basis_set_type
      23              :    USE bibliography,                    ONLY: bussy2023,&
      24              :                                               cite_reference,&
      25              :                                               guidon2008,&
      26              :                                               guidon2009
      27              :    USE cell_types,                      ONLY: cell_type,&
      28              :                                               get_cell,&
      29              :                                               plane_distance,&
      30              :                                               scaled_to_real
      31              :    USE cp_array_utils,                  ONLY: cp_1d_logical_p_type
      32              :    USE cp_control_types,                ONLY: dft_control_type
      33              :    USE cp_dbcsr_api,                    ONLY: dbcsr_release,&
      34              :                                               dbcsr_type
      35              :    USE cp_files,                        ONLY: close_file,&
      36              :                                               file_exists,&
      37              :                                               open_file
      38              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      39              :                                               cp_logger_type
      40              :    USE cp_output_handling,              ONLY: cp_print_key_finished_output,&
      41              :                                               cp_print_key_unit_nr
      42              :    USE cp_units,                        ONLY: cp_unit_from_cp2k
      43              :    USE dbt_api,                         ONLY: &
      44              :         dbt_create, dbt_default_distvec, dbt_destroy, dbt_distribution_destroy, &
      45              :         dbt_distribution_new, dbt_distribution_type, dbt_mp_dims_create, dbt_pgrid_create, &
      46              :         dbt_pgrid_destroy, dbt_pgrid_type, dbt_type
      47              :    USE hfx_helpers,                     ONLY: count_cells_perd,&
      48              :                                               next_image_cell_perd
      49              :    USE input_constants,                 ONLY: &
      50              :         do_hfx_auto_shells, do_potential_coulomb, do_potential_gaussian, do_potential_id, &
      51              :         do_potential_long, do_potential_mix_cl, do_potential_mix_cl_trunc, do_potential_mix_lg, &
      52              :         do_potential_short, do_potential_truncated, hfx_ri_do_2c_diag, hfx_ri_do_2c_iter
      53              :    USE input_cp2k_hfx,                  ONLY: ri_mo,&
      54              :                                               ri_pmat
      55              :    USE input_section_types,             ONLY: section_vals_get,&
      56              :                                               section_vals_get_subs_vals,&
      57              :                                               section_vals_type,&
      58              :                                               section_vals_val_get
      59              :    USE kinds,                           ONLY: default_path_length,&
      60              :                                               default_string_length,&
      61              :                                               dp,&
      62              :                                               int_8
      63              :    USE libint_2c_3c,                    ONLY: compare_potential_types,&
      64              :                                               libint_potential_type
      65              :    USE libint_wrapper,                  ONLY: &
      66              :         cp_libint_cleanup_eri, cp_libint_cleanup_eri1, cp_libint_init_eri, cp_libint_init_eri1, &
      67              :         cp_libint_set_contrdepth, cp_libint_static_cleanup, cp_libint_static_init, cp_libint_t, &
      68              :         prim_data_f_size
      69              :    USE machine,                         ONLY: m_chdir,&
      70              :                                               m_getcwd
      71              :    USE mathlib,                         ONLY: erfc_cutoff
      72              :    USE message_passing,                 ONLY: mp_cart_type,&
      73              :                                               mp_para_env_type
      74              :    USE orbital_pointers,                ONLY: nco,&
      75              :                                               ncoset,&
      76              :                                               nso
      77              :    USE particle_methods,                ONLY: get_particle_set
      78              :    USE particle_types,                  ONLY: particle_type
      79              :    USE physcon,                         ONLY: a_bohr
      80              :    USE qs_integral_utils,               ONLY: basis_set_list_setup
      81              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      82              :                                               get_qs_kind_set,&
      83              :                                               qs_kind_type
      84              :    USE qs_tensors_types,                ONLY: &
      85              :         create_2c_tensor, create_3c_tensor, create_tensor_batches, default_block_size, &
      86              :         distribution_3d_create, distribution_3d_destroy, distribution_3d_type, pgf_block_sizes, &
      87              :         split_block_sizes
      88              :    USE string_utilities,                ONLY: compress
      89              :    USE t_c_g0,                          ONLY: free_C0
      90              : 
      91              : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
      92              : 
      93              : #include "./base/base_uses.f90"
      94              : 
      95              :    IMPLICIT NONE
      96              :    PRIVATE
      97              :    PUBLIC :: hfx_type, hfx_create, hfx_release, &
      98              :              hfx_set_distr_energy, &
      99              :              hfx_set_distr_forces, &
     100              :              hfx_cell_type, hfx_distribution, &
     101              :              hfx_potential_type, hfx_screening_type, &
     102              :              hfx_memory_type, hfx_load_balance_type, hfx_general_type, &
     103              :              hfx_container_type, hfx_cache_type, &
     104              :              hfx_basis_type, parse_memory_section, &
     105              :              hfx_init_container, &
     106              :              hfx_basis_info_type, hfx_screen_coeff_type, &
     107              :              hfx_reset_memory_usage_counter, pair_list_type, pair_list_element_type, &
     108              :              pair_set_list_type, hfx_p_kind, hfx_2D_map, hfx_pgf_list, &
     109              :              hfx_pgf_product_list, hfx_block_range_type, &
     110              :              alloc_containers, dealloc_containers, hfx_task_list_type, init_t_c_g0_lmax, &
     111              :              hfx_create_neighbor_cells, hfx_create_basis_types, hfx_release_basis_types, &
     112              :              hfx_ri_type, hfx_compression_type, block_ind_type, hfx_ri_init, hfx_ri_release, &
     113              :              compare_hfx_sections
     114              : 
     115              : #define CACHE_SIZE 1024
     116              : #define BITS_MAX_VAL 6
     117              : 
     118              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hfx_types'
     119              :    INTEGER, PARAMETER, PUBLIC                 :: max_atom_block = 32
     120              :    INTEGER, PARAMETER, PUBLIC                 :: max_images = 27
     121              :    REAL(dp), PARAMETER, PUBLIC                :: log_zero = -1000.0_dp
     122              :    REAL(dp), PARAMETER, PUBLIC                :: powell_min_log = -20.0_dp
     123              :    REAL(KIND=dp), DIMENSION(0:10), &
     124              :       PARAMETER, PUBLIC                       :: mul_fact = [1.0_dp, &
     125              :                                                              1.1781_dp, &
     126              :                                                              1.3333_dp, &
     127              :                                                              1.4726_dp, &
     128              :                                                              1.6000_dp, &
     129              :                                                              1.7181_dp, &
     130              :                                                              1.8286_dp, &
     131              :                                                              1.9328_dp, &
     132              :                                                              2.0317_dp, &
     133              :                                                              2.1261_dp, &
     134              :                                                              2.2165_dp]
     135              : 
     136              :    INTEGER, SAVE                                         :: init_t_c_g0_lmax = -1
     137              : 
     138              : !***
     139              : 
     140              : ! **************************************************************************************************
     141              :    TYPE hfx_potential_type
     142              :       INTEGER                                  :: potential_type = do_potential_coulomb !! 1/r/ erfc(wr)/r ...
     143              :       REAL(dp)                                 :: omega = 0.0_dp !! w
     144              :       REAL(dp)                                 :: scale_coulomb = 0.0_dp !! scaling factor for mixed potential
     145              :       REAL(dp)                                 :: scale_longrange = 0.0_dp !! scaling factor for mixed potential
     146              :       REAL(dp)                                 :: scale_gaussian = 0.0_dp!! scaling factor for mixed potential
     147              :       REAL(dp)                                 :: cutoff_radius = 0.0_dp!! cutoff radius if cutoff potential in use
     148              :       CHARACTER(default_path_length)           :: filename = ""
     149              :    END TYPE hfx_potential_type
     150              : 
     151              : ! **************************************************************************************************
     152              :    TYPE hfx_screening_type
     153              :       REAL(dp)                                 :: eps_schwarz = 0.0_dp !! threshold
     154              :       REAL(dp)                                 :: eps_schwarz_forces = 0.0_dp !! threshold
     155              :       LOGICAL                                  :: do_p_screening_forces = .FALSE. !! screen on P^2 ?
     156              :       LOGICAL                                  :: do_initial_p_screening = .FALSE. !! screen on initial guess?
     157              :    END TYPE hfx_screening_type
     158              : 
     159              : ! **************************************************************************************************
     160              :    TYPE hfx_memory_type
     161              :       INTEGER                                  :: max_memory = 0 !! user def max memory MiB
     162              :       INTEGER(int_8)                           :: max_compression_counter = 0_int_8 !! corresponding number of reals
     163              :       INTEGER(int_8)                           :: final_comp_counter_energy = 0_int_8
     164              :       LOGICAL                                  :: do_all_on_the_fly = .FALSE. !! max mem == 0 ?
     165              :       REAL(dp)                                 :: eps_storage_scaling = 0.0_dp
     166              :       INTEGER                                  :: cache_size = 0
     167              :       INTEGER                                  :: bits_max_val = 0
     168              :       INTEGER                                  :: actual_memory_usage = 0
     169              :       INTEGER                                  :: actual_memory_usage_disk = 0
     170              :       INTEGER(int_8)                           :: max_compression_counter_disk = 0_int_8
     171              :       LOGICAL                                  :: do_disk_storage = .FALSE.
     172              :       CHARACTER(len=default_path_length)       :: storage_location = ""
     173              :       INTEGER(int_8)                           :: ram_counter = 0_int_8
     174              :       INTEGER(int_8)                           :: ram_counter_forces = 0_int_8
     175              :       INTEGER(int_8)                           :: size_p_screen = 0_int_8
     176              :       LOGICAL                                  :: treat_forces_in_core = .FALSE.
     177              :       LOGICAL                                  :: recalc_forces = .FALSE.
     178              :    END TYPE hfx_memory_type
     179              : 
     180              : ! **************************************************************************************************
     181              :    TYPE hfx_periodic_type
     182              :       INTEGER                                  :: number_of_shells = -1 !! number of periodic image cells
     183              :       LOGICAL                                  :: do_periodic = .FALSE. !! periodic ?
     184              :       INTEGER                                  :: perd(3) = -1 !! x,xy,xyz,...
     185              :       INTEGER                                  :: mode = -1
     186              :       REAL(dp)                                 :: R_max_stress = 0.0_dp
     187              :       INTEGER                                  :: number_of_shells_from_input = 0
     188              :    END TYPE hfx_periodic_type
     189              : 
     190              : ! **************************************************************************************************
     191              :    TYPE hfx_load_balance_type
     192              :       INTEGER                                  :: nbins = 0
     193              :       INTEGER                                  :: block_size = 0
     194              :       INTEGER                                  :: nblocks = 0
     195              :       LOGICAL                                  :: rtp_redistribute = .FALSE.
     196              :       LOGICAL                                  :: blocks_initialized = .FALSE.
     197              :       LOGICAL                                  :: do_randomize = .FALSE.
     198              :    END TYPE hfx_load_balance_type
     199              : 
     200              : ! **************************************************************************************************
     201              :    TYPE hfx_general_type
     202              :       REAL(dp)                                 :: fraction = 0.0_dp !! for hybrids
     203              :       INTEGER                                  :: hfx_library = 0
     204              :       LOGICAL                                  :: treat_lsd_in_core = .FALSE.
     205              :    END TYPE hfx_general_type
     206              : 
     207              : ! **************************************************************************************************
     208              :    TYPE hfx_cell_type
     209              :       REAL(dp)                                 :: cell(3) = 0.0_dp
     210              :       REAL(dp)                                 :: cell_r(3) = 0.0_dp
     211              :    END TYPE hfx_cell_type
     212              : 
     213              : ! **************************************************************************************************
     214              :    TYPE hfx_distribution
     215              :       INTEGER(int_8)                           :: istart = 0_int_8
     216              :       INTEGER(int_8)                           :: number_of_atom_quartets = 0_int_8
     217              :       INTEGER(int_8)                           :: cost = 0_int_8
     218              :       REAL(KIND=dp)                            :: time_first_scf = 0.0_dp
     219              :       REAL(KIND=dp)                            :: time_other_scf = 0.0_dp
     220              :       REAL(KIND=dp)                            :: time_forces = 0.0_dp
     221              :       INTEGER(int_8)                           :: ram_counter = 0_int_8
     222              :    END TYPE hfx_distribution
     223              : 
     224              : ! **************************************************************************************************
     225              :    TYPE pair_list_element_type
     226              :       INTEGER, DIMENSION(2) :: pair = 0
     227              :       INTEGER, DIMENSION(2) :: set_bounds = 0
     228              :       INTEGER, DIMENSION(2) :: kind_pair = 0
     229              :       REAL(KIND=dp)         :: r1(3) = 0.0_dp, r2(3) = 0.0_dp
     230              :       REAL(KIND=dp)         :: dist2 = 0.0_dp
     231              :    END TYPE pair_list_element_type
     232              : 
     233              :    ! **************************************************************************************************
     234              :    TYPE pair_set_list_type
     235              :       INTEGER, DIMENSION(2) :: pair = 0
     236              :    END TYPE pair_set_list_type
     237              : 
     238              : ! **************************************************************************************************
     239              :    TYPE pair_list_type
     240              :       TYPE(pair_list_element_type), DIMENSION(max_atom_block**2) :: elements = pair_list_element_type()
     241              :       INTEGER :: n_element = 0
     242              :    END TYPE pair_list_type
     243              : 
     244              : ! **************************************************************************************************
     245              :    TYPE hfx_cache_type
     246              :       INTEGER(int_8), DIMENSION(CACHE_SIZE)    :: DATA = 0_int_8
     247              :       INTEGER                                  :: element_counter = 0
     248              :    END TYPE hfx_cache_type
     249              : 
     250              : ! **************************************************************************************************
     251              :    TYPE hfx_container_node
     252              :       TYPE(hfx_container_node), POINTER        :: next => NULL(), prev => NULL()
     253              :       INTEGER(int_8), DIMENSION(CACHE_SIZE)    :: DATA = 0_int_8
     254              :    END TYPE hfx_container_node
     255              : 
     256              : ! **************************************************************************************************
     257              :    TYPE hfx_container_type
     258              :       TYPE(hfx_container_node), POINTER        :: first => NULL(), current => NULL()
     259              :       INTEGER                                  :: element_counter = 0
     260              :       INTEGER(int_8)                           :: file_counter = 0
     261              :       CHARACTER(LEN=5)                         :: desc = ""
     262              :       INTEGER                                  :: unit = -1
     263              :       CHARACTER(default_path_length)           :: filename = ""
     264              :    END TYPE hfx_container_type
     265              : 
     266              : ! **************************************************************************************************
     267              :    TYPE hfx_basis_type
     268              :       INTEGER, DIMENSION(:), POINTER           :: lmax => NULL()
     269              :       INTEGER, DIMENSION(:), POINTER           :: lmin => NULL()
     270              :       INTEGER, DIMENSION(:), POINTER           :: npgf => NULL()
     271              :       INTEGER                                  :: nset = 0
     272              :       REAL(dp), DIMENSION(:, :), POINTER        :: zet => NULL()
     273              :       INTEGER, DIMENSION(:), POINTER           :: nsgf => NULL()
     274              :       INTEGER, DIMENSION(:, :), POINTER         :: first_sgf => NULL()
     275              :       REAL(dp), DIMENSION(:, :), POINTER        :: sphi => NULL()
     276              :       INTEGER                                  :: nsgf_total = 0
     277              :       INTEGER, DIMENSION(:, :), POINTER         :: nl => NULL()
     278              :       INTEGER, DIMENSION(:, :), POINTER         :: nsgfl => NULL()
     279              :       INTEGER, DIMENSION(:), POINTER           :: nshell => NULL()
     280              :       REAL(dp), DIMENSION(:, :, :, :), POINTER &
     281              :          :: sphi_ext => NULL()
     282              :       REAL(dp), DIMENSION(:, :, :), POINTER   :: gcc => NULL()
     283              :       REAL(dp), DIMENSION(:), POINTER          :: set_radius => NULL()
     284              :       REAL(dp), DIMENSION(:, :), POINTER        :: pgf_radius => NULL()
     285              :       REAL(dp)                                 :: kind_radius = 0.0_dp
     286              :    END TYPE hfx_basis_type
     287              : 
     288              : ! **************************************************************************************************
     289              :    TYPE hfx_basis_info_type
     290              :       INTEGER                                  :: max_set = 0
     291              :       INTEGER                                  :: max_sgf = 0
     292              :       INTEGER                                  :: max_am = 0
     293              :    END TYPE hfx_basis_info_type
     294              : 
     295              : ! **************************************************************************************************
     296              :    TYPE hfx_screen_coeff_type
     297              :       REAL(dp)                                 :: x(2) = 0.0_dp
     298              :    END TYPE hfx_screen_coeff_type
     299              : 
     300              : ! **************************************************************************************************
     301              :    TYPE hfx_p_kind
     302              :       REAL(dp), DIMENSION(:, :, :, :), POINTER    :: p_kind => NULL()
     303              :    END TYPE hfx_p_kind
     304              : 
     305              : ! **************************************************************************************************
     306              :    TYPE hfx_2D_map
     307              :       INTEGER, DIMENSION(:), POINTER           :: iatom_list => NULL()
     308              :       INTEGER, DIMENSION(:), POINTER           :: jatom_list => NULL()
     309              :    END TYPE hfx_2D_map
     310              : 
     311              : ! **************************************************************************************************
     312              :    TYPE hfx_pgf_image
     313              :       REAL(dp)                                 :: ra(3) = 0.0_dp, rb(3) = 0.0_dp
     314              :       REAL(dp)                                 :: rab2 = 0.0_dp
     315              :       REAL(dp)                                 :: S1234 = 0.0_dp
     316              :       REAL(dp)                                 :: P(3) = 0.0_dp
     317              :       REAL(dp)                                 :: R = 0.0_dp
     318              :       REAL(dp)                                 :: pgf_max = 0.0_dp
     319              :       REAL(dp), DIMENSION(3)                   :: bcell = 0.0_dp
     320              :    END TYPE hfx_pgf_image
     321              : 
     322              : ! **************************************************************************************************
     323              :    TYPE hfx_pgf_list
     324              :       TYPE(hfx_pgf_image), DIMENSION(:), POINTER &
     325              :          :: image_list => NULL()
     326              :       INTEGER                                  :: nimages = 0
     327              :       REAL(dp)                                 :: zetapzetb = 0.0_dp
     328              :       REAL(dp)                                 :: ZetaInv = 0.0_dp
     329              :       REAL(dp)                                 :: zeta = 0.0_dp, zetb = 0.0_dp
     330              :       INTEGER                                  :: ipgf = 0, jpgf = 0
     331              :    END TYPE hfx_pgf_list
     332              : 
     333              : ! **************************************************************************************************
     334              :    TYPE hfx_pgf_product_list
     335              :       REAL(dp)                                 :: ra(3) = 0.0_dp, rb(3) = 0.0_dp, rc(3) = 0.0_dp, rd(3) = 0.0_dp
     336              :       REAL(dp)                                 :: ZetapEtaInv = 0.0_dp
     337              :       REAL(dp)                                 :: Rho = 0.0_dp, RhoInv = 0.0_dp
     338              :       REAL(dp)                                 :: P(3) = 0.0_dp, Q(3) = 0.0_dp, W(3) = 0.0_dp
     339              :       REAL(dp)                                 :: AB(3) = 0.0_dp, CD(3) = 0.0_dp
     340              :       REAL(dp)                                 :: Fm(prim_data_f_size) = 0.0_dp
     341              :    END TYPE hfx_pgf_product_list
     342              : 
     343              : ! **************************************************************************************************
     344              :    TYPE hfx_block_range_type
     345              :       INTEGER        :: istart = 0, iend = 0
     346              :       INTEGER(int_8) :: cost = 0_int_8
     347              :    END TYPE hfx_block_range_type
     348              : 
     349              : ! **************************************************************************************************
     350              :    TYPE hfx_task_list_type
     351              :       INTEGER                                  :: thread_id = 0
     352              :       INTEGER                                  :: bin_id = 0
     353              :       INTEGER(int_8)                           :: cost = 0_int_8
     354              :    END TYPE hfx_task_list_type
     355              : 
     356              :    TYPE :: hfx_compression_type
     357              :       TYPE(hfx_container_type), DIMENSION(:), &
     358              :          POINTER        :: maxval_container => NULL()
     359              :       TYPE(hfx_cache_type), DIMENSION(:), &
     360              :          POINTER            :: maxval_cache => NULL()
     361              :       TYPE(hfx_container_type), DIMENSION(:, :), &
     362              :          POINTER        :: integral_containers => NULL()
     363              :       TYPE(hfx_cache_type), DIMENSION(:, :), &
     364              :          POINTER            :: integral_caches => NULL()
     365              :       TYPE(hfx_container_type), POINTER :: maxval_container_disk => NULL()
     366              :       TYPE(hfx_cache_type)     :: maxval_cache_disk = hfx_cache_type()
     367              :       TYPE(hfx_cache_type)      :: integral_caches_disk(64) = hfx_cache_type()
     368              :       TYPE(hfx_container_type), POINTER, &
     369              :          DIMENSION(:)  :: integral_containers_disk => NULL()
     370              :    END TYPE hfx_compression_type
     371              : 
     372              :    TYPE :: block_ind_type
     373              :       INTEGER, DIMENSION(:, :), ALLOCATABLE :: ind
     374              :    END TYPE block_ind_type
     375              : 
     376              :    TYPE hfx_ri_type
     377              :       ! input parameters (see input_cp2k_hfx)
     378              :       REAL(KIND=dp) :: filter_eps = 0.0_dp, filter_eps_2c = 0.0_dp, filter_eps_storage = 0.0_dp, filter_eps_mo = 0.0_dp, &
     379              :                        eps_lanczos = 0.0_dp, eps_pgf_orb = 0.0_dp, eps_eigval = 0.0_dp, kp_RI_range = 0.0_dp, &
     380              :                        kp_image_range = 0.0_dp, kp_bump_rad = 0.0_dp
     381              :       INTEGER :: t2c_sqrt_order = 0, max_iter_lanczos = 0, flavor = 0, unit_nr_dbcsr = -1, unit_nr = -1, &
     382              :                  min_bsize = 0, max_bsize_MO = 0, t2c_method = 0, nelectron_total = 0, input_flavor = 0, &
     383              :                  ncell_RI = 0, nimg = 0, kp_stack_size = 0, nimg_nze = 0, kp_ngroups = 1
     384              :       LOGICAL :: check_2c_inv = .FALSE., calc_condnum = .FALSE.
     385              : 
     386              :       TYPE(libint_potential_type) :: ri_metric = libint_potential_type()
     387              : 
     388              :       ! input parameters from hfx
     389              :       TYPE(libint_potential_type) :: hfx_pot = libint_potential_type() ! interaction potential
     390              :       REAL(KIND=dp) :: eps_schwarz = 0.0_dp ! integral screening threshold
     391              :       REAL(KIND=dp) :: eps_schwarz_forces = 0.0_dp ! integral derivatives screening threshold
     392              : 
     393              :       LOGICAL :: same_op = .FALSE. ! whether RI operator is same as HF potential
     394              : 
     395              :       ! default process grid used for 3c tensors
     396              :       TYPE(dbt_pgrid_type), POINTER :: pgrid => NULL()
     397              :       TYPE(dbt_pgrid_type), POINTER :: pgrid_2d => NULL()
     398              : 
     399              :       ! distributions for (RI | AO AO) 3c integral tensor (non split)
     400              :       TYPE(distribution_3d_type) :: dist_3d = distribution_3d_type()
     401              :       TYPE(dbt_distribution_type) :: dist
     402              : 
     403              :       ! block sizes for RI and AO tensor dimensions (split)
     404              :       INTEGER, DIMENSION(:), ALLOCATABLE :: bsizes_RI, bsizes_AO, bsizes_RI_split, bsizes_AO_split, &
     405              :                                             bsizes_RI_fit, bsizes_AO_fit
     406              : 
     407              :       ! KP RI-HFX basis info
     408              :       INTEGER, DIMENSION(:), ALLOCATABLE ::  img_to_RI_cell, present_images, idx_to_img, img_to_idx, &
     409              :                                             RI_cell_to_img
     410              : 
     411              :       ! KP RI-HFX cost information for a given atom pair i,j at a given cell b
     412              :       REAL(dp), DIMENSION(:, :, :), ALLOCATABLE :: kp_cost
     413              : 
     414              :       ! KP distribution of iatom (of i,j atom pairs) to subgroups
     415              :       TYPE(cp_1d_logical_p_type), DIMENSION(:), ALLOCATABLE :: iatom_to_subgroup
     416              : 
     417              :       ! KP 3c tensors replicated on the subgroups
     418              :       TYPE(dbt_type), DIMENSION(:), ALLOCATABLE :: kp_t_3c_int
     419              : 
     420              :       ! Note: changed static DIMENSION(1,1) of dbt_type to allocatables as workaround for gfortran 8.3.0,
     421              :       ! with static dimension gfortran gets stuck during compilation
     422              : 
     423              :       ! 2c tensors in (AO | AO) format
     424              :       TYPE(dbt_type), DIMENSION(:, :), ALLOCATABLE :: rho_ao_t, ks_t
     425              : 
     426              :       ! 2c tensors in (RI | RI) format for forces
     427              :       TYPE(dbt_type), DIMENSION(:, :), ALLOCATABLE    :: t_2c_inv
     428              :       TYPE(dbt_type), DIMENSION(:, :), ALLOCATABLE    :: t_2c_pot
     429              : 
     430              :       ! 2c tensor in matrix format for K-points RI-HFX
     431              :       TYPE(dbcsr_type), DIMENSION(:, :), ALLOCATABLE  :: kp_mat_2c_pot
     432              : 
     433              :       ! 2c tensor in (RI | RI) format for contraction
     434              :       TYPE(dbt_type), DIMENSION(:, :), ALLOCATABLE    :: t_2c_int
     435              : 
     436              :       ! 3c integral tensor in (AO RI | AO) format for contraction
     437              :       TYPE(dbt_type), DIMENSION(:, :), ALLOCATABLE :: t_3c_int_ctr_1
     438              :       TYPE(block_ind_type), DIMENSION(:, :), ALLOCATABLE :: blk_indices
     439              :       TYPE(dbt_pgrid_type), POINTER                :: pgrid_1 => NULL()
     440              : 
     441              :       ! 3c integral tensor in ( AO | RI AO) (MO) or (AO RI | AO) (RHO) format for contraction
     442              :       TYPE(dbt_type), DIMENSION(:, :), ALLOCATABLE :: t_3c_int_ctr_2
     443              :       TYPE(dbt_pgrid_type), POINTER                :: pgrid_2 => NULL()
     444              : 
     445              :       ! 3c integral tensor in ( RI | AO AO ) format for contraction
     446              :       TYPE(dbt_type), DIMENSION(:, :), ALLOCATABLE :: t_3c_int_ctr_3
     447              : 
     448              :       ! 3c integral tensor in (RI | MO AO ) format for contraction
     449              :       TYPE(dbt_type), DIMENSION(:, :, :), ALLOCATABLE :: t_3c_int_mo
     450              :       TYPE(dbt_type), DIMENSION(:, :, :), ALLOCATABLE :: t_3c_ctr_RI
     451              :       TYPE(dbt_type), DIMENSION(:, :, :), ALLOCATABLE :: t_3c_ctr_KS
     452              :       TYPE(dbt_type), DIMENSION(:, :, :), ALLOCATABLE :: t_3c_ctr_KS_copy
     453              : 
     454              :       ! optional: sections for output handling
     455              :       ! alternatively set unit_nr_dbcsr (for logging tensor operations) and unit_nr (for general
     456              :       ! output) directly
     457              :       TYPE(section_vals_type), POINTER :: ri_section => NULL(), hfx_section => NULL()
     458              : 
     459              :       ! types of primary and auxiliary basis
     460              :       CHARACTER(len=default_string_length) :: orb_basis_type = "", ri_basis_type = ""
     461              : 
     462              :       ! memory reduction factor
     463              :       INTEGER :: n_mem_input = 0, n_mem = 0, n_mem_RI = 0, n_mem_flavor_switch = 0
     464              : 
     465              :       ! offsets for memory batches
     466              :       INTEGER, DIMENSION(:), ALLOCATABLE :: starts_array_mem_block, ends_array_mem_block
     467              :       INTEGER, DIMENSION(:), ALLOCATABLE :: starts_array_mem, ends_array_mem
     468              : 
     469              :       INTEGER, DIMENSION(:), ALLOCATABLE :: starts_array_RI_mem_block, ends_array_RI_mem_block
     470              :       INTEGER, DIMENSION(:), ALLOCATABLE :: starts_array_RI_mem, ends_array_RI_mem
     471              : 
     472              :       INTEGER(int_8) :: dbcsr_nflop = 0_int_8
     473              :       REAL(dp)       :: dbcsr_time = 0.0_dp
     474              :       INTEGER        :: num_pe = 0
     475              :       TYPE(hfx_compression_type), DIMENSION(:, :), ALLOCATABLE :: store_3c
     476              : 
     477              :    END TYPE hfx_ri_type
     478              : 
     479              : ! **************************************************************************************************
     480              : !> \brief stores some data used in construction of Kohn-Sham matrix
     481              : !> \param potential_parameter stores information on the potential (1/r, erfc(wr)/r
     482              : !> \param screening_parameter stores screening infos such as epsilon
     483              : !> \param memory_parameter stores infos on memory used for in-core calculations
     484              : !> \param periodic_parameter stores information on how to apply pbc
     485              : !> \param load_balance_parameter contains infos for Monte Carlo simulated annealing
     486              : !> \param general_paramter at the moment stores the fraction of HF amount to be included
     487              : !> \param maxval_container stores the maxvals in compressed form
     488              : !> \param maxval_cache cache for maxvals in decompressed form
     489              : !> \param integral_containers 64 containers for compressed integrals
     490              : !> \param integral_caches 64 caches for decompressed integrals
     491              : !> \param neighbor_cells manages handling of periodic cells
     492              : !> \param distribution_energy stores information on parallelization of energy
     493              : !> \param distribution_forces stores information on parallelization of forces
     494              : !> \param initial_p stores the initial guess if requested
     495              : !> \param is_assoc_atomic_block reflects KS sparsity
     496              : !> \param number_of_p_entries Size of P matrix
     497              : !> \param n_rep_hf Number of HFX replicas
     498              : !> \param b_first_load_balance_x flag to indicate if it is enough just to update
     499              : !>        the distribution of the integrals
     500              : !> \param full_ks_x full ks matrices
     501              : !> \param lib libint type for eris
     502              : !> \param basis_info contains information for basis sets
     503              : !> \param screen_funct_coeffs_pgf pgf based near field screening coefficients
     504              : !> \param pair_dist_radii_pgf pgf based radii coefficients of pair distributions
     505              : !> \param screen_funct_coeffs_set set based near field screening coefficients
     506              : !> \param screen_funct_coeffs_kind kind based near field screening coefficients
     507              : !> \param screen_funct_is_initialized flag that indicates if the coefficients
     508              : !>        have already been fitted
     509              : !> \par History
     510              : !>      11.2006 created [Manuel Guidon]
     511              : !>      02.2009 completely rewritten due to new screening
     512              : !> \author Manuel Guidon
     513              : ! **************************************************************************************************
     514              :    TYPE hfx_type
     515              :       TYPE(hfx_potential_type)                 :: potential_parameter = hfx_potential_type()
     516              :       TYPE(hfx_screening_type)                 :: screening_parameter = hfx_screening_type()
     517              :       TYPE(hfx_memory_type)                    :: memory_parameter = hfx_memory_type()
     518              :       TYPE(hfx_periodic_type)                  :: periodic_parameter = hfx_periodic_type()
     519              :       TYPE(hfx_load_balance_type)              :: load_balance_parameter = hfx_load_balance_type()
     520              :       TYPE(hfx_general_type)                   :: general_parameter = hfx_general_type()
     521              : 
     522              :       TYPE(hfx_compression_type) :: store_ints = hfx_compression_type()
     523              :       TYPE(hfx_compression_type) :: store_forces = hfx_compression_type()
     524              : 
     525              :       TYPE(hfx_cell_type), DIMENSION(:), &
     526              :          POINTER                       :: neighbor_cells => NULL()
     527              :       TYPE(hfx_distribution), DIMENSION(:), &
     528              :          POINTER         :: distribution_energy => NULL()
     529              :       TYPE(hfx_distribution), DIMENSION(:), &
     530              :          POINTER         :: distribution_forces => NULL()
     531              :       INTEGER, DIMENSION(:, :), POINTER         :: is_assoc_atomic_block => NULL()
     532              :       INTEGER                                  :: number_of_p_entries = 0
     533              :       TYPE(hfx_basis_type), DIMENSION(:), &
     534              :          POINTER           :: basis_parameter => NULL()
     535              :       INTEGER                                  :: n_rep_hf = 0
     536              :       LOGICAL                                  :: b_first_load_balance_energy = .FALSE., &
     537              :                                                   b_first_load_balance_forces = .FALSE.
     538              :       REAL(dp), DIMENSION(:, :), POINTER        :: full_ks_alpha => NULL()
     539              :       REAL(dp), DIMENSION(:, :), POINTER        :: full_ks_beta => NULL()
     540              :       TYPE(cp_libint_t)                        :: lib
     541              :       TYPE(hfx_basis_info_type)                :: basis_info = hfx_basis_info_type()
     542              :       TYPE(hfx_screen_coeff_type), &
     543              :          DIMENSION(:, :, :, :, :, :), POINTER     :: screen_funct_coeffs_pgf => NULL(), &
     544              :                                                      pair_dist_radii_pgf => NULL()
     545              :       TYPE(hfx_screen_coeff_type), &
     546              :          DIMENSION(:, :, :, :), POINTER         :: screen_funct_coeffs_set => NULL()
     547              :       TYPE(hfx_screen_coeff_type), &
     548              :          DIMENSION(:, :), POINTER             :: screen_funct_coeffs_kind => NULL()
     549              :       LOGICAL                                  :: screen_funct_is_initialized = .FALSE.
     550              :       TYPE(hfx_p_kind), DIMENSION(:), POINTER  :: initial_p => NULL()
     551              :       TYPE(hfx_p_kind), DIMENSION(:), POINTER  :: initial_p_forces => NULL()
     552              :       INTEGER, DIMENSION(:), POINTER           :: map_atom_to_kind_atom => NULL()
     553              :       TYPE(hfx_2D_map), DIMENSION(:), POINTER  :: map_atoms_to_cpus => NULL()
     554              :       INTEGER, DIMENSION(:, :), POINTER         :: atomic_block_offset => NULL()
     555              :       INTEGER, DIMENSION(:, :, :, :), POINTER     :: set_offset => NULL()
     556              :       INTEGER, DIMENSION(:), POINTER           :: block_offset => NULL()
     557              :       TYPE(hfx_block_range_type), DIMENSION(:), &
     558              :          POINTER      :: blocks => NULL()
     559              :       TYPE(hfx_task_list_type), DIMENSION(:), &
     560              :          POINTER        :: task_list => NULL()
     561              :       REAL(dp), DIMENSION(:, :), POINTER        :: pmax_atom => NULL(), pmax_atom_forces => NULL()
     562              :       TYPE(cp_libint_t)                         :: lib_deriv
     563              :       REAL(dp), DIMENSION(:, :), POINTER        :: pmax_block => NULL()
     564              :       LOGICAL, DIMENSION(:, :), POINTER         :: atomic_pair_list => NULL()
     565              :       LOGICAL, DIMENSION(:, :), POINTER         :: atomic_pair_list_forces => NULL()
     566              :       LOGICAL                                   :: do_hfx_ri = .FALSE.
     567              :       TYPE(hfx_ri_type), POINTER                :: ri_data => NULL()
     568              : 
     569              :       ! ACE fields
     570              :       LOGICAL  :: use_ace = .FALSE.
     571              :       INTEGER  :: ace_rebuild_freq = 20
     572              : 
     573              :       ! ACE pprojectors will be declared in hfx_admm_utils.F
     574              :       LOGICAL  :: ace_is_built = .FALSE.
     575              :       INTEGER  :: ace_build_counter = 0
     576              :    END TYPE hfx_type
     577              : 
     578              : CONTAINS
     579              : 
     580              : ! **************************************************************************************************
     581              : !> \brief - This routine allocates and initializes all types in hfx_data
     582              : !> \param x_data contains all relevant data structures for hfx runs
     583              : !> \param para_env ...
     584              : !> \param hfx_section input section
     585              : !> \param atomic_kind_set ...
     586              : !> \param qs_kind_set ...
     587              : !> \param particle_set ...
     588              : !> \param dft_control ...
     589              : !> \param cell ...
     590              : !> \param orb_basis ...
     591              : !> \param ri_basis ...
     592              : !> \param nelectron_total ...
     593              : !> \param nkp_grid ...
     594              : !> \par History
     595              : !>      09.2007 created [Manuel Guidon]
     596              : !>      01.2024 pushed basis set decision outside of routine, keeps default as
     597              : !>              orb_basis = "ORB" and ri_basis = "AUX_FIT"
     598              : !>              No more ADMM references!
     599              : !> \author Manuel Guidon
     600              : !> \note
     601              : !>      - All POINTERS and ALLOCATABLES are allocated, even if their size is
     602              : !>        unknown at invocation time
     603              : ! **************************************************************************************************
     604         1478 :    SUBROUTINE hfx_create(x_data, para_env, hfx_section, atomic_kind_set, qs_kind_set, &
     605              :                          particle_set, dft_control, cell, orb_basis, ri_basis, &
     606              :                          nelectron_total, nkp_grid)
     607              :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
     608              :       TYPE(mp_para_env_type)                             :: para_env
     609              :       TYPE(section_vals_type), POINTER                   :: hfx_section
     610              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     611              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     612              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     613              :       TYPE(dft_control_type), POINTER                    :: dft_control
     614              :       TYPE(cell_type), POINTER                           :: cell
     615              :       CHARACTER(LEN=*), OPTIONAL                         :: orb_basis, ri_basis
     616              :       INTEGER, OPTIONAL                                  :: nelectron_total
     617              :       INTEGER, DIMENSION(3), OPTIONAL                    :: nkp_grid
     618              : 
     619              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'hfx_create'
     620              : 
     621              :       CHARACTER(LEN=512)                                 :: error_msg
     622              :       CHARACTER(LEN=default_path_length)                 :: char_val
     623              :       CHARACTER(LEN=default_string_length)               :: orb_basis_type, ri_basis_type
     624              :       INTEGER :: handle, i, i_thread, iatom, ikind, int_val, irep, jkind, max_set, n_rep_hf, &
     625              :          n_threads, natom, natom_a, natom_b, nkind, nseta, nsetb, pbc_shells, storage_id
     626         1478 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: atom2kind, kind_of
     627              :       LOGICAL                                            :: do_ri, explicit, logic_val
     628              :       REAL(dp)                                           :: real_val
     629              :       TYPE(hfx_type), POINTER                            :: actual_x_data
     630              :       TYPE(section_vals_type), POINTER                   :: hf_pbc_section, hf_sub_section, &
     631              :                                                             hfx_ri_section
     632              : 
     633         1478 :       CALL timeset(routineN, handle)
     634              : 
     635         1478 :       CALL cite_reference(Guidon2008)
     636         1478 :       CALL cite_reference(Guidon2009)
     637              : 
     638         1478 :       natom = SIZE(particle_set)
     639              : 
     640              :       !! There might be 2 hf sections
     641         1478 :       CALL section_vals_get(hfx_section, n_repetition=n_rep_hf)
     642         1478 :       n_threads = 1
     643         1478 : !$    n_threads = omp_get_max_threads()
     644              : 
     645         1478 :       CALL section_vals_val_get(hfx_section, "RI%_SECTION_PARAMETERS_", l_val=do_ri)
     646         1478 :       IF (do_ri) n_threads = 1 ! RI implementation does not use threads
     647              : 
     648         1478 :       IF (PRESENT(orb_basis)) THEN
     649         1478 :          orb_basis_type = orb_basis
     650              :       ELSE
     651            0 :          orb_basis_type = "ORB"
     652              :       END IF
     653         1478 :       IF (PRESENT(ri_basis)) THEN
     654            0 :          ri_basis_type = ri_basis
     655              :       ELSE
     656         1478 :          ri_basis_type = "RI_HFX"
     657              :       END IF
     658              : 
     659      6257862 :       ALLOCATE (x_data(n_rep_hf, n_threads))
     660         2956 :       DO i_thread = 1, n_threads
     661         4444 :          DO irep = 1, n_rep_hf
     662         1488 :             actual_x_data => x_data(irep, i_thread)
     663              :             !! Get data from input file
     664              :             !!
     665              :             !! GENERAL params
     666         1488 :             CALL section_vals_val_get(hfx_section, "FRACTION", r_val=real_val, i_rep_section=irep)
     667         1488 :             actual_x_data%general_parameter%fraction = real_val
     668         1488 :             actual_x_data%n_rep_hf = n_rep_hf
     669              : 
     670         1488 :             NULLIFY (actual_x_data%map_atoms_to_cpus)
     671              : 
     672         1488 :             CALL section_vals_val_get(hfx_section, "TREAT_LSD_IN_CORE", l_val=logic_val, i_rep_section=irep)
     673         1488 :             actual_x_data%general_parameter%treat_lsd_in_core = logic_val
     674              : 
     675         1488 :             CALL section_vals_val_get(hfx_section, "HFX_LIBRARY", i_val=int_val, i_rep_section=irep)
     676         1488 :             actual_x_data%general_parameter%hfx_library = int_val
     677              : 
     678         1488 :             hfx_ri_section => section_vals_get_subs_vals(hfx_section, "RI")
     679         1488 :             CALL section_vals_val_get(hfx_ri_section, "_SECTION_PARAMETERS_", l_val=actual_x_data%do_hfx_ri)
     680              : 
     681              :             !! MEMORY section
     682         1488 :             hf_sub_section => section_vals_get_subs_vals(hfx_section, "MEMORY", i_rep_section=irep)
     683              :             CALL parse_memory_section(actual_x_data%memory_parameter, hf_sub_section, storage_id, i_thread, &
     684         1488 :                                       n_threads, para_env, irep, skip_disk=.FALSE., skip_in_core_forces=.FALSE.)
     685              : 
     686              :             !! PERIODIC section
     687         1488 :             hf_sub_section => section_vals_get_subs_vals(hfx_section, "PERIODIC", i_rep_section=irep)
     688         1488 :             CALL section_vals_val_get(hf_sub_section, "NUMBER_OF_SHELLS", i_val=int_val)
     689         1488 :             actual_x_data%periodic_parameter%number_of_shells = int_val
     690         1488 :             actual_x_data%periodic_parameter%mode = int_val
     691         1488 :             CALL get_cell(cell=cell, periodic=actual_x_data%periodic_parameter%perd)
     692         5952 :             IF (SUM(actual_x_data%periodic_parameter%perd) == 0) THEN
     693         1040 :                actual_x_data%periodic_parameter%do_periodic = .FALSE.
     694              :             ELSE
     695          448 :                actual_x_data%periodic_parameter%do_periodic = .TRUE.
     696              :             END IF
     697              : 
     698              :             !! SCREENING section
     699         1488 :             hf_sub_section => section_vals_get_subs_vals(hfx_section, "SCREENING", i_rep_section=irep)
     700         1488 :             CALL section_vals_val_get(hf_sub_section, "EPS_SCHWARZ", r_val=real_val)
     701         1488 :             actual_x_data%screening_parameter%eps_schwarz = real_val
     702         1488 :             CALL section_vals_val_get(hf_sub_section, "EPS_SCHWARZ_FORCES", r_val=real_val, explicit=explicit)
     703         1488 :             IF (explicit) THEN
     704          204 :                actual_x_data%screening_parameter%eps_schwarz_forces = real_val
     705              :             ELSE
     706              :                actual_x_data%screening_parameter%eps_schwarz_forces = &
     707         1284 :                   100._dp*actual_x_data%screening_parameter%eps_schwarz
     708              :             END IF
     709         1488 :             CALL section_vals_val_get(hf_sub_section, "SCREEN_P_FORCES", l_val=logic_val)
     710         1488 :             actual_x_data%screening_parameter%do_p_screening_forces = logic_val
     711         1488 :             CALL section_vals_val_get(hf_sub_section, "SCREEN_ON_INITIAL_P", l_val=logic_val)
     712         1488 :             actual_x_data%screening_parameter%do_initial_p_screening = logic_val
     713         1488 :             actual_x_data%screen_funct_is_initialized = .FALSE.
     714              : 
     715              :             !! INTERACTION_POTENTIAL section
     716         1488 :             hf_sub_section => section_vals_get_subs_vals(hfx_section, "INTERACTION_POTENTIAL", i_rep_section=irep)
     717         1488 :             CALL section_vals_val_get(hf_sub_section, "POTENTIAL_TYPE", i_val=int_val)
     718         1488 :             actual_x_data%potential_parameter%potential_type = int_val
     719         1488 :             CALL section_vals_val_get(hf_sub_section, "OMEGA", r_val=real_val)
     720         1488 :             actual_x_data%potential_parameter%omega = real_val
     721         1488 :             CALL section_vals_val_get(hf_sub_section, "SCALE_COULOMB", r_val=real_val)
     722         1488 :             actual_x_data%potential_parameter%scale_coulomb = real_val
     723         1488 :             CALL section_vals_val_get(hf_sub_section, "SCALE_LONGRANGE", r_val=real_val)
     724         1488 :             actual_x_data%potential_parameter%scale_longrange = real_val
     725         1488 :             CALL section_vals_val_get(hf_sub_section, "SCALE_GAUSSIAN", r_val=real_val)
     726         1488 :             actual_x_data%potential_parameter%scale_gaussian = real_val
     727         1488 :             IF (actual_x_data%potential_parameter%potential_type == do_potential_truncated .OR. &
     728              :                 actual_x_data%potential_parameter%potential_type == do_potential_mix_cl_trunc) THEN
     729          376 :                CALL section_vals_val_get(hf_sub_section, "CUTOFF_RADIUS", r_val=real_val)
     730          376 :                actual_x_data%potential_parameter%cutoff_radius = real_val
     731          376 :                CALL section_vals_val_get(hf_sub_section, "T_C_G_DATA", c_val=char_val)
     732          376 :                CALL compress(char_val, .TRUE.)
     733              :                ! ** Check if file is there
     734          376 :                IF (.NOT. file_exists(char_val)) THEN
     735              :                   WRITE (error_msg, '(A,A,A)') "Truncated hfx calculation requested. The file containing "// &
     736            0 :                      "the data could not be found at ", TRIM(char_val), " Please check T_C_G_DATA "// &
     737            0 :                      "in the INTERACTION_POTENTIAL section"
     738            0 :                   CPABORT(error_msg)
     739              :                ELSE
     740          376 :                   actual_x_data%potential_parameter%filename = char_val
     741              :                END IF
     742              :             END IF
     743         1488 :             IF (actual_x_data%potential_parameter%potential_type == do_potential_short) THEN
     744              :                CALL erfc_cutoff(actual_x_data%screening_parameter%eps_schwarz, &
     745              :                                 actual_x_data%potential_parameter%omega, &
     746           48 :                                 actual_x_data%potential_parameter%cutoff_radius)
     747           48 :                CALL section_vals_val_get(hf_sub_section, "CUTOFF_RADIUS", explicit=explicit)
     748           48 :                IF (explicit) THEN
     749            0 :                   CALL section_vals_val_get(hf_sub_section, "CUTOFF_RADIUS", r_val=real_val)
     750              :                   IF (real_val < actual_x_data%potential_parameter%cutoff_radius .AND. &
     751            0 :                       i_thread == 1 .AND. irep == 1) THEN
     752              :                      WRITE (error_msg, '(A,F6.3,A,ES8.1,A,F6.3,A,F6.3,A)') &
     753              :                         "Periodic Hartree Fock calculation requested with the use "// &
     754            0 :                         "of a shortrange potential erfc(omega*r)/r. Given omega = ", &
     755            0 :                         actual_x_data%potential_parameter%omega, " and EPS_SCHWARZ = ", &
     756            0 :                         actual_x_data%screening_parameter%eps_schwarz, ", the requested "// &
     757            0 :                         "cutoff radius ", real_val*a_bohr*1e+10_dp, " A is smaller than "// &
     758            0 :                         "what is necessary to satisfy erfc(omega*r)/r = EPS_SCHWARZ at r = ", &
     759            0 :                         actual_x_data%potential_parameter%cutoff_radius*a_bohr*1e+10_dp, &
     760              :                         " A. Increase input value (or omit keyword to use program default) "// &
     761            0 :                         "to ensure accuracy."
     762            0 :                      CPWARN(error_msg)
     763              :                   END IF
     764            0 :                   actual_x_data%potential_parameter%cutoff_radius = real_val
     765              :                END IF
     766              :             END IF
     767         1488 :             IF (actual_x_data%potential_parameter%potential_type == do_potential_id) THEN
     768           28 :                actual_x_data%potential_parameter%cutoff_radius = 0.0_dp
     769              :             END IF
     770              : 
     771              :             !! LOAD_BALANCE section
     772         1488 :             hf_sub_section => section_vals_get_subs_vals(hfx_section, "LOAD_BALANCE", i_rep_section=irep)
     773         1488 :             CALL section_vals_val_get(hf_sub_section, "NBINS", i_val=int_val)
     774         1488 :             actual_x_data%load_balance_parameter%nbins = MAX(1, int_val)
     775         1488 :             actual_x_data%load_balance_parameter%blocks_initialized = .FALSE.
     776              : 
     777         1488 :             CALL section_vals_val_get(hf_sub_section, "RANDOMIZE", l_val=logic_val)
     778         1488 :             actual_x_data%load_balance_parameter%do_randomize = logic_val
     779              : 
     780         1488 :             actual_x_data%load_balance_parameter%rtp_redistribute = .FALSE.
     781         1488 :             IF (ASSOCIATED(dft_control%rtp_control)) THEN
     782           36 :                actual_x_data%load_balance_parameter%rtp_redistribute = dft_control%rtp_control%hfx_redistribute
     783              :             END IF
     784              : 
     785         1488 :             CALL section_vals_val_get(hf_sub_section, "BLOCK_SIZE", i_val=int_val)
     786              :             ! negative values ask for a computed default
     787         1488 :             IF (int_val <= 0) THEN
     788              :                ! this gives a reasonable number of blocks for binning, yet typically results in blocking.
     789              :                int_val = CEILING(0.1_dp*natom/ &
     790         1488 :                                  REAL(actual_x_data%load_balance_parameter%nbins*n_threads*para_env%num_pe, KIND=dp)**(0.25_dp))
     791              :             END IF
     792              :             ! at least 1 atom per block, and avoid overly large blocks
     793         1488 :             actual_x_data%load_balance_parameter%block_size = MIN(max_atom_block, MAX(1, int_val))
     794              : 
     795              :             CALL hfx_create_basis_types(actual_x_data%basis_parameter, actual_x_data%basis_info, qs_kind_set, &
     796         1488 :                                         orb_basis_type)
     797              : 
     798              : !!**************************************************************************************************
     799              : !! **        !! ** This code writes the contraction routines
     800              : !! **        !! ** Very UGLY: BASIS_SET has to be 1 primitive and lmin=lmax=l. For g-functions
     801              : !! **        !! **
     802              : !! **        !! ** 1  4  4  1  1
     803              : !! **        !! **    1.0  1.0
     804              : !! **        !! **
     805              : !! **        k = max_am - 1
     806              : !! **        write(filename,'(A,I0,A)') "sphi",k+1,"a"
     807              : !! **        OPEN(UNIT=31415,FILE=filename)
     808              : !! **        DO i=ncoset(k)+1,SIZE(sphi_a,1)
     809              : !! **          DO j=1,SIZE(sphi_a,2)
     810              : !! **            IF( sphi_a(i,j) /= 0.0_dp) THEN
     811              : !! **              write(31415,'(A,I0,A,I0,A,I0,A,I0,A,I0,A)') "buffer1(i+imax*(",&
     812              : !! **                          j,&
     813              : !! **                          "-1)) = buffer1(i+imax*(",&
     814              : !! **                          j,&
     815              : !! **                          "-1)) + work(",&
     816              : !! **                          i-ncoset(k),&
     817              : !! **                          "+(i-1)*kmax) * sphi_a(",&
     818              : !! **                          i-ncoset(k),&
     819              : !! **                          ",",&
     820              : !! **                          j,&
     821              : !! **                          "+s_offset_a1)"
     822              : !! **            END IF
     823              : !! **          END DO
     824              : !! **        END DO
     825              : !! **        CLOSE(UNIT=31415)
     826              : !! **        write(filename,'(A,I0,A)') "sphi",k+1,"b"
     827              : !! **        OPEN(UNIT=31415,FILE=filename)
     828              : !! **        DO i=ncoset(k)+1,SIZE(sphi_a,1)
     829              : !! **          DO j=1,SIZE(sphi_a,2)
     830              : !! **            IF( sphi_a(i,j) /= 0.0_dp) THEN
     831              : !! **               write(31415,'(A,I0,A,I0,A,I0,A,I0,A,I0,A)') "buffer2(i+imax*(",&
     832              : !! **                          j,&
     833              : !! **                          "-1)) = buffer2(i+imax*(",&
     834              : !! **                          j,&
     835              : !! **                          "-1)) + buffer1(",&
     836              : !! **                          i-ncoset(k),&
     837              : !! **                          "+(i-1)*kmax) * sphi_b(",&
     838              : !! **                          i-ncoset(k),&
     839              : !! **                          ",",&
     840              : !! **                          j,&
     841              : !! **                          "+s_offset_b1)"
     842              : !! **
     843              : !! **            END IF
     844              : !! **          END DO
     845              : !! **        END DO
     846              : !! **        CLOSE(UNIT=31415)
     847              : !! **        write(filename,'(A,I0,A)') "sphi",k+1,"c"
     848              : !! **        OPEN(UNIT=31415,FILE=filename)
     849              : !! **        DO i=ncoset(k)+1,SIZE(sphi_a,1)
     850              : !! **          DO j=1,SIZE(sphi_a,2)
     851              : !! **            IF( sphi_a(i,j) /= 0.0_dp) THEN
     852              : !! **               write(31415,'(A,I0,A,I0,A,I0,A,I0,A,I0,A)') "buffer1(i+imax*(",&
     853              : !! **                          j,&
     854              : !! **                          "-1)) = buffer1(i+imax*(",&
     855              : !! **                          j,&
     856              : !! **                          "-1)) + buffer2(",&
     857              : !! **                          i-ncoset(k),&
     858              : !! **                          "+(i-1)*kmax) * sphi_c(",&
     859              : !! **                          i-ncoset(k),&
     860              : !! **                          ",",&
     861              : !! **                          j,&
     862              : !! **                          "+s_offset_c1)"
     863              : !! **
     864              : !! **            END IF
     865              : !! **          END DO
     866              : !! **        END DO
     867              : !! **        CLOSE(UNIT=31415)
     868              : !! **        write(filename,'(A,I0,A)') "sphi",k+1,"d"
     869              : !! **        OPEN(UNIT=31415,FILE=filename)
     870              : !! **        DO i=ncoset(k)+1,SIZE(sphi_a,1)
     871              : !! **          DO j=1,SIZE(sphi_a,2)
     872              : !! **            IF( sphi_a(i,j) /= 0.0_dp) THEN
     873              : !! **
     874              : !! **
     875              : !! **               write(31415,'(A,I0,A)') "primitives(s_offset_a1+i3, s_offset_b1+i2, s_offset_c1+i1, s_offset_d1+",&
     876              : !! **                           j,")= &"
     877              : !! **               write(31415,'(A,I0,A)') "primitives(s_offset_a1+i3, s_offset_b1+i2, s_offset_c1+i1, s_offset_d1+",&
     878              : !! **                           j,")+ &"
     879              : !! **               write(31415,'(A,I0,A,I0,A,I0,A)') "buffer1(",&
     880              : !! **                          i-ncoset(k),&
     881              : !! **                          "+(i-1)*kmax) * sphi_d(",&
     882              : !! **                          i-ncoset(k),&
     883              : !! **                          ",",&
     884              : !! **                          j,&
     885              : !! **                          "+s_offset_d1)"
     886              : !! **
     887              : !! **
     888              : !! **            END IF
     889              : !! **          END DO
     890              : !! **        END DO
     891              : !! **        CLOSE(UNIT=31415)
     892              : !! **        stop
     893              : !! *************************************************************************************************************************
     894              : 
     895         1488 :             IF (actual_x_data%periodic_parameter%do_periodic) THEN
     896          448 :                hf_pbc_section => section_vals_get_subs_vals(hfx_section, "PERIODIC", i_rep_section=irep)
     897          448 :                CALL section_vals_val_get(hf_pbc_section, "NUMBER_OF_SHELLS", i_val=pbc_shells)
     898          448 :                actual_x_data%periodic_parameter%number_of_shells_from_input = pbc_shells
     899         3584 :                ALLOCATE (actual_x_data%neighbor_cells(1))
     900          896 :                CALL hfx_create_neighbor_cells(actual_x_data, pbc_shells, cell, i_thread, nkp_grid=nkp_grid)
     901              :             ELSE
     902         8320 :                ALLOCATE (actual_x_data%neighbor_cells(1))
     903              :                ! ** Initialize this guy to enable non periodic stress regtests
     904         1040 :                actual_x_data%periodic_parameter%R_max_stress = 1.0_dp
     905              :             END IF
     906              : 
     907         1488 :             nkind = SIZE(qs_kind_set, 1)
     908         1488 :             max_set = actual_x_data%basis_info%max_set
     909              : 
     910              :             !! ** This guy is allocated on the master thread only
     911         1488 :             IF (i_thread == 1) THEN
     912         5952 :                ALLOCATE (actual_x_data%is_assoc_atomic_block(natom, natom))
     913         4464 :                ALLOCATE (actual_x_data%atomic_block_offset(natom, natom))
     914         8928 :                ALLOCATE (actual_x_data%set_offset(max_set, max_set, nkind, nkind))
     915         4464 :                ALLOCATE (actual_x_data%block_offset(para_env%num_pe + 1))
     916              :             END IF
     917              : 
     918         2976 :             ALLOCATE (actual_x_data%distribution_forces(1))
     919         2976 :             ALLOCATE (actual_x_data%distribution_energy(1))
     920              : 
     921         1488 :             actual_x_data%memory_parameter%size_p_screen = 0_int_8
     922         1488 :             IF (i_thread == 1) THEN
     923         5952 :                ALLOCATE (actual_x_data%atomic_pair_list(natom, natom))
     924         4464 :                ALLOCATE (actual_x_data%atomic_pair_list_forces(natom, natom))
     925              :             END IF
     926              : 
     927         1488 :             IF (actual_x_data%screening_parameter%do_initial_p_screening .OR. &
     928              :                 actual_x_data%screening_parameter%do_p_screening_forces) THEN
     929              :                !! ** This guy is allocated on the master thread only
     930         1458 :                IF (i_thread == 1) THEN
     931         5832 :                   ALLOCATE (actual_x_data%pmax_atom(natom, natom))
     932         8768 :                   ALLOCATE (actual_x_data%initial_p(nkind*(nkind + 1)/2))
     933         1458 :                   i = 1
     934         4120 :                   DO ikind = 1, nkind
     935         2662 :                      CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_a)
     936         2662 :                      nseta = actual_x_data%basis_parameter(ikind)%nset
     937         8514 :                      DO jkind = ikind, nkind
     938         4394 :                         CALL get_atomic_kind(atomic_kind_set(jkind), natom=natom_b)
     939         4394 :                         nsetb = actual_x_data%basis_parameter(jkind)%nset
     940        26364 :                         ALLOCATE (actual_x_data%initial_p(i)%p_kind(nseta, nsetb, natom_a, natom_b))
     941              :                         actual_x_data%memory_parameter%size_p_screen = &
     942         4394 :                            actual_x_data%memory_parameter%size_p_screen + nseta*nsetb*natom_a*natom_b
     943        11450 :                         i = i + 1
     944              :                      END DO
     945              :                   END DO
     946              : 
     947         4374 :                   ALLOCATE (actual_x_data%pmax_atom_forces(natom, natom))
     948         7310 :                   ALLOCATE (actual_x_data%initial_p_forces(nkind*(nkind + 1)/2))
     949         1458 :                   i = 1
     950         4120 :                   DO ikind = 1, nkind
     951         2662 :                      CALL get_atomic_kind(atomic_kind_set(ikind), natom=natom_a)
     952         2662 :                      nseta = actual_x_data%basis_parameter(ikind)%nset
     953         8514 :                      DO jkind = ikind, nkind
     954         4394 :                         CALL get_atomic_kind(atomic_kind_set(jkind), natom=natom_b)
     955         4394 :                         nsetb = actual_x_data%basis_parameter(jkind)%nset
     956        26364 :                         ALLOCATE (actual_x_data%initial_p_forces(i)%p_kind(nseta, nsetb, natom_a, natom_b))
     957              :                         actual_x_data%memory_parameter%size_p_screen = &
     958         4394 :                            actual_x_data%memory_parameter%size_p_screen + nseta*nsetb*natom_a*natom_b
     959        11450 :                         i = i + 1
     960              :                      END DO
     961              :                   END DO
     962              :                END IF
     963         4374 :                ALLOCATE (actual_x_data%map_atom_to_kind_atom(natom))
     964         1458 :                CALL get_atomic_kind_set(atomic_kind_set, kind_of=kind_of)
     965              : 
     966         4374 :                ALLOCATE (atom2kind(nkind))
     967         1458 :                atom2kind = 0
     968         6138 :                DO iatom = 1, natom
     969         4680 :                   ikind = kind_of(iatom)
     970         4680 :                   atom2kind(ikind) = atom2kind(ikind) + 1
     971         6138 :                   actual_x_data%map_atom_to_kind_atom(iatom) = atom2kind(ikind)
     972              :                END DO
     973         1458 :                DEALLOCATE (kind_of, atom2kind)
     974              :             END IF
     975              : 
     976              :             ! ** Initialize libint type
     977         1488 :             CALL cp_libint_static_init()
     978         1488 :             CALL cp_libint_init_eri(actual_x_data%lib, actual_x_data%basis_info%max_am)
     979         1488 :             CALL cp_libint_init_eri1(actual_x_data%lib_deriv, actual_x_data%basis_info%max_am)
     980         1488 :             CALL cp_libint_set_contrdepth(actual_x_data%lib, 1)
     981         1488 :             CALL cp_libint_set_contrdepth(actual_x_data%lib_deriv, 1)
     982              : 
     983         1488 :             CALL alloc_containers(actual_x_data%store_ints, 1)
     984         1488 :             CALL alloc_containers(actual_x_data%store_forces, 1)
     985              : 
     986         1488 :             actual_x_data%store_ints%maxval_cache_disk%element_counter = 1
     987         1488 :             ALLOCATE (actual_x_data%store_ints%maxval_container_disk)
     988      1525200 :             ALLOCATE (actual_x_data%store_ints%maxval_container_disk%first)
     989         1488 :             actual_x_data%store_ints%maxval_container_disk%first%prev => NULL()
     990         1488 :             actual_x_data%store_ints%maxval_container_disk%first%next => NULL()
     991         1488 :             actual_x_data%store_ints%maxval_container_disk%current => actual_x_data%store_ints%maxval_container_disk%first
     992      1525200 :             actual_x_data%store_ints%maxval_container_disk%current%data = 0
     993         1488 :             actual_x_data%store_ints%maxval_container_disk%element_counter = 1
     994         1488 :             actual_x_data%store_ints%maxval_container_disk%file_counter = 1
     995         1488 :             actual_x_data%store_ints%maxval_container_disk%desc = 'Max_'
     996         1488 :             actual_x_data%store_ints%maxval_container_disk%unit = -1
     997              :             WRITE (actual_x_data%store_ints%maxval_container_disk%filename, '(A,I0,A,A,A)') &
     998         1488 :                TRIM(actual_x_data%memory_parameter%storage_location), &
     999         2976 :                storage_id, "_", actual_x_data%store_ints%maxval_container_disk%desc, "6"
    1000         1488 :             CALL compress(actual_x_data%store_ints%maxval_container_disk%filename, .TRUE.)
    1001        96720 :             ALLOCATE (actual_x_data%store_ints%integral_containers_disk(64))
    1002        96720 :             DO i = 1, 64
    1003        95232 :                actual_x_data%store_ints%integral_caches_disk(i)%element_counter = 1
    1004     97612800 :                actual_x_data%store_ints%integral_caches_disk(i)%data = 0
    1005     97612800 :                ALLOCATE (actual_x_data%store_ints%integral_containers_disk(i)%first)
    1006        95232 :                actual_x_data%store_ints%integral_containers_disk(i)%first%prev => NULL()
    1007        95232 :                actual_x_data%store_ints%integral_containers_disk(i)%first%next => NULL()
    1008              :                actual_x_data%store_ints%integral_containers_disk(i)%current => &
    1009        95232 :                   actual_x_data%store_ints%integral_containers_disk(i)%first
    1010     97612800 :                actual_x_data%store_ints%integral_containers_disk(i)%current%data = 0
    1011        95232 :                actual_x_data%store_ints%integral_containers_disk(i)%element_counter = 1
    1012        95232 :                actual_x_data%store_ints%integral_containers_disk(i)%file_counter = 1
    1013        95232 :                actual_x_data%store_ints%integral_containers_disk(i)%desc = 'Int_'
    1014        95232 :                actual_x_data%store_ints%integral_containers_disk(i)%unit = -1
    1015              :                WRITE (actual_x_data%store_ints%integral_containers_disk(i)%filename, '(A,I0,A,A,I0)') &
    1016        95232 :                   TRIM(actual_x_data%memory_parameter%storage_location), &
    1017       190464 :                   storage_id, "_", actual_x_data%store_ints%integral_containers_disk(i)%desc, i
    1018        96720 :                CALL compress(actual_x_data%store_ints%integral_containers_disk(i)%filename, .TRUE.)
    1019              :             END DO
    1020              : 
    1021         1488 :             actual_x_data%b_first_load_balance_energy = .TRUE.
    1022         1488 :             actual_x_data%b_first_load_balance_forces = .TRUE.
    1023              : 
    1024         1488 :             hf_sub_section => section_vals_get_subs_vals(hfx_section, "RI", i_rep_section=irep)
    1025         1488 :             IF (actual_x_data%do_hfx_ri) THEN
    1026          114 :                CPASSERT(PRESENT(nelectron_total))
    1027          798 :                ALLOCATE (actual_x_data%ri_data)
    1028              :                CALL hfx_ri_init_read_input_from_hfx(actual_x_data%ri_data, actual_x_data, hfx_section, &
    1029              :                                                     hf_sub_section, qs_kind_set, &
    1030              :                                                     particle_set, atomic_kind_set, dft_control, para_env, irep, &
    1031          114 :                                                     nelectron_total, orb_basis_type, ri_basis_type)
    1032              :             END IF
    1033              : 
    1034              :             ! ACE section — read only on thread 1 to avoid redundant work
    1035        13382 :             IF (i_thread == 1) THEN
    1036              :                hf_sub_section => section_vals_get_subs_vals(hfx_section, "ACE", &
    1037         1488 :                                                             i_rep_section=irep)
    1038         1488 :                CALL section_vals_get(hf_sub_section, explicit=logic_val)
    1039         1488 :                IF (logic_val) THEN
    1040              :                   CALL section_vals_val_get(hf_sub_section, "ACTIVE", &
    1041            8 :                                             l_val=actual_x_data%use_ace)
    1042              :                   CALL section_vals_val_get(hf_sub_section, "REBUILD_FREQUENCY", &
    1043            8 :                                             i_val=actual_x_data%ace_rebuild_freq)
    1044              :                END IF
    1045              :                ! Sanity checks
    1046         1488 :                IF (actual_x_data%use_ace) THEN
    1047              :                   ! ACE requires HFX to be meaningful
    1048            8 :                   IF (actual_x_data%general_parameter%fraction <= 0.0_dp) THEN
    1049            0 :                      CPABORT("ACE requires FRACTION > 0.")
    1050              :                   END IF
    1051              :                   ! If frequency is 1, it is full HFX
    1052            8 :                   IF (actual_x_data%ace_rebuild_freq < 1) THEN
    1053            0 :                      CPABORT("ACE: REBUILD_FREQUENCY must be >= 1")
    1054              :                   END IF
    1055              :                END IF
    1056              :             END IF
    1057              :          END DO
    1058              :       END DO
    1059              : 
    1060         2966 :       DO irep = 1, n_rep_hf
    1061         1488 :          actual_x_data => x_data(irep, 1)
    1062         2966 :          CALL hfx_print_info(actual_x_data, hfx_section, irep)
    1063              :       END DO
    1064              : 
    1065         1478 :       CALL timestop(handle)
    1066              : 
    1067         5912 :    END SUBROUTINE hfx_create
    1068              : 
    1069              : ! **************************************************************************************************
    1070              : !> \brief Read RI input and initialize RI data for use within Hartree-Fock
    1071              : !> \param ri_data ...
    1072              : !> \param x_data ...
    1073              : !> \param hfx_section ...
    1074              : !> \param ri_section ...
    1075              : !> \param qs_kind_set ...
    1076              : !> \param particle_set ...
    1077              : !> \param atomic_kind_set ...
    1078              : !> \param dft_control ...
    1079              : !> \param para_env ...
    1080              : !> \param irep ...
    1081              : !> \param nelectron_total ...
    1082              : !> \param orb_basis_type ...
    1083              : !> \param ri_basis_type ...
    1084              : ! **************************************************************************************************
    1085          114 :    SUBROUTINE hfx_ri_init_read_input_from_hfx(ri_data, x_data, hfx_section, ri_section, qs_kind_set, &
    1086              :                                               particle_set, atomic_kind_set, dft_control, para_env, irep, &
    1087              :                                               nelectron_total, orb_basis_type, ri_basis_type)
    1088              :       TYPE(hfx_ri_type), INTENT(INOUT)                   :: ri_data
    1089              :       TYPE(hfx_type), INTENT(INOUT)                      :: x_data
    1090              :       TYPE(section_vals_type), POINTER                   :: hfx_section, ri_section
    1091              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1092              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1093              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1094              :       TYPE(dft_control_type), POINTER                    :: dft_control
    1095              :       TYPE(mp_para_env_type)                             :: para_env
    1096              :       INTEGER, INTENT(IN)                                :: irep, nelectron_total
    1097              :       CHARACTER(LEN=*)                                   :: orb_basis_type, ri_basis_type
    1098              : 
    1099              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'hfx_ri_init_read_input_from_hfx'
    1100              : 
    1101              :       CHARACTER(LEN=512)                                 :: error_msg
    1102              :       CHARACTER(LEN=default_path_length)                 :: char_val, t_c_filename
    1103              :       INTEGER                                            :: handle, unit_nr, unit_nr_dbcsr
    1104              :       TYPE(cp_logger_type), POINTER                      :: logger
    1105              :       TYPE(section_vals_type), POINTER                   :: hf_sub_section
    1106              : 
    1107          114 :       CALL timeset(routineN, handle)
    1108              : 
    1109          114 :       NULLIFY (hf_sub_section)
    1110              : 
    1111              :       ASSOCIATE (hfx_pot => ri_data%hfx_pot)
    1112          114 :          hfx_pot%potential_type = x_data%potential_parameter%potential_type
    1113          114 :          hfx_pot%omega = x_data%potential_parameter%omega
    1114          114 :          hfx_pot%cutoff_radius = x_data%potential_parameter%cutoff_radius
    1115          114 :          hfx_pot%scale_coulomb = x_data%potential_parameter%scale_coulomb
    1116          114 :          hfx_pot%scale_longrange = x_data%potential_parameter%scale_longrange
    1117              :       END ASSOCIATE
    1118          114 :       ri_data%ri_section => ri_section
    1119          114 :       ri_data%hfx_section => hfx_section
    1120          114 :       ri_data%eps_schwarz = x_data%screening_parameter%eps_schwarz
    1121          114 :       ri_data%eps_schwarz_forces = x_data%screening_parameter%eps_schwarz_forces
    1122              : 
    1123          114 :       logger => cp_get_default_logger()
    1124              :       unit_nr_dbcsr = cp_print_key_unit_nr(logger, ri_data%ri_section, "PRINT%RI_INFO", &
    1125          114 :                                            extension=".dbcsrLog")
    1126              : 
    1127              :       unit_nr = cp_print_key_unit_nr(logger, ri_data%hfx_section, "HF_INFO", &
    1128          114 :                                      extension=".scfLog")
    1129              : 
    1130          114 :       hf_sub_section => section_vals_get_subs_vals(hfx_section, "INTERACTION_POTENTIAL", i_rep_section=irep)
    1131          114 :       CALL section_vals_val_get(hf_sub_section, "T_C_G_DATA", c_val=char_val)
    1132          114 :       CALL compress(char_val, .TRUE.)
    1133              : 
    1134          114 :       IF (.NOT. file_exists(char_val)) THEN
    1135              :          WRITE (error_msg, '(A,A,A)') "File not found. Please check T_C_G_DATA "// &
    1136            0 :             "in the INTERACTION_POTENTIAL section"
    1137            0 :          CPABORT(error_msg)
    1138              :       ELSE
    1139          114 :          t_c_filename = char_val
    1140              :       END IF
    1141              : 
    1142              :       CALL hfx_ri_init_read_input(ri_data, ri_section, qs_kind_set, particle_set, atomic_kind_set, &
    1143              :                                   orb_basis_type, ri_basis_type, para_env, unit_nr, unit_nr_dbcsr, &
    1144          114 :                                   nelectron_total, t_c_filename=t_c_filename)
    1145              : 
    1146          114 :       IF (dft_control%smear .AND. ri_data%flavor == ri_mo) THEN
    1147            0 :          CPABORT("RI_FLAVOR MO is not consistent with smearing. Please use RI_FLAVOR RHO.")
    1148              :       END IF
    1149              : 
    1150          114 :       CALL timestop(handle)
    1151              : 
    1152          114 :    END SUBROUTINE hfx_ri_init_read_input_from_hfx
    1153              : 
    1154              : ! **************************************************************************************************
    1155              : !> \brief General routine for reading input of RI section and initializing RI data
    1156              : !> \param ri_data ...
    1157              : !> \param ri_section ...
    1158              : !> \param qs_kind_set ...
    1159              : !> \param particle_set ...
    1160              : !> \param atomic_kind_set ...
    1161              : !> \param orb_basis_type ...
    1162              : !> \param ri_basis_type ...
    1163              : !> \param para_env ...
    1164              : !> \param unit_nr unit number of general output
    1165              : !> \param unit_nr_dbcsr unit number for logging DBCSR tensor operations
    1166              : !> \param nelectron_total ...
    1167              : !> \param t_c_filename ...
    1168              : ! **************************************************************************************************
    1169          114 :    SUBROUTINE hfx_ri_init_read_input(ri_data, ri_section, qs_kind_set, &
    1170              :                                      particle_set, atomic_kind_set, orb_basis_type, ri_basis_type, para_env, &
    1171              :                                      unit_nr, unit_nr_dbcsr, nelectron_total, t_c_filename)
    1172              :       TYPE(hfx_ri_type), INTENT(INOUT)                   :: ri_data
    1173              :       TYPE(section_vals_type), POINTER                   :: ri_section
    1174              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1175              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1176              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1177              :       CHARACTER(LEN=*), INTENT(IN)                       :: orb_basis_type, ri_basis_type
    1178              :       TYPE(mp_para_env_type)                             :: para_env
    1179              :       INTEGER, INTENT(IN)                                :: unit_nr, unit_nr_dbcsr, nelectron_total
    1180              :       CHARACTER(len=*), INTENT(IN), OPTIONAL             :: t_c_filename
    1181              : 
    1182              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'hfx_ri_init_read_input'
    1183              : 
    1184              :       INTEGER                                            :: handle
    1185              :       LOGICAL                                            :: explicit
    1186              :       REAL(dp)                                           :: eps_storage_scaling
    1187              : 
    1188          114 :       CALL timeset(routineN, handle)
    1189              : 
    1190          114 :       CALL section_vals_val_get(ri_section, "EPS_FILTER", r_val=ri_data%filter_eps)
    1191          114 :       CALL section_vals_val_get(ri_section, "EPS_FILTER_2C", r_val=ri_data%filter_eps_2c)
    1192          114 :       CALL section_vals_val_get(ri_section, "EPS_STORAGE_SCALING", r_val=eps_storage_scaling)
    1193          114 :       ri_data%filter_eps_storage = ri_data%filter_eps*eps_storage_scaling
    1194          114 :       CALL section_vals_val_get(ri_section, "EPS_FILTER_MO", r_val=ri_data%filter_eps_mo)
    1195              : 
    1196              :       ASSOCIATE (ri_metric => ri_data%ri_metric, hfx_pot => ri_data%hfx_pot)
    1197          114 :          CALL section_vals_val_get(ri_section, "RI_METRIC", i_val=ri_metric%potential_type, explicit=explicit)
    1198          114 :          IF (.NOT. explicit .OR. ri_metric%potential_type == 0) THEN
    1199           44 :             ri_metric%potential_type = hfx_pot%potential_type
    1200              :          END IF
    1201              : 
    1202          114 :          CALL section_vals_val_get(ri_section, "OMEGA", r_val=ri_metric%omega, explicit=explicit)
    1203          114 :          IF (.NOT. explicit) THEN
    1204          114 :             ri_metric%omega = hfx_pot%omega
    1205              :          END IF
    1206              : 
    1207          114 :          CALL section_vals_val_get(ri_section, "CUTOFF_RADIUS", r_val=ri_metric%cutoff_radius, explicit=explicit)
    1208          114 :          IF (.NOT. explicit) THEN
    1209          106 :             ri_metric%cutoff_radius = hfx_pot%cutoff_radius
    1210              :          END IF
    1211              : 
    1212          114 :          CALL section_vals_val_get(ri_section, "SCALE_COULOMB", r_val=ri_metric%scale_coulomb, explicit=explicit)
    1213          114 :          IF (.NOT. explicit) THEN
    1214          114 :             ri_metric%scale_coulomb = hfx_pot%scale_coulomb
    1215              :          END IF
    1216              : 
    1217          114 :          CALL section_vals_val_get(ri_section, "SCALE_LONGRANGE", r_val=ri_metric%scale_longrange, explicit=explicit)
    1218          114 :          IF (.NOT. explicit) THEN
    1219          114 :             ri_metric%scale_longrange = hfx_pot%scale_longrange
    1220              :          END IF
    1221              : 
    1222          114 :          IF (ri_metric%potential_type == do_potential_short) THEN
    1223            2 :             CALL erfc_cutoff(ri_data%eps_schwarz, ri_metric%omega, ri_metric%cutoff_radius)
    1224              :          END IF
    1225          114 :          IF (ri_metric%potential_type == do_potential_id) ri_metric%cutoff_radius = 0.0_dp
    1226              :       END ASSOCIATE
    1227              : 
    1228          114 :       CALL section_vals_val_get(ri_section, "2C_MATRIX_FUNCTIONS", i_val=ri_data%t2c_method)
    1229          114 :       CALL section_vals_val_get(ri_section, "EPS_EIGVAL", r_val=ri_data%eps_eigval)
    1230          114 :       CALL section_vals_val_get(ri_section, "CHECK_2C_MATRIX", l_val=ri_data%check_2c_inv)
    1231          114 :       CALL section_vals_val_get(ri_section, "CALC_COND_NUM", l_val=ri_data%calc_condnum)
    1232          114 :       CALL section_vals_val_get(ri_section, "SQRT_ORDER", i_val=ri_data%t2c_sqrt_order)
    1233          114 :       CALL section_vals_val_get(ri_section, "EPS_LANCZOS", r_val=ri_data%eps_lanczos)
    1234          114 :       CALL section_vals_val_get(ri_section, "MAX_ITER_LANCZOS", i_val=ri_data%max_iter_lanczos)
    1235          114 :       CALL section_vals_val_get(ri_section, "RI_FLAVOR", i_val=ri_data%flavor)
    1236          114 :       CALL section_vals_val_get(ri_section, "EPS_PGF_ORB", r_val=ri_data%eps_pgf_orb)
    1237          114 :       CALL section_vals_val_get(ri_section, "MIN_BLOCK_SIZE", i_val=ri_data%min_bsize)
    1238          114 :       CALL section_vals_val_get(ri_section, "MAX_BLOCK_SIZE_MO", i_val=ri_data%max_bsize_MO)
    1239          114 :       CALL section_vals_val_get(ri_section, "MEMORY_CUT", i_val=ri_data%n_mem_input)
    1240          114 :       CALL section_vals_val_get(ri_section, "FLAVOR_SWITCH_MEMORY_CUT", i_val=ri_data%n_mem_flavor_switch)
    1241              : 
    1242          114 :       ri_data%orb_basis_type = orb_basis_type
    1243          114 :       ri_data%ri_basis_type = ri_basis_type
    1244          114 :       ri_data%nelectron_total = nelectron_total
    1245          114 :       ri_data%input_flavor = ri_data%flavor
    1246              : 
    1247          114 :       IF (PRESENT(t_c_filename)) THEN
    1248          114 :          ri_data%ri_metric%filename = t_c_filename
    1249          114 :          ri_data%hfx_pot%filename = t_c_filename
    1250              :       END IF
    1251              : 
    1252          114 :       ri_data%unit_nr_dbcsr = unit_nr_dbcsr
    1253          114 :       ri_data%unit_nr = unit_nr
    1254          114 :       ri_data%dbcsr_nflop = 0
    1255          114 :       ri_data%dbcsr_time = 0.0_dp
    1256              : 
    1257          114 :       CALL hfx_ri_init(ri_data, qs_kind_set, particle_set, atomic_kind_set, para_env)
    1258              : 
    1259          114 :       CALL timestop(handle)
    1260              : 
    1261          798 :    END SUBROUTINE hfx_ri_init_read_input
    1262              : 
    1263              : ! **************************************************************************************************
    1264              : !> \brief ...
    1265              : !> \param ri_data ...
    1266              : !> \param qs_kind_set ...
    1267              : !> \param particle_set ...
    1268              : !> \param atomic_kind_set ...
    1269              : !> \param para_env ...
    1270              : ! **************************************************************************************************
    1271          136 :    SUBROUTINE hfx_ri_init(ri_data, qs_kind_set, particle_set, atomic_kind_set, para_env)
    1272              :       TYPE(hfx_ri_type), INTENT(INOUT)                   :: ri_data
    1273              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1274              :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
    1275              :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
    1276              :       TYPE(mp_para_env_type)                             :: para_env
    1277              : 
    1278              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'hfx_ri_init'
    1279              : 
    1280              :       INTEGER                                            :: handle, i_mem, j_mem, MO_dim, natom, &
    1281              :                                                             nkind, nproc
    1282          136 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: bsizes_AO_store, bsizes_RI_store, dist1, &
    1283          136 :                                                             dist2, dist3, dist_AO_1, dist_AO_2, &
    1284              :                                                             dist_RI
    1285              :       INTEGER, DIMENSION(2)                              :: pdims_2d
    1286              :       INTEGER, DIMENSION(3)                              :: pdims
    1287              :       LOGICAL                                            :: same_op
    1288              :       TYPE(distribution_3d_type)                         :: dist_3d
    1289              :       TYPE(gto_basis_set_p_type), ALLOCATABLE, &
    1290          136 :          DIMENSION(:)                                    :: basis_set_AO, basis_set_RI
    1291          136 :       TYPE(mp_cart_type)                                 :: mp_comm_3d
    1292              : 
    1293          136 :       CALL cite_reference(Bussy2023)
    1294              : 
    1295          136 :       CALL timeset(routineN, handle)
    1296              : 
    1297              :       ! initialize libint
    1298          136 :       CALL cp_libint_static_init()
    1299              : 
    1300          136 :       natom = SIZE(particle_set)
    1301          136 :       nkind = SIZE(qs_kind_set, 1)
    1302          136 :       nproc = para_env%num_pe
    1303              : 
    1304              :       ASSOCIATE (ri_metric => ri_data%ri_metric, hfx_pot => ri_data%hfx_pot)
    1305          136 :          IF (ri_metric%potential_type == do_potential_short) THEN
    1306            2 :             CALL erfc_cutoff(ri_data%eps_schwarz, ri_metric%omega, ri_metric%cutoff_radius)
    1307              :          END IF
    1308              : 
    1309          136 :          IF (hfx_pot%potential_type == do_potential_short) THEN
    1310              :             ! need a more accurate threshold for determining 2-center integral operator range
    1311              :             ! because stability of matrix inversion/sqrt is sensitive to this
    1312            4 :             CALL erfc_cutoff(ri_data%filter_eps_2c, hfx_pot%omega, hfx_pot%cutoff_radius)
    1313              :          END IF
    1314              :          ! determine whether RI metric is same operator as used in HFX
    1315          136 :          same_op = compare_potential_types(ri_metric, hfx_pot)
    1316              :       END ASSOCIATE
    1317              : 
    1318          136 :       ri_data%same_op = same_op
    1319              : 
    1320          136 :       pdims = 0
    1321          136 :       CALL mp_comm_3d%create(para_env, 3, pdims)
    1322              : 
    1323          408 :       ALLOCATE (ri_data%bsizes_RI(natom))
    1324          272 :       ALLOCATE (ri_data%bsizes_AO(natom))
    1325         1016 :       ALLOCATE (basis_set_RI(nkind), basis_set_AO(nkind))
    1326          136 :       CALL basis_set_list_setup(basis_set_RI, ri_data%ri_basis_type, qs_kind_set)
    1327          136 :       CALL get_particle_set(particle_set, qs_kind_set, nsgf=ri_data%bsizes_RI, basis=basis_set_RI)
    1328          136 :       CALL basis_set_list_setup(basis_set_AO, ri_data%orb_basis_type, qs_kind_set)
    1329          136 :       CALL get_particle_set(particle_set, qs_kind_set, nsgf=ri_data%bsizes_AO, basis=basis_set_AO)
    1330              : 
    1331          272 :       ALLOCATE (dist_RI(natom))
    1332          272 :       ALLOCATE (dist_AO_1(natom))
    1333          272 :       ALLOCATE (dist_AO_2(natom))
    1334          136 :       CALL dbt_default_distvec(natom, pdims(1), ri_data%bsizes_RI, dist_RI)
    1335          136 :       CALL dbt_default_distvec(natom, pdims(2), ri_data%bsizes_AO, dist_AO_1)
    1336          136 :       CALL dbt_default_distvec(natom, pdims(3), ri_data%bsizes_AO, dist_AO_2)
    1337              :       CALL distribution_3d_create(dist_3d, dist_RI, dist_ao_1, dist_ao_2, nkind, particle_set, &
    1338          136 :                                   mp_comm_3d, own_comm=.TRUE.)
    1339              : 
    1340          408 :       ALLOCATE (ri_data%pgrid)
    1341          136 :       CALL dbt_pgrid_create(para_env, pdims, ri_data%pgrid)
    1342              : 
    1343          408 :       ALLOCATE (ri_data%pgrid_2d)
    1344          136 :       pdims_2d = 0
    1345          136 :       CALL dbt_pgrid_create(para_env, pdims_2d, ri_data%pgrid_2d)
    1346              : 
    1347          136 :       ri_data%dist_3d = dist_3d
    1348              : 
    1349              :       CALL dbt_distribution_new(ri_data%dist, ri_data%pgrid, &
    1350          136 :                                 dist_RI, dist_AO_1, dist_AO_2)
    1351              : 
    1352          136 :       DEALLOCATE (dist_AO_1, dist_AO_2, dist_RI)
    1353              : 
    1354          136 :       ri_data%num_pe = para_env%num_pe
    1355              : 
    1356              :       ! initialize tensors expressed in basis representation
    1357          136 :       CALL pgf_block_sizes(atomic_kind_set, basis_set_AO, ri_data%min_bsize, ri_data%bsizes_AO_split)
    1358          136 :       CALL pgf_block_sizes(atomic_kind_set, basis_set_RI, ri_data%min_bsize, ri_data%bsizes_RI_split)
    1359              : 
    1360          136 :       CALL pgf_block_sizes(atomic_kind_set, basis_set_AO, 1, bsizes_AO_store)
    1361          136 :       CALL pgf_block_sizes(atomic_kind_set, basis_set_RI, 1, bsizes_RI_store)
    1362              : 
    1363          666 :       CALL split_block_sizes([SUM(ri_data%bsizes_AO)], ri_data%bsizes_AO_fit, default_block_size)
    1364          666 :       CALL split_block_sizes([SUM(ri_data%bsizes_RI)], ri_data%bsizes_RI_fit, default_block_size)
    1365              : 
    1366          136 :       IF (ri_data%flavor == ri_pmat) THEN
    1367              : 
    1368              :          !2 batching loops in RHO flavor SCF calculations => need to take the square root of MEMORY_CUT
    1369          118 :          ri_data%n_mem = ri_data%n_mem_input
    1370          118 :          ri_data%n_mem_RI = ri_data%n_mem_input
    1371              : 
    1372              :          CALL create_tensor_batches(ri_data%bsizes_AO_split, ri_data%n_mem, ri_data%starts_array_mem, &
    1373              :                                     ri_data%ends_array_mem, ri_data%starts_array_mem_block, &
    1374          118 :                                     ri_data%ends_array_mem_block)
    1375              : 
    1376              :          CALL create_tensor_batches(ri_data%bsizes_RI_split, ri_data%n_mem_RI, &
    1377              :                                     ri_data%starts_array_RI_mem, ri_data%ends_array_RI_mem, &
    1378          118 :                                     ri_data%starts_array_RI_mem_block, ri_data%ends_array_RI_mem_block)
    1379              : 
    1380          354 :          ALLOCATE (ri_data%pgrid_1)
    1381          354 :          ALLOCATE (ri_data%pgrid_2)
    1382          118 :          pdims = 0
    1383              : 
    1384              :          CALL dbt_mp_dims_create(nproc, pdims, [SIZE(ri_data%bsizes_AO_split), SIZE(ri_data%bsizes_RI_split), &
    1385          472 :                                                 SIZE(ri_data%bsizes_AO_split)])
    1386              : 
    1387          118 :          CALL dbt_pgrid_create(para_env, pdims, ri_data%pgrid_1)
    1388              : 
    1389          826 :          pdims = pdims([2, 1, 3])
    1390          118 :          CALL dbt_pgrid_create(para_env, pdims, ri_data%pgrid_2)
    1391              : 
    1392         1062 :          ALLOCATE (ri_data%t_3c_int_ctr_1(1, 1))
    1393              :          CALL create_3c_tensor(ri_data%t_3c_int_ctr_1(1, 1), dist1, dist2, dist3, &
    1394              :                                ri_data%pgrid_1, ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, &
    1395          118 :                                ri_data%bsizes_AO_split, [1, 2], [3], name="(AO RI | AO)")
    1396          118 :          DEALLOCATE (dist1, dist2, dist3)
    1397              : 
    1398         1516 :          ALLOCATE (ri_data%blk_indices(ri_data%n_mem, ri_data%n_mem_RI))
    1399       250732 :          ALLOCATE (ri_data%store_3c(ri_data%n_mem, ri_data%n_mem_RI))
    1400          410 :          DO i_mem = 1, ri_data%n_mem
    1401         1162 :          DO j_mem = 1, ri_data%n_mem_RI
    1402         1044 :             CALL alloc_containers(ri_data%store_3c(i_mem, j_mem), 1)
    1403              :          END DO
    1404              :          END DO
    1405              : 
    1406         1062 :          ALLOCATE (ri_data%t_3c_int_ctr_2(1, 1))
    1407              :          CALL create_3c_tensor(ri_data%t_3c_int_ctr_2(1, 1), dist1, dist2, dist3, &
    1408              :                                ri_data%pgrid_1, ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, &
    1409          118 :                                ri_data%bsizes_AO_split, [1, 2], [3], name="(AO RI | AO)")
    1410          118 :          DEALLOCATE (dist1, dist2, dist3)
    1411              : 
    1412         1062 :          ALLOCATE (ri_data%t_3c_int_ctr_3(1, 1))
    1413              :          CALL create_3c_tensor(ri_data%t_3c_int_ctr_3(1, 1), dist1, dist2, dist3, &
    1414              :                                ri_data%pgrid_2, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
    1415          118 :                                ri_data%bsizes_AO_split, [1], [2, 3], name="(RI | AO AO)")
    1416          118 :          DEALLOCATE (dist1, dist2, dist3)
    1417              : 
    1418         1062 :          ALLOCATE (ri_data%t_2c_int(1, 1))
    1419              :          CALL create_2c_tensor(ri_data%t_2c_int(1, 1), dist1, dist2, ri_data%pgrid_2d, &
    1420              :                                ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, &
    1421          118 :                                name="(RI | RI)")
    1422          118 :          DEALLOCATE (dist1, dist2)
    1423              : 
    1424              :          !We store previous Pmat and KS mat, so that we can work with Delta P and gain sprasity as we go
    1425         1180 :          ALLOCATE (ri_data%rho_ao_t(2, 1))
    1426              :          CALL create_2c_tensor(ri_data%rho_ao_t(1, 1), dist1, dist2, ri_data%pgrid_2d, &
    1427              :                                ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
    1428          118 :                                name="(AO | AO)")
    1429          118 :          DEALLOCATE (dist1, dist2)
    1430          118 :          CALL dbt_create(ri_data%rho_ao_t(1, 1), ri_data%rho_ao_t(2, 1))
    1431              : 
    1432         1180 :          ALLOCATE (ri_data%ks_t(2, 1))
    1433              :          CALL create_2c_tensor(ri_data%ks_t(1, 1), dist1, dist2, ri_data%pgrid_2d, &
    1434              :                                ri_data%bsizes_AO_split, ri_data%bsizes_AO_split, &
    1435          118 :                                name="(AO | AO)")
    1436          118 :          DEALLOCATE (dist1, dist2)
    1437          118 :          CALL dbt_create(ri_data%ks_t(1, 1), ri_data%ks_t(2, 1))
    1438              : 
    1439           18 :       ELSE IF (ri_data%flavor == ri_mo) THEN
    1440          180 :          ALLOCATE (ri_data%t_2c_int(2, 1))
    1441              : 
    1442              :          CALL create_2c_tensor(ri_data%t_2c_int(1, 1), dist1, dist2, ri_data%pgrid_2d, &
    1443              :                                ri_data%bsizes_RI_fit, ri_data%bsizes_RI_fit, &
    1444           18 :                                name="(RI | RI)")
    1445           18 :          CALL dbt_create(ri_data%t_2c_int(1, 1), ri_data%t_2c_int(2, 1))
    1446              : 
    1447           18 :          DEALLOCATE (dist1, dist2)
    1448              : 
    1449          162 :          ALLOCATE (ri_data%t_3c_int_ctr_1(1, 1))
    1450              : 
    1451           54 :          ALLOCATE (ri_data%pgrid_1)
    1452           54 :          ALLOCATE (ri_data%pgrid_2)
    1453              :          pdims = 0
    1454              : 
    1455           18 :          ri_data%n_mem = ri_data%n_mem_input**2
    1456           18 :          IF (ri_data%n_mem > ri_data%nelectron_total/2) ri_data%n_mem = MAX(ri_data%nelectron_total/2, 1)
    1457              :          ! Size of dimension corresponding to MOs is nelectron/2 and divided by the memory factor
    1458              :          ! we are using ceiling of that division to make sure that no MO dimension (after memory cut)
    1459              :          ! is larger than this (it is however not a problem for load balancing if actual MO dimension
    1460              :          ! is slightly smaller)
    1461           18 :          MO_dim = MAX((ri_data%nelectron_total/2 - 1)/ri_data%n_mem + 1, 1)
    1462           18 :          MO_dim = (MO_dim - 1)/ri_data%max_bsize_MO + 1
    1463              : 
    1464           18 :          pdims = 0
    1465           72 :          CALL dbt_mp_dims_create(nproc, pdims, [SIZE(ri_data%bsizes_AO_split), SIZE(ri_data%bsizes_RI_split), MO_dim])
    1466              : 
    1467           18 :          CALL dbt_pgrid_create(para_env, pdims, ri_data%pgrid_1)
    1468              : 
    1469          126 :          pdims = pdims([3, 2, 1])
    1470           18 :          CALL dbt_pgrid_create(para_env, pdims, ri_data%pgrid_2)
    1471              : 
    1472              :          CALL create_3c_tensor(ri_data%t_3c_int_ctr_1(1, 1), dist1, dist2, dist3, &
    1473              :                                ri_data%pgrid_1, ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
    1474           18 :                                [1, 2], [3], name="(AO RI | AO)")
    1475           18 :          DEALLOCATE (dist1, dist2, dist3)
    1476              : 
    1477          162 :          ALLOCATE (ri_data%t_3c_int_ctr_2(1, 1))
    1478              :          CALL create_3c_tensor(ri_data%t_3c_int_ctr_2(1, 1), dist1, dist2, dist3, &
    1479              :                                ri_data%pgrid_2, ri_data%bsizes_AO_split, ri_data%bsizes_RI_split, ri_data%bsizes_AO_split, &
    1480           18 :                                [1], [2, 3], name="(AO | RI AO)")
    1481           18 :          DEALLOCATE (dist1, dist2, dist3)
    1482              : 
    1483              :       END IF
    1484              : 
    1485              :       !For forces
    1486         1224 :       ALLOCATE (ri_data%t_2c_inv(1, 1))
    1487              :       CALL create_2c_tensor(ri_data%t_2c_inv(1, 1), dist1, dist2, ri_data%pgrid_2d, &
    1488              :                             ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, &
    1489          136 :                             name="(RI | RI)")
    1490          136 :       DEALLOCATE (dist1, dist2)
    1491              : 
    1492         1224 :       ALLOCATE (ri_data%t_2c_pot(1, 1))
    1493              :       CALL create_2c_tensor(ri_data%t_2c_pot(1, 1), dist1, dist2, ri_data%pgrid_2d, &
    1494              :                             ri_data%bsizes_RI_split, ri_data%bsizes_RI_split, &
    1495          136 :                             name="(RI | RI)")
    1496          136 :       DEALLOCATE (dist1, dist2)
    1497              : 
    1498          136 :       CALL timestop(handle)
    1499              : 
    1500          272 :    END SUBROUTINE hfx_ri_init
    1501              : 
    1502              : ! **************************************************************************************************
    1503              : !> \brief ...
    1504              : !> \param ri_data ...
    1505              : ! **************************************************************************************************
    1506          114 :    SUBROUTINE hfx_ri_write_stats(ri_data)
    1507              :       TYPE(hfx_ri_type), INTENT(IN)                      :: ri_data
    1508              : 
    1509              :       REAL(dp)                                           :: my_flop_rate
    1510              : 
    1511              :       ASSOCIATE (unit_nr => ri_data%unit_nr, dbcsr_nflop => ri_data%dbcsr_nflop, &
    1512              :                  dbcsr_time => ri_data%dbcsr_time, num_pe => ri_data%num_pe)
    1513          114 :          my_flop_rate = REAL(dbcsr_nflop, dp)/(1.0E09_dp*ri_data%dbcsr_time)
    1514          114 :          IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(/T2,A,T73,ES8.2)") &
    1515           51 :             "RI-HFX PERFORMANCE| DBT total number of flops:", REAL(dbcsr_nflop*num_pe, dp)
    1516          114 :          IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T2,A,T66,F15.2)") &
    1517           51 :             "RI-HFX PERFORMANCE| DBT total execution time:", dbcsr_time
    1518          114 :          IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T2,A,T66,F15.2)") &
    1519          165 :             "RI-HFX PERFORMANCE| DBT flop rate (Gflops / MPI rank):", my_flop_rate
    1520              :       END ASSOCIATE
    1521          114 :    END SUBROUTINE hfx_ri_write_stats
    1522              : 
    1523              : ! **************************************************************************************************
    1524              : !> \brief ...
    1525              : !> \param ri_data ...
    1526              : !> \param write_stats ...
    1527              : ! **************************************************************************************************
    1528          136 :    SUBROUTINE hfx_ri_release(ri_data, write_stats)
    1529              :       TYPE(hfx_ri_type), INTENT(INOUT)                   :: ri_data
    1530              :       LOGICAL, OPTIONAL                                  :: write_stats
    1531              : 
    1532              :       CHARACTER(LEN=*), PARAMETER                        :: routineN = 'hfx_ri_release'
    1533              : 
    1534              :       INTEGER                                            :: handle, i, i_mem, ispin, j, j_mem, unused
    1535              :       LOGICAL                                            :: my_write_stats
    1536              : 
    1537          136 :       CALL timeset(routineN, handle)
    1538              : 
    1539              :       ! cleanup libint
    1540          136 :       CALL cp_libint_static_cleanup()
    1541              : 
    1542          136 :       my_write_stats = .TRUE.
    1543          136 :       IF (PRESENT(write_stats)) my_write_stats = write_stats
    1544          136 :       IF (my_write_stats) CALL hfx_ri_write_stats(ri_data)
    1545              : 
    1546          136 :       IF (ASSOCIATED(ri_data%pgrid)) THEN
    1547          136 :          CALL dbt_pgrid_destroy(ri_data%pgrid)
    1548          136 :          DEALLOCATE (ri_data%pgrid)
    1549              :       END IF
    1550          136 :       IF (ASSOCIATED(ri_data%pgrid_1)) THEN
    1551          136 :          CALL dbt_pgrid_destroy(ri_data%pgrid_1)
    1552          136 :          DEALLOCATE (ri_data%pgrid_1)
    1553              :       END IF
    1554          136 :       IF (ASSOCIATED(ri_data%pgrid_2)) THEN
    1555          136 :          CALL dbt_pgrid_destroy(ri_data%pgrid_2)
    1556          136 :          DEALLOCATE (ri_data%pgrid_2)
    1557              :       END IF
    1558          136 :       IF (ASSOCIATED(ri_data%pgrid_2d)) THEN
    1559          136 :          CALL dbt_pgrid_destroy(ri_data%pgrid_2d)
    1560          136 :          DEALLOCATE (ri_data%pgrid_2d)
    1561              :       END IF
    1562              : 
    1563          136 :       CALL distribution_3d_destroy(ri_data%dist_3d)
    1564          136 :       CALL dbt_distribution_destroy(ri_data%dist)
    1565              : 
    1566          136 :       DEALLOCATE (ri_data%bsizes_RI)
    1567          136 :       DEALLOCATE (ri_data%bsizes_AO)
    1568          136 :       DEALLOCATE (ri_data%bsizes_AO_split)
    1569          136 :       DEALLOCATE (ri_data%bsizes_RI_split)
    1570          136 :       DEALLOCATE (ri_data%bsizes_AO_fit)
    1571          136 :       DEALLOCATE (ri_data%bsizes_RI_fit)
    1572              : 
    1573          136 :       IF (ri_data%flavor == ri_pmat) THEN
    1574          410 :          DO i_mem = 1, ri_data%n_mem
    1575         1162 :          DO j_mem = 1, ri_data%n_mem_RI
    1576         1044 :             CALL dealloc_containers(ri_data%store_3c(i_mem, j_mem), unused)
    1577              :          END DO
    1578              :          END DO
    1579              : 
    1580         1688 :          DO j = 1, SIZE(ri_data%t_3c_int_ctr_1, 2)
    1581         3258 :             DO i = 1, SIZE(ri_data%t_3c_int_ctr_1, 1)
    1582         3140 :                CALL dbt_destroy(ri_data%t_3c_int_ctr_1(i, j))
    1583              :             END DO
    1584              :          END DO
    1585         1688 :          DEALLOCATE (ri_data%t_3c_int_ctr_1)
    1586              : 
    1587          236 :          DO j = 1, SIZE(ri_data%t_3c_int_ctr_2, 2)
    1588          354 :             DO i = 1, SIZE(ri_data%t_3c_int_ctr_2, 1)
    1589          236 :                CALL dbt_destroy(ri_data%t_3c_int_ctr_2(i, j))
    1590              :             END DO
    1591              :          END DO
    1592          236 :          DEALLOCATE (ri_data%t_3c_int_ctr_2)
    1593              : 
    1594          236 :          DO j = 1, SIZE(ri_data%t_3c_int_ctr_3, 2)
    1595          354 :             DO i = 1, SIZE(ri_data%t_3c_int_ctr_3, 1)
    1596          236 :                CALL dbt_destroy(ri_data%t_3c_int_ctr_3(i, j))
    1597              :             END DO
    1598              :          END DO
    1599          236 :          DEALLOCATE (ri_data%t_3c_int_ctr_3)
    1600              : 
    1601          296 :          DO j = 1, SIZE(ri_data%t_2c_int, 2)
    1602          474 :             DO i = 1, SIZE(ri_data%t_2c_int, 1)
    1603          356 :                CALL dbt_destroy(ri_data%t_2c_int(i, j))
    1604              :             END DO
    1605              :          END DO
    1606          296 :          DEALLOCATE (ri_data%t_2c_int)
    1607              : 
    1608         1688 :          DO j = 1, SIZE(ri_data%rho_ao_t, 2)
    1609         3520 :             DO i = 1, SIZE(ri_data%rho_ao_t, 1)
    1610         3402 :                CALL dbt_destroy(ri_data%rho_ao_t(i, j))
    1611              :             END DO
    1612              :          END DO
    1613         1950 :          DEALLOCATE (ri_data%rho_ao_t)
    1614              : 
    1615         1688 :          DO j = 1, SIZE(ri_data%ks_t, 2)
    1616         3520 :             DO i = 1, SIZE(ri_data%ks_t, 1)
    1617         3402 :                CALL dbt_destroy(ri_data%ks_t(i, j))
    1618              :             END DO
    1619              :          END DO
    1620         1950 :          DEALLOCATE (ri_data%ks_t)
    1621              : 
    1622            0 :          DEALLOCATE (ri_data%starts_array_mem_block, ri_data%ends_array_mem_block, &
    1623          118 :                      ri_data%starts_array_mem, ri_data%ends_array_mem)
    1624            0 :          DEALLOCATE (ri_data%starts_array_RI_mem_block, ri_data%ends_array_RI_mem_block, &
    1625          118 :                      ri_data%starts_array_RI_mem, ri_data%ends_array_RI_mem)
    1626              : 
    1627          870 :          DEALLOCATE (ri_data%blk_indices)
    1628          118 :          DEALLOCATE (ri_data%store_3c)
    1629           18 :       ELSE IF (ri_data%flavor == ri_mo) THEN
    1630           18 :          CALL dbt_destroy(ri_data%t_3c_int_ctr_1(1, 1))
    1631           18 :          CALL dbt_destroy(ri_data%t_3c_int_ctr_2(1, 1))
    1632           36 :          DEALLOCATE (ri_data%t_3c_int_ctr_1)
    1633           36 :          DEALLOCATE (ri_data%t_3c_int_ctr_2)
    1634              : 
    1635           40 :          DO ispin = 1, SIZE(ri_data%t_3c_int_mo, 1)
    1636           22 :             CALL dbt_destroy(ri_data%t_3c_int_mo(ispin, 1, 1))
    1637           22 :             CALL dbt_destroy(ri_data%t_3c_ctr_RI(ispin, 1, 1))
    1638           22 :             CALL dbt_destroy(ri_data%t_3c_ctr_KS(ispin, 1, 1))
    1639           40 :             CALL dbt_destroy(ri_data%t_3c_ctr_KS_copy(ispin, 1, 1))
    1640              :          END DO
    1641           54 :          DO ispin = 1, 2
    1642           54 :             CALL dbt_destroy(ri_data%t_2c_int(ispin, 1))
    1643              :          END DO
    1644           54 :          DEALLOCATE (ri_data%t_2c_int)
    1645           40 :          DEALLOCATE (ri_data%t_3c_int_mo)
    1646           40 :          DEALLOCATE (ri_data%t_3c_ctr_RI)
    1647           40 :          DEALLOCATE (ri_data%t_3c_ctr_KS)
    1648           40 :          DEALLOCATE (ri_data%t_3c_ctr_KS_copy)
    1649              :       END IF
    1650              : 
    1651          332 :       DO j = 1, SIZE(ri_data%t_2c_inv, 2)
    1652          528 :          DO i = 1, SIZE(ri_data%t_2c_inv, 1)
    1653          392 :             CALL dbt_destroy(ri_data%t_2c_inv(i, j))
    1654              :          END DO
    1655              :       END DO
    1656          332 :       DEALLOCATE (ri_data%t_2c_inv)
    1657              : 
    1658          332 :       DO j = 1, SIZE(ri_data%t_2c_pot, 2)
    1659          528 :          DO i = 1, SIZE(ri_data%t_2c_pot, 1)
    1660          392 :             CALL dbt_destroy(ri_data%t_2c_pot(i, j))
    1661              :          END DO
    1662              :       END DO
    1663          332 :       DEALLOCATE (ri_data%t_2c_pot)
    1664              : 
    1665          136 :       IF (ALLOCATED(ri_data%kp_mat_2c_pot)) THEN
    1666         1572 :          DO j = 1, SIZE(ri_data%kp_mat_2c_pot, 2)
    1667         3084 :             DO i = 1, SIZE(ri_data%kp_mat_2c_pot, 1)
    1668         3024 :                CALL dbcsr_release(ri_data%kp_mat_2c_pot(i, j))
    1669              :             END DO
    1670              :          END DO
    1671           60 :          DEALLOCATE (ri_data%kp_mat_2c_pot)
    1672              :       END IF
    1673              : 
    1674          136 :       IF (ALLOCATED(ri_data%kp_t_3c_int)) THEN
    1675         1572 :          DO i = 1, SIZE(ri_data%kp_t_3c_int)
    1676         1572 :             CALL dbt_destroy(ri_data%kp_t_3c_int(i))
    1677              :          END DO
    1678         1572 :          DEALLOCATE (ri_data%kp_t_3c_int)
    1679              :       END IF
    1680              : 
    1681          136 :       IF (ALLOCATED(ri_data%rho_ao_t)) THEN
    1682            0 :          DO j = 1, SIZE(ri_data%rho_ao_t, 2)
    1683            0 :             DO i = 1, SIZE(ri_data%rho_ao_t, 1)
    1684            0 :                CALL dbt_destroy(ri_data%rho_ao_t(i, j))
    1685              :             END DO
    1686              :          END DO
    1687            0 :          DEALLOCATE (ri_data%rho_ao_t)
    1688              :       END IF
    1689              : 
    1690          136 :       IF (ALLOCATED(ri_data%ks_t)) THEN
    1691            0 :          DO j = 1, SIZE(ri_data%ks_t, 2)
    1692            0 :             DO i = 1, SIZE(ri_data%ks_t, 1)
    1693            0 :                CALL dbt_destroy(ri_data%ks_t(i, j))
    1694              :             END DO
    1695              :          END DO
    1696            0 :          DEALLOCATE (ri_data%ks_t)
    1697              :       END IF
    1698              : 
    1699          136 :       IF (ALLOCATED(ri_data%iatom_to_subgroup)) THEN
    1700          180 :          DO i = 1, SIZE(ri_data%iatom_to_subgroup)
    1701          180 :             DEALLOCATE (ri_data%iatom_to_subgroup(i)%array)
    1702              :          END DO
    1703           60 :          DEALLOCATE (ri_data%iatom_to_subgroup)
    1704              :       END IF
    1705              : 
    1706          136 :       CALL timestop(handle)
    1707          136 :    END SUBROUTINE hfx_ri_release
    1708              : 
    1709              : ! **************************************************************************************************
    1710              : !> \brief - This routine allocates and initializes the basis_info and basis_parameter types
    1711              : !> \param basis_parameter ...
    1712              : !> \param basis_info ...
    1713              : !> \param qs_kind_set ...
    1714              : !> \param basis_type ...
    1715              : !> \par History
    1716              : !>      07.2011 refactored
    1717              : ! **************************************************************************************************
    1718         2186 :    SUBROUTINE hfx_create_basis_types(basis_parameter, basis_info, qs_kind_set, &
    1719              :                                      basis_type)
    1720              :       TYPE(hfx_basis_type), DIMENSION(:), POINTER        :: basis_parameter
    1721              :       TYPE(hfx_basis_info_type)                          :: basis_info
    1722              :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
    1723              :       CHARACTER(LEN=*)                                   :: basis_type
    1724              : 
    1725              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'hfx_create_basis_types'
    1726              : 
    1727              :       INTEGER :: co_counter, handle, i, ikind, ipgf, iset, j, k, la, max_am_kind, max_coeff, &
    1728              :          max_nsgfl, max_pgf, max_pgf_kind, max_set, nkind, nl_count, nset, nseta, offset_a, &
    1729              :          offset_a1, s_offset_nl_a, sgfa, so_counter
    1730         2186 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, la_min, npgfa, nshell
    1731         2186 :       INTEGER, DIMENSION(:, :), POINTER                  :: first_sgfa, nl_a
    1732         2186 :       REAL(dp), DIMENSION(:, :), POINTER                 :: sphi_a
    1733              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_a
    1734              : 
    1735         2186 :       CALL timeset(routineN, handle)
    1736              : 
    1737              :       ! BASIS parameter
    1738         2186 :       nkind = SIZE(qs_kind_set, 1)
    1739              :       !
    1740        10556 :       ALLOCATE (basis_parameter(nkind))
    1741         6184 :       max_set = 0
    1742         6184 :       DO ikind = 1, nkind
    1743         3998 :          CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_a, basis_type=basis_type)
    1744              :          CALL get_qs_kind_set(qs_kind_set, &
    1745              :                               maxsgf=basis_info%max_sgf, &
    1746              :                               maxnset=basis_info%max_set, &
    1747              :                               maxlgto=basis_info%max_am, &
    1748         3998 :                               basis_type=basis_type)
    1749         3998 :          IF (basis_info%max_set < max_set) CPABORT("UNEXPECTED MAX_SET")
    1750         3998 :          max_set = MAX(max_set, basis_info%max_set)
    1751              :          CALL get_gto_basis_set(gto_basis_set=orb_basis_a, &
    1752              :                                 lmax=basis_parameter(ikind)%lmax, &
    1753              :                                 lmin=basis_parameter(ikind)%lmin, &
    1754              :                                 npgf=basis_parameter(ikind)%npgf, &
    1755              :                                 nset=basis_parameter(ikind)%nset, &
    1756              :                                 zet=basis_parameter(ikind)%zet, &
    1757              :                                 nsgf_set=basis_parameter(ikind)%nsgf, &
    1758              :                                 first_sgf=basis_parameter(ikind)%first_sgf, &
    1759              :                                 sphi=basis_parameter(ikind)%sphi, &
    1760              :                                 gcc=basis_parameter(ikind)%gcc, &
    1761              :                                 nsgf=basis_parameter(ikind)%nsgf_total, &
    1762              :                                 l=basis_parameter(ikind)%nl, &
    1763              :                                 nshell=basis_parameter(ikind)%nshell, &
    1764              :                                 set_radius=basis_parameter(ikind)%set_radius, &
    1765              :                                 pgf_radius=basis_parameter(ikind)%pgf_radius, &
    1766         6184 :                                 kind_radius=basis_parameter(ikind)%kind_radius)
    1767              :       END DO
    1768         6184 :       DO ikind = 1, nkind
    1769        15992 :          ALLOCATE (basis_parameter(ikind)%nsgfl(0:basis_info%max_am, max_set))
    1770        49604 :          basis_parameter(ikind)%nsgfl = 0
    1771         3998 :          nset = basis_parameter(ikind)%nset
    1772         3998 :          nshell => basis_parameter(ikind)%nshell
    1773        17548 :          DO iset = 1, nset
    1774        45580 :             DO i = 0, basis_info%max_am
    1775        30218 :                nl_count = 0
    1776        70570 :                DO j = 1, nshell(iset)
    1777        70570 :                   IF (basis_parameter(ikind)%nl(j, iset) == i) nl_count = nl_count + 1
    1778              :                END DO
    1779        41582 :                basis_parameter(ikind)%nsgfl(i, iset) = nl_count
    1780              :             END DO
    1781              :          END DO
    1782              :       END DO
    1783              : 
    1784              :       max_nsgfl = 0
    1785              :       max_pgf = 0
    1786         6184 :       DO ikind = 1, nkind
    1787         3998 :          max_coeff = 0
    1788         3998 :          max_am_kind = 0
    1789         3998 :          max_pgf_kind = 0
    1790         3998 :          npgfa => basis_parameter(ikind)%npgf
    1791         3998 :          nseta = basis_parameter(ikind)%nset
    1792         3998 :          nl_a => basis_parameter(ikind)%nsgfl
    1793         3998 :          la_max => basis_parameter(ikind)%lmax
    1794         3998 :          la_min => basis_parameter(ikind)%lmin
    1795        15362 :          DO iset = 1, nseta
    1796        11364 :             max_pgf_kind = MAX(max_pgf_kind, npgfa(iset))
    1797              :             max_pgf = MAX(max_pgf, npgfa(iset))
    1798        29278 :             DO la = la_min(iset), la_max(iset)
    1799        13916 :                max_nsgfl = MAX(max_nsgfl, nl_a(la, iset))
    1800        13916 :                max_coeff = MAX(max_coeff, nso(la)*nl_a(la, iset)*nco(la))
    1801        25280 :                max_am_kind = MAX(max_am_kind, la)
    1802              :             END DO
    1803              :          END DO
    1804        23988 :          ALLOCATE (basis_parameter(ikind)%sphi_ext(max_coeff, 0:max_am_kind, max_pgf_kind, nseta))
    1805      2213272 :          basis_parameter(ikind)%sphi_ext = 0.0_dp
    1806              :       END DO
    1807              : 
    1808         6184 :       DO ikind = 1, nkind
    1809         3998 :          sphi_a => basis_parameter(ikind)%sphi
    1810         3998 :          nseta = basis_parameter(ikind)%nset
    1811         3998 :          la_max => basis_parameter(ikind)%lmax
    1812         3998 :          la_min => basis_parameter(ikind)%lmin
    1813         3998 :          npgfa => basis_parameter(ikind)%npgf
    1814         3998 :          first_sgfa => basis_parameter(ikind)%first_sgf
    1815         3998 :          nl_a => basis_parameter(ikind)%nsgfl
    1816        17548 :          DO iset = 1, nseta
    1817        11364 :             sgfa = first_sgfa(1, iset)
    1818        36866 :             DO ipgf = 1, npgfa(iset)
    1819        21504 :                offset_a1 = (ipgf - 1)*ncoset(la_max(iset))
    1820        21504 :                s_offset_nl_a = 0
    1821        60930 :                DO la = la_min(iset), la_max(iset)
    1822        28062 :                   offset_a = offset_a1 + ncoset(la - 1)
    1823              :                   co_counter = 0
    1824        28062 :                   co_counter = co_counter + 1
    1825        28062 :                   so_counter = 0
    1826        87312 :                   DO k = sgfa + s_offset_nl_a, sgfa + s_offset_nl_a + nso(la)*nl_a(la, iset) - 1
    1827       249700 :                      DO i = offset_a + 1, offset_a + nco(la)
    1828       162388 :                         so_counter = so_counter + 1
    1829       221638 :                         basis_parameter(ikind)%sphi_ext(so_counter, la, ipgf, iset) = sphi_a(i, k)
    1830              :                      END DO
    1831              :                   END DO
    1832        49566 :                   s_offset_nl_a = s_offset_nl_a + nso(la)*(nl_a(la, iset))
    1833              :                END DO
    1834              :             END DO
    1835              :          END DO
    1836              :       END DO
    1837              : 
    1838         2186 :       CALL timestop(handle)
    1839              : 
    1840         2186 :    END SUBROUTINE hfx_create_basis_types
    1841              : 
    1842              : ! **************************************************************************************************
    1843              : !> \brief ...
    1844              : !> \param basis_parameter ...
    1845              : ! **************************************************************************************************
    1846         2186 :    SUBROUTINE hfx_release_basis_types(basis_parameter)
    1847              :       TYPE(hfx_basis_type), DIMENSION(:), POINTER        :: basis_parameter
    1848              : 
    1849              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'hfx_release_basis_types'
    1850              : 
    1851              :       INTEGER                                            :: handle, i
    1852              : 
    1853         2186 :       CALL timeset(routineN, handle)
    1854              : 
    1855              :       !! BASIS parameter
    1856         6184 :       DO i = 1, SIZE(basis_parameter)
    1857         3998 :          DEALLOCATE (basis_parameter(i)%nsgfl)
    1858         6184 :          DEALLOCATE (basis_parameter(i)%sphi_ext)
    1859              :       END DO
    1860         2186 :       DEALLOCATE (basis_parameter)
    1861         2186 :       CALL timestop(handle)
    1862              : 
    1863         2186 :    END SUBROUTINE hfx_release_basis_types
    1864              : 
    1865              : ! **************************************************************************************************
    1866              : !> \brief - Parses the memory section
    1867              : !> \param memory_parameter ...
    1868              : !> \param hf_sub_section ...
    1869              : !> \param storage_id ...
    1870              : !> \param i_thread ...
    1871              : !> \param n_threads ...
    1872              : !> \param para_env ...
    1873              : !> \param irep ...
    1874              : !> \param skip_disk ...
    1875              : !> \param skip_in_core_forces ...
    1876              : ! **************************************************************************************************
    1877         2488 :    SUBROUTINE parse_memory_section(memory_parameter, hf_sub_section, storage_id, &
    1878              :                                    i_thread, n_threads, para_env, irep, skip_disk, skip_in_core_forces)
    1879              :       TYPE(hfx_memory_type)                              :: memory_parameter
    1880              :       TYPE(section_vals_type), POINTER                   :: hf_sub_section
    1881              :       INTEGER, INTENT(OUT), OPTIONAL                     :: storage_id
    1882              :       INTEGER, INTENT(IN), OPTIONAL                      :: i_thread, n_threads
    1883              :       TYPE(mp_para_env_type), OPTIONAL                   :: para_env
    1884              :       INTEGER, INTENT(IN), OPTIONAL                      :: irep
    1885              :       LOGICAL, INTENT(IN)                                :: skip_disk, skip_in_core_forces
    1886              : 
    1887              :       CHARACTER(LEN=512)                                 :: error_msg
    1888              :       CHARACTER(LEN=default_path_length)                 :: char_val, filename, orig_wd
    1889              :       INTEGER                                            :: int_val, stat
    1890              :       LOGICAL                                            :: check, logic_val
    1891              :       REAL(dp)                                           :: real_val
    1892              : 
    1893              :       check = (PRESENT(storage_id) .EQV. PRESENT(i_thread)) .AND. &
    1894              :               (PRESENT(storage_id) .EQV. PRESENT(n_threads)) .AND. &
    1895              :               (PRESENT(storage_id) .EQV. PRESENT(para_env)) .AND. &
    1896         2488 :               (PRESENT(storage_id) .EQV. PRESENT(irep))
    1897            0 :       CPASSERT(check)
    1898              : 
    1899              :       ! Memory Storage
    1900         2488 :       CALL section_vals_val_get(hf_sub_section, "MAX_MEMORY", i_val=int_val)
    1901         2488 :       memory_parameter%max_memory = int_val
    1902         2488 :       memory_parameter%max_compression_counter = int_val*1024_int_8*128_int_8
    1903         2488 :       CALL section_vals_val_get(hf_sub_section, "EPS_STORAGE", r_val=real_val)
    1904         2488 :       memory_parameter%eps_storage_scaling = real_val
    1905         2488 :       IF (int_val == 0) THEN
    1906           20 :          memory_parameter%do_all_on_the_fly = .TRUE.
    1907              :       ELSE
    1908         2468 :          memory_parameter%do_all_on_the_fly = .FALSE.
    1909              :       END IF
    1910         2488 :       memory_parameter%cache_size = CACHE_SIZE
    1911         2488 :       memory_parameter%bits_max_val = BITS_MAX_VAL
    1912         2488 :       memory_parameter%actual_memory_usage = 1
    1913         2488 :       IF (.NOT. skip_in_core_forces) THEN
    1914         1488 :          CALL section_vals_val_get(hf_sub_section, "TREAT_FORCES_IN_CORE", l_val=logic_val)
    1915         1488 :          memory_parameter%treat_forces_in_core = logic_val
    1916              :       END IF
    1917              : 
    1918              :       ! ** IF MAX_MEM == 0 overwrite this flag to false
    1919         2488 :       IF (memory_parameter%do_all_on_the_fly) memory_parameter%treat_forces_in_core = .FALSE.
    1920              : 
    1921              :       ! Disk Storage
    1922         2488 :       IF (.NOT. skip_disk) THEN
    1923         1488 :          memory_parameter%actual_memory_usage_disk = 1
    1924         1488 :          CALL section_vals_val_get(hf_sub_section, "MAX_DISK_SPACE", i_val=int_val)
    1925         1488 :          memory_parameter%max_compression_counter_disk = int_val*1024_int_8*128_int_8
    1926         1488 :          IF (int_val == 0) THEN
    1927         1482 :             memory_parameter%do_disk_storage = .FALSE.
    1928              :          ELSE
    1929            6 :             memory_parameter%do_disk_storage = .TRUE.
    1930              :          END IF
    1931         1488 :          CALL section_vals_val_get(hf_sub_section, "STORAGE_LOCATION", c_val=char_val)
    1932         1488 :          CALL compress(char_val, .TRUE.)
    1933              :          !! Add ending / if necessary
    1934              : 
    1935         1488 :          IF (SCAN(char_val, "/", .TRUE.) /= LEN_TRIM(char_val)) THEN
    1936         1488 :             WRITE (filename, '(A,A)') TRIM(char_val), "/"
    1937         1488 :             CALL compress(filename)
    1938              :          ELSE
    1939            0 :             filename = TRIM(char_val)
    1940              :          END IF
    1941         1488 :          CALL compress(filename, .TRUE.)
    1942              : 
    1943              :          !! quickly check if we can write on storage_location
    1944         1488 :          CALL m_getcwd(orig_wd)
    1945         1488 :          CALL m_chdir(TRIM(filename), stat)
    1946         1488 :          IF (stat /= 0) THEN
    1947            0 :             WRITE (error_msg, '(A,A,A)') "Request for disk storage failed due to unknown error while writing to ", &
    1948            0 :                TRIM(filename), ". Please check STORAGE_LOCATION"
    1949            0 :             CPABORT(error_msg)
    1950              :          END IF
    1951         1488 :          CALL m_chdir(orig_wd, stat)
    1952              : 
    1953         1488 :          memory_parameter%storage_location = filename
    1954         1488 :          CALL compress(memory_parameter%storage_location, .TRUE.)
    1955              :       ELSE
    1956         1000 :          memory_parameter%do_disk_storage = .FALSE.
    1957              :       END IF
    1958         2488 :       IF (PRESENT(storage_id)) THEN
    1959         1488 :          storage_id = (irep - 1)*para_env%num_pe*n_threads + para_env%mepos*n_threads + i_thread - 1
    1960              :       END IF
    1961         2488 :    END SUBROUTINE parse_memory_section
    1962              : 
    1963              : ! **************************************************************************************************
    1964              : !> \brief - This routine deallocates all data structures
    1965              : !> \param x_data contains all relevant data structures for hfx runs
    1966              : !> \par History
    1967              : !>      09.2007 created [Manuel Guidon]
    1968              : !> \author Manuel Guidon
    1969              : ! **************************************************************************************************
    1970         1478 :    SUBROUTINE hfx_release(x_data)
    1971              :       TYPE(hfx_type), DIMENSION(:, :), POINTER           :: x_data
    1972              : 
    1973              :       INTEGER                                            :: i, i_thread, irep, n_rep_hf, n_threads
    1974              :       TYPE(cp_logger_type), POINTER                      :: logger
    1975              :       TYPE(hfx_type), POINTER                            :: actual_x_data
    1976              : 
    1977              : !! There might be 2 hf sections
    1978              : 
    1979         1478 :       n_rep_hf = x_data(1, 1)%n_rep_hf
    1980         1478 :       n_threads = SIZE(x_data, 2)
    1981              : 
    1982         1478 :       IF (x_data(1, 1)%potential_parameter%potential_type == do_potential_truncated .OR. &
    1983              :           x_data(1, 1)%potential_parameter%potential_type == do_potential_mix_cl_trunc) THEN
    1984          376 :          init_t_c_g0_lmax = -1
    1985          376 :          CALL free_C0()
    1986              :       END IF
    1987         2956 :       DO i_thread = 1, n_threads
    1988         4444 :          DO irep = 1, n_rep_hf
    1989         1488 :             actual_x_data => x_data(irep, i_thread)
    1990         1488 :             DEALLOCATE (actual_x_data%neighbor_cells)
    1991         1488 :             DEALLOCATE (actual_x_data%distribution_energy)
    1992         1488 :             DEALLOCATE (actual_x_data%distribution_forces)
    1993              : 
    1994         1488 :             IF (actual_x_data%load_balance_parameter%blocks_initialized) THEN
    1995         1366 :                DEALLOCATE (actual_x_data%blocks)
    1996         1366 :                IF (i_thread == 1) THEN
    1997         1366 :                   DEALLOCATE (actual_x_data%pmax_block)
    1998              :                END IF
    1999              :             END IF
    2000              : 
    2001         1488 :             IF (i_thread == 1) THEN
    2002         1488 :                DEALLOCATE (actual_x_data%atomic_pair_list)
    2003         1488 :                DEALLOCATE (actual_x_data%atomic_pair_list_forces)
    2004              :             END IF
    2005              : 
    2006         1488 :             IF (actual_x_data%screening_parameter%do_initial_p_screening .OR. &
    2007              :                 actual_x_data%screening_parameter%do_p_screening_forces) THEN
    2008         1458 :                IF (i_thread == 1) THEN
    2009         1458 :                   DEALLOCATE (actual_x_data%pmax_atom)
    2010         5852 :                   DO i = 1, SIZE(actual_x_data%initial_p)
    2011         5852 :                      DEALLOCATE (actual_x_data%initial_p(i)%p_kind)
    2012              :                   END DO
    2013         1458 :                   DEALLOCATE (actual_x_data%initial_p)
    2014              : 
    2015         1458 :                   DEALLOCATE (actual_x_data%pmax_atom_forces)
    2016         5852 :                   DO i = 1, SIZE(actual_x_data%initial_p_forces)
    2017         5852 :                      DEALLOCATE (actual_x_data%initial_p_forces(i)%p_kind)
    2018              :                   END DO
    2019         1458 :                   DEALLOCATE (actual_x_data%initial_p_forces)
    2020              :                END IF
    2021         1458 :                DEALLOCATE (actual_x_data%map_atom_to_kind_atom)
    2022              :             END IF
    2023         1488 :             IF (i_thread == 1) THEN
    2024         1488 :                DEALLOCATE (actual_x_data%is_assoc_atomic_block)
    2025         1488 :                DEALLOCATE (actual_x_data%atomic_block_offset)
    2026         1488 :                DEALLOCATE (actual_x_data%set_offset)
    2027         1488 :                DEALLOCATE (actual_x_data%block_offset)
    2028              :             END IF
    2029              : 
    2030              :             !! BASIS parameter
    2031         1488 :             CALL hfx_release_basis_types(actual_x_data%basis_parameter)
    2032              : 
    2033              :             !MK Release libint and libderiv data structure
    2034         1488 :             CALL cp_libint_cleanup_eri(actual_x_data%lib)
    2035         1488 :             CALL cp_libint_cleanup_eri1(actual_x_data%lib_deriv)
    2036         1488 :             CALL cp_libint_static_cleanup()
    2037              : 
    2038              :             !! Deallocate containers
    2039         1488 :             CALL dealloc_containers(actual_x_data%store_ints, actual_x_data%memory_parameter%actual_memory_usage)
    2040         1488 :             CALL dealloc_containers(actual_x_data%store_forces, actual_x_data%memory_parameter%actual_memory_usage)
    2041              : 
    2042              :             !! Deallocate containers
    2043              :             CALL hfx_init_container(actual_x_data%store_ints%maxval_container_disk, &
    2044              :                                     actual_x_data%memory_parameter%actual_memory_usage_disk, &
    2045         1488 :                                     .FALSE.)
    2046         1488 :             IF (actual_x_data%memory_parameter%do_disk_storage) THEN
    2047            6 :                CALL close_file(unit_number=actual_x_data%store_ints%maxval_container_disk%unit, file_status="DELETE")
    2048              :             END IF
    2049         1488 :             DEALLOCATE (actual_x_data%store_ints%maxval_container_disk%first)
    2050         1488 :             DEALLOCATE (actual_x_data%store_ints%maxval_container_disk)
    2051              : 
    2052        96720 :             DO i = 1, 64
    2053              :                CALL hfx_init_container(actual_x_data%store_ints%integral_containers_disk(i), &
    2054              :                                        actual_x_data%memory_parameter%actual_memory_usage_disk, &
    2055        95232 :                                        .FALSE.)
    2056        95232 :                IF (actual_x_data%memory_parameter%do_disk_storage) THEN
    2057          384 :                   CALL close_file(unit_number=actual_x_data%store_ints%integral_containers_disk(i)%unit, file_status="DELETE")
    2058              :                END IF
    2059        96720 :                DEALLOCATE (actual_x_data%store_ints%integral_containers_disk(i)%first)
    2060              :             END DO
    2061         1488 :             DEALLOCATE (actual_x_data%store_ints%integral_containers_disk)
    2062              : 
    2063              :             ! ** screening functions
    2064         1488 :             IF (actual_x_data%screen_funct_is_initialized) THEN
    2065         1366 :                DEALLOCATE (actual_x_data%screen_funct_coeffs_set)
    2066         1366 :                DEALLOCATE (actual_x_data%screen_funct_coeffs_kind)
    2067         1366 :                DEALLOCATE (actual_x_data%pair_dist_radii_pgf)
    2068         1366 :                DEALLOCATE (actual_x_data%screen_funct_coeffs_pgf)
    2069         1366 :                actual_x_data%screen_funct_is_initialized = .FALSE.
    2070              :             END IF
    2071              : 
    2072              :             ! ** maps
    2073         1488 :             IF (ASSOCIATED(actual_x_data%map_atoms_to_cpus)) THEN
    2074         4096 :                DO i = 1, SIZE(actual_x_data%map_atoms_to_cpus)
    2075         2730 :                   DEALLOCATE (actual_x_data%map_atoms_to_cpus(i)%iatom_list)
    2076         4096 :                   DEALLOCATE (actual_x_data%map_atoms_to_cpus(i)%jatom_list)
    2077              :                END DO
    2078         1366 :                DEALLOCATE (actual_x_data%map_atoms_to_cpus)
    2079              :             END IF
    2080              : 
    2081         1488 :             IF (actual_x_data%do_hfx_ri) THEN
    2082          114 :                CALL hfx_ri_release(actual_x_data%ri_data)
    2083          114 :                IF (ASSOCIATED(actual_x_data%ri_data%ri_section)) THEN
    2084          114 :                   logger => cp_get_default_logger()
    2085              :                   CALL cp_print_key_finished_output(actual_x_data%ri_data%unit_nr_dbcsr, logger, actual_x_data%ri_data%ri_section, &
    2086          114 :                                                     "PRINT%RI_INFO")
    2087              :                END IF
    2088          114 :                IF (ASSOCIATED(actual_x_data%ri_data%hfx_section)) THEN
    2089          114 :                   logger => cp_get_default_logger()
    2090              :                   CALL cp_print_key_finished_output(actual_x_data%ri_data%unit_nr, logger, actual_x_data%ri_data%hfx_section, &
    2091          114 :                                                     "HF_INFO")
    2092              :                END IF
    2093          114 :                DEALLOCATE (actual_x_data%ri_data)
    2094              :             END IF
    2095              : 
    2096              :             ! ACE cleanup — just reset scalars, ace_W is managed elsewhere
    2097         1488 :             actual_x_data%use_ace = .FALSE.
    2098         1488 :             actual_x_data%ace_is_built = .FALSE.
    2099         2966 :             actual_x_data%ace_build_counter = 0
    2100              :          END DO
    2101              : 
    2102              :       END DO
    2103              : 
    2104         1478 :       DEALLOCATE (x_data)
    2105         1478 :    END SUBROUTINE hfx_release
    2106              : 
    2107              : ! **************************************************************************************************
    2108              : !> \brief - This routine computes the neighbor cells that are taken into account
    2109              : !>        in periodic runs
    2110              : !> \param x_data contains all relevant data structures for hfx runs
    2111              : !> \param pbc_shells number of shells taken into account
    2112              : !> \param cell cell
    2113              : !> \param i_thread current thread ID
    2114              : !> \param nkp_grid ...
    2115              : !> \par History
    2116              : !>      09.2007 created [Manuel Guidon]
    2117              : !> \author Manuel Guidon
    2118              : ! **************************************************************************************************
    2119        10281 :    SUBROUTINE hfx_create_neighbor_cells(x_data, pbc_shells, cell, i_thread, nkp_grid)
    2120              :       TYPE(hfx_type), POINTER                            :: x_data
    2121              :       INTEGER, INTENT(INOUT)                             :: pbc_shells
    2122              :       TYPE(cell_type), POINTER                           :: cell
    2123              :       INTEGER, INTENT(IN)                                :: i_thread
    2124              :       INTEGER, DIMENSION(3), OPTIONAL                    :: nkp_grid
    2125              : 
    2126              :       CHARACTER(LEN=512)                                 :: error_msg
    2127              :       CHARACTER(LEN=64)                                  :: char_nshells
    2128              :       INTEGER :: i, idx, ikind, ipgf, iset, ishell, j, jkind, jpgf, jset, jshell, k, kshell, l, &
    2129              :          m(3), max_shell, nkp(3), nseta, nsetb, perd(3), total_number_of_cells, ub, ub_max
    2130        10281 :       INTEGER, DIMENSION(:), POINTER                     :: la_max, lb_max, npgfa, npgfb
    2131              :       LOGICAL                                            :: do_kpoints, image_cell_found, &
    2132              :                                                             nothing_more_to_add
    2133              :       REAL(dp) :: cross_product(3), dist_min, distance(14), l_min, normal(3, 6), P(3, 14), &
    2134              :          plane_vector(3, 2), point_in_plane(3), r(3), R1, R_max, R_max_stress, s(3), x, y, z, Zeta1
    2135        10281 :       REAL(dp), DIMENSION(:, :), POINTER                 :: zeta, zetb
    2136        10281 :       TYPE(hfx_cell_type), ALLOCATABLE, DIMENSION(:)     :: tmp_neighbor_cells
    2137              : 
    2138        10281 :       total_number_of_cells = 0
    2139              : 
    2140        41124 :       nkp = 1
    2141        10281 :       IF (PRESENT(nkp_grid)) nkp = nkp_grid
    2142        40944 :       do_kpoints = ANY(nkp > 1)
    2143              : 
    2144              :       ! ** Check some settings
    2145        10281 :       IF (i_thread == 1) THEN
    2146              :          IF (x_data%potential_parameter%potential_type /= do_potential_truncated .AND. &
    2147              :              x_data%potential_parameter%potential_type /= do_potential_short .AND. &
    2148          448 :              x_data%potential_parameter%potential_type /= do_potential_mix_cl_trunc .AND. &
    2149              :              x_data%potential_parameter%potential_type /= do_potential_id) THEN
    2150              :             CALL cp_warn(__LOCATION__, &
    2151              :                          "Periodic Hartree Fock calculation requested without use "// &
    2152              :                          "of a truncated or shortrange potential. This may lead to unphysical total energies. "// &
    2153          104 :                          "Use a truncated  potential to avoid possible problems.")
    2154          344 :          ELSE IF (x_data%potential_parameter%potential_type /= do_potential_id) THEN
    2155              :             !If k-points, use the Born-von Karman super cell as reference
    2156              :             l_min = MIN(REAL(nkp(1), dp)*plane_distance(1, 0, 0, cell), &
    2157              :                         REAL(nkp(2), dp)*plane_distance(0, 1, 0, cell), &
    2158          316 :                         REAL(nkp(3), dp)*plane_distance(0, 0, 1, cell))
    2159          316 :             l_min = 0.5_dp*l_min
    2160          316 :             IF (x_data%potential_parameter%cutoff_radius >= l_min) THEN
    2161           38 :                IF (.NOT. do_kpoints) THEN
    2162              :                   WRITE (error_msg, "(A,F6.3,A,F6.3,A)") &
    2163              :                      "Periodic Hartree Fock calculation requested with the use "// &
    2164              :                      "of a truncated or shortrange potential. "// &
    2165           38 :                      "The cutoff radius (", x_data%potential_parameter%cutoff_radius*a_bohr*1e+10_dp, &
    2166           38 :                      " A) is larger than half the minimal cell dimension (", &
    2167           38 :                      l_min*a_bohr*1e+10_dp, " A). This may lead to unphysical "// &
    2168              :                      "total energies. Reduce the cutoff radius in order to avoid "// &
    2169           76 :                      "possible problems."
    2170              :                ELSE
    2171              :                   WRITE (error_msg, "(A,F6.3,A,F6.3,A)") &
    2172              :                      "K-point Hartree-Fock calculation requested with the use of a "// &
    2173            0 :                      "truncated or shortrange potential. The cutoff radius (", &
    2174            0 :                      x_data%potential_parameter%cutoff_radius*a_bohr*1e+10_dp, &
    2175            0 :                      " A) is larger than half the minimal Born-von Karman supercell dimension (", &
    2176            0 :                      l_min*a_bohr*1e+10_dp, " A). This may lead "// &
    2177              :                      "to unphysical total energies. Reduce the cutoff radius or increase "// &
    2178            0 :                      "the number of K-points in order to avoid possible problems."
    2179              :                END IF
    2180           38 :                CALL cp_warn(__LOCATION__, error_msg)
    2181              :             END IF
    2182              :          END IF
    2183              :       END IF
    2184              : 
    2185        17717 :       SELECT CASE (x_data%potential_parameter%potential_type)
    2186              :       CASE (do_potential_truncated, do_potential_mix_cl_trunc, do_potential_short)
    2187         7436 :          R_max = 0.0_dp
    2188        20546 :          DO ikind = 1, SIZE(x_data%basis_parameter)
    2189        13110 :             la_max => x_data%basis_parameter(ikind)%lmax
    2190        13110 :             zeta => x_data%basis_parameter(ikind)%zet
    2191        13110 :             nseta = x_data%basis_parameter(ikind)%nset
    2192        13110 :             npgfa => x_data%basis_parameter(ikind)%npgf
    2193        45124 :             DO jkind = 1, SIZE(x_data%basis_parameter)
    2194        24578 :                lb_max => x_data%basis_parameter(jkind)%lmax
    2195        24578 :                zetb => x_data%basis_parameter(jkind)%zet
    2196        24578 :                nsetb = x_data%basis_parameter(jkind)%nset
    2197        24578 :                npgfb => x_data%basis_parameter(jkind)%npgf
    2198       102590 :                DO iset = 1, nseta
    2199       280060 :                   DO jset = 1, nsetb
    2200       582586 :                      DO ipgf = 1, npgfa(iset)
    2201      1123098 :                         DO jpgf = 1, npgfb(jset)
    2202       605414 :                            Zeta1 = zeta(ipgf, iset) + zetb(jpgf, jset)
    2203              :                            R1 = 1.0_dp/SQRT(Zeta1)*mul_fact(la_max(iset) + lb_max(jset))* &
    2204       605414 :                                 SQRT(-LOG(x_data%screening_parameter%eps_schwarz))
    2205       932518 :                            R_max = MAX(R1, R_max)
    2206              :                         END DO
    2207              :                      END DO
    2208              :                   END DO
    2209              :                END DO
    2210              :             END DO
    2211              :          END DO
    2212              : 
    2213         7436 :          R_max = 2.0_dp*R_max + x_data%potential_parameter%cutoff_radius
    2214         7436 :          nothing_more_to_add = .FALSE.
    2215         7436 :          max_shell = 0
    2216         7436 :          total_number_of_cells = 0
    2217         7436 :          ub = 1
    2218         7436 :          DEALLOCATE (x_data%neighbor_cells)
    2219        59488 :          ALLOCATE (x_data%neighbor_cells(1))
    2220        29744 :          x_data%neighbor_cells(1)%cell = 0.0_dp
    2221        29744 :          x_data%neighbor_cells(1)%cell_r = 0.0_dp
    2222              : 
    2223              :          ! ** What follows is kind of a ray tracing algorithm
    2224              :          ! ** Given a image cell (ishell, jshell, kshell) we try to figure out the
    2225              :          ! ** shortest distance of this image cell to the basic unit cell (0,0,0), i.e. the point
    2226              :          ! ** (0.0, 0.0, 0.0)
    2227              :          ! ** This is achieved by checking the 8 Corners of the cell, and, in addition, the shortest distance
    2228              :          ! ** to all 6 faces. The faces are only taken into account if the penetration point of the normal
    2229              :          ! ** to the plane defined by a face lies within this face.
    2230              :          ! ** This is very fast, because no trigonometric functions are being used
    2231              :          ! ** The points are defined as follows
    2232              :          ! **
    2233              :          ! **
    2234              :          ! **               _________________________
    2235              :          ! **              /P4____________________P8/|
    2236              :          ! **             / / ___________________/ / |
    2237              :          ! **            / / /| |               / /  |       z
    2238              :          ! **           / / / | |              / / . |      /|\  _ y
    2239              :          ! **          / / /| | |             / / /| |       |   /|
    2240              :          ! **         / / / | | |            / / / | |       |  /
    2241              :          ! **        / / /  | | |           / / /| | |       | /
    2242              :          ! **       / /_/___| | |__________/ / / | | |       |/
    2243              :          ! **      /P2______| | |_________P6/ /  | | |       ----------> x
    2244              :          ! **      | _______| | |_________| | |  | | |
    2245              :          ! **      | | |    | | |________________| | |
    2246              :          ! **      | | |    |P3___________________P7 |
    2247              :          ! **      | | |   / / _________________  / /
    2248              :          ! **      | | |  / / /           | | |/ / /
    2249              :          ! **      | | | / / /            | | | / /
    2250              :          ! **      | | |/ / /             | | |/ /
    2251              :          ! **      | | | / /              | | ' /
    2252              :          ! **      | | |/_/_______________| |  /
    2253              :          ! **      | |____________________| | /
    2254              :          ! **      |P1_____________________P5/
    2255              :          ! **
    2256              :          ! **
    2257              : 
    2258              :          DO WHILE (.NOT. nothing_more_to_add)
    2259              :             ! Calculate distances to the eight points P1 to P8
    2260        30424 :             image_cell_found = .FALSE.
    2261      1307872 :             ALLOCATE (tmp_neighbor_cells(1:ub))
    2262      1034056 :             DO i = 1, ub - 1
    2263      1034056 :                tmp_neighbor_cells(i) = x_data%neighbor_cells(i)
    2264              :             END DO
    2265        30424 :             ub_max = (2*max_shell + 1)**3
    2266        30424 :             DEALLOCATE (x_data%neighbor_cells)
    2267      4734460 :             ALLOCATE (x_data%neighbor_cells(1:ub_max))
    2268      1034056 :             DO i = 1, ub - 1
    2269      1034056 :                x_data%neighbor_cells(i) = tmp_neighbor_cells(i)
    2270              :             END DO
    2271      3487436 :             DO i = ub, ub_max
    2272     13828048 :                x_data%neighbor_cells(i)%cell = 0.0_dp
    2273     13858472 :                x_data%neighbor_cells(i)%cell_r = 0.0_dp
    2274              :             END DO
    2275              : 
    2276        30424 :             DEALLOCATE (tmp_neighbor_cells)
    2277              : 
    2278       121696 :             perd(1:3) = x_data%periodic_parameter%perd(1:3)
    2279              : 
    2280       156092 :             DO ishell = -max_shell*perd(1), max_shell*perd(1)
    2281       850944 :             DO jshell = -max_shell*perd(2), max_shell*perd(2)
    2282      5164836 :             DO kshell = -max_shell*perd(3), max_shell*perd(3)
    2283      4344316 :                IF (MAX(ABS(ishell), ABS(jshell), ABS(kshell)) /= max_shell) CYCLE
    2284              :                idx = 0
    2285      8594784 :                DO j = 0, 1
    2286      5729856 :                   x = -1.0_dp/2.0_dp + j*1.0_dp
    2287     20054496 :                   DO k = 0, 1
    2288     11459712 :                      y = -1.0_dp/2.0_dp + k*1.0_dp
    2289     40108992 :                      DO l = 0, 1
    2290     22919424 :                         z = -1.0_dp/2.0_dp + l*1.0_dp
    2291     22919424 :                         idx = idx + 1
    2292     22919424 :                         P(1, idx) = x + ishell
    2293     22919424 :                         P(2, idx) = y + jshell
    2294     22919424 :                         P(3, idx) = z + kshell
    2295     22919424 :                         CALL scaled_to_real(r, P(:, idx), cell)
    2296     91677696 :                         distance(idx) = SQRT(SUM(r**2))
    2297    103137408 :                         P(1:3, idx) = r
    2298              :                      END DO
    2299              :                   END DO
    2300              :                END DO
    2301              :                ! Now check distance to Faces and only take them into account if the base point lies within quadrilateral
    2302              : 
    2303              :                ! Face A (1342) 1 is the reference
    2304      2864928 :                idx = idx + 1
    2305     11459712 :                plane_vector(:, 1) = P(:, 3) - P(:, 1)
    2306     11459712 :                plane_vector(:, 2) = P(:, 2) - P(:, 1)
    2307      2864928 :                cross_product(1) = plane_vector(2, 1)*plane_vector(3, 2) - plane_vector(3, 1)*plane_vector(2, 2)
    2308      2864928 :                cross_product(2) = plane_vector(3, 1)*plane_vector(1, 2) - plane_vector(1, 1)*plane_vector(3, 2)
    2309      2864928 :                cross_product(3) = plane_vector(1, 1)*plane_vector(2, 2) - plane_vector(2, 1)*plane_vector(1, 2)
    2310     20054496 :                normal(:, 1) = cross_product/SQRT(SUM(cross_product**2))
    2311     11459712 :                point_in_plane = -normal(:, 1)*(normal(1, 1)*P(1, 1) + normal(2, 1)*P(2, 1) + normal(3, 1)*P(3, 1))
    2312              : 
    2313      2864928 :                IF (point_is_in_quadrilateral(P(:, 1), P(:, 3), P(:, 4), P(:, 2), point_in_plane)) THEN
    2314        54240 :                   distance(idx) = ABS(normal(1, 1)*P(1, 1) + normal(2, 1)*P(2, 1) + normal(3, 1)*P(3, 1))
    2315              :                ELSE
    2316      2810688 :                   distance(idx) = HUGE(distance(idx))
    2317              :                END IF
    2318              : 
    2319              :                ! Face B (1562) 1 is the reference
    2320      2864928 :                idx = idx + 1
    2321     11459712 :                plane_vector(:, 1) = P(:, 2) - P(:, 1)
    2322     11459712 :                plane_vector(:, 2) = P(:, 5) - P(:, 1)
    2323      2864928 :                cross_product(1) = plane_vector(2, 1)*plane_vector(3, 2) - plane_vector(3, 1)*plane_vector(2, 2)
    2324      2864928 :                cross_product(2) = plane_vector(3, 1)*plane_vector(1, 2) - plane_vector(1, 1)*plane_vector(3, 2)
    2325      2864928 :                cross_product(3) = plane_vector(1, 1)*plane_vector(2, 2) - plane_vector(2, 1)*plane_vector(1, 2)
    2326     20054496 :                normal(:, 1) = cross_product/SQRT(SUM(cross_product**2))
    2327     11459712 :                point_in_plane = -normal(:, 1)*(normal(1, 1)*P(1, 1) + normal(2, 1)*P(2, 1) + normal(3, 1)*P(3, 1))
    2328              : 
    2329      2864928 :                IF (point_is_in_quadrilateral(P(:, 1), P(:, 5), P(:, 6), P(:, 2), point_in_plane)) THEN
    2330        54416 :                   distance(idx) = ABS(normal(1, 1)*P(1, 1) + normal(2, 1)*P(2, 1) + normal(3, 1)*P(3, 1))
    2331              :                ELSE
    2332      2810512 :                   distance(idx) = HUGE(distance(idx))
    2333              :                END IF
    2334              : 
    2335              :                ! Face C (5786) 5 is the reference
    2336      2864928 :                idx = idx + 1
    2337     11459712 :                plane_vector(:, 1) = P(:, 7) - P(:, 5)
    2338     11459712 :                plane_vector(:, 2) = P(:, 6) - P(:, 5)
    2339      2864928 :                cross_product(1) = plane_vector(2, 1)*plane_vector(3, 2) - plane_vector(3, 1)*plane_vector(2, 2)
    2340      2864928 :                cross_product(2) = plane_vector(3, 1)*plane_vector(1, 2) - plane_vector(1, 1)*plane_vector(3, 2)
    2341      2864928 :                cross_product(3) = plane_vector(1, 1)*plane_vector(2, 2) - plane_vector(2, 1)*plane_vector(1, 2)
    2342     20054496 :                normal(:, 1) = cross_product/SQRT(SUM(cross_product**2))
    2343     11459712 :                point_in_plane = -normal(:, 1)*(normal(1, 1)*P(1, 5) + normal(2, 1)*P(2, 5) + normal(3, 1)*P(3, 5))
    2344              : 
    2345      2864928 :                IF (point_is_in_quadrilateral(P(:, 5), P(:, 7), P(:, 8), P(:, 6), point_in_plane)) THEN
    2346        54240 :                   distance(idx) = ABS(normal(1, 1)*P(1, 5) + normal(2, 1)*P(2, 5) + normal(3, 1)*P(3, 5))
    2347              :                ELSE
    2348      2810688 :                   distance(idx) = HUGE(distance(idx))
    2349              :                END IF
    2350              : 
    2351              :                ! Face D (3784) 3 is the reference
    2352      2864928 :                idx = idx + 1
    2353     11459712 :                plane_vector(:, 1) = P(:, 7) - P(:, 3)
    2354     11459712 :                plane_vector(:, 2) = P(:, 4) - P(:, 3)
    2355      2864928 :                cross_product(1) = plane_vector(2, 1)*plane_vector(3, 2) - plane_vector(3, 1)*plane_vector(2, 2)
    2356      2864928 :                cross_product(2) = plane_vector(3, 1)*plane_vector(1, 2) - plane_vector(1, 1)*plane_vector(3, 2)
    2357      2864928 :                cross_product(3) = plane_vector(1, 1)*plane_vector(2, 2) - plane_vector(2, 1)*plane_vector(1, 2)
    2358     20054496 :                normal(:, 1) = cross_product/SQRT(SUM(cross_product**2))
    2359     11459712 :                point_in_plane = -normal(:, 1)*(normal(1, 1)*P(1, 3) + normal(2, 1)*P(2, 3) + normal(3, 1)*P(3, 3))
    2360              : 
    2361      2864928 :                IF (point_is_in_quadrilateral(P(:, 3), P(:, 7), P(:, 8), P(:, 4), point_in_plane)) THEN
    2362        54416 :                   distance(idx) = ABS(normal(1, 1)*P(1, 3) + normal(2, 1)*P(2, 3) + normal(3, 1)*P(3, 3))
    2363              :                ELSE
    2364      2810512 :                   distance(idx) = HUGE(distance(idx))
    2365              :                END IF
    2366              : 
    2367              :                ! Face E (2684) 2 is the reference
    2368      2864928 :                idx = idx + 1
    2369     11459712 :                plane_vector(:, 1) = P(:, 6) - P(:, 2)
    2370     11459712 :                plane_vector(:, 2) = P(:, 4) - P(:, 2)
    2371      2864928 :                cross_product(1) = plane_vector(2, 1)*plane_vector(3, 2) - plane_vector(3, 1)*plane_vector(2, 2)
    2372      2864928 :                cross_product(2) = plane_vector(3, 1)*plane_vector(1, 2) - plane_vector(1, 1)*plane_vector(3, 2)
    2373      2864928 :                cross_product(3) = plane_vector(1, 1)*plane_vector(2, 2) - plane_vector(2, 1)*plane_vector(1, 2)
    2374     20054496 :                normal(:, 1) = cross_product/SQRT(SUM(cross_product**2))
    2375     11459712 :                point_in_plane = -normal(:, 1)*(normal(1, 1)*P(1, 2) + normal(2, 1)*P(2, 2) + normal(3, 1)*P(3, 2))
    2376              : 
    2377      2864928 :                IF (point_is_in_quadrilateral(P(:, 2), P(:, 6), P(:, 8), P(:, 4), point_in_plane)) THEN
    2378        54220 :                   distance(idx) = ABS(normal(1, 1)*P(1, 2) + normal(2, 1)*P(2, 2) + normal(3, 1)*P(3, 2))
    2379              :                ELSE
    2380      2810708 :                   distance(idx) = HUGE(distance(idx))
    2381              :                END IF
    2382              : 
    2383              :                ! Face F (1573) 1 is the reference
    2384      2864928 :                idx = idx + 1
    2385     11459712 :                plane_vector(:, 1) = P(:, 5) - P(:, 1)
    2386     11459712 :                plane_vector(:, 2) = P(:, 3) - P(:, 1)
    2387      2864928 :                cross_product(1) = plane_vector(2, 1)*plane_vector(3, 2) - plane_vector(3, 1)*plane_vector(2, 2)
    2388      2864928 :                cross_product(2) = plane_vector(3, 1)*plane_vector(1, 2) - plane_vector(1, 1)*plane_vector(3, 2)
    2389      2864928 :                cross_product(3) = plane_vector(1, 1)*plane_vector(2, 2) - plane_vector(2, 1)*plane_vector(1, 2)
    2390     20054496 :                normal(:, 1) = cross_product/SQRT(SUM(cross_product**2))
    2391     11459712 :                point_in_plane = -normal(:, 1)*(normal(1, 1)*P(1, 1) + normal(2, 1)*P(2, 1) + normal(3, 1)*P(3, 1))
    2392              : 
    2393      2864928 :                IF (point_is_in_quadrilateral(P(:, 1), P(:, 5), P(:, 7), P(:, 3), point_in_plane)) THEN
    2394        54220 :                   distance(idx) = ABS(normal(1, 1)*P(1, 1) + normal(2, 1)*P(2, 1) + normal(3, 1)*P(3, 1))
    2395              :                ELSE
    2396      2810708 :                   distance(idx) = HUGE(distance(idx))
    2397              :                END IF
    2398              : 
    2399     42973920 :                dist_min = MINVAL(distance)
    2400      2864928 :                IF (max_shell == 0) THEN
    2401         7436 :                   image_cell_found = .TRUE.
    2402              :                END IF
    2403      3559780 :                IF (dist_min < R_max) THEN
    2404       665848 :                   total_number_of_cells = total_number_of_cells + 1
    2405      2663392 :                   x_data%neighbor_cells(ub)%cell = REAL([ishell, jshell, kshell], dp)
    2406       665848 :                   ub = ub + 1
    2407       665848 :                   image_cell_found = .TRUE.
    2408              :                END IF
    2409              : 
    2410              :             END DO
    2411              :             END DO
    2412              :             END DO
    2413        30424 :             IF (image_cell_found) THEN
    2414        22988 :                max_shell = max_shell + 1
    2415              :             ELSE
    2416              :                nothing_more_to_add = .TRUE.
    2417              :             END IF
    2418              :          END DO
    2419              :          ! now remove what is not needed
    2420       732772 :          ALLOCATE (tmp_neighbor_cells(total_number_of_cells))
    2421       673284 :          DO i = 1, ub - 1
    2422       673284 :             tmp_neighbor_cells(i) = x_data%neighbor_cells(i)
    2423              :          END DO
    2424         7436 :          DEALLOCATE (x_data%neighbor_cells)
    2425              :          ! If we only need the supercell, total_number_of_cells is still 0, repair
    2426         7436 :          IF (total_number_of_cells == 0) THEN
    2427            0 :             total_number_of_cells = 1
    2428            0 :             ALLOCATE (x_data%neighbor_cells(total_number_of_cells))
    2429            0 :             DO i = 1, total_number_of_cells
    2430            0 :                x_data%neighbor_cells(i)%cell = 0.0_dp
    2431            0 :                x_data%neighbor_cells(i)%cell_r = 0.0_dp
    2432              :             END DO
    2433              :          ELSE
    2434       725336 :             ALLOCATE (x_data%neighbor_cells(total_number_of_cells))
    2435       673284 :             DO i = 1, total_number_of_cells
    2436       673284 :                x_data%neighbor_cells(i) = tmp_neighbor_cells(i)
    2437              :             END DO
    2438              :          END IF
    2439         7436 :          DEALLOCATE (tmp_neighbor_cells)
    2440              : 
    2441         7436 :          IF (x_data%periodic_parameter%number_of_shells == do_hfx_auto_shells) THEN
    2442              :             ! Do nothing
    2443              :          ELSE
    2444           60 :             total_number_of_cells = 0
    2445          206 :             DO i = 0, x_data%periodic_parameter%number_of_shells
    2446          206 :                total_number_of_cells = total_number_of_cells + count_cells_perd(i, x_data%periodic_parameter%perd)
    2447              :             END DO
    2448           60 :             IF (total_number_of_cells < SIZE(x_data%neighbor_cells)) THEN
    2449           60 :                IF (i_thread == 1) THEN
    2450            4 :                   WRITE (char_nshells, '(I3)') SIZE(x_data%neighbor_cells)
    2451              :                   WRITE (error_msg, '(A,A,A)') "Periodic Hartree Fock calculation requested with use "// &
    2452              :                      "of a truncated potential. The number of shells to be considered "// &
    2453              :                      "might be too small. CP2K conservatively estimates to need "//TRIM(char_nshells)//" periodic images "// &
    2454            4 :                      "Please carefully check if you get converged results."
    2455            4 :                   CPWARN(error_msg)
    2456              :                END IF
    2457              :             END IF
    2458           60 :             total_number_of_cells = 0
    2459          206 :             DO i = 0, x_data%periodic_parameter%number_of_shells
    2460          206 :                total_number_of_cells = total_number_of_cells + count_cells_perd(i, x_data%periodic_parameter%perd)
    2461              :             END DO
    2462           60 :             DEALLOCATE (x_data%neighbor_cells)
    2463              : 
    2464         1272 :             ALLOCATE (x_data%neighbor_cells(total_number_of_cells))
    2465           60 :             m = 0
    2466           60 :             i = 1
    2467         3168 :             DO WHILE (SUM(m**2) <= x_data%periodic_parameter%number_of_shells)
    2468         2928 :                x_data%neighbor_cells(i)%cell = REAL(m, dp)
    2469          732 :                CALL next_image_cell_perd(m, x_data%periodic_parameter%perd)
    2470          732 :                i = i + 1
    2471              :             END DO
    2472              :          END IF
    2473              :       CASE DEFAULT
    2474         2845 :          total_number_of_cells = 0
    2475         2845 :          IF (pbc_shells == -1) pbc_shells = 0
    2476         5690 :          DO i = 0, pbc_shells
    2477         5690 :             total_number_of_cells = total_number_of_cells + count_cells_perd(i, x_data%periodic_parameter%perd)
    2478              :          END DO
    2479         2845 :          DEALLOCATE (x_data%neighbor_cells)
    2480              : 
    2481        28450 :          ALLOCATE (x_data%neighbor_cells(total_number_of_cells))
    2482              : 
    2483         2845 :          m = 0
    2484         2845 :          i = 1
    2485        33041 :          DO WHILE (SUM(m**2) <= pbc_shells)
    2486        11380 :             x_data%neighbor_cells(i)%cell = REAL(m, dp)
    2487         2845 :             CALL next_image_cell_perd(m, x_data%periodic_parameter%perd)
    2488         5690 :             i = i + 1
    2489              :          END DO
    2490              :       END SELECT
    2491              : 
    2492              :       ! ** Transform into real coord
    2493       674846 :       DO i = 1, SIZE(x_data%neighbor_cells)
    2494              :          r = 0.0_dp
    2495      2658260 :          x_data%neighbor_cells(i)%cell_r(:) = 0.0_dp
    2496      2658260 :          s = x_data%neighbor_cells(i)%cell(:)
    2497       674846 :          CALL scaled_to_real(x_data%neighbor_cells(i)%cell_r, s, cell)
    2498              :       END DO
    2499        10281 :       x_data%periodic_parameter%number_of_shells = pbc_shells
    2500              : 
    2501        10281 :       R_max_stress = 0.0_dp
    2502       674846 :       DO i = 1, SIZE(x_data%neighbor_cells)
    2503      2668541 :          R_max_stress = MAX(R_max_stress, MAXVAL(ABS(x_data%neighbor_cells(i)%cell_r(:))))
    2504              :       END DO
    2505       133653 :       R_max_stress = R_max_stress + ABS(MAXVAL(cell%hmat(:, :)))
    2506        10281 :       x_data%periodic_parameter%R_max_stress = R_max_stress
    2507              : 
    2508        10281 :    END SUBROUTINE hfx_create_neighbor_cells
    2509              : 
    2510              :    ! performs a fuzzy check of being in a quadrilateral
    2511              : ! **************************************************************************************************
    2512              : !> \brief ...
    2513              : !> \param A ...
    2514              : !> \param B ...
    2515              : !> \param C ...
    2516              : !> \param D ...
    2517              : !> \param P ...
    2518              : !> \return ...
    2519              : ! **************************************************************************************************
    2520     17189568 :    FUNCTION point_is_in_quadrilateral(A, B, C, D, P)
    2521              :       REAL(dp)                                           :: A(3), B(3), C(3), D(3), P(3)
    2522              :       LOGICAL                                            :: point_is_in_quadrilateral
    2523              : 
    2524              :       REAL(dp), PARAMETER :: fuzzy = 1000.0_dp*EPSILON(1.0_dp)
    2525              : 
    2526              :       REAL(dp)                                           :: dot00, dot01, dot02, dot11, dot12, &
    2527              :                                                             invDenom, u, v, v0(3), v1(3), v2(3)
    2528              : 
    2529     17189568 :       point_is_in_quadrilateral = .FALSE.
    2530              : 
    2531              :       ! ** Check for both triangles ABC and ACD
    2532              :       ! **
    2533              :       ! **     D -------------- C
    2534              :       ! **    /                /
    2535              :       ! **   /                /
    2536              :       ! **  A----------------B
    2537              :       ! **
    2538              :       ! **
    2539              :       ! **
    2540              : 
    2541              :       ! ** ABC
    2542              : 
    2543     68758272 :       v0 = D - A
    2544     68758272 :       v1 = C - A
    2545     68758272 :       v2 = P - A
    2546              : 
    2547              :       ! ** Compute dot products
    2548     68758272 :       dot00 = DOT_PRODUCT(v0, v0)
    2549     68758272 :       dot01 = DOT_PRODUCT(v0, v1)
    2550     68758272 :       dot02 = DOT_PRODUCT(v0, v2)
    2551     68758272 :       dot11 = DOT_PRODUCT(v1, v1)
    2552     68758272 :       dot12 = DOT_PRODUCT(v1, v2)
    2553              : 
    2554              :       ! ** Compute barycentric coordinates
    2555     17189568 :       invDenom = 1/(dot00*dot11 - dot01*dot01)
    2556     17189568 :       u = (dot11*dot02 - dot01*dot12)*invDenom
    2557     17189568 :       v = (dot00*dot12 - dot01*dot02)*invDenom
    2558              :       ! ** Check if point is in triangle
    2559     17189568 :       IF ((u >= 0 - fuzzy) .AND. (v >= 0 - fuzzy) .AND. (u + v <= 1 + fuzzy)) THEN
    2560     17189568 :          point_is_in_quadrilateral = .TRUE.
    2561              :          RETURN
    2562              :       END IF
    2563     67479288 :       v0 = C - A
    2564     67479288 :       v1 = B - A
    2565     67479288 :       v2 = P - A
    2566              : 
    2567              :       ! ** Compute dot products
    2568     67479288 :       dot00 = DOT_PRODUCT(v0, v0)
    2569     67479288 :       dot01 = DOT_PRODUCT(v0, v1)
    2570     67479288 :       dot02 = DOT_PRODUCT(v0, v2)
    2571     67479288 :       dot11 = DOT_PRODUCT(v1, v1)
    2572     67479288 :       dot12 = DOT_PRODUCT(v1, v2)
    2573              : 
    2574              :       ! ** Compute barycentric coordinates
    2575     16869822 :       invDenom = 1/(dot00*dot11 - dot01*dot01)
    2576     16869822 :       u = (dot11*dot02 - dot01*dot12)*invDenom
    2577     16869822 :       v = (dot00*dot12 - dot01*dot02)*invDenom
    2578              : 
    2579              :       ! ** Check if point is in triangle
    2580     16869822 :       IF ((u >= 0 - fuzzy) .AND. (v >= 0 - fuzzy) .AND. (u + v <= 1 + fuzzy)) THEN
    2581         6006 :          point_is_in_quadrilateral = .TRUE.
    2582         6006 :          RETURN
    2583              :       END IF
    2584              : 
    2585              :    END FUNCTION point_is_in_quadrilateral
    2586              : 
    2587              : ! **************************************************************************************************
    2588              : !> \brief - This routine deletes all list entries in a container in order to
    2589              : !>        deallocate the memory.
    2590              : !> \param container container that contains the compressed elements
    2591              : !> \param memory_usage ...
    2592              : !> \param do_disk_storage ...
    2593              : !> \par History
    2594              : !>      10.2007 created [Manuel Guidon]
    2595              : !> \author Manuel Guidon
    2596              : ! **************************************************************************************************
    2597      3871780 :    SUBROUTINE hfx_init_container(container, memory_usage, do_disk_storage)
    2598              :       TYPE(hfx_container_type)                           :: container
    2599              :       INTEGER                                            :: memory_usage
    2600              :       LOGICAL                                            :: do_disk_storage
    2601              : 
    2602              :       TYPE(hfx_container_node), POINTER                  :: current, next
    2603              : 
    2604              : !! DEALLOCATE memory
    2605              : 
    2606      3871780 :       current => container%first
    2607      7924277 :       DO WHILE (ASSOCIATED(current))
    2608      4052497 :          next => current%next
    2609      4052497 :          DEALLOCATE (current)
    2610      4052497 :          current => next
    2611              :       END DO
    2612              : 
    2613              :       !! Allocate first list entry, init members
    2614   3972446280 :       ALLOCATE (container%first)
    2615              :       container%first%prev => NULL()
    2616              :       container%first%next => NULL()
    2617      3871780 :       container%current => container%first
    2618   3968574500 :       container%current%data = 0
    2619      3871780 :       container%element_counter = 1
    2620      3871780 :       memory_usage = 1
    2621              : 
    2622      3871780 :       IF (do_disk_storage) THEN
    2623              :          !! close the file, if this is no the first time
    2624          390 :          IF (container%unit /= -1) THEN
    2625            0 :             CALL close_file(unit_number=container%unit)
    2626              :          END IF
    2627              :          CALL open_file(file_name=TRIM(container%filename), file_status="UNKNOWN", file_form="UNFORMATTED", file_action="WRITE", &
    2628          390 :                         unit_number=container%unit)
    2629              :       END IF
    2630              : 
    2631      3871780 :    END SUBROUTINE hfx_init_container
    2632              : 
    2633              : ! **************************************************************************************************
    2634              : !> \brief - This routine stores the data obtained from the load balance routine
    2635              : !>        for the energy
    2636              : !> \param ptr_to_distr contains data to store
    2637              : !> \param x_data contains all relevant data structures for hfx runs
    2638              : !> \par History
    2639              : !>      09.2007 created [Manuel Guidon]
    2640              : !> \author Manuel Guidon
    2641              : ! **************************************************************************************************
    2642         2448 :    SUBROUTINE hfx_set_distr_energy(ptr_to_distr, x_data)
    2643              :       TYPE(hfx_distribution), DIMENSION(:), POINTER      :: ptr_to_distr
    2644              :       TYPE(hfx_type), POINTER                            :: x_data
    2645              : 
    2646         2448 :       DEALLOCATE (x_data%distribution_energy)
    2647              : 
    2648       163890 :       ALLOCATE (x_data%distribution_energy(SIZE(ptr_to_distr)))
    2649       317988 :       x_data%distribution_energy = ptr_to_distr
    2650              : 
    2651         2448 :    END SUBROUTINE hfx_set_distr_energy
    2652              : 
    2653              : ! **************************************************************************************************
    2654              : !> \brief - This routine stores the data obtained from the load balance routine
    2655              : !>        for the forces
    2656              : !> \param ptr_to_distr contains data to store
    2657              : !> \param x_data contains all relevant data structures for hfx runs
    2658              : !> \par History
    2659              : !>      09.2007 created [Manuel Guidon]
    2660              : !> \author Manuel Guidon
    2661              : ! **************************************************************************************************
    2662         1498 :    SUBROUTINE hfx_set_distr_forces(ptr_to_distr, x_data)
    2663              :       TYPE(hfx_distribution), DIMENSION(:), POINTER      :: ptr_to_distr
    2664              :       TYPE(hfx_type), POINTER                            :: x_data
    2665              : 
    2666         1498 :       DEALLOCATE (x_data%distribution_forces)
    2667              : 
    2668       100360 :       ALLOCATE (x_data%distribution_forces(SIZE(ptr_to_distr)))
    2669       194740 :       x_data%distribution_forces = ptr_to_distr
    2670              : 
    2671         1498 :    END SUBROUTINE hfx_set_distr_forces
    2672              : 
    2673              : ! **************************************************************************************************
    2674              : !> \brief - resets the maximum memory usage for a HFX calculation subtracting
    2675              : !>          all relevant buffers from the input MAX_MEM value and add 10% of
    2676              : !>          safety margin
    2677              : !> \param memory_parameter Memory information
    2678              : !> \param subtr_size_mb size of buffers in MiB
    2679              : !> \par History
    2680              : !>      02.2009 created [Manuel Guidon]
    2681              : !> \author Manuel Guidon
    2682              : ! **************************************************************************************************
    2683        41035 :    SUBROUTINE hfx_reset_memory_usage_counter(memory_parameter, subtr_size_mb)
    2684              : 
    2685              :       TYPE(hfx_memory_type)                              :: memory_parameter
    2686              :       INTEGER(int_8), INTENT(IN)                         :: subtr_size_mb
    2687              : 
    2688              :       INTEGER(int_8)                                     :: max_memory
    2689              : 
    2690        41035 :       max_memory = memory_parameter%max_memory
    2691        41035 :       max_memory = max_memory - subtr_size_mb
    2692        41035 :       IF (max_memory <= 0) THEN
    2693           38 :          memory_parameter%do_all_on_the_fly = .TRUE.
    2694           38 :          memory_parameter%max_compression_counter = 0
    2695              :       ELSE
    2696        40997 :          memory_parameter%do_all_on_the_fly = .FALSE.
    2697        40997 :          memory_parameter%max_compression_counter = max_memory*1024_int_8*128_int_8
    2698              :       END IF
    2699        41035 :    END SUBROUTINE hfx_reset_memory_usage_counter
    2700              : 
    2701              : ! **************************************************************************************************
    2702              : !> \brief - This routine prints some information on HFX
    2703              : !> \param x_data contains all relevant data structures for hfx runs
    2704              : !> \param hfx_section HFX input section
    2705              : !> \par History
    2706              : !>      03.2008 created [Manuel Guidon]
    2707              : !> \author Manuel Guidon
    2708              : ! **************************************************************************************************
    2709         1374 :    SUBROUTINE hfx_print_std_info(x_data, hfx_section)
    2710              :       TYPE(hfx_type), POINTER                            :: x_data
    2711              :       TYPE(section_vals_type), POINTER                   :: hfx_section
    2712              : 
    2713              :       INTEGER                                            :: iw
    2714              :       TYPE(cp_logger_type), POINTER                      :: logger
    2715              : 
    2716         1374 :       NULLIFY (logger)
    2717         1374 :       logger => cp_get_default_logger()
    2718              : 
    2719              :       iw = cp_print_key_unit_nr(logger, hfx_section, "HF_INFO", &
    2720         1374 :                                 extension=".scfLog")
    2721              : 
    2722         1374 :       IF (iw > 0) THEN
    2723              :          WRITE (UNIT=iw, FMT="((T3,A,T73,ES8.1))") &
    2724          338 :             "HFX_INFO| EPS_SCHWARZ:     ", x_data%screening_parameter%eps_schwarz
    2725              :          WRITE (UNIT=iw, FMT="((T3,A,T73,ES8.1))") &
    2726          338 :             "HFX_INFO| EPS_SCHWARZ_FORCES     ", x_data%screening_parameter%eps_schwarz_forces
    2727              :          WRITE (UNIT=iw, FMT="((T3,A,T73,ES8.1))") &
    2728          338 :             "HFX_INFO| EPS_STORAGE_SCALING:     ", x_data%memory_parameter%eps_storage_scaling
    2729              :          WRITE (UNIT=iw, FMT="((T3,A,T61,I20))") &
    2730          338 :             "HFX_INFO| NBINS:     ", x_data%load_balance_parameter%nbins
    2731              :          WRITE (UNIT=iw, FMT="((T3,A,T61,I20))") &
    2732          338 :             "HFX_INFO| BLOCK_SIZE:     ", x_data%load_balance_parameter%block_size
    2733          338 :          IF (x_data%periodic_parameter%do_periodic) THEN
    2734           98 :             IF (x_data%periodic_parameter%mode == -1) THEN
    2735              :                WRITE (UNIT=iw, FMT="((T3,A,T77,A))") &
    2736           96 :                   "HFX_INFO| NUMBER_OF_SHELLS:     ", "AUTO"
    2737              :             ELSE
    2738              :                WRITE (UNIT=iw, FMT="((T3,A,T61,I20))") &
    2739            2 :                   "HFX_INFO| NUMBER_OF_SHELLS:     ", x_data%periodic_parameter%mode
    2740              :             END IF
    2741              :             WRITE (UNIT=iw, FMT="((T3,A,T61,I20))") &
    2742           98 :                "HFX_INFO| Number of periodic shells considered:     ", x_data%periodic_parameter%number_of_shells
    2743              :             WRITE (UNIT=iw, FMT="((T3,A,T61,I20),/)") &
    2744           98 :                "HFX_INFO| Number of periodic cells considered:     ", SIZE(x_data%neighbor_cells)
    2745              :          ELSE
    2746              :             WRITE (UNIT=iw, FMT="((T3,A,T77,A))") &
    2747          240 :                "HFX_INFO| Number of periodic shells considered:     ", "NONE"
    2748              :             WRITE (UNIT=iw, FMT="((T3,A,T77,A),/)") &
    2749          240 :                "HFX_INFO| Number of periodic cells considered:     ", "NONE"
    2750              :          END IF
    2751              :       END IF
    2752         1374 :    END SUBROUTINE hfx_print_std_info
    2753              : 
    2754              : ! **************************************************************************************************
    2755              : !> \brief ...
    2756              : !> \param ri_data ...
    2757              : !> \param hfx_section ...
    2758              : ! **************************************************************************************************
    2759          114 :    SUBROUTINE hfx_print_ri_info(ri_data, hfx_section)
    2760              :       TYPE(hfx_ri_type), POINTER                         :: ri_data
    2761              :       TYPE(section_vals_type), POINTER                   :: hfx_section
    2762              : 
    2763              :       INTEGER                                            :: iw
    2764              :       REAL(dp)                                           :: rc_ang
    2765              :       TYPE(cp_logger_type), POINTER                      :: logger
    2766              :       TYPE(section_vals_type), POINTER                   :: ri_section
    2767              : 
    2768          114 :       NULLIFY (logger, ri_section)
    2769          114 :       logger => cp_get_default_logger()
    2770              : 
    2771          114 :       ri_section => ri_data%ri_section
    2772              : 
    2773              :       iw = cp_print_key_unit_nr(logger, hfx_section, "HF_INFO", &
    2774          114 :                                 extension=".scfLog")
    2775              : 
    2776          114 :       IF (iw > 0) THEN
    2777              : 
    2778              :          ASSOCIATE (ri_metric => ri_data%ri_metric, hfx_pot => ri_data%hfx_pot)
    2779           62 :             SELECT CASE (ri_metric%potential_type)
    2780              :             CASE (do_potential_coulomb)
    2781              :                WRITE (UNIT=iw, FMT="(/T3,A,T74,A)") &
    2782           11 :                   "HFX_RI_INFO| RI metric: ", "COULOMB"
    2783              :             CASE (do_potential_short)
    2784              :                WRITE (UNIT=iw, FMT="(T3,A,T71,A)") &
    2785            1 :                   "HFX_RI_INFO| RI metric: ", "SHORTRANGE"
    2786              :                WRITE (iw, '(T3,A,T61,F20.10)') &
    2787            1 :                   "HFX_RI_INFO| Omega:     ", ri_metric%omega
    2788            1 :                rc_ang = cp_unit_from_cp2k(ri_metric%cutoff_radius, "angstrom")
    2789              :                WRITE (iw, '(T3,A,T61,F20.10)') &
    2790            1 :                   "HFX_RI_INFO| Cutoff Radius [angstrom]:     ", rc_ang
    2791              :             CASE (do_potential_long)
    2792              :                WRITE (UNIT=iw, FMT="(T3,A,T72,A)") &
    2793            0 :                   "HFX_RI_INFO| RI metric: ", "LONGRANGE"
    2794              :                WRITE (iw, '(T3,A,T61,F20.10)') &
    2795            0 :                   "HFX_RI_INFO| Omega:     ", ri_metric%omega
    2796              :             CASE (do_potential_id)
    2797              :                WRITE (UNIT=iw, FMT="(T3,A,T74,A)") &
    2798           33 :                   "HFX_RI_INFO| RI metric: ", "OVERLAP"
    2799              :             CASE (do_potential_truncated)
    2800              :                WRITE (UNIT=iw, FMT="(T3,A,T64,A)") &
    2801            5 :                   "HFX_RI_INFO| RI metric: ", "TRUNCATED COULOMB"
    2802            5 :                rc_ang = cp_unit_from_cp2k(ri_metric%cutoff_radius, "angstrom")
    2803              :                WRITE (iw, '(T3,A,T61,F20.10)') &
    2804           56 :                   "HFX_RI_INFO| Cutoff Radius [angstrom]:     ", rc_ang
    2805              :             END SELECT
    2806              : 
    2807              :          END ASSOCIATE
    2808           54 :          SELECT CASE (ri_data%flavor)
    2809              :          CASE (ri_mo)
    2810              :             WRITE (UNIT=iw, FMT="(T3, A, T79, A)") &
    2811            3 :                "HFX_RI_INFO| RI flavor: ", "MO"
    2812              :          CASE (ri_pmat)
    2813              :             WRITE (UNIT=iw, FMT="(T3, A, T78, A)") &
    2814           51 :                "HFX_RI_INFO| RI flavor: ", "RHO"
    2815              :          END SELECT
    2816           51 :          SELECT CASE (ri_data%t2c_method)
    2817              :          CASE (hfx_ri_do_2c_iter)
    2818              :             WRITE (UNIT=iw, FMT="(T3, A, T69, A)") &
    2819            0 :                "HFX_RI_INFO| Matrix SQRT/INV", "DBCSR / iter"
    2820              :          CASE (hfx_ri_do_2c_diag)
    2821              :             WRITE (UNIT=iw, FMT="(T3, A, T65, A)") &
    2822           51 :                "HFX_RI_INFO| Matrix SQRT/INV", "Dense / diag"
    2823              :          END SELECT
    2824              :          WRITE (UNIT=iw, FMT="(T3, A, T73, ES8.1)") &
    2825           51 :             "HFX_RI_INFO| EPS_FILTER", ri_data%filter_eps
    2826              :          WRITE (UNIT=iw, FMT="(T3, A, T73, ES8.1)") &
    2827           51 :             "HFX_RI_INFO| EPS_FILTER 2-center", ri_data%filter_eps_2c
    2828              :          WRITE (UNIT=iw, FMT="(T3, A, T73, ES8.1)") &
    2829           51 :             "HFX_RI_INFO| EPS_FILTER storage", ri_data%filter_eps_storage
    2830              :          WRITE (UNIT=iw, FMT="(T3, A, T73, ES8.1)") &
    2831           51 :             "HFX_RI_INFO| EPS_FILTER MO", ri_data%filter_eps_mo
    2832              :          WRITE (UNIT=iw, FMT="(T3, A, T73, ES8.1)") &
    2833           51 :             "HFX_RI_INFO| EPS_PGF_ORB", ri_data%eps_pgf_orb
    2834              :          WRITE (UNIT=iw, FMT="((T3, A, T73, ES8.1))") &
    2835           51 :             "HFX_RI_INFO| EPS_SCHWARZ:     ", ri_data%eps_schwarz
    2836              :          WRITE (UNIT=iw, FMT="((T3, A, T73, ES8.1))") &
    2837           51 :             "HFX_RI_INFO| EPS_SCHWARZ_FORCES:     ", ri_data%eps_schwarz_forces
    2838              :          WRITE (UNIT=iw, FMT="(T3, A, T78, I3)") &
    2839           51 :             "HFX_RI_INFO| Minimum block size", ri_data%min_bsize
    2840              :          WRITE (UNIT=iw, FMT="(T3, A, T78, I3)") &
    2841           51 :             "HFX_RI_INFO| MO block size", ri_data%max_bsize_MO
    2842              :          WRITE (UNIT=iw, FMT="(T3, A, T79, I2)") &
    2843           51 :             "HFX_RI_INFO| Memory reduction factor", ri_data%n_mem_input
    2844              :       END IF
    2845              : 
    2846          114 :    END SUBROUTINE hfx_print_ri_info
    2847              : 
    2848              : ! **************************************************************************************************
    2849              : !> \brief ...
    2850              : !> \param x_data ...
    2851              : !> \param hfx_section ...
    2852              : !> \param i_rep ...
    2853              : ! **************************************************************************************************
    2854         1488 :    SUBROUTINE hfx_print_info(x_data, hfx_section, i_rep)
    2855              :       TYPE(hfx_type), POINTER                            :: x_data
    2856              :       TYPE(section_vals_type), POINTER                   :: hfx_section
    2857              :       INTEGER, INTENT(IN)                                :: i_rep
    2858              : 
    2859              :       INTEGER                                            :: iw
    2860              :       REAL(dp)                                           :: rc_ang
    2861              :       TYPE(cp_logger_type), POINTER                      :: logger
    2862              : 
    2863         1488 :       NULLIFY (logger)
    2864         1488 :       logger => cp_get_default_logger()
    2865              : 
    2866              :       iw = cp_print_key_unit_nr(logger, hfx_section, "HF_INFO", &
    2867         1488 :                                 extension=".scfLog")
    2868              : 
    2869         1488 :       IF (iw > 0) THEN
    2870              :          WRITE (UNIT=iw, FMT="(/,(T3,A,T61,I20))") &
    2871          389 :             "HFX_INFO| Replica ID:     ", i_rep
    2872              : 
    2873              :          WRITE (iw, '(T3,A,T61,F20.10)') &
    2874          389 :             "HFX_INFO| FRACTION:     ", x_data%general_parameter%fraction
    2875          636 :          SELECT CASE (x_data%potential_parameter%potential_type)
    2876              :          CASE (do_potential_coulomb)
    2877              :             WRITE (UNIT=iw, FMT="((T3,A,T74,A))") &
    2878          247 :                "HFX_INFO| Interaction Potential:     ", "COULOMB"
    2879              :          CASE (do_potential_short)
    2880              :             WRITE (UNIT=iw, FMT="((T3,A,T71,A))") &
    2881           12 :                "HFX_INFO| Interaction Potential:    ", "SHORTRANGE"
    2882              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2883           12 :                "HFX_INFO| Omega:     ", x_data%potential_parameter%omega
    2884           12 :             rc_ang = cp_unit_from_cp2k(x_data%potential_parameter%cutoff_radius, "angstrom")
    2885              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2886           12 :                "HFX_INFO| Cutoff Radius [angstrom]:     ", rc_ang
    2887              :          CASE (do_potential_long)
    2888              :             WRITE (UNIT=iw, FMT="((T3,A,T72,A))") &
    2889            4 :                "HFX_INFO| Interaction Potential:     ", "LONGRANGE"
    2890              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2891            4 :                "HFX_INFO| Omega:     ", x_data%potential_parameter%omega
    2892              :          CASE (do_potential_mix_cl)
    2893              :             WRITE (UNIT=iw, FMT="((T3,A,T75,A))") &
    2894            7 :                "HFX_INFO| Interaction Potential:     ", "MIX_CL"
    2895              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2896            7 :                "HFX_INFO| Omega:     ", x_data%potential_parameter%omega
    2897              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2898            7 :                "HFX_INFO| SCALE_COULOMB:     ", x_data%potential_parameter%scale_coulomb
    2899              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2900            7 :                "HFX_INFO| SCALE_LONGRANGE:     ", x_data%potential_parameter%scale_longrange
    2901              :          CASE (do_potential_gaussian)
    2902              :             WRITE (UNIT=iw, FMT="((T3,A,T73,A))") &
    2903            0 :                "HFX_INFO| Interaction Potential:     ", "GAUSSIAN"
    2904              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2905            0 :                "HFX_INFO| Omega:     ", x_data%potential_parameter%omega
    2906              :          CASE (do_potential_mix_lg)
    2907              :             WRITE (UNIT=iw, FMT="((T3,A,T75,A))") &
    2908            2 :                "HFX_INFO| Interaction Potential:    ", "MIX_LG"
    2909              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2910            2 :                "HFX_INFO| Omega:     ", x_data%potential_parameter%omega
    2911              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2912            2 :                "HFX_INFO| SCALE_LONGRANGE:     ", x_data%potential_parameter%scale_longrange
    2913              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2914            2 :                "HFX_INFO| SCALE_GAUSSIAN:    ", x_data%potential_parameter%scale_gaussian
    2915              :          CASE (do_potential_id)
    2916              :             WRITE (UNIT=iw, FMT="((T3,A,T73,A))") &
    2917           14 :                "HFX_INFO| Interaction Potential:    ", "IDENTITY"
    2918              :          CASE (do_potential_truncated)
    2919              :             WRITE (UNIT=iw, FMT="((T3,A,T72,A))") &
    2920           94 :                "HFX_INFO| Interaction Potential:    ", "TRUNCATED"
    2921           94 :             rc_ang = cp_unit_from_cp2k(x_data%potential_parameter%cutoff_radius, "angstrom")
    2922              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2923           94 :                "HFX_INFO| Cutoff Radius [angstrom]:     ", rc_ang
    2924              :          CASE (do_potential_mix_cl_trunc)
    2925              :             WRITE (UNIT=iw, FMT="((T3,A,T65,A))") &
    2926            9 :                "HFX_INFO| Interaction Potential:    ", "TRUNCATED MIX_CL"
    2927            9 :             rc_ang = cp_unit_from_cp2k(x_data%potential_parameter%cutoff_radius, "angstrom")
    2928              :             WRITE (iw, '(T3,A,T61,F20.10)') &
    2929          398 :                "HFX_INFO| Cutoff Radius [angstrom]:     ", rc_ang
    2930              :          END SELECT
    2931              : 
    2932              :       END IF
    2933         1488 :       IF (x_data%do_hfx_ri) THEN
    2934          114 :          CALL hfx_print_ri_info(x_data%ri_data, hfx_section)
    2935              :       ELSE
    2936         1374 :          CALL hfx_print_std_info(x_data, hfx_section)
    2937              :       END IF
    2938              : 
    2939              :       ! ACE section
    2940         1488 :       IF (x_data%use_ace .AND. iw > 0) THEN
    2941              :          WRITE (UNIT=iw, FMT="(/,T3,A)") &
    2942            4 :             "HFX_INFO| ACE (Adaptively Compressed Exchange): ACTIVE"
    2943              :          WRITE (UNIT=iw, FMT="(T3,A,T61,I20)") &
    2944            4 :             "HFX_INFO| ACE rebuild frequency:     ", x_data%ace_rebuild_freq
    2945              :       END IF
    2946              : 
    2947              :       CALL cp_print_key_finished_output(iw, logger, hfx_section, &
    2948         1488 :                                         "HF_INFO")
    2949         1488 :    END SUBROUTINE hfx_print_info
    2950              : 
    2951              : ! **************************************************************************************************
    2952              : !> \brief ...
    2953              : !> \param DATA ...
    2954              : !> \param memory_usage ...
    2955              : ! **************************************************************************************************
    2956        32960 :    SUBROUTINE dealloc_containers(DATA, memory_usage)
    2957              :       TYPE(hfx_compression_type)                         :: data
    2958              :       INTEGER                                            :: memory_usage
    2959              : 
    2960              :       INTEGER                                            :: bin, i
    2961              : 
    2962        65920 :       DO bin = 1, SIZE(data%maxval_container)
    2963              :          CALL hfx_init_container(data%maxval_container(bin), memory_usage, &
    2964        32960 :                                  .FALSE.)
    2965        65920 :          DEALLOCATE (data%maxval_container(bin)%first)
    2966              :       END DO
    2967        32960 :       DEALLOCATE (data%maxval_container)
    2968        32960 :       DEALLOCATE (data%maxval_cache)
    2969              : 
    2970        65920 :       DO bin = 1, SIZE(data%integral_containers, 2)
    2971      2175360 :          DO i = 1, 64
    2972              :             CALL hfx_init_container(data%integral_containers(i, bin), memory_usage, &
    2973      2109440 :                                     .FALSE.)
    2974      2142400 :             DEALLOCATE (data%integral_containers(i, bin)%first)
    2975              :          END DO
    2976              :       END DO
    2977        32960 :       DEALLOCATE (data%integral_containers)
    2978              : 
    2979        32960 :       DEALLOCATE (data%integral_caches)
    2980              : 
    2981        32960 :    END SUBROUTINE dealloc_containers
    2982              : 
    2983              : ! **************************************************************************************************
    2984              : !> \brief ...
    2985              : !> \param DATA ...
    2986              : !> \param bin_size ...
    2987              : ! **************************************************************************************************
    2988        32960 :    SUBROUTINE alloc_containers(DATA, bin_size)
    2989              :       TYPE(hfx_compression_type)                         :: data
    2990              :       INTEGER, INTENT(IN)                                :: bin_size
    2991              : 
    2992              :       INTEGER                                            :: bin, i
    2993              : 
    2994     33882880 :       ALLOCATE (data%maxval_cache(bin_size))
    2995        65920 :       DO bin = 1, bin_size
    2996        65920 :          data%maxval_cache(bin)%element_counter = 1
    2997              :       END DO
    2998       131840 :       ALLOCATE (data%maxval_container(bin_size))
    2999        65920 :       DO bin = 1, bin_size
    3000     33816960 :          ALLOCATE (data%maxval_container(bin)%first)
    3001              :          data%maxval_container(bin)%first%prev => NULL()
    3002              :          data%maxval_container(bin)%first%next => NULL()
    3003        32960 :          data%maxval_container(bin)%current => data%maxval_container(bin)%first
    3004     33784000 :          data%maxval_container(bin)%current%data = 0
    3005        65920 :          data%maxval_container(bin)%element_counter = 1
    3006              :       END DO
    3007              : 
    3008      2241280 :       ALLOCATE (data%integral_containers(64, bin_size))
    3009     35992320 :       ALLOCATE (data%integral_caches(64, bin_size))
    3010              : 
    3011        65920 :       DO bin = 1, bin_size
    3012      2175360 :          DO i = 1, 64
    3013      2109440 :             data%integral_caches(i, bin)%element_counter = 1
    3014   2162176000 :             data%integral_caches(i, bin)%data = 0
    3015   2164285440 :             ALLOCATE (data%integral_containers(i, bin)%first)
    3016              :             data%integral_containers(i, bin)%first%prev => NULL()
    3017              :             data%integral_containers(i, bin)%first%next => NULL()
    3018      2109440 :             data%integral_containers(i, bin)%current => data%integral_containers(i, bin)%first
    3019   2162176000 :             data%integral_containers(i, bin)%current%data = 0
    3020      2142400 :             data%integral_containers(i, bin)%element_counter = 1
    3021              :          END DO
    3022              :       END DO
    3023              : 
    3024        32960 :    END SUBROUTINE alloc_containers
    3025              : 
    3026              : ! **************************************************************************************************
    3027              : !> \brief Compares the non-technical parts of two HFX input section and check whether they are the same
    3028              : !>        Ignore things that would not change results (MEMORY, LOAD_BALANCE)
    3029              : !> \param hfx_section1 ...
    3030              : !> \param hfx_section2 ...
    3031              : !> \param is_identical ...
    3032              : !> \param same_except_frac ...
    3033              : !> \return ...
    3034              : ! **************************************************************************************************
    3035          582 :    SUBROUTINE compare_hfx_sections(hfx_section1, hfx_section2, is_identical, same_except_frac)
    3036              : 
    3037              :       TYPE(section_vals_type), POINTER                   :: hfx_section1, hfx_section2
    3038              :       LOGICAL, INTENT(OUT)                               :: is_identical
    3039              :       LOGICAL, INTENT(OUT), OPTIONAL                     :: same_except_frac
    3040              : 
    3041              :       CHARACTER(LEN=default_path_length)                 :: cval1, cval2
    3042              :       INTEGER                                            :: irep, ival1, ival2, n_rep_hf1, n_rep_hf2
    3043              :       LOGICAL                                            :: lval1, lval2
    3044              :       REAL(dp)                                           :: rval1, rval2
    3045              :       TYPE(section_vals_type), POINTER                   :: hfx_sub_section1, hfx_sub_section2
    3046              : 
    3047          194 :       is_identical = .TRUE.
    3048          194 :       IF (PRESENT(same_except_frac)) same_except_frac = .FALSE.
    3049              : 
    3050          194 :       CALL section_vals_get(hfx_section1, n_repetition=n_rep_hf1)
    3051          194 :       CALL section_vals_get(hfx_section2, n_repetition=n_rep_hf2)
    3052          194 :       is_identical = n_rep_hf1 == n_rep_hf2
    3053          200 :       IF (.NOT. is_identical) RETURN
    3054              : 
    3055          134 :       DO irep = 1, n_rep_hf1
    3056           70 :          CALL section_vals_val_get(hfx_section1, "PW_HFX", l_val=lval1, i_rep_section=irep)
    3057           70 :          CALL section_vals_val_get(hfx_section2, "PW_HFX", l_val=lval2, i_rep_section=irep)
    3058           70 :          IF (lval1 .NEQV. lval2) is_identical = .FALSE.
    3059              : 
    3060           70 :          CALL section_vals_val_get(hfx_section1, "PW_HFX_BLOCKSIZE", i_val=ival1, i_rep_section=irep)
    3061           70 :          CALL section_vals_val_get(hfx_section2, "PW_HFX_BLOCKSIZE", i_val=ival2, i_rep_section=irep)
    3062           70 :          IF (ival1 /= ival2) is_identical = .FALSE.
    3063              : 
    3064           70 :          CALL section_vals_val_get(hfx_section1, "TREAT_LSD_IN_CORE", l_val=lval1, i_rep_section=irep)
    3065           70 :          CALL section_vals_val_get(hfx_section2, "TREAT_LSD_IN_CORE", l_val=lval2, i_rep_section=irep)
    3066           70 :          IF (lval1 .NEQV. lval2) is_identical = .FALSE.
    3067              : 
    3068           70 :          hfx_sub_section1 => section_vals_get_subs_vals(hfx_section1, "INTERACTION_POTENTIAL", i_rep_section=irep)
    3069           70 :          hfx_sub_section2 => section_vals_get_subs_vals(hfx_section2, "INTERACTION_POTENTIAL", i_rep_section=irep)
    3070              : 
    3071           70 :          CALL section_vals_val_get(hfx_sub_section1, "OMEGA", r_val=rval1, i_rep_section=irep)
    3072           70 :          CALL section_vals_val_get(hfx_sub_section2, "OMEGA", r_val=rval2, i_rep_section=irep)
    3073           70 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3074              : 
    3075           70 :          CALL section_vals_val_get(hfx_sub_section1, "POTENTIAL_TYPE", i_val=ival1, i_rep_section=irep)
    3076           70 :          CALL section_vals_val_get(hfx_sub_section2, "POTENTIAL_TYPE", i_val=ival2, i_rep_section=irep)
    3077           70 :          IF (ival1 /= ival2) is_identical = .FALSE.
    3078           70 :          IF (.NOT. is_identical) RETURN
    3079              : 
    3080           64 :          IF (ival1 == do_potential_truncated .OR. ival1 == do_potential_mix_cl_trunc) THEN
    3081            6 :             CALL section_vals_val_get(hfx_sub_section1, "CUTOFF_RADIUS", r_val=rval1, i_rep_section=irep)
    3082            6 :             CALL section_vals_val_get(hfx_sub_section2, "CUTOFF_RADIUS", r_val=rval2, i_rep_section=irep)
    3083            6 :             IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3084              : 
    3085            6 :             CALL section_vals_val_get(hfx_sub_section1, "T_C_G_DATA", c_val=cval1, i_rep_section=irep)
    3086            6 :             CALL section_vals_val_get(hfx_sub_section2, "T_C_G_DATA", c_val=cval2, i_rep_section=irep)
    3087            6 :             IF (cval1 /= cval2) is_identical = .FALSE.
    3088              :          END IF
    3089              : 
    3090           64 :          CALL section_vals_val_get(hfx_sub_section1, "SCALE_COULOMB", r_val=rval1, i_rep_section=irep)
    3091           64 :          CALL section_vals_val_get(hfx_sub_section2, "SCALE_COULOMB", r_val=rval2, i_rep_section=irep)
    3092           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3093              : 
    3094           64 :          CALL section_vals_val_get(hfx_sub_section1, "SCALE_GAUSSIAN", r_val=rval1, i_rep_section=irep)
    3095           64 :          CALL section_vals_val_get(hfx_sub_section2, "SCALE_GAUSSIAN", r_val=rval2, i_rep_section=irep)
    3096           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3097              : 
    3098           64 :          CALL section_vals_val_get(hfx_sub_section1, "SCALE_LONGRANGE", r_val=rval1, i_rep_section=irep)
    3099           64 :          CALL section_vals_val_get(hfx_sub_section2, "SCALE_LONGRANGE", r_val=rval2, i_rep_section=irep)
    3100           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3101              : 
    3102           64 :          hfx_sub_section1 => section_vals_get_subs_vals(hfx_section1, "PERIODIC", i_rep_section=irep)
    3103           64 :          hfx_sub_section2 => section_vals_get_subs_vals(hfx_section2, "PERIODIC", i_rep_section=irep)
    3104              : 
    3105           64 :          CALL section_vals_val_get(hfx_sub_section1, "NUMBER_OF_SHELLS", i_val=ival1, i_rep_section=irep)
    3106           64 :          CALL section_vals_val_get(hfx_sub_section2, "NUMBER_OF_SHELLS", i_val=ival2, i_rep_section=irep)
    3107           64 :          IF (ival1 /= ival2) is_identical = .FALSE.
    3108              : 
    3109           64 :          hfx_sub_section1 => section_vals_get_subs_vals(hfx_section1, "RI", i_rep_section=irep)
    3110           64 :          hfx_sub_section2 => section_vals_get_subs_vals(hfx_section2, "RI", i_rep_section=irep)
    3111              : 
    3112           64 :          CALL section_vals_val_get(hfx_sub_section1, "_SECTION_PARAMETERS_", l_val=lval1, i_rep_section=irep)
    3113           64 :          CALL section_vals_val_get(hfx_sub_section2, "_SECTION_PARAMETERS_", l_val=lval2, i_rep_section=irep)
    3114           64 :          IF (lval1 .NEQV. lval2) is_identical = .FALSE.
    3115              : 
    3116           64 :          CALL section_vals_val_get(hfx_sub_section1, "CUTOFF_RADIUS", r_val=rval1, i_rep_section=irep)
    3117           64 :          CALL section_vals_val_get(hfx_sub_section2, "CUTOFF_RADIUS", r_val=rval2, i_rep_section=irep)
    3118           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3119              : 
    3120           64 :          CALL section_vals_val_get(hfx_sub_section1, "EPS_EIGVAL", r_val=rval1, i_rep_section=irep)
    3121           64 :          CALL section_vals_val_get(hfx_sub_section2, "EPS_EIGVAL", r_val=rval2, i_rep_section=irep)
    3122           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3123              : 
    3124           64 :          CALL section_vals_val_get(hfx_sub_section1, "EPS_FILTER", r_val=rval1, i_rep_section=irep)
    3125           64 :          CALL section_vals_val_get(hfx_sub_section2, "EPS_FILTER", r_val=rval2, i_rep_section=irep)
    3126           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3127              : 
    3128           64 :          CALL section_vals_val_get(hfx_sub_section1, "EPS_FILTER_2C", r_val=rval1, i_rep_section=irep)
    3129           64 :          CALL section_vals_val_get(hfx_sub_section2, "EPS_FILTER_2C", r_val=rval2, i_rep_section=irep)
    3130           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3131              : 
    3132           64 :          CALL section_vals_val_get(hfx_sub_section1, "EPS_FILTER_MO", r_val=rval1, i_rep_section=irep)
    3133           64 :          CALL section_vals_val_get(hfx_sub_section2, "EPS_FILTER_MO", r_val=rval2, i_rep_section=irep)
    3134           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3135              : 
    3136           64 :          CALL section_vals_val_get(hfx_sub_section1, "EPS_PGF_ORB", r_val=rval1, i_rep_section=irep)
    3137           64 :          CALL section_vals_val_get(hfx_sub_section2, "EPS_PGF_ORB", r_val=rval2, i_rep_section=irep)
    3138           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3139              : 
    3140           64 :          CALL section_vals_val_get(hfx_sub_section1, "MAX_BLOCK_SIZE_MO", i_val=ival1, i_rep_section=irep)
    3141           64 :          CALL section_vals_val_get(hfx_sub_section2, "MAX_BLOCK_SIZE_MO", i_val=ival2, i_rep_section=irep)
    3142           64 :          IF (ival1 /= ival2) is_identical = .FALSE.
    3143              : 
    3144           64 :          CALL section_vals_val_get(hfx_sub_section1, "MIN_BLOCK_SIZE", i_val=ival1, i_rep_section=irep)
    3145           64 :          CALL section_vals_val_get(hfx_sub_section2, "MIN_BLOCK_SIZE", i_val=ival2, i_rep_section=irep)
    3146           64 :          IF (ival1 /= ival2) is_identical = .FALSE.
    3147              : 
    3148           64 :          CALL section_vals_val_get(hfx_sub_section1, "OMEGA", r_val=rval1, i_rep_section=irep)
    3149           64 :          CALL section_vals_val_get(hfx_sub_section2, "OMEGA", r_val=rval2, i_rep_section=irep)
    3150           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3151              : 
    3152           64 :          CALL section_vals_val_get(hfx_sub_section1, "RI_FLAVOR", i_val=ival1, i_rep_section=irep)
    3153           64 :          CALL section_vals_val_get(hfx_sub_section2, "RI_FLAVOR", i_val=ival2, i_rep_section=irep)
    3154           64 :          IF (ival1 /= ival2) is_identical = .FALSE.
    3155              : 
    3156           64 :          CALL section_vals_val_get(hfx_sub_section1, "RI_METRIC", i_val=ival1, i_rep_section=irep)
    3157           64 :          CALL section_vals_val_get(hfx_sub_section2, "RI_METRIC", i_val=ival2, i_rep_section=irep)
    3158           64 :          IF (ival1 /= ival2) is_identical = .FALSE.
    3159              : 
    3160           64 :          hfx_sub_section1 => section_vals_get_subs_vals(hfx_section1, "SCREENING", i_rep_section=irep)
    3161           64 :          hfx_sub_section2 => section_vals_get_subs_vals(hfx_section2, "SCREENING", i_rep_section=irep)
    3162              : 
    3163           64 :          CALL section_vals_val_get(hfx_sub_section1, "EPS_SCHWARZ", r_val=rval1, i_rep_section=irep)
    3164           64 :          CALL section_vals_val_get(hfx_sub_section2, "EPS_SCHWARZ", r_val=rval2, i_rep_section=irep)
    3165           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3166              : 
    3167           64 :          CALL section_vals_val_get(hfx_sub_section1, "EPS_SCHWARZ_FORCES", r_val=rval1, i_rep_section=irep)
    3168           64 :          CALL section_vals_val_get(hfx_sub_section2, "EPS_SCHWARZ_FORCES", r_val=rval2, i_rep_section=irep)
    3169           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3170              : 
    3171           64 :          CALL section_vals_val_get(hfx_sub_section1, "P_SCREEN_CORRECTION_FACTOR", r_val=rval1, i_rep_section=irep)
    3172           64 :          CALL section_vals_val_get(hfx_sub_section2, "P_SCREEN_CORRECTION_FACTOR", r_val=rval2, i_rep_section=irep)
    3173           64 :          IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3174              : 
    3175           64 :          CALL section_vals_val_get(hfx_sub_section1, "SCREEN_ON_INITIAL_P", l_val=lval1, i_rep_section=irep)
    3176           64 :          CALL section_vals_val_get(hfx_sub_section2, "SCREEN_ON_INITIAL_P", l_val=lval2, i_rep_section=irep)
    3177           64 :          IF (lval1 .NEQV. lval2) is_identical = .FALSE.
    3178              : 
    3179           64 :          CALL section_vals_val_get(hfx_sub_section1, "SCREEN_P_FORCES", l_val=lval1, i_rep_section=irep)
    3180           64 :          CALL section_vals_val_get(hfx_sub_section2, "SCREEN_P_FORCES", l_val=lval2, i_rep_section=irep)
    3181         1758 :          IF (lval1 .NEQV. lval2) is_identical = .FALSE.
    3182              : 
    3183              :       END DO
    3184              : 
    3185              :       !Test of the fraction
    3186           64 :       IF (is_identical) THEN
    3187          120 :          DO irep = 1, n_rep_hf1
    3188           60 :             CALL section_vals_val_get(hfx_section1, "FRACTION", r_val=rval1, i_rep_section=irep)
    3189           60 :             CALL section_vals_val_get(hfx_section2, "FRACTION", r_val=rval2, i_rep_section=irep)
    3190          120 :             IF (ABS(rval1 - rval2) > EPSILON(1.0_dp)) is_identical = .FALSE.
    3191              :          END DO
    3192              : 
    3193           60 :          IF (PRESENT(same_except_frac)) THEN
    3194           36 :             IF (.NOT. is_identical) same_except_frac = .TRUE.
    3195              :          END IF
    3196              :       END IF
    3197              : 
    3198              :    END SUBROUTINE compare_hfx_sections
    3199              : 
    3200            0 : END MODULE hfx_types
    3201              : 
        

Generated by: LCOV version 2.0-1