Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Routines to calculate derivatives with respect to basis function origin
10 : !> \par History
11 : !> 04.2008 created [Manuel Guidon]
12 : !> \author Manuel Guidon
13 : ! **************************************************************************************************
14 : MODULE hfx_derivatives
15 : USE admm_types, ONLY: admm_type
16 : USE atomic_kind_types, ONLY: atomic_kind_type, &
17 : get_atomic_kind_set
18 : USE cell_types, ONLY: cell_type, &
19 : pbc
20 : USE cp_control_types, ONLY: dft_control_type
21 : USE cp_files, ONLY: close_file, &
22 : open_file
23 : USE cp_log_handling, ONLY: cp_get_default_logger, &
24 : cp_logger_type
25 : USE cp_output_handling, ONLY: cp_p_file, &
26 : cp_print_key_finished_output, &
27 : cp_print_key_should_output, &
28 : cp_print_key_unit_nr
29 : USE message_passing, ONLY: mp_para_env_type
30 : USE cp_dbcsr_api, ONLY: dbcsr_get_matrix_type, &
31 : dbcsr_p_type, &
32 : dbcsr_type_antisymmetric
33 : USE four_center_integral_interface, ONLY: four_center_integral_context_type
34 : USE four_center_integral_methods, ONLY: forces4, &
35 : pgf_product_list_size
36 : USE gamma, ONLY: init_md_ftable
37 : USE hfx_communication, ONLY: get_full_density
38 : USE hfx_compression_methods, ONLY: hfx_add_mult_cache_elements, &
39 : hfx_add_single_cache_element, &
40 : hfx_decompress_first_cache, &
41 : hfx_flush_last_cache, &
42 : hfx_get_mult_cache_elements, &
43 : hfx_get_single_cache_element, &
44 : hfx_reset_cache_and_container
45 : USE hfx_load_balance_methods, ONLY: collect_load_balance_info, &
46 : hfx_load_balance, &
47 : hfx_update_load_balance
48 : USE hfx_pair_list_methods, ONLY: build_atomic_pair_list, &
49 : build_pair_list
50 : USE hfx_screening_methods, ONLY: update_pmax_mat
51 : USE hfx_types, ONLY: &
52 : alloc_containers, dealloc_containers, hfx_basis_info_type, hfx_basis_type, hfx_cache_type, &
53 : hfx_cell_type, hfx_container_type, hfx_distribution, hfx_general_type, hfx_init_container, &
54 : hfx_load_balance_type, hfx_memory_type, hfx_p_kind, hfx_pgf_list, hfx_pgf_product_list, &
55 : hfx_potential_type, hfx_screen_coeff_type, hfx_screening_type, hfx_task_list_type, &
56 : hfx_type, init_t_c_g0_lmax, log_zero, pair_list_type, pair_set_list_type
57 : USE input_constants, ONLY: do_potential_mix_cl_trunc, &
58 : do_potential_truncated, &
59 : hfx_do_eval_forces
60 : USE input_section_types, ONLY: section_vals_type
61 : USE kinds, ONLY: dp, &
62 : int_8
63 : USE machine, ONLY: m_walltime
64 : USE mathconstants, ONLY: fac
65 : USE orbital_pointers, ONLY: nco, &
66 : ncoset, &
67 : nso
68 : USE particle_types, ONLY: particle_type
69 : USE qs_environment_types, ONLY: get_qs_env, &
70 : qs_environment_type
71 : USE qs_force_types, ONLY: qs_force_type
72 : USE t_c_g0, ONLY: init
73 : USE util, ONLY: sort
74 : USE virial_types, ONLY: virial_type
75 :
76 : !$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
77 :
78 : #include "./base/base_uses.f90"
79 :
80 : IMPLICIT NONE
81 : PRIVATE
82 :
83 : PUBLIC :: derivatives_four_center
84 :
85 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'hfx_derivatives'
86 :
87 : !***
88 :
89 : CONTAINS
90 :
91 : ! **************************************************************************************************
92 : !> \brief computes four center derivatives for a full basis set and updates the
93 : !> forces%fock_4c arrays. Uses all 8 eri symmetries
94 : !> \param qs_env ...
95 : !> \param rho_ao density matrix
96 : !> \param rho_ao_resp relaxed density matrix from response
97 : !> \param hfx_section HFX input section
98 : !> \param para_env para_env
99 : !> \param irep ID of HFX replica
100 : !> \param use_virial ...
101 : !> \param adiabatic_rescale_factor parameter used for MCY3 hybrid
102 : !> \param resp_only Calculate only forces from response density
103 : !> \par History
104 : !> 06.2007 created [Manuel Guidon]
105 : !> 08.2007 optimized load balance [Manuel Guidon]
106 : !> 02.2009 completely rewritten screening part [Manuel Guidon]
107 : !> 12.2017 major bug fix. removed wrong cycle that was causing segfault.
108 : !> see https://groups.google.com/forum/#!topic/cp2k/pc6B14XOALY
109 : !> [Tobias Binninger + Valery Weber]
110 : !> \author Manuel Guidon
111 : ! **************************************************************************************************
112 2012 : SUBROUTINE derivatives_four_center(qs_env, rho_ao, rho_ao_resp, hfx_section, para_env, &
113 : irep, use_virial, adiabatic_rescale_factor, resp_only, &
114 : external_x_data, nspins)
115 :
116 : TYPE(qs_environment_type), POINTER :: qs_env
117 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao
118 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: rho_ao_resp
119 : TYPE(section_vals_type), POINTER :: hfx_section
120 : TYPE(mp_para_env_type), POINTER :: para_env
121 : INTEGER, INTENT(IN) :: irep
122 : LOGICAL, INTENT(IN) :: use_virial
123 : REAL(dp), INTENT(IN), OPTIONAL :: adiabatic_rescale_factor
124 : LOGICAL, INTENT(IN), OPTIONAL :: resp_only
125 : TYPE(hfx_type), DIMENSION(:, :), POINTER, OPTIONAL :: external_x_data
126 : INTEGER, INTENT(IN), OPTIONAL :: nspins
127 :
128 : CHARACTER(LEN=*), PARAMETER :: routineN = 'derivatives_four_center'
129 :
130 : INTEGER :: atomic_offset_ac, atomic_offset_ad, atomic_offset_bc, atomic_offset_bd, bin, &
131 : bits_max_val, buffer_left, buffer_size, buffer_start, cache_size, coord, current_counter, &
132 : forces_map(4, 2), handle, handle_bin, handle_getP, handle_load, handle_main, i, i_atom, &
133 : i_list_ij, i_list_kl, i_set_list_ij, i_set_list_ij_start, i_set_list_ij_stop, &
134 : i_set_list_kl, i_set_list_kl_start, i_set_list_kl_stop, i_thread, iatom, iatom_block, &
135 : iatom_end, iatom_start, ikind, iset, iw, j, j_atom, jatom, jatom_block, jatom_end, &
136 : jatom_start, jkind, jset, k, k_atom, katom, katom_block, katom_end, katom_start
137 : INTEGER :: kind_kind_idx, kkind, kset, l_atom, l_max, latom, latom_block, latom_end, &
138 : latom_start, lkind, lset, max_am, max_pgf, max_set, my_bin_id, my_bin_size, my_thread_id, &
139 : n_threads, natom, nbits, ncob, ncos_max, nints, nkimages, nkind, nneighbors, nseta, &
140 : nsetb, nsgf_max, my_nspins, sgfb, shm_task_counter, shm_total_bins, sphi_a_u1, sphi_a_u2, &
141 : sphi_a_u3, sphi_b_u1, sphi_b_u2, sphi_b_u3, sphi_c_u1, sphi_c_u2, sphi_c_u3, sphi_d_u1, &
142 : sphi_d_u2, sphi_d_u3, swap_id, tmp_i4, unit_id
143 : INTEGER(int_8) :: atom_block, counter, estimate_to_store_int, max_val_memory, &
144 : mem_compression_counter, mem_eris, mem_max_val, my_current_counter, my_istart, &
145 : n_processes, nblocks, ncpu, neris_incore, neris_onthefly, neris_tmp, neris_total, &
146 : nprim_ints, shm_neris_incore, shm_neris_onthefly, shm_neris_total, shm_nprim_ints, &
147 : shm_stor_count_max_val, shm_storage_counter_integrals, stor_count_max_val, &
148 : storage_counter_integrals, tmp_block, tmp_i8(6)
149 2012 : INTEGER(int_8), ALLOCATABLE, DIMENSION(:) :: tmp_task_list_cost
150 2012 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of, last_sgf_global, &
151 2012 : nimages, tmp_index
152 2012 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min, lc_max, lc_min, ld_max, &
153 4024 : ld_min, npgfa, npgfb, npgfc, npgfd, nsgfa, nsgfb, nsgfc, nsgfd, shm_block_offset
154 4024 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfb, nsgfl_a, nsgfl_b, nsgfl_c, nsgfl_d, &
155 2012 : offset_ac_set, offset_ad_set, offset_bc_set, offset_bd_set, shm_atomic_block_offset
156 : INTEGER, DIMENSION(:, :), POINTER, SAVE :: shm_is_assoc_atomic_block
157 2012 : INTEGER, DIMENSION(:, :, :, :), POINTER :: shm_set_offset
158 : INTEGER, SAVE :: shm_number_of_p_entries
159 : LOGICAL :: bins_left, buffer_overflow, do_dynamic_load_balancing, do_it, do_periodic, &
160 : do_print_load_balance_info, is_anti_symmetric, my_resp_only, screen_pmat_forces, &
161 : treat_forces_in_core, use_disk_storage, with_resp_density
162 2012 : LOGICAL, DIMENSION(:, :), POINTER :: shm_atomic_pair_list
163 : REAL(dp) :: bintime_start, bintime_stop, cartesian_estimate, cartesian_estimate_virial, &
164 : compression_factor, eps_schwarz, eps_storage, fac, hf_fraction, ln_10, log10_eps_schwarz, &
165 : log10_pmax, log_2, max_contraction_val, max_val1, max_val2, max_val2_set, &
166 : my_adiabatic_rescale_factor, pmax_atom, pmax_blocks, pmax_entry, pmax_tmp, ra(3), rab2, &
167 : rb(3), rc(3), rcd2, rd(3), spherical_estimate, spherical_estimate_virial, symm_fac, &
168 : tmp_virial(3, 3)
169 2012 : REAL(dp), ALLOCATABLE, DIMENSION(:) :: ede_buffer1, ede_buffer2, ede_primitives_tmp, &
170 2012 : ede_primitives_tmp_virial, ede_work, ede_work2, ede_work2_virial, ede_work_forces, &
171 4024 : ede_work_virial, pac_buf, pac_buf_beta, pac_buf_resp, pac_buf_resp_beta, pad_buf, &
172 2012 : pad_buf_beta, pad_buf_resp, pad_buf_resp_beta, pbc_buf, pbc_buf_beta, pbc_buf_resp, &
173 2012 : pbc_buf_resp_beta, pbd_buf, pbd_buf_beta, pbd_buf_resp, pbd_buf_resp_beta
174 2012 : REAL(dp), ALLOCATABLE, DIMENSION(:), TARGET :: primitive_forces, primitive_forces_virial
175 2012 : REAL(dp), DIMENSION(:), POINTER :: full_density_resp, &
176 4024 : full_density_resp_beta, T2
177 2012 : REAL(dp), DIMENSION(:, :), POINTER :: full_density_alpha, full_density_beta, &
178 2012 : max_contraction, ptr_p_1, ptr_p_2, ptr_p_3, ptr_p_4, shm_pmax_atom, shm_pmax_block, &
179 2012 : sphi_b, zeta, zetb, zetc, zetd
180 2012 : REAL(dp), DIMENSION(:, :, :), POINTER :: sphi_a_ext_set, sphi_b_ext_set, &
181 2012 : sphi_c_ext_set, sphi_d_ext_set
182 2012 : REAL(dp), DIMENSION(:, :, :, :), POINTER :: sphi_a_ext, sphi_b_ext, sphi_c_ext, &
183 2012 : sphi_d_ext
184 : REAL(KIND=dp) :: coeffs_kind_max0
185 : TYPE(admm_type), POINTER :: admm_env
186 2012 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
187 : TYPE(cell_type), POINTER :: cell
188 : TYPE(four_center_integral_context_type) :: private_context
189 : TYPE(cp_logger_type), POINTER :: logger
190 : TYPE(dft_control_type), POINTER :: dft_control
191 : TYPE(hfx_basis_info_type), POINTER :: basis_info
192 2012 : TYPE(hfx_basis_type), DIMENSION(:), POINTER :: basis_parameter
193 2012 : TYPE(hfx_cache_type), DIMENSION(:), POINTER :: integral_caches
194 : TYPE(hfx_cache_type), POINTER :: maxval_cache
195 2012 : TYPE(hfx_container_type), DIMENSION(:), POINTER :: integral_containers
196 : TYPE(hfx_container_type), POINTER :: maxval_container
197 : TYPE(hfx_distribution), POINTER :: distribution_forces
198 : TYPE(hfx_general_type) :: general_parameter
199 : TYPE(hfx_load_balance_type), POINTER :: load_balance_parameter
200 : TYPE(hfx_memory_type), POINTER :: memory_parameter
201 2012 : TYPE(hfx_p_kind), DIMENSION(:), POINTER :: shm_initial_p
202 2012 : TYPE(hfx_pgf_list), ALLOCATABLE, DIMENSION(:) :: pgf_list_ij, pgf_list_kl
203 : TYPE(hfx_pgf_product_list), ALLOCATABLE, &
204 2012 : DIMENSION(:) :: pgf_product_list
205 : TYPE(hfx_potential_type) :: potential_parameter
206 : TYPE(hfx_screen_coeff_type), DIMENSION(:, :), &
207 2012 : POINTER :: screen_coeffs_kind, tmp_R_1, tmp_R_2, &
208 2012 : tmp_screen_pgf1, tmp_screen_pgf2
209 : TYPE(hfx_screen_coeff_type), &
210 2012 : DIMENSION(:, :, :, :), POINTER :: screen_coeffs_set
211 : TYPE(hfx_screen_coeff_type), &
212 2012 : DIMENSION(:, :, :, :, :, :), POINTER :: radii_pgf, screen_coeffs_pgf
213 : TYPE(hfx_screening_type) :: screening_parameter
214 2012 : TYPE(hfx_task_list_type), DIMENSION(:), POINTER :: shm_task_list, tmp_task_list
215 : TYPE(hfx_type), POINTER :: actual_x_data
216 2012 : TYPE(hfx_type), DIMENSION(:, :), POINTER :: my_x_data
217 : TYPE(pair_list_type) :: list_ij, list_kl
218 : TYPE(pair_set_list_type), ALLOCATABLE, &
219 2012 : DIMENSION(:) :: set_list_ij, set_list_kl
220 2012 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
221 2012 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
222 : TYPE(virial_type), POINTER :: virial
223 :
224 2012 : NULLIFY (dft_control, admm_env)
225 :
226 2012 : with_resp_density = .FALSE.
227 684 : IF (ASSOCIATED(rho_ao_resp)) with_resp_density = .TRUE.
228 :
229 2012 : my_resp_only = .FALSE.
230 2012 : IF (PRESENT(resp_only)) my_resp_only = resp_only
231 :
232 2012 : is_anti_symmetric = dbcsr_get_matrix_type(rho_ao(1, 1)%matrix) == dbcsr_type_antisymmetric
233 :
234 : CALL get_qs_env(qs_env, &
235 : admm_env=admm_env, &
236 : particle_set=particle_set, &
237 : atomic_kind_set=atomic_kind_set, &
238 : cell=cell, &
239 2012 : dft_control=dft_control)
240 :
241 2012 : IF (PRESENT(nspins)) THEN
242 252 : my_nspins = nspins
243 : ELSE
244 1760 : my_nspins = dft_control%nspins
245 : END IF
246 2012 : nkimages = dft_control%nimages
247 2012 : CPASSERT(nkimages == 1)
248 :
249 2012 : my_x_data => qs_env%x_data
250 2012 : IF (PRESENT(external_x_data)) my_x_data => external_x_data
251 :
252 : !! One atom systems have no contribution to forces
253 2012 : IF (SIZE(particle_set, 1) == 1) THEN
254 4 : IF (.NOT. use_virial) RETURN
255 : END IF
256 :
257 2008 : CALL timeset(routineN, handle)
258 : !! Calculate l_max used in fgamma , because init_md_ftable is definitely not thread safe
259 2008 : nkind = SIZE(atomic_kind_set, 1)
260 2008 : l_max = 0
261 5786 : DO ikind = 1, nkind
262 16122 : l_max = MAX(l_max, MAXVAL(my_x_data(1, 1)%basis_parameter(ikind)%lmax))
263 : END DO
264 2008 : l_max = 4*l_max + 1
265 2008 : CALL init_md_ftable(l_max)
266 :
267 2008 : IF (my_x_data(1, 1)%potential_parameter%potential_type == do_potential_truncated .OR. &
268 : my_x_data(1, 1)%potential_parameter%potential_type == do_potential_mix_cl_trunc) THEN
269 752 : IF (l_max > init_t_c_g0_lmax) THEN
270 208 : CALL open_file(unit_number=unit_id, file_name=my_x_data(1, 1)%potential_parameter%filename)
271 208 : CALL init(l_max, unit_id, para_env%mepos, para_env)
272 208 : CALL close_file(unit_id)
273 208 : init_t_c_g0_lmax = l_max
274 : END IF
275 : END IF
276 :
277 2008 : n_threads = 1
278 2008 : !$ n_threads = omp_get_max_threads()
279 :
280 2008 : shm_neris_total = 0
281 2008 : shm_nprim_ints = 0
282 2008 : shm_neris_onthefly = 0
283 2008 : shm_storage_counter_integrals = 0
284 2008 : shm_neris_incore = 0
285 2008 : shm_stor_count_max_val = 0
286 :
287 : !! get force array
288 2008 : CALL get_qs_env(qs_env=qs_env, force=force, virial=virial)
289 :
290 2008 : my_adiabatic_rescale_factor = 1.0_dp
291 2008 : IF (PRESENT(adiabatic_rescale_factor)) THEN
292 260 : my_adiabatic_rescale_factor = adiabatic_rescale_factor
293 : END IF
294 :
295 : !$OMP PARALLEL DEFAULT(NONE) &
296 : !$OMP SHARED(qs_env,&
297 : !$OMP rho_ao,&
298 : !$OMP rho_ao_resp,&
299 : !$OMP with_resp_density,&
300 : !$OMP hfx_section,&
301 : !$OMP para_env,&
302 : !$OMP irep,&
303 : !$OMP my_resp_only,&
304 : !$OMP ncoset,&
305 : !$OMP nco,&
306 : !$OMP nso,&
307 : !$OMP n_threads,&
308 : !$OMP full_density_alpha,&
309 : !$OMP full_density_resp,&
310 : !$OMP full_density_resp_beta,&
311 : !$OMP full_density_beta,&
312 : !$OMP shm_initial_p,&
313 : !$OMP shm_is_assoc_atomic_block,&
314 : !$OMP shm_number_of_p_entries,&
315 : !$OMP force,&
316 : !$OMP virial,&
317 : !$OMP my_adiabatic_rescale_factor,&
318 : !$OMP shm_neris_total,&
319 : !$OMP shm_neris_onthefly,&
320 : !$OMP shm_storage_counter_integrals,&
321 : !$OMP shm_neris_incore,&
322 : !$OMP shm_nprim_ints,&
323 : !$OMP shm_stor_count_max_val,&
324 : !$OMP cell,&
325 : !$OMP screen_coeffs_set,&
326 : !$OMP screen_coeffs_kind,&
327 : !$OMP screen_coeffs_pgf,&
328 : !$OMP pgf_product_list_size,&
329 : !$OMP nkind,&
330 : !$OMP is_anti_symmetric,&
331 : !$OMP radii_pgf,&
332 : !$OMP shm_atomic_block_offset,&
333 : !$OMP shm_set_offset,&
334 : !$OMP shm_block_offset,&
335 : !$OMP shm_task_counter,&
336 : !$OMP shm_task_list,&
337 : !$OMP shm_total_bins,&
338 : !$OMP shm_pmax_block,&
339 : !$OMP shm_atomic_pair_list,&
340 : !$OMP shm_pmax_atom,&
341 : !$OMP use_virial,&
342 : !$OMP do_print_load_balance_info,&
343 : !$OMP nkimages,my_nspins,my_x_data)&
344 : !$OMP PRIVATE(actual_x_data,atomic_kind_set,atomic_offset_ac,atomic_offset_ad,atomic_offset_bc,&
345 : !$OMP atomic_offset_bd,atom_of_kind,basis_info,&
346 : !$OMP basis_parameter,bin,bins_left,bintime_start,bintime_stop,bits_max_val,buffer_left,buffer_overflow,buffer_size,&
347 : !$OMP buffer_start,cache_size,cartesian_estimate,cartesian_estimate_virial,&
348 : !$OMP coeffs_kind_max0,compression_factor,counter,current_counter,&
349 : !$OMP distribution_forces,do_dynamic_load_balancing,do_it,do_periodic,ede_buffer1,ede_buffer2,&
350 : !$OMP ede_primitives_tmp,ede_primitives_tmp_virial,&
351 : !$OMP ede_work,ede_work2,ede_work2_virial,ede_work_forces,ede_work_virial,eps_schwarz,eps_storage,estimate_to_store_int,&
352 : !$OMP fac,first_sgfb,forces_map,general_parameter,handle_bin,handle_getp,handle_load,&
353 : !$OMP handle_main,hf_fraction,i_atom,iatom_end,iatom_start,ikind,integral_caches,integral_containers,&
354 : !$OMP i_set_list_ij_start,i_set_list_ij_stop,i_set_list_kl_start,i_set_list_kl_stop,i_thread,iw,j_atom,jatom_end,&
355 : !$OMP jatom_start,jkind,katom,k_atom,katom_block,katom_end,katom_start,kind_kind_idx,&
356 : !$OMP kind_of,kkind,kset,la_max,la_min,last_sgf_global,latom,l_atom,&
357 : !$OMP latom_block,latom_end,latom_start,lb_max,lb_min,lc_max,lc_min,ld_max,&
358 : !$OMP ld_min,list_ij,list_kl,lkind,ln_10,load_balance_parameter,log10_eps_schwarz,log10_pmax,&
359 : !$OMP log_2,logger,lset,max_am,max_contraction,max_contraction_val,max_pgf,max_set,&
360 : !$OMP max_val1,max_val2,max_val2_set,maxval_cache,maxval_container,max_val_memory,mem_compression_counter,mem_eris,&
361 : !$OMP mem_max_val,memory_parameter,my_bin_id,my_bin_size,my_current_counter,my_istart,my_thread_id,natom,&
362 : !$OMP nbits,nblocks,ncob,ncos_max,ncpu,neris_incore,neris_onthefly,neris_tmp,&
363 : !$OMP neris_total,nimages,nints,nneighbors,npgfa,npgfb,npgfc,npgfd,&
364 : !$OMP nprim_ints,n_processes,nseta,nsetb,nsgfa,nsgfb,nsgfc,nsgfd,&
365 : !$OMP nsgfl_a,nsgfl_b,nsgfl_c,nsgfl_d,nsgf_max,offset_ac_set,offset_ad_set,&
366 : !$OMP offset_bc_set,offset_bd_set,pac_buf,pac_buf_beta,pac_buf_resp,pac_buf_resp_beta,pad_buf,pad_buf_beta,pad_buf_resp,&
367 : !$OMP pad_buf_resp_beta,particle_set,pbc_buf,pbc_buf_beta,pbc_buf_resp,pbc_buf_resp_beta,pbd_buf,pbd_buf_beta, &
368 : !$OMP pbd_buf_resp, pbd_buf_resp_beta, pgf_list_ij,&
369 : !$OMP pgf_list_kl,pgf_product_list,pmax_atom,pmax_blocks,pmax_entry,pmax_tmp,potential_parameter,primitive_forces,&
370 : !$OMP primitive_forces_virial,private_context,ptr_p_1,ptr_p_2,ptr_p_3,ptr_p_4,ra,rab2,&
371 : !$OMP rb,rc,rcd2,rd,screening_parameter,screen_pmat_forces,set_list_ij,set_list_kl,&
372 : !$OMP sgfb,spherical_estimate,spherical_estimate_virial,sphi_a_ext,sphi_a_ext_set,sphi_a_u1,sphi_a_u2,sphi_a_u3,&
373 : !$OMP sphi_b,sphi_b_ext,sphi_b_ext_set,sphi_b_u1,sphi_b_u2,sphi_b_u3,sphi_c_ext,sphi_c_ext_set,&
374 : !$OMP sphi_c_u1,sphi_c_u2,sphi_c_u3,sphi_d_ext,sphi_d_ext_set,sphi_d_u1,sphi_d_u2,sphi_d_u3,&
375 : !$OMP storage_counter_integrals,stor_count_max_val,swap_id,symm_fac,t2,tmp_block,tmp_i8, tmp_i4,&
376 : !$OMP tmp_index,tmp_r_1,tmp_r_2,tmp_screen_pgf1,tmp_screen_pgf2,tmp_task_list,tmp_task_list_cost,tmp_virial,&
377 2008 : !$OMP treat_forces_in_core,use_disk_storage,zeta,zetb,zetc,zetd)
378 :
379 : i_thread = 0
380 : !$ i_thread = omp_get_thread_num()
381 :
382 : ln_10 = LOG(10.0_dp)
383 : log_2 = LOG10(2.0_dp)
384 : actual_x_data => my_x_data(irep, i_thread + 1)
385 : do_periodic = actual_x_data%periodic_parameter%do_periodic
386 :
387 : screening_parameter = actual_x_data%screening_parameter
388 : general_parameter = actual_x_data%general_parameter
389 : potential_parameter = actual_x_data%potential_parameter
390 : basis_info => actual_x_data%basis_info
391 :
392 : load_balance_parameter => actual_x_data%load_balance_parameter
393 : basis_parameter => actual_x_data%basis_parameter
394 :
395 : ! IF(with_resp_density) THEN
396 : ! ! here we also do a copy of the original load_balance_parameter
397 : ! ! since if MP2 forces are required after the calculation of the HFX
398 : ! ! derivatives we need to calculate again the SCF energy.
399 : ! ALLOCATE(load_balance_parameter_energy)
400 : ! load_balance_parameter_energy = actual_x_data%load_balance_parameter
401 : ! END IF
402 :
403 : memory_parameter => actual_x_data%memory_parameter
404 :
405 : cache_size = memory_parameter%cache_size
406 : bits_max_val = memory_parameter%bits_max_val
407 :
408 : use_disk_storage = .FALSE.
409 :
410 : CALL get_qs_env(qs_env=qs_env, &
411 : atomic_kind_set=atomic_kind_set, &
412 : particle_set=particle_set)
413 :
414 : max_set = basis_info%max_set
415 : max_am = basis_info%max_am
416 : natom = SIZE(particle_set, 1)
417 :
418 : treat_forces_in_core = memory_parameter%treat_forces_in_core
419 :
420 : hf_fraction = general_parameter%fraction
421 : hf_fraction = hf_fraction*my_adiabatic_rescale_factor
422 : eps_schwarz = screening_parameter%eps_schwarz_forces
423 : IF (eps_schwarz < 0.0_dp) THEN
424 : log10_eps_schwarz = log_zero
425 : ELSE
426 : !! ** make eps_schwarz tighter in case of a stress calculation
427 : IF (use_virial) eps_schwarz = eps_schwarz/actual_x_data%periodic_parameter%R_max_stress
428 : log10_eps_schwarz = LOG10(eps_schwarz)
429 : END IF
430 : screen_pmat_forces = screening_parameter%do_p_screening_forces
431 : ! don't do density screening in case of response forces
432 : IF (with_resp_density) screen_pmat_forces = .FALSE.
433 :
434 : eps_storage = eps_schwarz*memory_parameter%eps_storage_scaling
435 :
436 : counter = 0_int_8
437 :
438 : !! Copy the libint_guy
439 : private_context = actual_x_data%eri4_context
440 :
441 : !! Get screening parameter
442 :
443 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
444 : atom_of_kind=atom_of_kind, &
445 : kind_of=kind_of)
446 :
447 : !! Create helper arrray for mapping local basis functions to global ones
448 : ALLOCATE (last_sgf_global(0:natom))
449 : last_sgf_global(0) = 0
450 : DO iatom = 1, natom
451 : ikind = kind_of(iatom)
452 : last_sgf_global(iatom) = last_sgf_global(iatom - 1) + basis_parameter(ikind)%nsgf_total
453 : END DO
454 :
455 : ALLOCATE (max_contraction(max_set, natom))
456 :
457 : max_contraction = 0.0_dp
458 : max_pgf = 0
459 : DO jatom = 1, natom
460 : jkind = kind_of(jatom)
461 : lb_max => basis_parameter(jkind)%lmax
462 : npgfb => basis_parameter(jkind)%npgf
463 : nsetb = basis_parameter(jkind)%nset
464 : first_sgfb => basis_parameter(jkind)%first_sgf
465 : sphi_b => basis_parameter(jkind)%sphi
466 : nsgfb => basis_parameter(jkind)%nsgf
467 : DO jset = 1, nsetb
468 : ! takes the primitive to contracted transformation into account
469 : ncob = npgfb(jset)*ncoset(lb_max(jset))
470 : sgfb = first_sgfb(1, jset)
471 : ! if the primitives are assumed to be all of max_val2, max_val2*p2s_b becomes
472 : ! the maximum value after multiplication with sphi_b
473 : max_contraction(jset, jatom) = MAXVAL([(SUM(ABS(sphi_b(1:ncob, i))), i=sgfb, sgfb + nsgfb(jset) - 1)])
474 : max_pgf = MAX(max_pgf, npgfb(jset))
475 : END DO
476 : END DO
477 :
478 : ncpu = para_env%num_pe
479 : n_processes = ncpu*n_threads
480 :
481 : !! initialize some counters
482 : neris_total = 0_int_8
483 : neris_incore = 0_int_8
484 : neris_onthefly = 0_int_8
485 : mem_eris = 0_int_8
486 : mem_max_val = 0_int_8
487 : compression_factor = 0.0_dp
488 : nprim_ints = 0_int_8
489 : neris_tmp = 0_int_8
490 : max_val_memory = 1_int_8
491 :
492 : !$OMP MASTER
493 : !! Set pointer for is_assoc helper
494 : shm_is_assoc_atomic_block => actual_x_data%is_assoc_atomic_block
495 : shm_number_of_p_entries = actual_x_data%number_of_p_entries
496 : shm_atomic_block_offset => actual_x_data%atomic_block_offset
497 : shm_set_offset => actual_x_data%set_offset
498 : shm_block_offset => actual_x_data%block_offset
499 :
500 : NULLIFY (full_density_alpha)
501 : NULLIFY (full_density_beta)
502 : ALLOCATE (full_density_alpha(shm_block_offset(ncpu + 1), nkimages))
503 :
504 : !! Get the full density from all the processors
505 : CALL timeset(routineN//"_getP", handle_getP)
506 : CALL get_full_density(para_env, full_density_alpha(:, 1), rho_ao(1, 1)%matrix, shm_number_of_p_entries, &
507 : shm_block_offset, &
508 : kind_of, basis_parameter, get_max_vals_spin=.FALSE., &
509 : antisymmetric=is_anti_symmetric)
510 : ! for now only closed shell case
511 : IF (with_resp_density) THEN
512 : NULLIFY (full_density_resp)
513 : ALLOCATE (full_density_resp(shm_block_offset(ncpu + 1)))
514 : CALL get_full_density(para_env, full_density_resp, rho_ao_resp(1)%matrix, shm_number_of_p_entries, &
515 : shm_block_offset, &
516 : kind_of, basis_parameter, get_max_vals_spin=.FALSE., &
517 : antisymmetric=is_anti_symmetric)
518 : END IF
519 :
520 : IF (my_nspins == 2) THEN
521 : ALLOCATE (full_density_beta(shm_block_offset(ncpu + 1), 1))
522 : CALL get_full_density(para_env, full_density_beta(:, 1), rho_ao(2, 1)%matrix, shm_number_of_p_entries, &
523 : shm_block_offset, &
524 : kind_of, basis_parameter, get_max_vals_spin=.FALSE., &
525 : antisymmetric=is_anti_symmetric)
526 : ! With resp density
527 : IF (with_resp_density) THEN
528 : NULLIFY (full_density_resp_beta)
529 : ALLOCATE (full_density_resp_beta(shm_block_offset(ncpu + 1)))
530 : CALL get_full_density(para_env, full_density_resp_beta, rho_ao_resp(2)%matrix, shm_number_of_p_entries, &
531 : shm_block_offset, &
532 : kind_of, basis_parameter, get_max_vals_spin=.FALSE., &
533 : antisymmetric=is_anti_symmetric)
534 : END IF
535 :
536 : END IF
537 : CALL timestop(handle_getP)
538 :
539 : !! Calculate max entries for screening on actual density. If screen_p_mat_forces = FALSE, the
540 : !! matrix is initialized to 1.0
541 : IF (screen_pmat_forces) THEN
542 : NULLIFY (shm_initial_p)
543 : shm_initial_p => actual_x_data%initial_p_forces
544 : shm_pmax_atom => actual_x_data%pmax_atom_forces
545 : IF (memory_parameter%recalc_forces) THEN
546 : CALL update_pmax_mat(shm_initial_p, &
547 : actual_x_data%map_atom_to_kind_atom, &
548 : actual_x_data%set_offset, &
549 : actual_x_data%atomic_block_offset, &
550 : shm_pmax_atom, &
551 : full_density_alpha, full_density_beta, &
552 : natom, kind_of, basis_parameter, &
553 : nkind, actual_x_data%is_assoc_atomic_block, my_nspins)
554 : END IF
555 : END IF
556 :
557 : ! restore as full density the HF density
558 : ! maybe in the future
559 : IF (with_resp_density .AND. .NOT. my_resp_only) THEN
560 : full_density_alpha(:, 1) = full_density_alpha(:, 1) - full_density_resp
561 : IF (my_nspins == 2) THEN
562 : full_density_beta(:, 1) = &
563 : full_density_beta(:, 1) - full_density_resp_beta
564 : END IF
565 : ! full_density_resp=full_density+full_density_resp
566 : END IF
567 :
568 : screen_coeffs_set => actual_x_data%screen_funct_coeffs_set
569 : screen_coeffs_kind => actual_x_data%screen_funct_coeffs_kind
570 : screen_coeffs_pgf => actual_x_data%screen_funct_coeffs_pgf
571 : radii_pgf => actual_x_data%pair_dist_radii_pgf
572 : shm_pmax_block => actual_x_data%pmax_block
573 :
574 : !$OMP END MASTER
575 : !$OMP BARRIER
576 :
577 : !$OMP MASTER
578 : CALL timeset(routineN//"_load", handle_load)
579 : !$OMP END MASTER
580 : !! Load balance the work
581 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
582 : IF (actual_x_data%b_first_load_balance_forces) THEN
583 : CALL hfx_load_balance(actual_x_data, eps_schwarz, particle_set, max_set, para_env, &
584 : screen_coeffs_set, screen_coeffs_kind, &
585 : shm_is_assoc_atomic_block, do_periodic, &
586 : load_balance_parameter, kind_of, basis_parameter, shm_initial_p, &
587 : shm_pmax_atom, i_thread, n_threads, &
588 : cell, screen_pmat_forces, actual_x_data%map_atom_to_kind_atom, &
589 : nkind, hfx_do_eval_forces, shm_pmax_block, use_virial)
590 : actual_x_data%b_first_load_balance_forces = .FALSE.
591 : ELSE
592 : CALL hfx_update_load_balance(actual_x_data, para_env, &
593 : load_balance_parameter, &
594 : i_thread, n_threads, hfx_do_eval_forces)
595 : END IF
596 : END IF
597 : !$OMP MASTER
598 : CALL timestop(handle_load)
599 : !$OMP END MASTER
600 :
601 : !! precompute maximum nco and allocate scratch
602 : ncos_max = 0
603 : nsgf_max = 0
604 : DO iatom = 1, natom
605 : ikind = kind_of(iatom)
606 : nseta = basis_parameter(ikind)%nset
607 : npgfa => basis_parameter(ikind)%npgf
608 : la_max => basis_parameter(ikind)%lmax
609 : nsgfa => basis_parameter(ikind)%nsgf
610 : DO iset = 1, nseta
611 : ncos_max = MAX(ncos_max, ncoset(la_max(iset)))
612 : nsgf_max = MAX(nsgf_max, nsgfa(iset))
613 : END DO
614 : END DO
615 :
616 : !! Allocate work arrays
617 : ALLOCATE (primitive_forces(12*nsgf_max**4))
618 : primitive_forces = 0.0_dp
619 :
620 : ! ** Allocate buffers for pgf_lists
621 : nneighbors = SIZE(actual_x_data%neighbor_cells)
622 : ALLOCATE (pgf_list_ij(max_pgf**2))
623 : ALLOCATE (pgf_list_kl(max_pgf**2))
624 : !$OMP ATOMIC READ
625 : tmp_i4 = pgf_product_list_size
626 : ALLOCATE (pgf_product_list(tmp_i4))
627 : ALLOCATE (nimages(max_pgf**2))
628 :
629 : DO i = 1, max_pgf**2
630 : ALLOCATE (pgf_list_ij(i)%image_list(nneighbors))
631 : ALLOCATE (pgf_list_kl(i)%image_list(nneighbors))
632 : END DO
633 :
634 : ALLOCATE (pbd_buf(nsgf_max**2))
635 : ALLOCATE (pbc_buf(nsgf_max**2))
636 : ALLOCATE (pad_buf(nsgf_max**2))
637 : ALLOCATE (pac_buf(nsgf_max**2))
638 : IF (with_resp_density) THEN
639 : ALLOCATE (pbd_buf_resp(nsgf_max**2))
640 : ALLOCATE (pbc_buf_resp(nsgf_max**2))
641 : ALLOCATE (pad_buf_resp(nsgf_max**2))
642 : ALLOCATE (pac_buf_resp(nsgf_max**2))
643 : END IF
644 : IF (my_nspins == 2) THEN
645 : ALLOCATE (pbd_buf_beta(nsgf_max**2))
646 : ALLOCATE (pbc_buf_beta(nsgf_max**2))
647 : ALLOCATE (pad_buf_beta(nsgf_max**2))
648 : ALLOCATE (pac_buf_beta(nsgf_max**2))
649 : IF (with_resp_density) THEN
650 : ALLOCATE (pbd_buf_resp_beta(nsgf_max**2))
651 : ALLOCATE (pbc_buf_resp_beta(nsgf_max**2))
652 : ALLOCATE (pad_buf_resp_beta(nsgf_max**2))
653 : ALLOCATE (pac_buf_resp_beta(nsgf_max**2))
654 : END IF
655 : END IF
656 :
657 : ALLOCATE (ede_work(ncos_max**4*12))
658 : ALLOCATE (ede_work2(ncos_max**4*12))
659 : ALLOCATE (ede_work_forces(ncos_max**4*12))
660 : ALLOCATE (ede_buffer1(ncos_max**4))
661 : ALLOCATE (ede_buffer2(ncos_max**4))
662 : ALLOCATE (ede_primitives_tmp(nsgf_max**4))
663 :
664 : IF (use_virial) THEN
665 : ALLOCATE (primitive_forces_virial(12*nsgf_max**4*3))
666 : primitive_forces_virial = 0.0_dp
667 : ALLOCATE (ede_work_virial(ncos_max**4*12*3))
668 : ALLOCATE (ede_work2_virial(ncos_max**4*12*3))
669 : ALLOCATE (ede_primitives_tmp_virial(nsgf_max**4))
670 : tmp_virial = 0.0_dp
671 : ELSE
672 : ! dummy allocation
673 : ALLOCATE (primitive_forces_virial(1))
674 : primitive_forces_virial = 0.0_dp
675 : ALLOCATE (ede_work_virial(1))
676 : ALLOCATE (ede_work2_virial(1))
677 : ALLOCATE (ede_primitives_tmp_virial(1))
678 : END IF
679 :
680 : !! Start caluclating integrals of the form (ab|cd) or (ij|kl)
681 : !! In order to do so, there is a main four-loop structure that takes into account the two symmetries
682 : !!
683 : !! (ab|cd) = (ba|cd) = (ab|dc) = (ba|dc)
684 : !!
685 : !! by iterating in the following way
686 : !!
687 : !! DO iatom=1,natom and DO katom=1,natom
688 : !! DO jatom=iatom,natom DO latom=katom,natom
689 : !!
690 : !! The third symmetry
691 : !!
692 : !! (ab|cd) = (cd|ab)
693 : !!
694 : !! is taken into account by the following criterion:
695 : !!
696 : !! IF(katom+latom<=iatom+jatom) THEN
697 : !! IF( ((iatom+jatom)==(katom+latom) ) .AND.(katom<iatom)) CYCLE
698 : !!
699 : !! Furthermore, if iatom==jatom==katom==latom we cycle, because the derivatives are zero anyway.
700 : !!
701 : !! Depending on the degeneracy of an integral the exchange contribution is multiplied by a corresponding
702 : !! factor ( symm_fac ).
703 : !!
704 : !! If one quartet does not pass the screening we CYCLE on the outer most possible loop. Thats why we use
705 : !! different hierarchies of short range screening matrices.
706 : !!
707 : !! If we do a parallel run, each process owns a unique array of workloads. Here, a workload is
708 : !! defined as :
709 : !!
710 : !! istart, jstart, kstart, lstart, number_of_atom_quartets, initial_cpu_id
711 : !!
712 : !! This tells the process where to start the main loops and how many bunches of integrals it has to
713 : !! calculate. The original parallelization is a simple modulo distribution that is binned and
714 : !! optimized in the load_balance routines. Since the Monte Carlo routines can swap processors,
715 : !! we need to know which was the initial cpu_id.
716 : !! Furthermore, the indices iatom, jatom, katom, latom have to be set to istart, jstart, kstart and
717 : !! lstart only the first time the loop is executed. All subsequent loops have to start with one or
718 : !! iatom and katom respectively. Therefore, we use flags like first_j_loop etc.
719 :
720 : !$OMP BARRIER
721 : !$OMP MASTER
722 : CALL timeset(routineN//"_main", handle_main)
723 : !$OMP END MASTER
724 : !$OMP BARRIER
725 :
726 : coeffs_kind_max0 = MAXVAL(screen_coeffs_kind(:, :)%x(2))
727 : ALLOCATE (set_list_ij((max_set*load_balance_parameter%block_size)**2))
728 : ALLOCATE (set_list_kl((max_set*load_balance_parameter%block_size)**2))
729 :
730 : !$OMP BARRIER
731 :
732 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
733 : actual_x_data%distribution_forces%ram_counter = HUGE(distribution_forces%ram_counter)
734 : memory_parameter%ram_counter_forces = HUGE(memory_parameter%ram_counter_forces)
735 : END IF
736 :
737 : IF (treat_forces_in_core) THEN
738 : buffer_overflow = .FALSE.
739 : ELSE
740 : buffer_overflow = .TRUE.
741 : END IF
742 :
743 : do_dynamic_load_balancing = .TRUE.
744 : IF (n_threads == 1) do_dynamic_load_balancing = .FALSE.
745 :
746 : IF (do_dynamic_load_balancing) THEN
747 : my_bin_size = SIZE(actual_x_data%distribution_forces)
748 : ELSE
749 : my_bin_size = 1
750 : END IF
751 : !! We do not need the containers if MAX_MEM = 0
752 : IF (treat_forces_in_core) THEN
753 : !! IF new md step -> reinitialize containers
754 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
755 : CALL dealloc_containers(actual_x_data%store_forces, memory_parameter%actual_memory_usage)
756 : CALL alloc_containers(actual_x_data%store_forces, my_bin_size)
757 :
758 : DO bin = 1, my_bin_size
759 : maxval_container => actual_x_data%store_forces%maxval_container(bin)
760 : integral_containers => actual_x_data%store_forces%integral_containers(:, bin)
761 : CALL hfx_init_container(maxval_container, memory_parameter%actual_memory_usage, .FALSE.)
762 : DO i = 1, 64
763 : CALL hfx_init_container(integral_containers(i), memory_parameter%actual_memory_usage, .FALSE.)
764 : END DO
765 : END DO
766 : END IF
767 :
768 : !! Decompress the first cache for maxvals and integrals
769 : IF (.NOT. actual_x_data%memory_parameter%recalc_forces) THEN
770 : DO bin = 1, my_bin_size
771 : maxval_cache => actual_x_data%store_forces%maxval_cache(bin)
772 : maxval_container => actual_x_data%store_forces%maxval_container(bin)
773 : integral_caches => actual_x_data%store_forces%integral_caches(:, bin)
774 : integral_containers => actual_x_data%store_forces%integral_containers(:, bin)
775 : CALL hfx_decompress_first_cache(bits_max_val, maxval_cache, maxval_container, &
776 : memory_parameter%actual_memory_usage, .FALSE.)
777 : DO i = 1, 64
778 : CALL hfx_decompress_first_cache(i, integral_caches(i), integral_containers(i), &
779 : memory_parameter%actual_memory_usage, .FALSE.)
780 : END DO
781 : END DO
782 : END IF
783 : END IF
784 :
785 : !$OMP BARRIER
786 : !$OMP MASTER
787 : IF (do_dynamic_load_balancing) THEN
788 : ! ** Lets construct the task list
789 : shm_total_bins = 0
790 : DO i = 1, n_threads
791 : shm_total_bins = shm_total_bins + SIZE(my_x_data(irep, i)%distribution_forces)
792 : END DO
793 : ALLOCATE (tmp_task_list(shm_total_bins))
794 : shm_task_counter = 0
795 : DO i = 1, n_threads
796 : DO bin = 1, SIZE(my_x_data(irep, i)%distribution_forces)
797 : shm_task_counter = shm_task_counter + 1
798 : tmp_task_list(shm_task_counter)%thread_id = i
799 : tmp_task_list(shm_task_counter)%bin_id = bin
800 : tmp_task_list(shm_task_counter)%cost = my_x_data(irep, i)%distribution_forces(bin)%cost
801 : END DO
802 : END DO
803 :
804 : ! ** Now sort the task list
805 : ALLOCATE (tmp_task_list_cost(shm_total_bins))
806 : ALLOCATE (tmp_index(shm_total_bins))
807 :
808 : DO i = 1, shm_total_bins
809 : tmp_task_list_cost(i) = tmp_task_list(i)%cost
810 : END DO
811 :
812 : CALL sort(tmp_task_list_cost, shm_total_bins, tmp_index)
813 :
814 : ALLOCATE (actual_x_data%task_list(shm_total_bins))
815 :
816 : DO i = 1, shm_total_bins
817 : actual_x_data%task_list(i) = tmp_task_list(tmp_index(shm_total_bins - i + 1))
818 : END DO
819 :
820 : shm_task_list => actual_x_data%task_list
821 : shm_task_counter = 0
822 :
823 : DEALLOCATE (tmp_task_list_cost, tmp_index, tmp_task_list)
824 : END IF
825 :
826 : !! precalculate maximum density matrix elements in blocks
827 : shm_pmax_block => actual_x_data%pmax_block
828 : actual_x_data%pmax_block = 0.0_dp
829 : IF (screen_pmat_forces) THEN
830 : DO iatom_block = 1, SIZE(actual_x_data%blocks)
831 : iatom_start = actual_x_data%blocks(iatom_block)%istart
832 : iatom_end = actual_x_data%blocks(iatom_block)%iend
833 : DO jatom_block = 1, SIZE(actual_x_data%blocks)
834 : jatom_start = actual_x_data%blocks(jatom_block)%istart
835 : jatom_end = actual_x_data%blocks(jatom_block)%iend
836 : shm_pmax_block(iatom_block, jatom_block) = MAXVAL(shm_pmax_atom(iatom_start:iatom_end, jatom_start:jatom_end))
837 : END DO
838 : END DO
839 : END IF
840 : shm_atomic_pair_list => actual_x_data%atomic_pair_list_forces
841 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
842 : CALL build_atomic_pair_list(natom, shm_atomic_pair_list, kind_of, basis_parameter, particle_set, &
843 : do_periodic, screen_coeffs_kind, coeffs_kind_max0, log10_eps_schwarz, cell, &
844 : actual_x_data%blocks)
845 : END IF
846 :
847 : my_bin_size = SIZE(actual_x_data%distribution_forces)
848 : DO bin = 1, my_bin_size
849 : actual_x_data%distribution_forces(bin)%time_forces = 0.0_dp
850 : END DO
851 : !$OMP END MASTER
852 : !$OMP BARRIER
853 :
854 : IF (treat_forces_in_core) THEN
855 : IF (my_bin_size > 0) THEN
856 : maxval_container => actual_x_data%store_forces%maxval_container(1)
857 : maxval_cache => actual_x_data%store_forces%maxval_cache(1)
858 :
859 : integral_containers => actual_x_data%store_forces%integral_containers(:, 1)
860 : integral_caches => actual_x_data%store_forces%integral_caches(:, 1)
861 : END IF
862 : END IF
863 :
864 : nblocks = load_balance_parameter%nblocks
865 :
866 : bins_left = .TRUE.
867 : do_it = .TRUE.
868 : bin = 0
869 : DO WHILE (bins_left)
870 : IF (.NOT. do_dynamic_load_balancing) THEN
871 : bin = bin + 1
872 : IF (bin > my_bin_size) THEN
873 : do_it = .FALSE.
874 : bins_left = .FALSE.
875 : ELSE
876 : do_it = .TRUE.
877 : bins_left = .TRUE.
878 : distribution_forces => actual_x_data%distribution_forces(bin)
879 : END IF
880 : ELSE
881 : !$OMP CRITICAL(hfxderivatives_critical)
882 : shm_task_counter = shm_task_counter + 1
883 : IF (shm_task_counter <= shm_total_bins) THEN
884 : my_thread_id = shm_task_list(shm_task_counter)%thread_id
885 : my_bin_id = shm_task_list(shm_task_counter)%bin_id
886 : IF (treat_forces_in_core) THEN
887 : maxval_cache => my_x_data(irep, my_thread_id)%store_forces%maxval_cache(my_bin_id)
888 : maxval_container => my_x_data(irep, my_thread_id)%store_forces%maxval_container(my_bin_id)
889 : integral_caches => my_x_data(irep, my_thread_id)%store_forces%integral_caches(:, my_bin_id)
890 : integral_containers => my_x_data(irep, my_thread_id)%store_forces%integral_containers(:, my_bin_id)
891 : END IF
892 : distribution_forces => my_x_data(irep, my_thread_id)%distribution_forces(my_bin_id)
893 : do_it = .TRUE.
894 : bins_left = .TRUE.
895 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
896 : distribution_forces%ram_counter = HUGE(distribution_forces%ram_counter)
897 : END IF
898 : counter = 0_Int_8
899 : ELSE
900 : do_it = .FALSE.
901 : bins_left = .FALSE.
902 : END IF
903 : !$OMP END CRITICAL(hfxderivatives_critical)
904 : END IF
905 :
906 : IF (.NOT. do_it) CYCLE
907 : !$OMP MASTER
908 : CALL timeset(routineN//"_bin", handle_bin)
909 : !$OMP END MASTER
910 : bintime_start = m_walltime()
911 : my_istart = distribution_forces%istart
912 : my_current_counter = 0
913 : IF (distribution_forces%number_of_atom_quartets == 0 .OR. &
914 : my_istart == -1_int_8) my_istart = nblocks**4
915 : atomic_blocks: DO atom_block = my_istart, nblocks**4 - 1, n_processes
916 : latom_block = INT(MODULO(atom_block, nblocks)) + 1
917 : tmp_block = atom_block/nblocks
918 : katom_block = INT(MODULO(tmp_block, nblocks)) + 1
919 : IF (latom_block < katom_block) CYCLE atomic_blocks
920 : tmp_block = tmp_block/nblocks
921 : jatom_block = INT(MODULO(tmp_block, nblocks)) + 1
922 : tmp_block = tmp_block/nblocks
923 : iatom_block = INT(MODULO(tmp_block, nblocks)) + 1
924 : IF (jatom_block < iatom_block) CYCLE atomic_blocks
925 : my_current_counter = my_current_counter + 1
926 : IF (my_current_counter > distribution_forces%number_of_atom_quartets) EXIT atomic_blocks
927 :
928 : iatom_start = actual_x_data%blocks(iatom_block)%istart
929 : iatom_end = actual_x_data%blocks(iatom_block)%iend
930 : jatom_start = actual_x_data%blocks(jatom_block)%istart
931 : jatom_end = actual_x_data%blocks(jatom_block)%iend
932 : katom_start = actual_x_data%blocks(katom_block)%istart
933 : katom_end = actual_x_data%blocks(katom_block)%iend
934 : latom_start = actual_x_data%blocks(latom_block)%istart
935 : latom_end = actual_x_data%blocks(latom_block)%iend
936 :
937 : pmax_blocks = MAX(shm_pmax_block(katom_block, iatom_block) + &
938 : shm_pmax_block(latom_block, jatom_block), &
939 : shm_pmax_block(latom_block, iatom_block) + &
940 : shm_pmax_block(katom_block, jatom_block))
941 :
942 : IF (2.0_dp*coeffs_kind_max0 + pmax_blocks < log10_eps_schwarz) CYCLE atomic_blocks
943 :
944 : CALL build_pair_list(natom, list_ij, set_list_ij, iatom_start, iatom_end, &
945 : jatom_start, jatom_end, &
946 : kind_of, basis_parameter, particle_set, &
947 : do_periodic, screen_coeffs_set, screen_coeffs_kind, coeffs_kind_max0, &
948 : log10_eps_schwarz, cell, pmax_blocks, shm_atomic_pair_list)
949 :
950 : CALL build_pair_list(natom, list_kl, set_list_kl, katom_start, katom_end, &
951 : latom_start, latom_end, &
952 : kind_of, basis_parameter, particle_set, &
953 : do_periodic, screen_coeffs_set, screen_coeffs_kind, coeffs_kind_max0, &
954 : log10_eps_schwarz, cell, pmax_blocks, shm_atomic_pair_list)
955 :
956 : DO i_list_ij = 1, list_ij%n_element
957 : iatom = list_ij%elements(i_list_ij)%pair(1)
958 : jatom = list_ij%elements(i_list_ij)%pair(2)
959 : i_set_list_ij_start = list_ij%elements(i_list_ij)%set_bounds(1)
960 : i_set_list_ij_stop = list_ij%elements(i_list_ij)%set_bounds(2)
961 : ikind = list_ij%elements(i_list_ij)%kind_pair(1)
962 : jkind = list_ij%elements(i_list_ij)%kind_pair(2)
963 : ra = list_ij%elements(i_list_ij)%r1
964 : rb = list_ij%elements(i_list_ij)%r2
965 : rab2 = list_ij%elements(i_list_ij)%dist2
966 :
967 : la_max => basis_parameter(ikind)%lmax
968 : la_min => basis_parameter(ikind)%lmin
969 : npgfa => basis_parameter(ikind)%npgf
970 : nseta = basis_parameter(ikind)%nset
971 : zeta => basis_parameter(ikind)%zet
972 : nsgfa => basis_parameter(ikind)%nsgf
973 : sphi_a_ext => basis_parameter(ikind)%sphi_ext(:, :, :, :)
974 : nsgfl_a => basis_parameter(ikind)%nsgfl
975 : sphi_a_u1 = UBOUND(sphi_a_ext, 1)
976 : sphi_a_u2 = UBOUND(sphi_a_ext, 2)
977 : sphi_a_u3 = UBOUND(sphi_a_ext, 3)
978 :
979 : lb_max => basis_parameter(jkind)%lmax
980 : lb_min => basis_parameter(jkind)%lmin
981 : npgfb => basis_parameter(jkind)%npgf
982 : nsetb = basis_parameter(jkind)%nset
983 : zetb => basis_parameter(jkind)%zet
984 : nsgfb => basis_parameter(jkind)%nsgf
985 : sphi_b_ext => basis_parameter(jkind)%sphi_ext(:, :, :, :)
986 : nsgfl_b => basis_parameter(jkind)%nsgfl
987 : sphi_b_u1 = UBOUND(sphi_b_ext, 1)
988 : sphi_b_u2 = UBOUND(sphi_b_ext, 2)
989 : sphi_b_u3 = UBOUND(sphi_b_ext, 3)
990 :
991 : i_atom = atom_of_kind(iatom)
992 : forces_map(1, 1) = ikind
993 : forces_map(1, 2) = i_atom
994 : j_atom = atom_of_kind(jatom)
995 : forces_map(2, 1) = jkind
996 : forces_map(2, 2) = j_atom
997 :
998 : DO i_list_kl = 1, list_kl%n_element
999 : katom = list_kl%elements(i_list_kl)%pair(1)
1000 : latom = list_kl%elements(i_list_kl)%pair(2)
1001 :
1002 : !All four centers equivalent => zero-contribution
1003 : !VIIRAL IF((iatom==jatom .AND. iatom==katom .AND. iatom==latom)) CYCLE
1004 : IF (.NOT. (katom + latom <= iatom + jatom)) CYCLE
1005 : IF (((iatom + jatom) == (katom + latom)) .AND. (katom < iatom)) CYCLE
1006 :
1007 : i_set_list_kl_start = list_kl%elements(i_list_kl)%set_bounds(1)
1008 : i_set_list_kl_stop = list_kl%elements(i_list_kl)%set_bounds(2)
1009 : kkind = list_kl%elements(i_list_kl)%kind_pair(1)
1010 : lkind = list_kl%elements(i_list_kl)%kind_pair(2)
1011 : rc = list_kl%elements(i_list_kl)%r1
1012 : rd = list_kl%elements(i_list_kl)%r2
1013 : rcd2 = list_kl%elements(i_list_kl)%dist2
1014 :
1015 : IF (screen_pmat_forces) THEN
1016 : pmax_atom = MAX(shm_pmax_atom(katom, iatom) + &
1017 : shm_pmax_atom(latom, jatom), &
1018 : shm_pmax_atom(latom, iatom) + &
1019 : shm_pmax_atom(katom, jatom))
1020 : ELSE
1021 : pmax_atom = 0.0_dp
1022 : END IF
1023 :
1024 : IF ((screen_coeffs_kind(jkind, ikind)%x(1)*rab2 + &
1025 : screen_coeffs_kind(jkind, ikind)%x(2)) + &
1026 : (screen_coeffs_kind(lkind, kkind)%x(1)*rcd2 + &
1027 : screen_coeffs_kind(lkind, kkind)%x(2)) + pmax_atom < log10_eps_schwarz) CYCLE
1028 :
1029 : IF (.NOT. (shm_is_assoc_atomic_block(latom, iatom) >= 1 .AND. &
1030 : shm_is_assoc_atomic_block(katom, iatom) >= 1 .AND. &
1031 : shm_is_assoc_atomic_block(katom, jatom) >= 1 .AND. &
1032 : shm_is_assoc_atomic_block(latom, jatom) >= 1)) CYCLE
1033 : k_atom = atom_of_kind(katom)
1034 : forces_map(3, 1) = kkind
1035 : forces_map(3, 2) = k_atom
1036 :
1037 : l_atom = atom_of_kind(latom)
1038 : forces_map(4, 1) = lkind
1039 : forces_map(4, 2) = l_atom
1040 :
1041 : IF (my_nspins == 1) THEN
1042 : fac = 0.25_dp*hf_fraction
1043 : ELSE
1044 : fac = 0.5_dp*hf_fraction
1045 : END IF
1046 : !calculate symmetry_factor
1047 : symm_fac = 0.25_dp
1048 : IF (iatom == jatom) symm_fac = symm_fac*2.0_dp
1049 : IF (katom == latom) symm_fac = symm_fac*2.0_dp
1050 : IF (iatom == katom .AND. jatom == latom .AND. &
1051 : iatom /= jatom .AND. katom /= latom) symm_fac = symm_fac*2.0_dp
1052 : IF (iatom == katom .AND. iatom == jatom .AND. &
1053 : katom == latom) symm_fac = symm_fac*2.0_dp
1054 :
1055 : symm_fac = 1.0_dp/symm_fac
1056 : fac = fac*symm_fac
1057 :
1058 : lc_max => basis_parameter(kkind)%lmax
1059 : lc_min => basis_parameter(kkind)%lmin
1060 : npgfc => basis_parameter(kkind)%npgf
1061 : zetc => basis_parameter(kkind)%zet
1062 : nsgfc => basis_parameter(kkind)%nsgf
1063 : sphi_c_ext => basis_parameter(kkind)%sphi_ext(:, :, :, :)
1064 : nsgfl_c => basis_parameter(kkind)%nsgfl
1065 : sphi_c_u1 = UBOUND(sphi_c_ext, 1)
1066 : sphi_c_u2 = UBOUND(sphi_c_ext, 2)
1067 : sphi_c_u3 = UBOUND(sphi_c_ext, 3)
1068 :
1069 : ld_max => basis_parameter(lkind)%lmax
1070 : ld_min => basis_parameter(lkind)%lmin
1071 : npgfd => basis_parameter(lkind)%npgf
1072 : zetd => basis_parameter(lkind)%zet
1073 : nsgfd => basis_parameter(lkind)%nsgf
1074 : sphi_d_ext => basis_parameter(lkind)%sphi_ext(:, :, :, :)
1075 : nsgfl_d => basis_parameter(lkind)%nsgfl
1076 : sphi_d_u1 = UBOUND(sphi_d_ext, 1)
1077 : sphi_d_u2 = UBOUND(sphi_d_ext, 2)
1078 : sphi_d_u3 = UBOUND(sphi_d_ext, 3)
1079 :
1080 : atomic_offset_bd = shm_atomic_block_offset(jatom, latom)
1081 : atomic_offset_bc = shm_atomic_block_offset(jatom, katom)
1082 : atomic_offset_ad = shm_atomic_block_offset(iatom, latom)
1083 : atomic_offset_ac = shm_atomic_block_offset(iatom, katom)
1084 :
1085 : IF (jatom < latom) THEN
1086 : offset_bd_set => shm_set_offset(:, :, lkind, jkind)
1087 : ELSE
1088 : offset_bd_set => shm_set_offset(:, :, jkind, lkind)
1089 : END IF
1090 : IF (jatom < katom) THEN
1091 : offset_bc_set => shm_set_offset(:, :, kkind, jkind)
1092 : ELSE
1093 : offset_bc_set => shm_set_offset(:, :, jkind, kkind)
1094 : END IF
1095 : IF (iatom < latom) THEN
1096 : offset_ad_set => shm_set_offset(:, :, lkind, ikind)
1097 : ELSE
1098 : offset_ad_set => shm_set_offset(:, :, ikind, lkind)
1099 : END IF
1100 : IF (iatom < katom) THEN
1101 : offset_ac_set => shm_set_offset(:, :, kkind, ikind)
1102 : ELSE
1103 : offset_ac_set => shm_set_offset(:, :, ikind, kkind)
1104 : END IF
1105 :
1106 : IF (screen_pmat_forces) THEN
1107 : swap_id = 16
1108 : kind_kind_idx = INT(get_1D_idx(kkind, ikind, INT(nkind, int_8)))
1109 : IF (ikind >= kkind) THEN
1110 : ptr_p_1 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1111 : actual_x_data%map_atom_to_kind_atom(katom), &
1112 : actual_x_data%map_atom_to_kind_atom(iatom))
1113 : ELSE
1114 : ptr_p_1 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1115 : actual_x_data%map_atom_to_kind_atom(iatom), &
1116 : actual_x_data%map_atom_to_kind_atom(katom))
1117 : swap_id = swap_id + 1
1118 : END IF
1119 : kind_kind_idx = INT(get_1D_idx(lkind, jkind, INT(nkind, int_8)))
1120 : IF (jkind >= lkind) THEN
1121 : ptr_p_2 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1122 : actual_x_data%map_atom_to_kind_atom(latom), &
1123 : actual_x_data%map_atom_to_kind_atom(jatom))
1124 : ELSE
1125 : ptr_p_2 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1126 : actual_x_data%map_atom_to_kind_atom(jatom), &
1127 : actual_x_data%map_atom_to_kind_atom(latom))
1128 : swap_id = swap_id + 2
1129 : END IF
1130 : kind_kind_idx = INT(get_1D_idx(lkind, ikind, INT(nkind, int_8)))
1131 : IF (ikind >= lkind) THEN
1132 : ptr_p_3 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1133 : actual_x_data%map_atom_to_kind_atom(latom), &
1134 : actual_x_data%map_atom_to_kind_atom(iatom))
1135 : ELSE
1136 : ptr_p_3 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1137 : actual_x_data%map_atom_to_kind_atom(iatom), &
1138 : actual_x_data%map_atom_to_kind_atom(latom))
1139 : swap_id = swap_id + 4
1140 : END IF
1141 : kind_kind_idx = INT(get_1D_idx(kkind, jkind, INT(nkind, int_8)))
1142 : IF (jkind >= kkind) THEN
1143 : ptr_p_4 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1144 : actual_x_data%map_atom_to_kind_atom(katom), &
1145 : actual_x_data%map_atom_to_kind_atom(jatom))
1146 : ELSE
1147 : ptr_p_4 => shm_initial_p(kind_kind_idx)%p_kind(:, :, &
1148 : actual_x_data%map_atom_to_kind_atom(jatom), &
1149 : actual_x_data%map_atom_to_kind_atom(katom))
1150 : swap_id = swap_id + 8
1151 : END IF
1152 : END IF
1153 :
1154 : !! At this stage, check for memory used in compression
1155 :
1156 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
1157 : IF (treat_forces_in_core) THEN
1158 : ! ** We know the maximum amount of integrals that we can store per MPI-process
1159 : ! ** Now we need to sum the current memory usage among all openMP threads
1160 : ! ** We can just read what is currently stored on the corresponding x_data type
1161 : ! ** If this is thread i and it tries to read the data from thread j, that is
1162 : ! ** currently writing that data, we just dont care, because the possible error
1163 : ! ** is of the order of CACHE_SIZE
1164 : mem_compression_counter = 0
1165 : DO i = 1, n_threads
1166 : !$OMP ATOMIC READ
1167 : tmp_i4 = my_x_data(irep, i)%memory_parameter%actual_memory_usage
1168 : mem_compression_counter = mem_compression_counter + &
1169 : tmp_i4*memory_parameter%cache_size
1170 : END DO
1171 : IF (mem_compression_counter + memory_parameter%final_comp_counter_energy &
1172 : > memory_parameter%max_compression_counter) THEN
1173 : buffer_overflow = .TRUE.
1174 : IF (do_dynamic_load_balancing) THEN
1175 : distribution_forces%ram_counter = counter
1176 : ELSE
1177 : memory_parameter%ram_counter_forces = counter
1178 : END IF
1179 : ELSE
1180 : counter = counter + 1
1181 : buffer_overflow = .FALSE.
1182 : END IF
1183 : END IF
1184 : ELSE
1185 : IF (treat_forces_in_core) THEN
1186 : IF (do_dynamic_load_balancing) THEN
1187 : IF (distribution_forces%ram_counter == counter) THEN
1188 : buffer_overflow = .TRUE.
1189 : ELSE
1190 : counter = counter + 1
1191 : buffer_overflow = .FALSE.
1192 : END IF
1193 : ELSE
1194 : IF (memory_parameter%ram_counter_forces == counter) THEN
1195 : buffer_overflow = .TRUE.
1196 : ELSE
1197 : counter = counter + 1
1198 : buffer_overflow = .FALSE.
1199 : END IF
1200 : END IF
1201 : END IF
1202 : END IF
1203 :
1204 : DO i_set_list_ij = i_set_list_ij_start, i_set_list_ij_stop
1205 : iset = set_list_ij(i_set_list_ij)%pair(1)
1206 : jset = set_list_ij(i_set_list_ij)%pair(2)
1207 :
1208 : ncob = npgfb(jset)*ncoset(lb_max(jset))
1209 : max_val1 = screen_coeffs_set(jset, iset, jkind, ikind)%x(1)*rab2 + &
1210 : screen_coeffs_set(jset, iset, jkind, ikind)%x(2)
1211 : !! Near field screening
1212 : IF (max_val1 + (screen_coeffs_kind(lkind, kkind)%x(1)*rcd2 + &
1213 : screen_coeffs_kind(lkind, kkind)%x(2)) + pmax_atom < log10_eps_schwarz) CYCLE
1214 :
1215 : DO i_set_list_kl = i_set_list_kl_start, i_set_list_kl_stop
1216 : kset = set_list_kl(i_set_list_kl)%pair(1)
1217 : lset = set_list_kl(i_set_list_kl)%pair(2)
1218 :
1219 : max_val2_set = (screen_coeffs_set(lset, kset, lkind, kkind)%x(1)*rcd2 + &
1220 : screen_coeffs_set(lset, kset, lkind, kkind)%x(2))
1221 : max_val2 = max_val1 + max_val2_set
1222 :
1223 : !! Near field screening
1224 : IF (max_val2 + pmax_atom < log10_eps_schwarz) CYCLE
1225 :
1226 : IF (screen_pmat_forces) THEN
1227 : CALL get_pmax_val(ptr_p_1, ptr_p_2, ptr_p_3, ptr_p_4, &
1228 : iset, jset, kset, lset, &
1229 : pmax_tmp, swap_id)
1230 :
1231 : log10_pmax = log_2 + pmax_tmp
1232 : ELSE
1233 : log10_pmax = 0.0_dp
1234 : END IF
1235 :
1236 : max_val2 = max_val2 + log10_pmax
1237 : IF (max_val2 < log10_eps_schwarz) CYCLE
1238 :
1239 : pmax_entry = EXP(log10_pmax*ln_10)
1240 : !! store current number of integrals, update total number and number of integrals in buffer
1241 : current_counter = nsgfa(iset)*nsgfb(jset)*nsgfc(kset)*nsgfd(lset)*12
1242 : IF (buffer_overflow) THEN
1243 : neris_onthefly = neris_onthefly + current_counter
1244 : END IF
1245 :
1246 : !! Get integrals from buffer and update Kohn-Sham matrix
1247 : IF (.NOT. buffer_overflow .AND. .NOT. actual_x_data%memory_parameter%recalc_forces) THEN
1248 : nints = current_counter
1249 : CALL hfx_get_single_cache_element(estimate_to_store_int, 6, &
1250 : maxval_cache, maxval_container, memory_parameter%actual_memory_usage, &
1251 : use_disk_storage)
1252 : spherical_estimate = SET_EXPONENT(1.0_dp, estimate_to_store_int + 1)
1253 : ! IF (spherical_estimate*pmax_entry < eps_schwarz) CYCLE
1254 : IF (.NOT. use_virial) THEN
1255 : IF (spherical_estimate*pmax_entry < eps_schwarz) CYCLE
1256 : END IF
1257 : nbits = EXPONENT(ANINT(spherical_estimate*pmax_entry/eps_storage)) + 1
1258 : buffer_left = nints
1259 : buffer_start = 1
1260 : neris_incore = neris_incore + INT(nints, int_8)
1261 : DO WHILE (buffer_left > 0)
1262 : buffer_size = MIN(buffer_left, cache_size)
1263 : CALL hfx_get_mult_cache_elements(primitive_forces(buffer_start), &
1264 : buffer_size, nbits, &
1265 : integral_caches(nbits), &
1266 : integral_containers(nbits), &
1267 : eps_storage, pmax_entry, &
1268 : memory_parameter%actual_memory_usage, &
1269 : use_disk_storage)
1270 : buffer_left = buffer_left - buffer_size
1271 : buffer_start = buffer_start + buffer_size
1272 : END DO
1273 : END IF
1274 : !! Calculate integrals if we run out of buffer or the geometry did change
1275 : IF (actual_x_data%memory_parameter%recalc_forces .OR. buffer_overflow) THEN
1276 : sphi_a_ext_set => sphi_a_ext(:, :, :, iset)
1277 : sphi_b_ext_set => sphi_b_ext(:, :, :, jset)
1278 : sphi_c_ext_set => sphi_c_ext(:, :, :, kset)
1279 : sphi_d_ext_set => sphi_d_ext(:, :, :, lset)
1280 : max_contraction_val = max_contraction(iset, iatom)* &
1281 : max_contraction(jset, jatom)* &
1282 : max_contraction(kset, katom)* &
1283 : max_contraction(lset, latom)* &
1284 : pmax_entry
1285 : tmp_R_1 => radii_pgf(:, :, jset, iset, jkind, ikind)
1286 : tmp_R_2 => radii_pgf(:, :, lset, kset, lkind, kkind)
1287 : tmp_screen_pgf1 => screen_coeffs_pgf(:, :, jset, iset, jkind, ikind)
1288 : tmp_screen_pgf2 => screen_coeffs_pgf(:, :, lset, kset, lkind, kkind)
1289 :
1290 : CALL forces4(private_context, ra, rb, rc, rd, npgfa(iset), npgfb(jset), &
1291 : npgfc(kset), npgfd(lset), &
1292 : la_min(iset), la_max(iset), lb_min(jset), lb_max(jset), &
1293 : lc_min(kset), lc_max(kset), ld_min(lset), ld_max(lset), &
1294 : nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1295 : sphi_a_u1, sphi_a_u2, sphi_a_u3, &
1296 : sphi_b_u1, sphi_b_u2, sphi_b_u3, &
1297 : sphi_c_u1, sphi_c_u2, sphi_c_u3, &
1298 : sphi_d_u1, sphi_d_u2, sphi_d_u3, &
1299 : zeta(1:npgfa(iset), iset), zetb(1:npgfb(jset), jset), &
1300 : zetc(1:npgfc(kset), kset), zetd(1:npgfd(lset), lset), &
1301 : primitive_forces, &
1302 : potential_parameter, &
1303 : actual_x_data%neighbor_cells, &
1304 : screen_coeffs_set(jset, iset, jkind, ikind)%x, &
1305 : screen_coeffs_set(lset, kset, lkind, kkind)%x, eps_schwarz, &
1306 : max_contraction_val, cartesian_estimate, cell, neris_tmp, &
1307 : log10_pmax, log10_eps_schwarz, &
1308 : tmp_R_1, tmp_R_2, tmp_screen_pgf1, tmp_screen_pgf2, &
1309 : pgf_list_ij, pgf_list_kl, pgf_product_list, &
1310 : nsgfl_a(:, iset), nsgfl_b(:, jset), &
1311 : nsgfl_c(:, kset), nsgfl_d(:, lset), &
1312 : sphi_a_ext_set, sphi_b_ext_set, sphi_c_ext_set, sphi_d_ext_set, &
1313 : ede_work, ede_work2, ede_work_forces, &
1314 : ede_buffer1, ede_buffer2, ede_primitives_tmp, &
1315 : nimages, do_periodic, use_virial, ede_work_virial, ede_work2_virial, &
1316 : ede_primitives_tmp_virial, primitive_forces_virial, &
1317 : cartesian_estimate_virial)
1318 :
1319 : nints = nsgfa(iset)*nsgfb(jset)*nsgfc(kset)*nsgfd(lset)*12
1320 : neris_total = neris_total + nints
1321 : nprim_ints = nprim_ints + neris_tmp
1322 : ! IF (cartesian_estimate == 0.0_dp) cartesian_estimate = TINY(cartesian_estimate)
1323 : ! estimate_to_store_int = EXPONENT(cartesian_estimate)
1324 : ! estimate_to_store_int = MAX(estimate_to_store_int, -15_int_8)
1325 : ! cartesian_estimate = SET_EXPONENT(1.0_dp, estimate_to_store_int+1)
1326 : ! IF (.NOT. buffer_overflow .AND. actual_x_data%memory_parameter%recalc_forces) THEN
1327 : ! IF (cartesian_estimate < eps_schwarz) THEN
1328 : ! CALL hfx_add_single_cache_element( &
1329 : ! estimate_to_store_int, 6, &
1330 : ! maxval_cache, maxval_container, memory_parameter%actual_memory_usage, &
1331 : ! use_disk_storage, max_val_memory)
1332 : ! END IF
1333 : ! END IF
1334 : !
1335 : ! IF (.NOT. use_virial) THEN
1336 : ! IF (cartesian_estimate < eps_schwarz) CYCLE
1337 : ! END IF
1338 :
1339 : !! Compress the array for storage
1340 : spherical_estimate = 0.0_dp
1341 : IF (cartesian_estimate /= 0.0_dp) THEN
1342 : DO i = 1, nints
1343 : spherical_estimate = MAX(spherical_estimate, ABS(primitive_forces(i)))
1344 : END DO
1345 : END IF
1346 :
1347 : spherical_estimate_virial = 0.0_dp
1348 : IF (use_virial .AND. cartesian_estimate_virial /= 0.0_dp) THEN
1349 : DO i = 1, 3*nints
1350 : spherical_estimate_virial = MAX(spherical_estimate_virial, ABS(primitive_forces_virial(i)))
1351 : END DO
1352 : END IF
1353 :
1354 : IF (spherical_estimate == 0.0_dp) spherical_estimate = TINY(spherical_estimate)
1355 : estimate_to_store_int = EXPONENT(spherical_estimate)
1356 : estimate_to_store_int = MAX(estimate_to_store_int, -15_int_8)
1357 : IF (.NOT. buffer_overflow .AND. actual_x_data%memory_parameter%recalc_forces) THEN
1358 : CALL hfx_add_single_cache_element(estimate_to_store_int, 6, &
1359 : maxval_cache, maxval_container, &
1360 : memory_parameter%actual_memory_usage, &
1361 : use_disk_storage, max_val_memory)
1362 : END IF
1363 : spherical_estimate = SET_EXPONENT(1.0_dp, estimate_to_store_int + 1)
1364 : IF (.NOT. use_virial) THEN
1365 : IF (spherical_estimate*pmax_entry < eps_schwarz) CYCLE
1366 : END IF
1367 : IF (.NOT. buffer_overflow) THEN
1368 : nbits = EXPONENT(ANINT(spherical_estimate*pmax_entry/eps_storage)) + 1
1369 : buffer_left = nints
1370 : buffer_start = 1
1371 : ! neris_incore = neris_incore+nints
1372 : neris_incore = neris_incore + INT(nints, int_8)
1373 :
1374 : DO WHILE (buffer_left > 0)
1375 : buffer_size = MIN(buffer_left, CACHE_SIZE)
1376 : CALL hfx_add_mult_cache_elements(primitive_forces(buffer_start), &
1377 : buffer_size, nbits, &
1378 : integral_caches(nbits), &
1379 : integral_containers(nbits), &
1380 : eps_storage, pmax_entry, &
1381 : memory_parameter%actual_memory_usage, &
1382 : use_disk_storage)
1383 : buffer_left = buffer_left - buffer_size
1384 : buffer_start = buffer_start + buffer_size
1385 : END DO
1386 : ELSE
1387 : !! In order to be consistent with in-core part, round all the eris wrt. eps_schwarz
1388 : !! but only if we treat forces in-core
1389 : IF (treat_forces_in_core .AND. cartesian_estimate /= 0.0_dp) THEN
1390 : DO i = 1, nints
1391 : primitive_forces(i) = primitive_forces(i)*pmax_entry
1392 : IF (ABS(primitive_forces(i)) > eps_storage) THEN
1393 : primitive_forces(i) = ANINT(primitive_forces(i)/eps_storage, dp)*eps_storage/pmax_entry
1394 : ELSE
1395 : primitive_forces(i) = 0.0_dp
1396 : END IF
1397 : END DO
1398 : END IF
1399 : END IF
1400 : IF (cartesian_estimate == 0.0_dp .AND. &
1401 : (.NOT. use_virial .OR. cartesian_estimate_virial == 0.0_dp)) CYCLE
1402 : END IF
1403 : IF (with_resp_density) THEN
1404 : CALL prefetch_density_matrix(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1405 : full_density_alpha(:, 1), pbd_buf, pbc_buf, pad_buf, pac_buf, &
1406 : iatom, jatom, katom, latom, &
1407 : iset, jset, kset, lset, offset_bd_set, offset_bc_set, &
1408 : offset_ad_set, offset_ac_set, atomic_offset_bd, atomic_offset_bc, &
1409 : atomic_offset_ad, atomic_offset_ac, is_anti_symmetric)
1410 : CALL prefetch_density_matrix(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1411 : full_density_resp, pbd_buf_resp, pbc_buf_resp, pad_buf_resp, pac_buf_resp, &
1412 : iatom, jatom, katom, latom, &
1413 : iset, jset, kset, lset, offset_bd_set, offset_bc_set, &
1414 : offset_ad_set, offset_ac_set, atomic_offset_bd, atomic_offset_bc, &
1415 : atomic_offset_ad, atomic_offset_ac, is_anti_symmetric)
1416 : ELSE
1417 : CALL prefetch_density_matrix(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1418 : full_density_alpha(:, 1), pbd_buf, pbc_buf, pad_buf, pac_buf, &
1419 : iatom, jatom, katom, latom, &
1420 : iset, jset, kset, lset, offset_bd_set, offset_bc_set, &
1421 : offset_ad_set, offset_ac_set, atomic_offset_bd, atomic_offset_bc, &
1422 : atomic_offset_ad, atomic_offset_ac, is_anti_symmetric)
1423 : END IF
1424 : IF (my_nspins == 2) THEN
1425 : IF (with_resp_density) THEN
1426 : CALL prefetch_density_matrix(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1427 : full_density_beta(:, 1), pbd_buf_beta, pbc_buf_beta, &
1428 : pad_buf_beta, pac_buf_beta, iatom, jatom, katom, latom, &
1429 : iset, jset, kset, lset, offset_bd_set, offset_bc_set, &
1430 : offset_ad_set, offset_ac_set, atomic_offset_bd, atomic_offset_bc, &
1431 : atomic_offset_ad, atomic_offset_ac, is_anti_symmetric)
1432 : CALL prefetch_density_matrix(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1433 : full_density_resp_beta, pbd_buf_resp_beta, pbc_buf_resp_beta, &
1434 : pad_buf_resp_beta, pac_buf_resp_beta, iatom, jatom, katom, latom, &
1435 : iset, jset, kset, lset, offset_bd_set, offset_bc_set, &
1436 : offset_ad_set, offset_ac_set, atomic_offset_bd, atomic_offset_bc, &
1437 : atomic_offset_ad, atomic_offset_ac, is_anti_symmetric)
1438 : ELSE
1439 : CALL prefetch_density_matrix(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1440 : full_density_beta(:, 1), pbd_buf_beta, pbc_buf_beta, pad_buf_beta, &
1441 : pac_buf_beta, iatom, jatom, katom, latom, &
1442 : iset, jset, kset, lset, offset_bd_set, offset_bc_set, &
1443 : offset_ad_set, offset_ac_set, atomic_offset_bd, atomic_offset_bc, &
1444 : atomic_offset_ad, atomic_offset_ac, is_anti_symmetric)
1445 : END IF
1446 : END IF
1447 : IF (spherical_estimate*pmax_entry >= eps_schwarz) THEN
1448 : DO coord = 1, 12
1449 : T2 => primitive_forces((coord - 1)*nsgfa(iset)*nsgfb(jset)*nsgfc(kset)*nsgfd(lset) + 1: &
1450 : coord*nsgfa(iset)*nsgfb(jset)*nsgfc(kset)*nsgfd(lset))
1451 :
1452 : IF (with_resp_density) THEN
1453 : CALL update_forces(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1454 : pbd_buf, pbc_buf, pad_buf, pac_buf, fac, &
1455 : T2, force, forces_map, coord, &
1456 : pbd_buf_resp, pbc_buf_resp, pad_buf_resp, pac_buf_resp, &
1457 : my_resp_only)
1458 : ELSE
1459 : CALL update_forces(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1460 : pbd_buf, pbc_buf, pad_buf, pac_buf, fac, &
1461 : T2, force, forces_map, coord)
1462 : END IF
1463 : IF (my_nspins == 2) THEN
1464 : IF (with_resp_density) THEN
1465 : CALL update_forces(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1466 : pbd_buf_beta, pbc_buf_beta, pad_buf_beta, pac_buf_beta, &
1467 : fac, T2, force, forces_map, coord, &
1468 : pbd_buf_resp_beta, pbc_buf_resp_beta, &
1469 : pad_buf_resp_beta, pac_buf_resp_beta, &
1470 : my_resp_only)
1471 : ELSE
1472 : CALL update_forces(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1473 : pbd_buf_beta, pbc_buf_beta, pad_buf_beta, pac_buf_beta, fac, &
1474 : T2, force, forces_map, coord)
1475 : END IF
1476 : END IF
1477 : END DO !coord
1478 : END IF
1479 : IF (use_virial .AND. spherical_estimate_virial*pmax_entry >= eps_schwarz) THEN
1480 : DO coord = 1, 12
1481 : DO i = 1, 3
1482 : T2 => primitive_forces_virial( &
1483 : ((i - 1)*12 + coord - 1)*nsgfa(iset)*nsgfb(jset)*nsgfc(kset)*nsgfd(lset) + 1: &
1484 : ((i - 1)*12 + coord)*nsgfa(iset)*nsgfb(jset)*nsgfc(kset)*nsgfd(lset))
1485 : IF (with_resp_density) THEN
1486 : CALL update_virial(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1487 : pbd_buf, pbc_buf, pad_buf, pac_buf, fac, &
1488 : T2, tmp_virial, coord, i, &
1489 : pbd_buf_resp, pbc_buf_resp, pad_buf_resp, &
1490 : pac_buf_resp, my_resp_only)
1491 : ELSE
1492 : CALL update_virial(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1493 : pbd_buf, pbc_buf, pad_buf, pac_buf, fac, &
1494 : T2, tmp_virial, coord, i)
1495 : END IF
1496 : IF (my_nspins == 2) THEN
1497 : IF (with_resp_density) THEN
1498 : CALL update_virial(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1499 : pbd_buf_beta, pbc_buf_beta, pad_buf_beta, pac_buf_beta, &
1500 : fac, T2, tmp_virial, coord, i, &
1501 : pbd_buf_resp_beta, pbc_buf_resp_beta, &
1502 : pad_buf_resp_beta, pac_buf_resp_beta, &
1503 : my_resp_only)
1504 : ELSE
1505 : CALL update_virial(nsgfa(iset), nsgfb(jset), nsgfc(kset), nsgfd(lset), &
1506 : pbd_buf_beta, pbc_buf_beta, pad_buf_beta, pac_buf_beta, &
1507 : fac, T2, tmp_virial, coord, i)
1508 : END IF
1509 : END IF
1510 : END DO
1511 : END DO !coord
1512 : END IF
1513 :
1514 : END DO !i_set_list_kl
1515 : END DO !i_set_list_ij
1516 : END DO !i_list_kl
1517 : END DO !i_list_ij
1518 : END DO atomic_blocks
1519 : bintime_stop = m_walltime()
1520 : distribution_forces%time_forces = bintime_stop - bintime_start
1521 : !$OMP MASTER
1522 : CALL timestop(handle_bin)
1523 : !$OMP END MASTER
1524 : END DO !bin
1525 :
1526 : !$OMP MASTER
1527 : logger => cp_get_default_logger()
1528 : do_print_load_balance_info = .FALSE.
1529 : do_print_load_balance_info = BTEST(cp_print_key_should_output(logger%iter_info, hfx_section, &
1530 : "LOAD_BALANCE%PRINT/LOAD_BALANCE_INFO"), cp_p_file)
1531 : !$OMP END MASTER
1532 : !$OMP BARRIER
1533 : IF (do_print_load_balance_info) THEN
1534 : iw = -1
1535 : !$OMP MASTER
1536 : iw = cp_print_key_unit_nr(logger, hfx_section, "LOAD_BALANCE%PRINT/LOAD_BALANCE_INFO", &
1537 : extension=".scfLog")
1538 : !$OMP END MASTER
1539 :
1540 : CALL collect_load_balance_info(para_env, actual_x_data, iw, n_threads, i_thread, &
1541 : hfx_do_eval_forces)
1542 :
1543 : !$OMP MASTER
1544 : CALL cp_print_key_finished_output(iw, logger, hfx_section, &
1545 : "LOAD_BALANCE%PRINT/LOAD_BALANCE_INFO")
1546 : !$OMP END MASTER
1547 : END IF
1548 :
1549 : IF (use_virial) THEN
1550 : DO i = 1, 3
1551 : DO j = 1, 3
1552 : DO k = 1, 3
1553 : !$OMP ATOMIC
1554 : virial%pv_fock_4c(i, j) = virial%pv_fock_4c(i, j) + tmp_virial(i, k)*cell%hmat(j, k)
1555 : END DO
1556 : END DO
1557 : END DO
1558 : END IF
1559 :
1560 : !$OMP BARRIER
1561 : !! Get some number about ERIS
1562 : !$OMP ATOMIC
1563 : shm_neris_total = shm_neris_total + neris_total
1564 : !$OMP ATOMIC
1565 : shm_neris_onthefly = shm_neris_onthefly + neris_onthefly
1566 : !$OMP ATOMIC
1567 : shm_nprim_ints = shm_nprim_ints + nprim_ints
1568 :
1569 : storage_counter_integrals = memory_parameter%actual_memory_usage* &
1570 : memory_parameter%cache_size
1571 : stor_count_max_val = max_val_memory*memory_parameter%cache_size
1572 : !$OMP ATOMIC
1573 : shm_storage_counter_integrals = shm_storage_counter_integrals + storage_counter_integrals
1574 : !$OMP ATOMIC
1575 : shm_neris_incore = shm_neris_incore + neris_incore
1576 : !$OMP ATOMIC
1577 : shm_stor_count_max_val = shm_stor_count_max_val + stor_count_max_val
1578 : !$OMP BARRIER
1579 :
1580 : ! IF(with_resp_density) THEN
1581 : ! ! restore original load_balance_parameter
1582 : ! actual_x_data%load_balance_parameter = load_balance_parameter_energy
1583 : ! DEALLOCATE(load_balance_parameter_energy)
1584 : ! END IF
1585 :
1586 : !$OMP MASTER
1587 : !! Print some memeory information if this is the first step
1588 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
1589 : tmp_i8(1:6) = [shm_storage_counter_integrals, shm_neris_onthefly, shm_neris_incore, &
1590 : shm_neris_total, shm_nprim_ints, shm_stor_count_max_val]
1591 : CALL para_env%sum(tmp_i8)
1592 : shm_storage_counter_integrals = tmp_i8(1)
1593 : shm_neris_onthefly = tmp_i8(2)
1594 : shm_neris_incore = tmp_i8(3)
1595 : shm_neris_total = tmp_i8(4)
1596 : shm_nprim_ints = tmp_i8(5)
1597 : shm_stor_count_max_val = tmp_i8(6)
1598 : mem_eris = (shm_storage_counter_integrals + 128*1024 - 1)/1024/128
1599 : compression_factor = REAL(shm_neris_incore, dp)/REAL(shm_storage_counter_integrals, dp)
1600 : mem_max_val = (shm_stor_count_max_val + 128*1024 - 1)/1024/128
1601 :
1602 : IF (shm_neris_incore == 0) THEN
1603 : mem_eris = 0
1604 : compression_factor = 0.0_dp
1605 : END IF
1606 :
1607 : logger => cp_get_default_logger()
1608 :
1609 : iw = cp_print_key_unit_nr(logger, hfx_section, "HF_INFO", &
1610 : extension=".scfLog")
1611 : IF (iw > 0) THEN
1612 : WRITE (UNIT=iw, FMT="(/,(T3,A,T65,I16))") &
1613 : "HFX_MEM_INFO| Number of cart. primitive DERIV's calculated: ", shm_nprim_ints
1614 :
1615 : WRITE (UNIT=iw, FMT="((T3,A,T60,I21))") &
1616 : "HFX_MEM_INFO| Number of sph. DERIV's calculated: ", shm_neris_total
1617 :
1618 : WRITE (UNIT=iw, FMT="((T3,A,T60,I21))") &
1619 : "HFX_MEM_INFO| Number of sph. DERIV's stored in-core: ", shm_neris_incore
1620 :
1621 : WRITE (UNIT=iw, FMT="((T3,A,T62,I19))") &
1622 : "HFX_MEM_INFO| Number of sph. DERIV's calculated on the fly: ", shm_neris_onthefly
1623 :
1624 : WRITE (UNIT=iw, FMT="((T3,A,T60,I21))") &
1625 : "HFX_MEM_INFO| Total memory consumption DERIV's RAM [MiB]: ", mem_eris
1626 :
1627 : WRITE (UNIT=iw, FMT="((T3,A,T60,I21))") &
1628 : "HFX_MEM_INFO| Whereof max-vals [MiB]: ", mem_max_val
1629 :
1630 : WRITE (UNIT=iw, FMT="((T3,A,T60,F21.2),/)") &
1631 : "HFX_MEM_INFO| Total compression factor DERIV's RAM: ", compression_factor
1632 : END IF
1633 :
1634 : CALL cp_print_key_finished_output(iw, logger, hfx_section, &
1635 : "HF_INFO")
1636 : END IF
1637 : !$OMP END MASTER
1638 :
1639 : !! flush caches if the geometry changed
1640 : IF (do_dynamic_load_balancing) THEN
1641 : my_bin_size = SIZE(actual_x_data%distribution_forces)
1642 : ELSE
1643 : my_bin_size = 1
1644 : END IF
1645 :
1646 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
1647 : IF (treat_forces_in_core) THEN
1648 : DO bin = 1, my_bin_size
1649 : maxval_cache => actual_x_data%store_forces%maxval_cache(bin)
1650 : maxval_container => actual_x_data%store_forces%maxval_container(bin)
1651 : integral_caches => actual_x_data%store_forces%integral_caches(:, bin)
1652 : integral_containers => actual_x_data%store_forces%integral_containers(:, bin)
1653 : CALL hfx_flush_last_cache(bits_max_val, maxval_cache, maxval_container, memory_parameter%actual_memory_usage, &
1654 : .FALSE.)
1655 : DO i = 1, 64
1656 : CALL hfx_flush_last_cache(i, integral_caches(i), integral_containers(i), &
1657 : memory_parameter%actual_memory_usage, .FALSE.)
1658 : END DO
1659 : END DO
1660 : END IF
1661 : END IF
1662 : !! reset all caches except we calculate all on the fly
1663 : IF (treat_forces_in_core) THEN
1664 : DO bin = 1, my_bin_size
1665 : maxval_cache => actual_x_data%store_forces%maxval_cache(bin)
1666 : maxval_container => actual_x_data%store_forces%maxval_container(bin)
1667 : integral_caches => actual_x_data%store_forces%integral_caches(:, bin)
1668 : integral_containers => actual_x_data%store_forces%integral_containers(:, bin)
1669 :
1670 : CALL hfx_reset_cache_and_container(maxval_cache, maxval_container, memory_parameter%actual_memory_usage, .FALSE.)
1671 : DO i = 1, 64
1672 : CALL hfx_reset_cache_and_container(integral_caches(i), integral_containers(i), &
1673 : memory_parameter%actual_memory_usage, &
1674 : .FALSE.)
1675 : END DO
1676 : END DO
1677 : END IF
1678 :
1679 : IF (actual_x_data%memory_parameter%recalc_forces) THEN
1680 : actual_x_data%memory_parameter%recalc_forces = .FALSE.
1681 : END IF
1682 :
1683 : !$OMP BARRIER
1684 : !$OMP MASTER
1685 : CALL timestop(handle_main)
1686 : !$OMP END MASTER
1687 : !$OMP BARRIER
1688 : DEALLOCATE (last_sgf_global)
1689 : !$OMP MASTER
1690 : DEALLOCATE (full_density_alpha)
1691 : IF (with_resp_density) THEN
1692 : DEALLOCATE (full_density_resp)
1693 : END IF
1694 : IF (my_nspins == 2) THEN
1695 : DEALLOCATE (full_density_beta)
1696 : IF (with_resp_density) THEN
1697 : DEALLOCATE (full_density_resp_beta)
1698 : END IF
1699 : END IF
1700 : IF (do_dynamic_load_balancing) THEN
1701 : DEALLOCATE (actual_x_data%task_list)
1702 : END IF
1703 : !$OMP END MASTER
1704 : DEALLOCATE (primitive_forces)
1705 : DEALLOCATE (atom_of_kind, kind_of)
1706 : DEALLOCATE (max_contraction)
1707 : DEALLOCATE (pbd_buf)
1708 : DEALLOCATE (pbc_buf)
1709 : DEALLOCATE (pad_buf)
1710 : DEALLOCATE (pac_buf)
1711 :
1712 : IF (with_resp_density) THEN
1713 : DEALLOCATE (pbd_buf_resp)
1714 : DEALLOCATE (pbc_buf_resp)
1715 : DEALLOCATE (pad_buf_resp)
1716 : DEALLOCATE (pac_buf_resp)
1717 : END IF
1718 :
1719 : DO i = 1, max_pgf**2
1720 : DEALLOCATE (pgf_list_ij(i)%image_list)
1721 : DEALLOCATE (pgf_list_kl(i)%image_list)
1722 : END DO
1723 :
1724 : DEALLOCATE (pgf_list_ij)
1725 : DEALLOCATE (pgf_list_kl)
1726 : DEALLOCATE (pgf_product_list)
1727 :
1728 : DEALLOCATE (set_list_ij, set_list_kl)
1729 :
1730 : DEALLOCATE (primitive_forces_virial)
1731 :
1732 : DEALLOCATE (ede_work, ede_work2, ede_work_forces, ede_buffer1, ede_buffer2, ede_primitives_tmp)
1733 :
1734 : DEALLOCATE (ede_work_virial, ede_work2_virial, ede_primitives_tmp_virial)
1735 :
1736 : DEALLOCATE (nimages)
1737 :
1738 : IF (my_nspins == 2) THEN
1739 : DEALLOCATE (pbd_buf_beta, pbc_buf_beta, pad_buf_beta, pac_buf_beta)
1740 : IF (with_resp_density) THEN
1741 : DEALLOCATE (pbd_buf_resp_beta)
1742 : DEALLOCATE (pbc_buf_resp_beta)
1743 : DEALLOCATE (pad_buf_resp_beta)
1744 : DEALLOCATE (pac_buf_resp_beta)
1745 : END IF
1746 : END IF
1747 :
1748 : !$OMP END PARALLEL
1749 :
1750 2008 : CALL timestop(handle)
1751 :
1752 4172888 : END SUBROUTINE derivatives_four_center
1753 :
1754 : ! **************************************************************************************************
1755 : !> \brief Given a 2d index pair, this function returns a 1d index pair for
1756 : !> a symmetric upper triangle NxN matrix
1757 : !> The compiler should inline this function, therefore it appears in
1758 : !> several modules
1759 : !> \param i 2d index
1760 : !> \param j 2d index
1761 : !> \param N matrix size
1762 : !> \return ...
1763 : !> \par History
1764 : !> 03.2009 created [Manuel Guidon]
1765 : !> \author Manuel Guidon
1766 : ! **************************************************************************************************
1767 63136 : PURE FUNCTION get_1D_idx(i, j, N)
1768 : INTEGER, INTENT(IN) :: i, j
1769 : INTEGER(int_8), INTENT(IN) :: N
1770 : INTEGER(int_8) :: get_1D_idx
1771 :
1772 : INTEGER(int_8) :: min_ij
1773 :
1774 63136 : min_ij = MIN(i, j)
1775 63136 : get_1D_idx = min_ij*N + MAX(i, j) - (min_ij - 1)*min_ij/2 - N
1776 :
1777 63136 : END FUNCTION get_1D_idx
1778 :
1779 : ! **************************************************************************************************
1780 : !> \brief This routine prefetches density matrix elements, i.e. reshuffles the
1781 : !> data in a way that they can be accessed later on in a cache friendly
1782 : !> way
1783 : !> \param ma_max Size of matrix blocks
1784 : !> \param mb_max Size of matrix blocks
1785 : !> \param mc_max Size of matrix blocks
1786 : !> \param md_max Size of matrix blocks
1787 : !> \param density ...
1788 : !> \param pbd buffer that will contain P(b,d)
1789 : !> \param pbc buffer that will contain P(b,c)
1790 : !> \param pad buffer that will contain P(a,d)
1791 : !> \param pac buffer that will contain P(a,c)
1792 : !> \param iatom ...
1793 : !> \param jatom ...
1794 : !> \param katom ...
1795 : !> \param latom ...
1796 : !> \param iset ...
1797 : !> \param jset ...
1798 : !> \param kset ...
1799 : !> \param lset ...
1800 : !> \param offset_bd_set ...
1801 : !> \param offset_bc_set ...
1802 : !> \param offset_ad_set ...
1803 : !> \param offset_ac_set ...
1804 : !> \param atomic_offset_bd ...
1805 : !> \param atomic_offset_bc ...
1806 : !> \param atomic_offset_ad ...
1807 : !> \param atomic_offset_ac ...
1808 : !> \param anti_symmetric ...
1809 : !> \par History
1810 : !> 03.2009 created [Manuel Guidon]
1811 : !> \author Manuel Guidon
1812 : ! **************************************************************************************************
1813 3193802 : SUBROUTINE prefetch_density_matrix(ma_max, mb_max, mc_max, md_max, &
1814 3193802 : density, pbd, pbc, pad, pac, &
1815 : iatom, jatom, katom, latom, &
1816 : iset, jset, kset, lset, offset_bd_set, offset_bc_set, &
1817 : offset_ad_set, offset_ac_set, atomic_offset_bd, atomic_offset_bc, &
1818 : atomic_offset_ad, atomic_offset_ac, anti_symmetric)
1819 :
1820 : INTEGER, INTENT(IN) :: ma_max, mb_max, mc_max, md_max
1821 : REAL(dp), DIMENSION(:), INTENT(IN) :: density
1822 : REAL(dp), DIMENSION(*), INTENT(INOUT) :: pbd, pbc, pad, pac
1823 : INTEGER, INTENT(IN) :: iatom, jatom, katom, latom, iset, jset, &
1824 : kset, lset
1825 : INTEGER, DIMENSION(:, :), POINTER :: offset_bd_set, offset_bc_set, &
1826 : offset_ad_set, offset_ac_set
1827 : INTEGER, INTENT(IN) :: atomic_offset_bd, atomic_offset_bc, &
1828 : atomic_offset_ad, atomic_offset_ac
1829 : LOGICAL :: anti_symmetric
1830 :
1831 : INTEGER :: i, j, ma, mb, mc, md, offset_ac, &
1832 : offset_ad, offset_bc, offset_bd
1833 : REAL(dp) :: fac
1834 :
1835 3193802 : fac = 1.0_dp
1836 3193802 : IF (anti_symmetric) fac = -1.0_dp
1837 3193802 : IF (jatom >= latom) THEN
1838 3187596 : i = 1
1839 3187596 : offset_bd = offset_bd_set(jset, lset) + atomic_offset_bd - 1
1840 3187596 : j = offset_bd
1841 9390202 : DO md = 1, md_max
1842 20309022 : DO mb = 1, mb_max
1843 10918820 : pbd(i) = density(j)*fac
1844 10918820 : i = i + 1
1845 17121426 : j = j + 1
1846 : END DO
1847 : END DO
1848 : ELSE
1849 6206 : i = 1
1850 6206 : offset_bd = offset_bd_set(lset, jset) + atomic_offset_bd - 1
1851 14840 : DO md = 1, md_max
1852 8634 : j = offset_bd + md - 1
1853 27686 : DO mb = 1, mb_max
1854 12846 : pbd(i) = density(j)
1855 12846 : i = i + 1
1856 21480 : j = j + md_max
1857 : END DO
1858 : END DO
1859 : END IF
1860 3193802 : IF (jatom >= katom) THEN
1861 3193802 : i = 1
1862 3193802 : offset_bc = offset_bc_set(jset, kset) + atomic_offset_bc - 1
1863 3193802 : j = offset_bc
1864 10478032 : DO mc = 1, mc_max
1865 22917310 : DO mb = 1, mb_max
1866 12439278 : pbc(i) = density(j)*fac
1867 12439278 : i = i + 1
1868 19723508 : j = j + 1
1869 : END DO
1870 : END DO
1871 : ELSE
1872 0 : i = 1
1873 0 : offset_bc = offset_bc_set(kset, jset) + atomic_offset_bc - 1
1874 0 : DO mc = 1, mc_max
1875 0 : j = offset_bc + mc - 1
1876 0 : DO mb = 1, mb_max
1877 0 : pbc(i) = density(j)
1878 0 : i = i + 1
1879 0 : j = j + mc_max
1880 : END DO
1881 : END DO
1882 : END IF
1883 3193802 : IF (iatom >= latom) THEN
1884 2457148 : i = 1
1885 2457148 : offset_ad = offset_ad_set(iset, lset) + atomic_offset_ad - 1
1886 2457148 : j = offset_ad
1887 7603951 : DO md = 1, md_max
1888 18448052 : DO ma = 1, ma_max
1889 10844101 : pad(i) = density(j)*fac
1890 10844101 : i = i + 1
1891 15990904 : j = j + 1
1892 : END DO
1893 : END DO
1894 : ELSE
1895 736654 : i = 1
1896 736654 : offset_ad = offset_ad_set(lset, iset) + atomic_offset_ad - 1
1897 1801091 : DO md = 1, md_max
1898 1064437 : j = offset_ad + md - 1
1899 4408196 : DO ma = 1, ma_max
1900 2607105 : pad(i) = density(j)
1901 2607105 : i = i + 1
1902 3671542 : j = j + md_max
1903 : END DO
1904 : END DO
1905 : END IF
1906 3193802 : IF (iatom >= katom) THEN
1907 3106373 : i = 1
1908 3106373 : offset_ac = offset_ac_set(iset, kset) + atomic_offset_ac - 1
1909 3106373 : j = offset_ac
1910 10263996 : DO mc = 1, mc_max
1911 25765115 : DO ma = 1, ma_max
1912 15501119 : pac(i) = density(j)*fac
1913 15501119 : i = i + 1
1914 22658742 : j = j + 1
1915 : END DO
1916 : END DO
1917 : ELSE
1918 87429 : i = 1
1919 87429 : offset_ac = offset_ac_set(kset, iset) + atomic_offset_ac - 1
1920 214036 : DO mc = 1, mc_max
1921 126607 : j = offset_ac + mc - 1
1922 596361 : DO ma = 1, ma_max
1923 382325 : pac(i) = density(j)
1924 382325 : i = i + 1
1925 508932 : j = j + mc_max
1926 : END DO
1927 : END DO
1928 : END IF
1929 3193802 : END SUBROUTINE prefetch_density_matrix
1930 :
1931 : ! **************************************************************************************************
1932 : !> \brief This routine updates the forces using buffered density matrices
1933 : !> \param ma_max Size of matrix blocks
1934 : !> \param mb_max Size of matrix blocks
1935 : !> \param mc_max Size of matrix blocks
1936 : !> \param md_max Size of matrix blocks
1937 : !> \param pbd buffer that will contain P(b,d)
1938 : !> \param pbc buffer that will contain P(b,c)
1939 : !> \param pad buffer that will contain P(a,d)
1940 : !> \param pac buffer that will contain P(a,c)
1941 : !> \param fac mulitplication factor (spin, symmetry)
1942 : !> \param prim primitive forces
1943 : !> \param force storage loacation for forces
1944 : !> \param forces_map index table
1945 : !> \param coord which of the 12 coords to be updated
1946 : !> \param pbd_resp ...
1947 : !> \param pbc_resp ...
1948 : !> \param pad_resp ...
1949 : !> \param pac_resp ...
1950 : !> \param resp_only ...
1951 : !> \par History
1952 : !> 03.2009 created [Manuel Guidon]
1953 : !> \author Manuel Guidon
1954 : ! **************************************************************************************************
1955 25764756 : SUBROUTINE update_forces(ma_max, mb_max, mc_max, md_max, &
1956 : pbd, pbc, pad, pac, fac, &
1957 25764756 : prim, force, forces_map, coord, &
1958 : pbd_resp, pbc_resp, pad_resp, pac_resp, resp_only)
1959 :
1960 : INTEGER, INTENT(IN) :: ma_max, mb_max, mc_max, md_max
1961 : REAL(dp), DIMENSION(*), INTENT(IN) :: pbd, pbc, pad, pac
1962 : REAL(dp), INTENT(IN) :: fac
1963 : REAL(dp), DIMENSION(ma_max*mb_max*mc_max*md_max), &
1964 : INTENT(IN) :: prim
1965 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1966 : INTEGER, INTENT(IN) :: forces_map(4, 2), coord
1967 : REAL(dp), DIMENSION(*), INTENT(IN), OPTIONAL :: pbd_resp, pbc_resp, pad_resp, pac_resp
1968 : LOGICAL, INTENT(IN), OPTIONAL :: resp_only
1969 :
1970 : INTEGER :: ma, mb, mc, md, p_index
1971 : LOGICAL :: full_force, with_resp_density
1972 : REAL(dp) :: temp1, temp1_resp, temp3, temp3_resp, &
1973 : temp4, teresp
1974 :
1975 25764756 : with_resp_density = .FALSE.
1976 : IF (PRESENT(pbd_resp) .AND. &
1977 : PRESENT(pbc_resp) .AND. &
1978 25764756 : PRESENT(pad_resp) .AND. &
1979 : PRESENT(pac_resp)) with_resp_density = .TRUE.
1980 :
1981 : IF (with_resp_density) THEN
1982 12534180 : full_force = .TRUE.
1983 12534180 : IF (PRESENT(resp_only)) full_force = .NOT. resp_only
1984 12534180 : p_index = 0
1985 12534180 : temp4 = 0.0_dp
1986 36648168 : DO md = 1, md_max
1987 95527968 : DO mc = 1, mc_max
1988 196567968 : DO mb = 1, mb_max
1989 113574180 : temp1 = pbc((mc - 1)*mb_max + mb)*fac
1990 113574180 : temp3 = pbd((md - 1)*mb_max + mb)*fac
1991 113574180 : temp1_resp = pbc_resp((mc - 1)*mb_max + mb)*fac
1992 113574180 : temp3_resp = pbd_resp((md - 1)*mb_max + mb)*fac
1993 491025648 : DO ma = 1, ma_max
1994 318571668 : p_index = p_index + 1
1995 : ! HF-SCF
1996 318571668 : IF (full_force) THEN
1997 : teresp = temp1*pad((md - 1)*ma_max + ma) + &
1998 102213732 : temp3*pac((mc - 1)*ma_max + ma)
1999 : ELSE
2000 : teresp = 0.0_dp
2001 : END IF
2002 : ! RESP+HF
2003 : teresp = teresp + &
2004 : pac((mc - 1)*ma_max + ma)*temp3_resp + &
2005 : pac_resp((mc - 1)*ma_max + ma)*temp3 + &
2006 : pad((md - 1)*ma_max + ma)*temp1_resp + &
2007 318571668 : pad_resp((md - 1)*ma_max + ma)*temp1
2008 432145848 : temp4 = temp4 + teresp*prim(p_index)
2009 : END DO !ma
2010 : END DO !mb
2011 : END DO !mc
2012 : END DO !md
2013 : ELSE
2014 : p_index = 0
2015 : temp4 = 0.0_dp
2016 39506952 : DO md = 1, md_max
2017 110089224 : DO mc = 1, mc_max
2018 237218544 : DO mb = 1, mb_max
2019 140359896 : temp1 = pbc((mc - 1)*mb_max + mb)*fac
2020 140359896 : temp3 = pbd((md - 1)*mb_max + mb)*fac
2021 679751700 : DO ma = 1, ma_max
2022 468809532 : p_index = p_index + 1
2023 : teresp = temp1*pad((md - 1)*ma_max + ma) + &
2024 468809532 : temp3*pac((mc - 1)*ma_max + ma)
2025 609169428 : temp4 = temp4 + teresp*prim(p_index)
2026 : END DO !ma
2027 : END DO !mb
2028 : END DO !mc
2029 : END DO !md
2030 : END IF
2031 :
2032 25764756 : !$OMP ATOMIC
2033 : force(forces_map((coord - 1)/3 + 1, 1))%fock_4c(MOD(coord - 1, 3) + 1, &
2034 : forces_map((coord - 1)/3 + 1, 2)) = &
2035 : force(forces_map((coord - 1)/3 + 1, 1))%fock_4c(MOD(coord - 1, 3) + 1, &
2036 : forces_map((coord - 1)/3 + 1, 2)) - &
2037 : temp4
2038 :
2039 25764756 : END SUBROUTINE update_forces
2040 :
2041 : ! **************************************************************************************************
2042 : !> \brief This routine updates the virial using buffered density matrices
2043 : !> \param ma_max Size of matrix blocks
2044 : !> \param mb_max Size of matrix blocks
2045 : !> \param mc_max Size of matrix blocks
2046 : !> \param md_max Size of matrix blocks
2047 : !> \param pbd buffer that will contain P(b,d)
2048 : !> \param pbc buffer that will contain P(b,c)
2049 : !> \param pad buffer that will contain P(a,d)
2050 : !> \param pac buffer that will contain P(a,c)
2051 : !> \param fac mulitplication factor (spin, symmetry)
2052 : !> \param prim primitive forces
2053 : !> \param tmp_virial ...
2054 : !> \param coord which of the 12 coords to be updated
2055 : !> \param l ...
2056 : !> \param pbd_resp ...
2057 : !> \param pbc_resp ...
2058 : !> \param pad_resp ...
2059 : !> \param pac_resp ...
2060 : !> \par History
2061 : !> 03.2009 created [Manuel Guidon]
2062 : !> \author Manuel Guidon
2063 : ! **************************************************************************************************
2064 6570468 : SUBROUTINE update_virial(ma_max, mb_max, mc_max, md_max, &
2065 : pbd, pbc, pad, pac, fac, &
2066 6570468 : prim, tmp_virial, coord, l, &
2067 : pbd_resp, pbc_resp, pad_resp, pac_resp, resp_only)
2068 :
2069 : INTEGER, INTENT(IN) :: ma_max, mb_max, mc_max, md_max
2070 : REAL(dp), DIMENSION(*), INTENT(IN) :: pbd, pbc, pad, pac
2071 : REAL(dp), INTENT(IN) :: fac
2072 : REAL(dp), DIMENSION(ma_max*mb_max*mc_max*md_max), &
2073 : INTENT(IN) :: prim
2074 : REAL(dp) :: tmp_virial(3, 3)
2075 : INTEGER, INTENT(IN) :: coord, l
2076 : REAL(dp), DIMENSION(*), INTENT(IN), OPTIONAL :: pbd_resp, pbc_resp, pad_resp, pac_resp
2077 : LOGICAL, INTENT(IN), OPTIONAL :: resp_only
2078 :
2079 : INTEGER :: i, j, ma, mb, mc, md, p_index
2080 : LOGICAL :: with_resp_density, full_force
2081 : REAL(dp) :: temp1, temp1_resp, temp3, temp3_resp, &
2082 : temp4, teresp
2083 :
2084 6570468 : with_resp_density = .FALSE.
2085 : IF (PRESENT(pbd_resp) .AND. &
2086 : PRESENT(pbc_resp) .AND. &
2087 6570468 : PRESENT(pad_resp) .AND. &
2088 : PRESENT(pac_resp)) with_resp_density = .TRUE.
2089 :
2090 : IF (with_resp_density) THEN
2091 5587056 : full_force = .TRUE.
2092 5587056 : IF (PRESENT(resp_only)) full_force = .NOT. resp_only
2093 5587056 : p_index = 0
2094 5587056 : temp4 = 0.0_dp
2095 16806024 : DO md = 1, md_max
2096 41978016 : DO mc = 1, mc_max
2097 91229400 : DO mb = 1, mb_max
2098 54838440 : temp1 = pbc((mc - 1)*mb_max + mb)*fac
2099 54838440 : temp3 = pbd((md - 1)*mb_max + mb)*fac
2100 54838440 : temp1_resp = pbc_resp((mc - 1)*mb_max + mb)*fac
2101 54838440 : temp3_resp = pbd_resp((md - 1)*mb_max + mb)*fac
2102 236614860 : DO ma = 1, ma_max
2103 156604428 : p_index = p_index + 1
2104 : ! HF-SCF
2105 156604428 : IF (full_force) THEN
2106 : teresp = temp1*pad((md - 1)*ma_max + ma) + &
2107 25168824 : temp3*pac((mc - 1)*ma_max + ma)
2108 : ELSE
2109 : teresp = 0.0_dp
2110 : END IF
2111 : ! RESP+HF
2112 : teresp = teresp + &
2113 : pac((mc - 1)*ma_max + ma)*temp3_resp + &
2114 : pac_resp((mc - 1)*ma_max + ma)*temp3 + &
2115 : pad((md - 1)*ma_max + ma)*temp1_resp + &
2116 156604428 : pad_resp((md - 1)*ma_max + ma)*temp1
2117 211442868 : temp4 = temp4 + teresp*prim(p_index)
2118 : END DO !ma
2119 : END DO !mb
2120 : END DO !mc
2121 : END DO !md
2122 : ELSE
2123 : p_index = 0
2124 : temp4 = 0.0_dp
2125 2505240 : DO md = 1, md_max
2126 5427684 : DO mc = 1, mc_max
2127 8390340 : DO mb = 1, mb_max
2128 3946068 : temp1 = pbc((mc - 1)*mb_max + mb)*fac
2129 3946068 : temp3 = pbd((md - 1)*mb_max + mb)*fac
2130 13873176 : DO ma = 1, ma_max
2131 7004664 : p_index = p_index + 1
2132 : teresp = temp1*pad((md - 1)*ma_max + ma) + &
2133 7004664 : temp3*pac((mc - 1)*ma_max + ma)
2134 10950732 : temp4 = temp4 + teresp*prim(p_index)
2135 : END DO !ma
2136 : END DO !mb
2137 : END DO !mc
2138 : END DO !md
2139 : END IF
2140 :
2141 6570468 : j = l
2142 6570468 : i = MOD(coord - 1, 3) + 1
2143 6570468 : tmp_virial(i, j) = tmp_virial(i, j) - temp4
2144 6570468 : END SUBROUTINE update_virial
2145 :
2146 : #:include 'hfx_get_pmax_val.fypp'
2147 :
2148 : END MODULE hfx_derivatives
|