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