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 interface to tblite
10 : !> \author JVP
11 : !> \history creation 09.2024
12 : ! **************************************************************************************************
13 :
14 : MODULE tblite_interface
15 :
16 : #if defined(__TBLITE)
17 : USE mctc_env, ONLY: error_type
18 : USE mctc_io, ONLY: structure_type, new
19 : USE mctc_io_symbols, ONLY: symbol_to_number
20 : USE tblite_adjlist, ONLY: adjacency_list, new_adjacency_list
21 : USE tblite_basis_type, ONLY: get_cutoff
22 : USE tblite_container, ONLY: container_cache
23 : USE tblite_container_type, ONLY: container_type
24 : USE tblite_cutoff, ONLY: get_lattice_points
25 : USE tblite_data_spin, ONLY: get_spin_constant
26 : USE tblite_integral_multipole, ONLY: multipole_cgto, multipole_grad_cgto, maxl, msao
27 : USE tblite_integral_type, ONLY: integral_type, new_integral
28 : USE tblite_scf, ONLY: get_mixer_dimension
29 : USE tblite_scf_info, ONLY: scf_info, atom_resolved, shell_resolved, &
30 : orbital_resolved, not_used
31 : USE tblite_scf_potential, ONLY: potential_type, new_potential, add_pot_to_h1
32 : USE tblite_spin, ONLY: spin_polarization, new_spin_polarization
33 : USE tblite_wavefunction_type, ONLY: wavefunction_type, new_wavefunction
34 : USE tblite_xtb_calculator, ONLY: xtb_calculator, new_xtb_calculator
35 : USE tblite_xtb_gfn1, ONLY: new_gfn1_calculator
36 : USE tblite_xtb_gfn2, ONLY: new_gfn2_calculator
37 : USE tblite_xtb_h0, ONLY: get_selfenergy, get_hamiltonian, get_occupation, &
38 : get_hamiltonian_gradient, tb_hamiltonian
39 : USE tblite_xtb_ipea1, ONLY: new_ipea1_calculator
40 : #endif
41 : USE ai_contraction, ONLY: block_add, &
42 : contraction
43 : USE ai_overlap, ONLY: overlap_ab
44 : USE atomic_kind_types, ONLY: atomic_kind_type, get_atomic_kind, get_atomic_kind_set
45 : USE atprop_types, ONLY: atprop_type
46 : USE basis_set_types, ONLY: gto_basis_set_type, gto_basis_set_p_type, &
47 : & allocate_gto_basis_set, write_gto_basis_set, process_gto_basis
48 : USE block_p_types, ONLY: block_p_type
49 : USE cell_types, ONLY: cell_type, get_cell
50 : USE cp_blacs_env, ONLY: cp_blacs_env_type
51 : USE cp_control_types, ONLY: dft_control_type, xtb_reference_cli_type
52 : USE cp_dbcsr_api, ONLY: dbcsr_type, dbcsr_p_type, dbcsr_create, dbcsr_add, dbcsr_copy, &
53 : dbcsr_get_block_p, dbcsr_finalize, &
54 : dbcsr_iterator_type, dbcsr_iterator_blocks_left, &
55 : dbcsr_iterator_start, dbcsr_iterator_stop, &
56 : dbcsr_iterator_next_block
57 : USE cp_dbcsr_contrib, ONLY: dbcsr_dot, dbcsr_print
58 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
59 : USE cp_dbcsr_operations, ONLY: dbcsr_allocate_matrix_set, dbcsr_deallocate_matrix_set
60 : USE cp_log_handling, ONLY: cp_get_default_logger, &
61 : cp_logger_type, cp_logger_get_default_io_unit
62 : USE cp_output_handling, ONLY: cp_print_key_should_output, &
63 : cp_print_key_unit_nr, cp_print_key_finished_output, &
64 : debug_print_level, high_print_level, silent_print_level
65 : USE cp_units, ONLY: cp_unit_from_cp2k
66 : USE input_constants, ONLY: gfn1xtb, gfn2xtb, ipea1xtb, smear_energy_window, &
67 : smear_fermi_dirac, smear_gaussian, smear_list, smear_mp, smear_mv, &
68 : tblite_cli_born_kernel_auto, tblite_cli_born_kernel_p16, &
69 : tblite_cli_born_kernel_still, tblite_cli_solution_state_bar1mol, &
70 : tblite_cli_solution_state_gsolv, tblite_cli_solution_state_reference, &
71 : tblite_cli_solvation_alpb, tblite_cli_solvation_cpcm, &
72 : tblite_cli_solvation_gb, tblite_cli_solvation_gbe, &
73 : tblite_cli_solvation_gbsa, &
74 : tblite_guess_ceh, tblite_guess_eeq, tblite_guess_sad, &
75 : tblite_mixer_damping_default, &
76 : tblite_mixer_max_weight_default, tblite_mixer_min_weight_default, &
77 : tblite_mixer_omega0_default, tblite_mixer_weight_factor_default, &
78 : tblite_scc_mixer_auto, tblite_scc_mixer_cp2k, &
79 : tblite_scc_mixer_none, tblite_scc_mixer_tblite, &
80 : tblite_solver_gvd, tblite_solver_gvr
81 : USE input_section_types, ONLY: section_vals_val_get
82 : USE kinds, ONLY: default_path_length, default_string_length, dp, int_8
83 : USE kpoint_types, ONLY: get_kpoint_info, kpoint_type
84 : USE memory_utilities, ONLY: reallocate
85 : USE message_passing, ONLY: mp_para_env_type
86 : USE mulliken, ONLY: ao_charges
87 : USE orbital_pointers, ONLY: ncoset
88 : USE particle_types, ONLY: particle_type
89 : USE qs_charge_mixing, ONLY: charge_mixing, tblite_scc_error_on_cp2k_scale, tblite_scc_pconv
90 : USE qs_condnum, ONLY: overlap_condnum
91 : USE qs_density_mixing_types, ONLY: modified_broyden_mixing_nr
92 : USE qs_energy_types, ONLY: qs_energy_type
93 : USE qs_environment_types, ONLY: get_qs_env, qs_environment_type
94 : USE qs_force_types, ONLY: qs_force_type, total_qs_force
95 : USE qs_integral_utils, ONLY: basis_set_list_setup, get_memory_usage
96 : USE qs_kind_types, ONLY: get_qs_kind, qs_kind_type, get_qs_kind_set
97 : USE qs_ks_types, ONLY: get_ks_env, qs_ks_env_type, set_ks_env
98 : USE qs_neighbor_list_types, ONLY: neighbor_list_iterator_create, neighbor_list_iterate, &
99 : get_iterator_info, neighbor_list_set_p_type, &
100 : neighbor_list_iterator_p_type, neighbor_list_iterator_release
101 : USE qs_overlap, ONLY: build_overlap_matrix, create_sab_matrix
102 : USE cp_dbcsr_output, ONLY: cp_dbcsr_write_sparse_matrix
103 : USE qs_rho_types, ONLY: qs_rho_get, qs_rho_type
104 : USE qs_scf_types, ONLY: qs_scf_env_type
105 : USE scf_control_types, ONLY: scf_control_type
106 : USE input_section_types, ONLY: section_vals_get_subs_vals, section_vals_type
107 : USE string_utilities, ONLY: integer_to_string
108 : #if defined(__TBLITE)
109 : USE tblite_scc_mixer, ONLY: new_cp2k_tblite_mixer
110 : #endif
111 : USE tblite_types, ONLY: tblite_type, deallocate_tblite_type, allocate_tblite_type
112 : USE virial_types, ONLY: virial_type
113 : USE xtb_types, ONLY: get_xtb_atom_param, xtb_atom_type
114 : USE xtb_types, ONLY: xtb_atom_type
115 :
116 : !$ USE OMP_LIB, ONLY: omp_destroy_lock, omp_init_lock, omp_set_lock, &
117 : !$ omp_unset_lock, omp_lock_kind
118 :
119 : #include "./base/base_uses.f90"
120 : IMPLICIT NONE
121 :
122 : PRIVATE
123 :
124 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'tblite_interface'
125 :
126 : INTEGER, PARAMETER :: dip_n = 3
127 : INTEGER, PARAMETER :: quad_n = 6
128 : REAL(KIND=dp), PARAMETER :: same_atom = 0.00001_dp
129 :
130 : PUBLIC :: tb_set_calculator, tb_init_geometry, tb_init_wf
131 : PUBLIC :: tb_get_basis, build_tblite_matrices
132 : PUBLIC :: tb_get_energy, tb_update_charges, tb_ham_add_coulomb
133 : PUBLIC :: tb_native_scc_mixer_active
134 : PUBLIC :: tb_scf_mixer_error
135 : PUBLIC :: tb_get_multipole
136 : PUBLIC :: tb_derive_dH_off
137 : PUBLIC :: tb_reference_cli_compare
138 :
139 : CONTAINS
140 :
141 : #if defined(__TBLITE)
142 : ! **************************************************************************************************
143 : !> \brief Project a tblite charge/magnetization quantity to a CP2K spin channel.
144 : !> \param values ...
145 : !> \param ispin ...
146 : !> \return ...
147 : ! **************************************************************************************************
148 67326590 : PURE FUNCTION tb_spin_project(values, ispin) RESULT(value)
149 :
150 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: values
151 : INTEGER, INTENT(IN) :: ispin
152 : REAL(KIND=dp) :: value
153 :
154 67326590 : value = values(1)
155 67326590 : IF (SIZE(values) > 1) THEN
156 1908282 : SELECT CASE (ispin)
157 : CASE (1)
158 636094 : value = values(1) + values(2)
159 : CASE (2)
160 636094 : value = values(1) - values(2)
161 : CASE DEFAULT
162 1272188 : value = values(1)
163 : END SELECT
164 : END IF
165 :
166 67326590 : END FUNCTION tb_spin_project
167 :
168 : ! **************************************************************************************************
169 : !> \brief Store a private copy of the converged density for tblite force derivatives.
170 : !> \param tb ...
171 : !> \param matrix_p ...
172 : ! **************************************************************************************************
173 5440 : SUBROUTINE tb_store_density_ref(tb, matrix_p)
174 :
175 : TYPE(tblite_type), POINTER :: tb
176 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p
177 :
178 : INTEGER :: img, ispin, nimg, nspin
179 :
180 5440 : nspin = SIZE(matrix_p, 1)
181 5440 : nimg = SIZE(matrix_p, 2)
182 5440 : IF (ASSOCIATED(tb%rho_ao_kp_ref)) THEN
183 5410 : IF (SIZE(tb%rho_ao_kp_ref, 1) /= nspin .OR. SIZE(tb%rho_ao_kp_ref, 2) /= nimg) THEN
184 0 : CALL dbcsr_deallocate_matrix_set(tb%rho_ao_kp_ref)
185 : END IF
186 : END IF
187 5440 : IF (.NOT. ASSOCIATED(tb%rho_ao_kp_ref)) THEN
188 30 : CALL dbcsr_allocate_matrix_set(tb%rho_ao_kp_ref, nspin, nimg)
189 114 : DO img = 1, nimg
190 282 : DO ispin = 1, nspin
191 252 : ALLOCATE (tb%rho_ao_kp_ref(ispin, img)%matrix)
192 : END DO
193 : END DO
194 : END IF
195 33290 : DO img = 1, nimg
196 88990 : DO ispin = 1, nspin
197 83550 : CALL dbcsr_copy(tb%rho_ao_kp_ref(ispin, img)%matrix, matrix_p(ispin, img)%matrix)
198 : END DO
199 : END DO
200 :
201 5440 : END SUBROUTINE tb_store_density_ref
202 : #endif
203 :
204 : ! **************************************************************************************************
205 : !> \brief intialize geometry objects ...
206 : !> \param qs_env ...
207 : !> \param tb ...
208 : ! **************************************************************************************************
209 188 : SUBROUTINE tb_init_geometry(qs_env, tb)
210 :
211 : TYPE(qs_environment_type), POINTER :: qs_env
212 : TYPE(tblite_type), POINTER :: tb
213 :
214 : #if defined(__TBLITE)
215 :
216 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tblite_init_geometry'
217 :
218 : TYPE(cell_type), POINTER :: cell
219 188 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
220 188 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
221 : INTEGER :: iatom, natom
222 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: xyz
223 : INTEGER :: handle, ikind
224 : INTEGER, DIMENSION(3) :: periodic
225 : LOGICAL, DIMENSION(3) :: lperiod
226 :
227 188 : CALL timeset(routineN, handle)
228 :
229 : !get info from environment vaiarable
230 188 : CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell, qs_kind_set=qs_kind_set)
231 :
232 : !get information about particles
233 188 : natom = SIZE(particle_set)
234 564 : ALLOCATE (xyz(3, natom))
235 188 : CALL allocate_tblite_type(tb)
236 564 : ALLOCATE (tb%el_num(natom))
237 1154 : tb%el_num = -9
238 1154 : DO iatom = 1, natom
239 3864 : xyz(:, iatom) = particle_set(iatom)%r(:)
240 966 : CALL get_atomic_kind(particle_set(iatom)%atomic_kind, kind_number=ikind)
241 966 : CALL get_qs_kind(qs_kind_set(ikind), zatom=tb%el_num(iatom))
242 2120 : IF (tb%el_num(iatom) < 1 .OR. tb%el_num(iatom) > 85) THEN
243 0 : CPABORT("only elements 1-85 are supported by tblite")
244 : END IF
245 : END DO
246 :
247 : !get information about cell / lattice
248 188 : CALL get_cell(cell=cell, periodic=periodic)
249 188 : lperiod(1) = periodic(1) == 1
250 188 : lperiod(2) = periodic(2) == 1
251 188 : lperiod(3) = periodic(3) == 1
252 :
253 : !prepare for the call to the dispersion function
254 188 : CALL new(tb%mol, tb%el_num, xyz, lattice=cell%hmat, periodic=lperiod)
255 :
256 188 : DEALLOCATE (xyz)
257 :
258 188 : CALL timestop(handle)
259 :
260 : #else
261 : MARK_USED(qs_env)
262 : MARK_USED(tb)
263 : CPABORT("Built without TBLITE")
264 : #endif
265 :
266 188 : END SUBROUTINE tb_init_geometry
267 :
268 : ! **************************************************************************************************
269 : !> \brief updating coordinates...
270 : !> \param qs_env ...
271 : !> \param tb ...
272 : ! **************************************************************************************************
273 2750 : SUBROUTINE tb_update_geometry(qs_env, tb)
274 :
275 : TYPE(qs_environment_type) :: qs_env
276 : TYPE(tblite_type) :: tb
277 :
278 : #if defined(__TBLITE)
279 :
280 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tblite_update_geometry'
281 :
282 : TYPE(cell_type), POINTER :: cell
283 2750 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
284 : INTEGER :: iatom, natom
285 2750 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: xyz
286 : INTEGER :: handle
287 :
288 2750 : CALL timeset(routineN, handle)
289 :
290 : !get info from environment vaiarable
291 2750 : NULLIFY (cell)
292 2750 : CALL get_qs_env(qs_env=qs_env, particle_set=particle_set, cell=cell)
293 :
294 : !get information about particles
295 2750 : natom = SIZE(particle_set)
296 8250 : ALLOCATE (xyz(3, natom))
297 14868 : DO iatom = 1, natom
298 51222 : xyz(:, iatom) = particle_set(iatom)%r(:)
299 : END DO
300 51222 : tb%mol%xyz(:, :) = xyz
301 35750 : tb%mol%lattice(:, :) = cell%hmat
302 :
303 2750 : DEALLOCATE (xyz)
304 :
305 2750 : CALL timestop(handle)
306 :
307 : #else
308 : MARK_USED(qs_env)
309 : MARK_USED(tb)
310 : CPABORT("Built without TBLITE")
311 : #endif
312 :
313 2750 : END SUBROUTINE tb_update_geometry
314 :
315 : ! **************************************************************************************************
316 : !> \brief initialize wavefunction ...
317 : !> \param tb ...
318 : !> \param dft_control ...
319 : ! **************************************************************************************************
320 188 : SUBROUTINE tb_init_wf(tb, dft_control)
321 :
322 : TYPE(tblite_type), POINTER :: tb
323 : TYPE(dft_control_type), POINTER :: dft_control
324 :
325 : #if defined(__TBLITE)
326 :
327 : INTEGER :: nSpin
328 :
329 : TYPE(scf_info) :: info
330 :
331 188 : nSpin = dft_control%nspins
332 0 : IF (nSpin /= 1 .AND. nSpin /= 2) CPABORT("tblite supports only one or two spin channels")
333 :
334 188 : tb%mol%charge = dft_control%charge
335 188 : tb%mol%uhf = MAX(0, dft_control%multiplicity - 1)
336 188 : IF (nSpin == 2) CALL tb_add_spin_polarization(tb)
337 :
338 188 : info = tb%calc%variable_info()
339 188 : IF (info%charge > shell_resolved) CPABORT("tblite: no support for orbital resolved charge")
340 188 : IF (info%dipole > atom_resolved) CPABORT("tblite: no support for shell resolved dipole moment")
341 188 : IF (info%quadrupole > atom_resolved) THEN
342 0 : CPABORT("tblite: no support shell resolved quadrupole moment")
343 : END IF
344 :
345 188 : CALL new_wavefunction(tb%wfn, tb%mol%nat, tb%calc%bas%nsh, tb%calc%bas%nao, nSpin, 0.0_dp)
346 188 : CALL get_occupation(tb%mol, tb%calc%bas, tb%calc%h0, tb%wfn%nocc, tb%wfn%n0at, tb%wfn%n0sh)
347 188 : CALL tb_reset_mixer(tb)
348 :
349 188 : CALL new_potential(tb%pot, tb%mol, tb%calc%bas, tb%wfn%nspin)
350 :
351 : !allocate quantities later required
352 1316 : ALLOCATE (tb%e_hal(tb%mol%nat), tb%e_rep(tb%mol%nat), tb%e_disp(tb%mol%nat))
353 1316 : ALLOCATE (tb%e_scd(tb%mol%nat), tb%e_es(tb%mol%nat), tb%e_int(tb%mol%nat))
354 564 : ALLOCATE (tb%selfenergy(tb%calc%bas%nsh))
355 564 : IF (ALLOCATED(tb%calc%ncoord)) ALLOCATE (tb%cn(tb%mol%nat))
356 :
357 : #else
358 : MARK_USED(tb)
359 : MARK_USED(dft_control)
360 : CPABORT("Built without TBLITE")
361 : #endif
362 :
363 188 : END SUBROUTINE tb_init_wf
364 :
365 : #if defined(__TBLITE)
366 : ! **************************************************************************************************
367 : !> \brief Add tblite's on-site spin-polarization interaction.
368 : !> \param tb ...
369 : ! **************************************************************************************************
370 30 : SUBROUTINE tb_add_spin_polarization(tb)
371 :
372 : TYPE(tblite_type), POINTER :: tb
373 :
374 30 : CLASS(container_type), ALLOCATABLE :: cont
375 30 : TYPE(spin_polarization), ALLOCATABLE :: spin
376 30 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: wll
377 :
378 30 : ALLOCATE (spin)
379 30 : CALL tb_get_spin_constants(tb, wll)
380 30 : CALL new_spin_polarization(spin, tb%mol, wll, tb%calc%bas%nsh_id)
381 30 : CALL MOVE_ALLOC(spin, cont)
382 30 : CALL tb%calc%push_back(cont)
383 :
384 30 : END SUBROUTINE tb_add_spin_polarization
385 :
386 : ! **************************************************************************************************
387 : !> \brief Build tblite spin constants for the current basis.
388 : !> \param tb ...
389 : !> \param wll ...
390 : ! **************************************************************************************************
391 30 : SUBROUTINE tb_get_spin_constants(tb, wll)
392 :
393 : TYPE(tblite_type), POINTER :: tb
394 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
395 : INTENT(OUT) :: wll
396 :
397 : INTEGER :: il, ish, izp, jl, jsh
398 :
399 150 : ALLOCATE (wll(tb%calc%bas%nsh, tb%calc%bas%nsh, tb%mol%nid))
400 30 : wll = 0.0_dp
401 68 : DO izp = 1, tb%mol%nid
402 144 : DO ish = 1, tb%calc%bas%nsh_id(izp)
403 76 : il = tb%calc%bas%cgto(ish, izp)%ang
404 270 : DO jsh = 1, tb%calc%bas%nsh_id(izp)
405 156 : jl = tb%calc%bas%cgto(jsh, izp)%ang
406 232 : wll(jsh, ish, izp) = get_spin_constant(jl, il, tb%mol%num(izp))
407 : END DO
408 : END DO
409 : END DO
410 :
411 30 : END SUBROUTINE tb_get_spin_constants
412 : #endif
413 :
414 : ! **************************************************************************************************
415 : !> \brief Reset tblite's internal SCC mixer for a new CP2K SCF cycle.
416 : !> \param tb ...
417 : ! **************************************************************************************************
418 2634 : SUBROUTINE tb_reset_mixer(tb)
419 :
420 : TYPE(tblite_type), POINTER :: tb
421 :
422 : #if defined(__TBLITE)
423 :
424 : TYPE(scf_info) :: info
425 :
426 2634 : info = tb%calc%variable_info()
427 5080 : IF (ALLOCATED(tb%mixer)) DEALLOCATE (tb%mixer)
428 : CALL new_cp2k_tblite_mixer(tb%mixer, tb%mixer_memory, &
429 : tb%wfn%nspin*get_mixer_dimension(tb%mol, tb%calc%bas, info), &
430 : tb%mixer_damping, tb%mixer_omega0, tb%mixer_min_weight, &
431 2634 : tb%mixer_max_weight, tb%mixer_weight_factor)
432 :
433 : #else
434 : MARK_USED(tb)
435 : CPABORT("Built without TBLITE")
436 : #endif
437 :
438 2634 : END SUBROUTINE tb_reset_mixer
439 :
440 : ! **************************************************************************************************
441 : !> \brief Configure tblite's internal SCC mixer from CP2K input.
442 : !> \param tb ...
443 : !> \param iterations ...
444 : !> \param memory ...
445 : !> \param damping ...
446 : !> \param omega0 ...
447 : !> \param min_weight ...
448 : !> \param max_weight ...
449 : !> \param weight_factor ...
450 : !> \param solver ...
451 : ! **************************************************************************************************
452 2446 : SUBROUTINE tb_configure_mixer(tb, iterations, memory, damping, omega0, min_weight, max_weight, &
453 : weight_factor, solver)
454 :
455 : TYPE(tblite_type), POINTER :: tb
456 : INTEGER, INTENT(IN) :: iterations, memory, solver
457 : REAL(KIND=dp), INTENT(IN) :: damping, max_weight, min_weight, omega0, &
458 : weight_factor
459 :
460 : #if defined(__TBLITE)
461 :
462 2446 : IF (iterations < 1) CPABORT("tblite SCC mixer ITERATIONS must be positive")
463 2446 : IF (memory < 1) CPABORT("tblite SCC mixer MEMORY must be positive")
464 2446 : IF (damping <= 0.0_dp) CPABORT("tblite SCC mixer damping must be positive")
465 2446 : IF (omega0 <= 0.0_dp) CPABORT("tblite SCC mixer OMEGA0 must be positive")
466 2446 : IF (min_weight <= 0.0_dp) CPABORT("tblite SCC mixer MIN_WEIGHT must be positive")
467 2446 : IF (max_weight <= 0.0_dp) CPABORT("tblite SCC mixer MAX_WEIGHT must be positive")
468 2446 : IF (max_weight < min_weight) THEN
469 0 : CPABORT("tblite SCC mixer MAX_WEIGHT must not be smaller than MIN_WEIGHT")
470 : END IF
471 2446 : IF (weight_factor <= 0.0_dp) CPABORT("tblite SCC mixer WEIGHT_FACTOR must be positive")
472 2446 : SELECT CASE (solver)
473 : CASE (tblite_solver_gvd, tblite_solver_gvr)
474 : CASE DEFAULT
475 2446 : CPABORT("Unknown tblite SCC mixer SOLVER")
476 : END SELECT
477 :
478 2446 : tb%calc%max_iter = iterations
479 2446 : tb%mixer_memory = memory
480 2446 : tb%mixer_solver = solver
481 2446 : tb%mixer_damping = damping
482 2446 : tb%calc%mixer_input%damping = damping
483 2446 : tb%mixer_omega0 = omega0
484 2446 : tb%mixer_min_weight = min_weight
485 2446 : tb%mixer_max_weight = max_weight
486 2446 : tb%mixer_weight_factor = weight_factor
487 :
488 : #else
489 : MARK_USED(tb)
490 : MARK_USED(iterations)
491 : MARK_USED(memory)
492 : MARK_USED(damping)
493 : MARK_USED(omega0)
494 : MARK_USED(min_weight)
495 : MARK_USED(max_weight)
496 : MARK_USED(weight_factor)
497 : MARK_USED(solver)
498 : CPABORT("Built without TBLITE")
499 : #endif
500 :
501 2446 : END SUBROUTINE tb_configure_mixer
502 :
503 : ! **************************************************************************************************
504 : !> \brief Return whether the tblite native SCC mixer is active for this run.
505 : !> \param dft_control ...
506 : !> \return ...
507 : ! **************************************************************************************************
508 93962 : FUNCTION tb_native_scc_mixer_active(dft_control) RESULT(use_native_mixer)
509 :
510 : TYPE(dft_control_type), POINTER :: dft_control
511 : LOGICAL :: use_native_mixer
512 :
513 93962 : use_native_mixer = .FALSE.
514 93962 : IF (.NOT. ASSOCIATED(dft_control)) RETURN
515 93962 : IF (dft_control%qs_control%do_ls_scf) RETURN
516 :
517 93962 : SELECT CASE (dft_control%qs_control%xtb_control%tblite_scc_mixer)
518 : CASE (tblite_scc_mixer_auto)
519 : use_native_mixer = .TRUE.
520 : CASE (tblite_scc_mixer_tblite)
521 5264 : use_native_mixer = .TRUE.
522 : CASE (tblite_scc_mixer_cp2k, tblite_scc_mixer_none)
523 5264 : use_native_mixer = .FALSE.
524 : CASE DEFAULT
525 93962 : CPABORT("Unknown tblite SCC mixer")
526 : END SELECT
527 :
528 : END FUNCTION tb_native_scc_mixer_active
529 :
530 : ! **************************************************************************************************
531 : !> \brief Return the native tblite SCC mixer residual on the CP2K iter_delta scale.
532 : !> \param dft_control ...
533 : !> \param tb ...
534 : !> \param eps_scf CP2K reporting scale for the native residual.
535 : !> \return ...
536 : ! **************************************************************************************************
537 24596 : FUNCTION tb_scf_mixer_error(dft_control, tb, eps_scf) RESULT(mixer_error)
538 :
539 : TYPE(dft_control_type), POINTER :: dft_control
540 : TYPE(tblite_type), POINTER :: tb
541 : REAL(KIND=dp), INTENT(IN) :: eps_scf
542 : REAL(KIND=dp) :: mixer_error
543 :
544 : #if defined(__TBLITE)
545 : REAL(KIND=dp) :: raw_error
546 : #endif
547 :
548 24596 : mixer_error = 0.0_dp
549 :
550 : #if defined(__TBLITE)
551 24596 : IF (.NOT. ASSOCIATED(tb)) RETURN
552 24596 : IF (.NOT. tb_native_scc_mixer_active(dft_control)) RETURN
553 22358 : IF (ALLOCATED(tb%mixer)) THEN
554 22358 : raw_error = REAL(tb%mixer%get_error(), KIND=dp)
555 : mixer_error = tblite_scc_error_on_cp2k_scale( &
556 : raw_error, eps_scf, &
557 22358 : tblite_scc_pconv*dft_control%qs_control%xtb_control%tblite_accuracy)
558 : END IF
559 : #else
560 : MARK_USED(dft_control)
561 : MARK_USED(tb)
562 : MARK_USED(eps_scf)
563 : #endif
564 :
565 : END FUNCTION tb_scf_mixer_error
566 :
567 : ! **************************************************************************************************
568 : !> \brief ...
569 : !> \param tb ...
570 : !> \param typ ...
571 : !> \param accuracy ...
572 : !> \param param_file ...
573 : ! **************************************************************************************************
574 188 : SUBROUTINE tb_set_calculator(tb, typ, accuracy, param_file)
575 :
576 : TYPE(tblite_type), POINTER :: tb
577 : INTEGER :: typ
578 : REAL(KIND=dp), INTENT(IN) :: accuracy
579 : CHARACTER(LEN=*), INTENT(IN) :: param_file
580 :
581 : #if defined(__TBLITE)
582 :
583 188 : TYPE(error_type), ALLOCATABLE :: error
584 :
585 188 : IF (ALLOCATED(tb%param)) DEALLOCATE (tb%param)
586 188 : IF (LEN_TRIM(param_file) > 0) THEN
587 0 : ALLOCATE (tb%param)
588 0 : CALL tb%param%load(TRIM(param_file), error)
589 0 : IF (ALLOCATED(error)) CPABORT("Could not load tblite PARAM file: "//TRIM(param_file))
590 0 : CALL new_xtb_calculator(tb%calc, tb%mol, tb%param, error)
591 : ELSE
592 188 : SELECT CASE (typ)
593 : CASE default
594 0 : CPABORT("Unknown xtb type")
595 : CASE (gfn1xtb)
596 70 : CALL new_gfn1_calculator(tb%calc, tb%mol, error)
597 : CASE (gfn2xtb)
598 102 : CALL new_gfn2_calculator(tb%calc, tb%mol, error)
599 : CASE (ipea1xtb)
600 188 : CALL new_ipea1_calculator(tb%calc, tb%mol, error)
601 : END SELECT
602 : END IF
603 188 : IF (ALLOCATED(error)) CPABORT("tblite calculator setup failed")
604 :
605 188 : tb%accuracy = accuracy
606 :
607 : #else
608 : MARK_USED(tb)
609 : MARK_USED(typ)
610 : MARK_USED(accuracy)
611 : MARK_USED(param_file)
612 : CPABORT("Built without TBLITE")
613 : #endif
614 :
615 188 : END SUBROUTINE tb_set_calculator
616 :
617 : ! **************************************************************************************************
618 : !> \brief ...
619 : !> \param qs_env ...
620 : !> \param tb ...
621 : !> \param para_env ...
622 : ! **************************************************************************************************
623 2750 : SUBROUTINE tb_init_ham(qs_env, tb, para_env)
624 :
625 : TYPE(qs_environment_type) :: qs_env
626 : TYPE(tblite_type) :: tb
627 : TYPE(mp_para_env_type) :: para_env
628 :
629 : #if defined(__TBLITE)
630 :
631 2750 : TYPE(container_cache) :: hcache, rcache
632 :
633 14868 : tb%e_hal = 0.0_dp
634 14868 : tb%e_rep = 0.0_dp
635 14868 : tb%e_disp = 0.0_dp
636 14868 : tb%e_int = 0.0_dp
637 2750 : IF (ALLOCATED(tb%grad)) THEN
638 3606 : tb%grad = 0.0_dp
639 150 : CALL tb_zero_force(qs_env)
640 : END IF
641 35750 : tb%sigma = 0.0_dp
642 :
643 2750 : IF (ALLOCATED(tb%calc%halogen)) THEN
644 1382 : CALL tb%calc%halogen%update(tb%mol, hcache)
645 1382 : IF (ALLOCATED(tb%grad)) THEN
646 2532 : tb%grad = 0.0_dp
647 : CALL tb%calc%halogen%get_engrad(tb%mol, hcache, tb%e_hal, &
648 84 : & tb%grad, tb%sigma)
649 : CALL tb_dump_sigma_component("after_halogen", tb%sigma, para_env)
650 84 : CALL tb_grad2force(qs_env, tb, para_env, 0)
651 : ELSE
652 1298 : CALL tb%calc%halogen%get_engrad(tb%mol, hcache, tb%e_hal)
653 : END IF
654 : END IF
655 :
656 2750 : IF (ALLOCATED(tb%calc%repulsion)) THEN
657 2750 : CALL tb%calc%repulsion%update(tb%mol, rcache)
658 2750 : IF (ALLOCATED(tb%grad)) THEN
659 3606 : tb%grad = 0.0_dp
660 : CALL tb%calc%repulsion%get_engrad(tb%mol, rcache, tb%e_rep, &
661 150 : & tb%grad, tb%sigma)
662 : CALL tb_dump_sigma_component("after_repulsion", tb%sigma, para_env)
663 150 : CALL tb_grad2force(qs_env, tb, para_env, 1)
664 : ELSE
665 2600 : CALL tb%calc%repulsion%get_engrad(tb%mol, rcache, tb%e_rep)
666 : END IF
667 : END IF
668 :
669 2750 : IF (ALLOCATED(tb%calc%dispersion)) THEN
670 2750 : CALL tb%calc%dispersion%update(tb%mol, tb%dcache)
671 2750 : IF (ALLOCATED(tb%grad)) THEN
672 3606 : tb%grad = 0.0_dp
673 : CALL tb%calc%dispersion%get_engrad(tb%mol, tb%dcache, tb%e_disp, &
674 150 : & tb%grad, tb%sigma)
675 : CALL tb_dump_sigma_component("after_dispersion_static", tb%sigma, para_env)
676 150 : CALL tb_grad2force(qs_env, tb, para_env, 2)
677 : ELSE
678 2600 : CALL tb%calc%dispersion%get_engrad(tb%mol, tb%dcache, tb%e_disp)
679 : END IF
680 : END IF
681 :
682 2750 : IF (ALLOCATED(tb%calc%interactions)) THEN
683 356 : CALL tb%calc%interactions%update(tb%mol, tb%icache)
684 : END IF
685 :
686 2750 : CALL new_potential(tb%pot, tb%mol, tb%calc%bas, tb%wfn%nspin)
687 2750 : IF (ALLOCATED(tb%calc%coulomb)) THEN
688 2750 : CALL tb%calc%coulomb%update(tb%mol, tb%cache)
689 : END IF
690 :
691 2750 : IF (ALLOCATED(tb%grad)) THEN
692 150 : IF (ALLOCATED(tb%calc%ncoord)) THEN
693 150 : CALL tb%calc%ncoord%get_cn(tb%mol, tb%cn, tb%dcndr, tb%dcndL)
694 : END IF
695 : CALL get_selfenergy(tb%calc%h0, tb%mol%id, tb%calc%bas%ish_at, &
696 150 : & tb%calc%bas%nsh_id, cn=tb%cn, selfenergy=tb%selfenergy, dsedcn=tb%dsedcn)
697 : ELSE
698 2600 : IF (ALLOCATED(tb%calc%ncoord)) THEN
699 2600 : CALL tb%calc%ncoord%get_cn(tb%mol, tb%cn)
700 : END IF
701 : CALL get_selfenergy(tb%calc%h0, tb%mol%id, tb%calc%bas%ish_at, &
702 2600 : & tb%calc%bas%nsh_id, cn=tb%cn, selfenergy=tb%selfenergy, dsedcn=tb%dsedcn)
703 : END IF
704 :
705 : #else
706 : MARK_USED(qs_env)
707 : MARK_USED(tb)
708 : MARK_USED(para_env)
709 : CPABORT("Built without TBLITE")
710 : #endif
711 :
712 2750 : END SUBROUTINE tb_init_ham
713 :
714 : ! **************************************************************************************************
715 : !> \brief ...
716 : !> \param qs_env ...
717 : !> \param tb ...
718 : !> \param energy ...
719 : ! **************************************************************************************************
720 25384 : SUBROUTINE tb_get_energy(qs_env, tb, energy)
721 :
722 : TYPE(qs_environment_type), POINTER :: qs_env
723 : TYPE(tblite_type), POINTER :: tb
724 : TYPE(qs_energy_type), POINTER :: energy
725 :
726 : #if defined(__TBLITE)
727 :
728 : INTEGER :: iounit
729 : TYPE(cp_logger_type), POINTER :: logger
730 : TYPE(section_vals_type), POINTER :: scf_section
731 : REAL(KIND=dp) :: xtb_inter
732 25384 : NULLIFY (scf_section, logger)
733 :
734 25384 : logger => cp_get_default_logger()
735 25384 : iounit = cp_logger_get_default_io_unit(logger)
736 25384 : scf_section => section_vals_get_subs_vals(qs_env%input, "DFT%SCF")
737 :
738 147844 : energy%repulsive = SUM(tb%e_rep)
739 147844 : energy%el_stat = SUM(tb%e_es)
740 147844 : energy%dispersion = SUM(tb%e_disp)
741 147844 : energy%dispersion_sc = SUM(tb%e_scd)
742 147844 : energy%xtb_xb_inter = SUM(tb%e_hal)
743 147844 : xtb_inter = SUM(tb%e_int)
744 :
745 : energy%total = energy%core + energy%repulsive + energy%el_stat + energy%dispersion &
746 : + energy%dispersion_sc + energy%xtb_xb_inter + xtb_inter &
747 25384 : + energy%kTS + energy%efield + energy%qmmm_el
748 :
749 : iounit = cp_print_key_unit_nr(logger, scf_section, "PRINT%DETAILED_ENERGY", &
750 25384 : extension=".scfLog")
751 25384 : IF (iounit > 0) THEN
752 : WRITE (UNIT=iounit, FMT="(/,(T9,A,T60,F20.10))") &
753 158 : "Repulsive pair potential energy: ", energy%repulsive, &
754 158 : "Zeroth order Hamiltonian energy: ", energy%core, &
755 158 : "Electrostatic energy: ", energy%el_stat, &
756 158 : "Self-consistent dispersion energy: ", energy%dispersion_sc, &
757 316 : "Non-self consistent dispersion energy: ", energy%dispersion
758 158 : IF (ABS(energy%xtb_xb_inter) > 1.e-9_dp) THEN
759 : WRITE (UNIT=iounit, FMT="(T9,A,T60,F20.10)") &
760 0 : "Correction for halogen bonding: ", energy%xtb_xb_inter
761 : END IF
762 158 : IF (ABS(xtb_inter) > 1.e-9_dp) THEN
763 : WRITE (UNIT=iounit, FMT="(T9,A,T60,F20.10)") &
764 0 : "Additional interaction (e.g. spin): ", xtb_inter
765 : END IF
766 158 : IF (ABS(energy%efield) > 1.e-9_dp) THEN
767 : WRITE (UNIT=iounit, FMT="(T9,A,T60,F20.10)") &
768 0 : "Electric field interaction energy: ", energy%efield
769 : END IF
770 158 : IF (qs_env%qmmm) THEN
771 : WRITE (UNIT=iounit, FMT="(T9,A,T60,F20.10)") &
772 0 : "QM/MM Electrostatic energy: ", energy%qmmm_el
773 : END IF
774 : END IF
775 : CALL cp_print_key_finished_output(iounit, logger, scf_section, &
776 25384 : "PRINT%DETAILED_ENERGY")
777 :
778 : #else
779 : MARK_USED(qs_env)
780 : MARK_USED(tb)
781 : MARK_USED(energy)
782 : CPABORT("Built without TBLITE")
783 : #endif
784 :
785 25384 : END SUBROUTINE tb_get_energy
786 :
787 : ! **************************************************************************************************
788 : !> \brief ...
789 : !> \param tb ...
790 : !> \param gto_basis_set ...
791 : !> \param element_symbol ...
792 : !> \param param ...
793 : !> \param occ ...
794 : ! **************************************************************************************************
795 324 : SUBROUTINE tb_get_basis(tb, gto_basis_set, element_symbol, param, occ)
796 :
797 : TYPE(tblite_type), POINTER :: tb
798 : TYPE(gto_basis_set_type), POINTER :: gto_basis_set
799 : CHARACTER(len=2), INTENT(IN) :: element_symbol
800 : TYPE(xtb_atom_type), POINTER :: param
801 : INTEGER, DIMENSION(5), INTENT(out) :: occ
802 :
803 : #if defined(__TBLITE)
804 :
805 : REAL(KIND=dp) :: docc
806 : CHARACTER(LEN=default_string_length) :: sng
807 : INTEGER :: ang, i_type, id_atom, ind_ao, ipgf, iSH, &
808 : ishell, ityp, maxl, mprim, natorb, &
809 : nset, nshell
810 : LOGICAL :: do_ortho
811 :
812 324 : CALL allocate_gto_basis_set(gto_basis_set)
813 :
814 : !identifying element in the bas data
815 324 : CALL symbol_to_number(i_type, element_symbol)
816 674 : DO id_atom = 1, tb%mol%nat
817 674 : IF (i_type == tb%el_num(id_atom)) EXIT
818 : END DO
819 324 : param%z = i_type
820 324 : param%symbol = element_symbol
821 324 : param%defined = .TRUE.
822 324 : ityp = tb%mol%id(id_atom)
823 :
824 : !getting size information
825 324 : nset = tb%calc%bas%nsh_id(ityp)
826 324 : nshell = 1
827 324 : mprim = 0
828 1058 : DO ishell = 1, nset
829 1058 : mprim = MAX(mprim, tb%calc%bas%cgto(ishell, ityp)%nprim)
830 : END DO
831 324 : param%nshell = nset
832 324 : natorb = 0
833 :
834 : !write basis set information
835 324 : CALL integer_to_string(mprim, sng)
836 324 : gto_basis_set%name = element_symbol//"_STO-"//TRIM(sng)//"G"
837 324 : gto_basis_set%nset = nset
838 324 : CALL reallocate(gto_basis_set%lmax, 1, nset)
839 324 : CALL reallocate(gto_basis_set%lmin, 1, nset)
840 324 : CALL reallocate(gto_basis_set%npgf, 1, nset)
841 324 : CALL reallocate(gto_basis_set%nshell, 1, nset)
842 324 : CALL reallocate(gto_basis_set%n, 1, 1, 1, nset)
843 324 : CALL reallocate(gto_basis_set%l, 1, 1, 1, nset)
844 324 : CALL reallocate(gto_basis_set%zet, 1, mprim, 1, nset)
845 324 : CALL reallocate(gto_basis_set%gcc, 1, mprim, 1, 1, 1, nset)
846 :
847 324 : ind_ao = 0
848 324 : maxl = 0
849 1058 : DO ishell = 1, nset
850 734 : ang = tb%calc%bas%cgto(ishell, ityp)%ang
851 734 : natorb = natorb + (2*ang + 1)
852 734 : param%lval(ishell) = ang
853 734 : maxl = MAX(ang, maxl)
854 734 : gto_basis_set%lmax(ishell) = ang
855 734 : gto_basis_set%lmin(ishell) = ang
856 734 : gto_basis_set%npgf(ishell) = tb%calc%bas%cgto(ishell, ityp)%nprim
857 734 : gto_basis_set%nshell(ishell) = nshell
858 734 : gto_basis_set%n(1, ishell) = ang + 1
859 734 : gto_basis_set%l(1, ishell) = ang
860 4388 : DO ipgf = 1, gto_basis_set%npgf(ishell)
861 3654 : gto_basis_set%gcc(ipgf, 1, ishell) = tb%calc%bas%cgto(ishell, ityp)%coeff(ipgf)
862 4388 : gto_basis_set%zet(ipgf, ishell) = tb%calc%bas%cgto(ishell, ityp)%alpha(ipgf)
863 : END DO
864 2692 : DO ipgf = 1, (2*ang + 1)
865 1634 : ind_ao = ind_ao + 1
866 1634 : param%lao(ind_ao) = ang
867 2368 : param%nao(ind_ao) = ishell
868 : END DO
869 : END DO
870 :
871 324 : do_ortho = .FALSE.
872 324 : CALL process_gto_basis(gto_basis_set, do_ortho, nset, maxl)
873 :
874 : !setting additional values in parameter
875 324 : param%rcut = get_cutoff(tb%calc%bas, tb%accuracy)
876 324 : param%natorb = natorb
877 324 : param%lmax = maxl !max angular momentum
878 :
879 : !getting occupation
880 324 : occ = 0
881 324 : docc = 0.0_dp
882 324 : IF (tb%calc%bas%nsh_at(id_atom) > 5) CPABORT("too many shells in tblite")
883 1058 : DO iSh = 1, tb%calc%bas%nsh_at(id_atom)
884 734 : occ(iSh) = NINT(tb%calc%h0%refocc(iSh, ityp) + docc)
885 734 : docc = docc + tb%calc%h0%refocc(iSh, ityp) - REAL(occ(iSh))
886 1058 : param%occupation(iSh) = occ(iSh)
887 : END DO
888 324 : IF (ABS(docc) > 0.1_dp) CPABORT("Getting occupation numbers from tblite fails")
889 1944 : param%zeff = SUM(occ) !effective core charge
890 :
891 : !set normalization process
892 324 : gto_basis_set%norm_type = 3
893 :
894 : #else
895 : occ = 0
896 : MARK_USED(tb)
897 : MARK_USED(gto_basis_set)
898 : MARK_USED(element_symbol)
899 : MARK_USED(param)
900 : CPABORT("Built without TBLITE")
901 : #endif
902 :
903 324 : END SUBROUTINE tb_get_basis
904 :
905 : ! **************************************************************************************************
906 : !> \brief ...
907 : !> \param qs_env ...
908 : !> \param calculate_forces ...
909 : ! **************************************************************************************************
910 2750 : SUBROUTINE build_tblite_matrices(qs_env, calculate_forces)
911 :
912 : TYPE(qs_environment_type), POINTER :: qs_env
913 : LOGICAL, INTENT(IN) :: calculate_forces
914 :
915 : #if defined(__TBLITE)
916 :
917 : CHARACTER(LEN=*), PARAMETER :: routineN = 'build_tblite_matrices'
918 :
919 : INTEGER :: handle, maxder, nderivatives, nimg, img, nkind, i, &
920 : ic, iw, iatom, jatom, ikind, jkind, iset, jset, n1, n2, icol, &
921 : irow, ia, ib, sgfa, sgfb, ldsab, nseta, nsetb, &
922 : natorb_a, natorb_b, raw_iatom, raw_jatom, &
923 : slot, idim, jdim
924 : LOGICAL :: found, norml1, norml2, use_arnoldi
925 : REAL(KIND=dp) :: dr, dshpoly, ff, hij_base, r2, rr
926 : REAL(KIND=dp) :: native_dot_tmp, native_cn_icol, native_cn_irow, &
927 : native_dot_weight
928 : INTEGER, DIMENSION(3) :: cell
929 : REAL(KIND=dp) :: hij, shpoly
930 : REAL(KIND=dp), DIMENSION(2) :: condnum
931 : REAL(KIND=dp), DIMENSION(3) :: native_h0_overlap_force, native_radial_force, raw_rij, rij
932 : REAL(KIND=dp), DIMENSION(3, 3) :: native_radial_dot
933 2750 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
934 2750 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
935 2750 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: owork
936 2750 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: native_cn_deriv_thread
937 2750 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: native_radial_force_thread
938 5500 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: oint, sint, hint
939 2750 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :) :: radial_hint
940 2750 : INTEGER, DIMENSION(:), POINTER :: la_max, la_min, lb_max, lb_min
941 2750 : INTEGER, DIMENSION(:), POINTER :: npgfa, npgfb, nsgfa, nsgfb
942 2750 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
943 2750 : REAL(KIND=dp), DIMENSION(:), POINTER :: set_radius_a, set_radius_b
944 2750 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: rpgfa, rpgfb, zeta, zetb, scon_a, scon_b
945 5500 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: fblock, pblock, sblock
946 35750 : TYPE(block_p_type), DIMENSION(3, 3) :: radial_blocks
947 : !$ INTEGER :: hash, hash1, lock_num
948 : !$ INTEGER(KIND=int_8) :: iatom8
949 2750 : !$ INTEGER(kind=omp_lock_kind), ALLOCATABLE, DIMENSION(:) :: locks
950 : INTEGER, PARAMETER :: nlock = 501
951 :
952 2750 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
953 : TYPE(atprop_type), POINTER :: atprop
954 : TYPE(cp_blacs_env_type), POINTER :: blacs_env
955 : TYPE(cp_logger_type), POINTER :: logger
956 2750 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_dh_native, matrix_h, matrix_p, &
957 2750 : matrix_q_native, matrix_s, matrix_s_native, matrix_w
958 : TYPE(dft_control_type), POINTER :: dft_control
959 2750 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
960 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
961 2750 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
962 : TYPE(kpoint_type), POINTER :: kpoints
963 2750 : TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_orb
964 2750 : TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_kp
965 : TYPE(mp_para_env_type), POINTER :: para_env
966 : TYPE(qs_energy_type), POINTER :: energy
967 : TYPE(qs_ks_env_type), POINTER :: ks_env
968 2750 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
969 : TYPE(qs_rho_type), POINTER :: rho
970 : TYPE(tblite_type), POINTER :: tb
971 : TYPE(tb_hamiltonian), POINTER :: h0
972 : TYPE(virial_type), POINTER :: virial
973 :
974 2750 : CALL timeset(routineN, handle)
975 :
976 2750 : NULLIFY (ks_env, energy, atomic_kind_set, qs_kind_set)
977 2750 : NULLIFY (matrix_dh_native, matrix_h, matrix_q_native, matrix_s, matrix_s_native, atprop, dft_control)
978 2750 : NULLIFY (sab_orb, sab_kp, rho, tb, kpoints, cell_to_index)
979 :
980 : CALL get_qs_env(qs_env=qs_env, &
981 : ks_env=ks_env, para_env=para_env, &
982 : energy=energy, &
983 : atomic_kind_set=atomic_kind_set, &
984 : qs_kind_set=qs_kind_set, &
985 : matrix_h_kp=matrix_h, &
986 : matrix_s_kp=matrix_s, &
987 : atprop=atprop, &
988 : dft_control=dft_control, &
989 : sab_orb=sab_orb, &
990 : sab_kp=sab_kp, &
991 2750 : rho=rho, tb_tblite=tb)
992 2750 : h0 => tb%calc%h0
993 :
994 : !update geometry (required for debug / geometry optimization)
995 2750 : CALL tb_update_geometry(qs_env, tb)
996 :
997 2750 : nkind = SIZE(atomic_kind_set)
998 2750 : nderivatives = 0
999 2750 : IF (calculate_forces) THEN
1000 150 : nderivatives = 1
1001 150 : IF (ALLOCATED(tb%grad)) DEALLOCATE (tb%grad)
1002 450 : ALLOCATE (tb%grad(3, tb%mol%nat))
1003 150 : IF (ALLOCATED(tb%dsedcn)) DEALLOCATE (tb%dsedcn)
1004 450 : ALLOCATE (tb%dsedcn(tb%calc%bas%nsh))
1005 150 : IF (ALLOCATED(tb%calc%ncoord)) THEN
1006 150 : IF (ALLOCATED(tb%dcndr)) DEALLOCATE (tb%dcndr)
1007 600 : ALLOCATE (tb%dcndr(3, tb%mol%nat, tb%mol%nat))
1008 150 : IF (ALLOCATED(tb%dcndL)) DEALLOCATE (tb%dcndL)
1009 450 : ALLOCATE (tb%dcndL(3, 3, tb%mol%nat))
1010 : END IF
1011 : ELSE
1012 2600 : IF (ALLOCATED(tb%grad)) DEALLOCATE (tb%grad)
1013 2600 : IF (ALLOCATED(tb%dcndr)) DEALLOCATE (tb%dcndr)
1014 2600 : IF (ALLOCATED(tb%dcndL)) DEALLOCATE (tb%dcndL)
1015 : END IF
1016 2750 : maxder = ncoset(nderivatives)
1017 2750 : nimg = dft_control%nimages
1018 2750 : IF (nimg > 1) THEN
1019 1286 : IF (.NOT. ASSOCIATED(sab_kp)) CPABORT("Missing k-point neighbor list for tblite")
1020 1286 : sab_orb => sab_kp
1021 1286 : CALL get_ks_env(ks_env=ks_env, kpoints=kpoints)
1022 1286 : CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
1023 : END IF
1024 :
1025 : !intialise hamiltonian
1026 2750 : CALL tb_init_ham(qs_env, tb, para_env)
1027 :
1028 : ! get density matrtix
1029 2750 : CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
1030 :
1031 : ! set up matrices for force calculations
1032 2750 : IF (calculate_forces) THEN
1033 150 : NULLIFY (force, matrix_w, virial)
1034 : CALL get_qs_env(qs_env=qs_env, &
1035 : matrix_w_kp=matrix_w, &
1036 150 : virial=virial, force=force)
1037 :
1038 150 : IF (SIZE(matrix_p, 1) == 2) THEN
1039 152 : DO img = 1, nimg
1040 : CALL dbcsr_add(matrix_p(1, img)%matrix, matrix_p(2, img)%matrix, &
1041 130 : alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1042 : CALL dbcsr_add(matrix_w(1, img)%matrix, matrix_w(2, img)%matrix, &
1043 152 : alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
1044 : END DO
1045 : END IF
1046 216 : tb%use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
1047 : END IF
1048 :
1049 2750 : IF (calculate_forces) THEN
1050 150 : CALL dbcsr_allocate_matrix_set(matrix_q_native, 1, nimg)
1051 5052 : DO img = 1, nimg
1052 4902 : ALLOCATE (matrix_q_native(1, img)%matrix)
1053 : CALL dbcsr_copy(matrix_q_native(1, img)%matrix, matrix_w(1, img)%matrix, &
1054 5052 : name="TBLITE NATIVE OVERLAP FORCE MATRIX")
1055 : END DO
1056 : END IF
1057 :
1058 2750 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind, kind_of=kind_of)
1059 2750 : IF (calculate_forces) THEN
1060 450 : ALLOCATE (native_radial_force_thread(3, SIZE(atom_of_kind)))
1061 450 : ALLOCATE (native_cn_deriv_thread(SIZE(atom_of_kind)))
1062 150 : native_cn_deriv_thread = 0.0_dp
1063 150 : native_radial_force_thread = 0.0_dp
1064 : END IF
1065 :
1066 : ! set up basis set lists
1067 12872 : ALLOCATE (basis_set_list(nkind))
1068 2750 : CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
1069 :
1070 : ! allocate overlap matrix
1071 2750 : CALL dbcsr_allocate_matrix_set(matrix_s, 1, nimg)
1072 : CALL create_sab_matrix(ks_env, matrix_s, "OVERLAP MATRIX", basis_set_list, basis_set_list, &
1073 2750 : sab_orb, .TRUE.)
1074 2750 : CALL set_ks_env(ks_env, matrix_s_kp=matrix_s)
1075 :
1076 : ! initialize H matrix
1077 2750 : CALL dbcsr_allocate_matrix_set(matrix_h, 1, nimg)
1078 73724 : DO img = 1, nimg
1079 70974 : ALLOCATE (matrix_h(1, img)%matrix)
1080 : CALL dbcsr_create(matrix_h(1, img)%matrix, template=matrix_s(1, img)%matrix, &
1081 70974 : name="HAMILTONIAN MATRIX")
1082 73724 : CALL cp_dbcsr_alloc_block_from_nbl(matrix_h(1, img)%matrix, sab_orb)
1083 : END DO
1084 2750 : CALL set_ks_env(ks_env, matrix_h_kp=matrix_h)
1085 2750 : IF (calculate_forces .AND. nimg > 1) THEN
1086 90 : CALL dbcsr_allocate_matrix_set(matrix_dh_native, 9, nimg)
1087 4932 : DO img = 1, nimg
1088 48510 : DO idim = 1, 9
1089 43578 : ALLOCATE (matrix_dh_native(idim, img)%matrix)
1090 : CALL dbcsr_create(matrix_dh_native(idim, img)%matrix, template=matrix_s(1, img)%matrix, &
1091 43578 : name="TBLITE H0 STRAIN DERIVATIVE")
1092 48420 : CALL cp_dbcsr_alloc_block_from_nbl(matrix_dh_native(idim, img)%matrix, sab_orb)
1093 : END DO
1094 : END DO
1095 : END IF
1096 2750 : ldsab = get_memory_usage(qs_kind_set, "ORB", "ORB")
1097 :
1098 2750 : native_radial_dot = 0.0_dp
1099 :
1100 : ! loop over all atom pairs with a non-zero overlap (sab_orb)
1101 : !$OMP PARALLEL DEFAULT(NONE) &
1102 : !$OMP SHARED (calculate_forces, basis_set_list, sab_orb, matrix_dh_native, matrix_s, matrix_h, matrix_p, &
1103 : !$OMP cell_to_index, nimg, atom_of_kind, qs_kind_set, tb, h0, ldsab, maxder, locks, &
1104 : !$OMP native_cn_deriv_thread, native_radial_force_thread, ncoset) &
1105 : !$OMP PRIVATE (slot, hash, hash1, iatom8, lock_num, ikind, jkind, iatom, jatom, cell, rij, ic, irow, &
1106 : !$OMP icol, dr, dshpoly, ff, hij_base, r2, raw_iatom, raw_jatom, &
1107 : !$OMP raw_rij, native_cn_icol, native_cn_irow, native_dot_weight, native_h0_overlap_force, &
1108 : !$OMP native_radial_force, &
1109 : !$OMP n1, n2, ia, ib, i, idim, jdim, iset, jset, sgfa, sgfb, &
1110 : !$OMP nseta, nsetb, natorb_a, &
1111 : !$OMP natorb_b, found, zeta, first_sgfa, la_max, la_min, npgfa, nsgfa, rpgfa, set_radius_a, &
1112 : !$OMP scon_a, first_sgfb, lb_max, lb_min, npgfb, nsgfb, rpgfb, set_radius_b, scon_b, zetb, rr, hij, shpoly, &
1113 : !$OMP owork, oint, sint, hint, radial_hint, basis_set_a, basis_set_b, sblock, fblock, &
1114 : !$OMP pblock, radial_blocks) &
1115 2750 : !$OMP REDUCTION (+ : native_radial_dot)
1116 :
1117 : !$OMP SINGLE
1118 : !$ ALLOCATE (locks(nlock))
1119 : !$OMP END SINGLE
1120 : !$OMP DO
1121 : !$ DO lock_num = 1, nlock
1122 : !$ CALL omp_init_lock(locks(lock_num))
1123 : !$ END DO
1124 : !$OMP END DO
1125 :
1126 : ALLOCATE (oint(ldsab, ldsab, maxder), owork(ldsab, ldsab))
1127 :
1128 : !$OMP DO SCHEDULE(GUIDED)
1129 : DO slot = 1, sab_orb(1)%nl_size
1130 :
1131 : ikind = sab_orb(1)%nlist_task(slot)%ikind
1132 : jkind = sab_orb(1)%nlist_task(slot)%jkind
1133 : iatom = sab_orb(1)%nlist_task(slot)%iatom
1134 : jatom = sab_orb(1)%nlist_task(slot)%jatom
1135 : cell(:) = sab_orb(1)%nlist_task(slot)%cell(:)
1136 : rij(1:3) = sab_orb(1)%nlist_task(slot)%r(1:3)
1137 : raw_iatom = iatom
1138 : raw_jatom = jatom
1139 : raw_rij = rij
1140 : native_cn_icol = 0.0_dp
1141 : native_cn_irow = 0.0_dp
1142 : native_h0_overlap_force = 0.0_dp
1143 : native_radial_force = 0.0_dp
1144 :
1145 : ! canonicalize pair ordering as in current serial flow
1146 : icol = MAX(iatom, jatom)
1147 : irow = MIN(iatom, jatom)
1148 : IF (iatom < jatom) THEN
1149 : rij = -rij
1150 : i = ikind
1151 : ikind = jkind
1152 : jkind = i
1153 : END IF
1154 :
1155 : dr = NORM2(rij(:))
1156 : r2 = dr*dr
1157 :
1158 : IF (nimg == 1) THEN
1159 : ic = 1
1160 : ELSE
1161 : ic = cell_to_index(cell(1), cell(2), cell(3))
1162 : CPASSERT(ic > 0)
1163 : END IF
1164 :
1165 : NULLIFY (sblock)
1166 : CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
1167 : row=irow, col=icol, BLOCK=sblock, found=found)
1168 : CPASSERT(found)
1169 : NULLIFY (fblock)
1170 : CALL dbcsr_get_block_p(matrix=matrix_h(1, ic)%matrix, &
1171 : row=irow, col=icol, BLOCK=fblock, found=found)
1172 : CPASSERT(found)
1173 : IF (calculate_forces) THEN
1174 : NULLIFY (pblock)
1175 : CALL dbcsr_get_block_p(matrix=matrix_p(1, ic)%matrix, &
1176 : row=irow, col=icol, BLOCK=pblock, found=found)
1177 : CPASSERT(found)
1178 : IF (nimg > 1) THEN
1179 : DO jdim = 1, 3
1180 : DO idim = 1, 3
1181 : NULLIFY (radial_blocks(idim, jdim)%block)
1182 : CALL dbcsr_get_block_p(matrix=matrix_dh_native(idim + 3*(jdim - 1), ic)%matrix, &
1183 : row=irow, col=icol, BLOCK=radial_blocks(idim, jdim)%block, &
1184 : found=found)
1185 : CPASSERT(found)
1186 : END DO
1187 : END DO
1188 : END IF
1189 : END IF
1190 :
1191 : ! --------- Overlap
1192 : !get basis information
1193 : basis_set_a => basis_set_list(ikind)%gto_basis_set
1194 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
1195 : basis_set_b => basis_set_list(jkind)%gto_basis_set
1196 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
1197 : ! basis a
1198 : first_sgfa => basis_set_a%first_sgf
1199 : la_max => basis_set_a%lmax
1200 : la_min => basis_set_a%lmin
1201 : npgfa => basis_set_a%npgf
1202 : nseta = basis_set_a%nset
1203 : nsgfa => basis_set_a%nsgf_set
1204 : rpgfa => basis_set_a%pgf_radius
1205 : set_radius_a => basis_set_a%set_radius
1206 : scon_a => basis_set_a%scon
1207 : zeta => basis_set_a%zet
1208 : ! basis b
1209 : first_sgfb => basis_set_b%first_sgf
1210 : lb_max => basis_set_b%lmax
1211 : lb_min => basis_set_b%lmin
1212 : npgfb => basis_set_b%npgf
1213 : nsetb = basis_set_b%nset
1214 : nsgfb => basis_set_b%nsgf_set
1215 : rpgfb => basis_set_b%pgf_radius
1216 : set_radius_b => basis_set_b%set_radius
1217 : scon_b => basis_set_b%scon
1218 : zetb => basis_set_b%zet
1219 :
1220 : natorb_a = 0
1221 : DO iset = 1, nseta
1222 : natorb_a = natorb_a + (2*basis_set_a%l(1, iset) + 1)
1223 : END DO
1224 : natorb_b = 0
1225 : DO iset = 1, nsetb
1226 : natorb_b = natorb_b + (2*basis_set_b%l(1, iset) + 1)
1227 : END DO
1228 : ALLOCATE (sint(natorb_a, natorb_b, maxder))
1229 : sint = 0.0_dp
1230 : ALLOCATE (hint(natorb_a, natorb_b, maxder))
1231 : hint = 0.0_dp
1232 : IF (calculate_forces .AND. nimg > 1) THEN
1233 : ALLOCATE (radial_hint(natorb_a, natorb_b, 3, 3))
1234 : radial_hint = 0.0_dp
1235 : END IF
1236 :
1237 : !----------------- overlap integrals
1238 : DO iset = 1, nseta
1239 : n1 = npgfa(iset)*(ncoset(la_max(iset)) - ncoset(la_min(iset) - 1))
1240 : sgfa = first_sgfa(1, iset)
1241 : DO jset = 1, nsetb
1242 : IF (set_radius_a(iset) + set_radius_b(jset) < dr) CYCLE
1243 : n2 = npgfb(jset)*(ncoset(lb_max(jset)) - ncoset(lb_min(jset) - 1))
1244 : sgfb = first_sgfb(1, jset)
1245 : IF (calculate_forces) THEN
1246 : CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
1247 : lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
1248 : rij, sab=oint(:, :, 1), dab=oint(:, :, 2:4))
1249 : ELSE
1250 : CALL overlap_ab(la_max(iset), la_min(iset), npgfa(iset), rpgfa(:, iset), zeta(:, iset), &
1251 : lb_max(jset), lb_min(jset), npgfb(jset), rpgfb(:, jset), zetb(:, jset), &
1252 : rij, sab=oint(:, :, 1))
1253 : END IF
1254 : ! Contraction
1255 : CALL contraction(oint(:, :, 1), owork, ca=scon_a(:, sgfa:), na=n1, ma=nsgfa(iset), &
1256 : cb=scon_b(:, sgfb:), nb=n2, mb=nsgfb(jset), fscale=1.0_dp, trans=.FALSE.)
1257 : CALL block_add("IN", owork, nsgfa(iset), nsgfb(jset), sint(:, :, 1), sgfa, sgfb, trans=.FALSE.)
1258 : IF (calculate_forces) THEN
1259 : DO i = 2, 4
1260 : CALL contraction(oint(:, :, i), owork, ca=scon_a(:, sgfa:), na=n1, ma=nsgfa(iset), &
1261 : cb=scon_b(:, sgfb:), nb=n2, mb=nsgfb(jset), fscale=1.0_dp, trans=.FALSE.)
1262 : CALL block_add("IN", owork, nsgfa(iset), nsgfb(jset), sint(:, :, i), sgfa, sgfb, trans=.FALSE.)
1263 : END DO
1264 : END IF
1265 : END DO
1266 : END DO
1267 :
1268 : !$ iatom8 = INT(iatom - 1, int_8)*INT(SIZE(atom_of_kind), int_8) + INT(jatom, int_8)
1269 : !$ hash1 = INT(MOD(iatom8, INT(nlock, int_8)) + 1)
1270 : ! update S matrix
1271 : !$ hash = hash1
1272 : !$ CALL omp_set_lock(locks(hash))
1273 : IF (icol <= irow) THEN
1274 : sblock(:, :) = sblock(:, :) + sint(:, :, 1)
1275 : ELSE
1276 : sblock(:, :) = sblock(:, :) + TRANSPOSE(sint(:, :, 1))
1277 : END IF
1278 : !$ CALL omp_unset_lock(locks(hash))
1279 :
1280 : ! --------- Hamiltonian
1281 : IF (icol == irow .AND. dr < same_atom) THEN
1282 : !get diagonal F matrix from selfenergy
1283 : n1 = tb%calc%bas%ish_at(icol)
1284 : DO iset = 1, nseta
1285 : sgfa = first_sgfa(1, iset)
1286 : hij = tb%selfenergy(n1 + iset)
1287 : DO ia = sgfa, sgfa + nsgfa(iset) - 1
1288 : hint(ia, ia, 1) = hij
1289 : IF (calculate_forces) THEN
1290 : native_cn_icol = native_cn_icol + tb%dsedcn(n1 + iset)*pblock(ia, ia)
1291 : DO jdim = 1, 3
1292 : DO idim = 1, 3
1293 : IF (nimg == 1) THEN
1294 : native_radial_dot(idim, jdim) = native_radial_dot(idim, jdim) + &
1295 : tb%dsedcn(n1 + iset)*tb%dcndL(idim, jdim, icol)*pblock(ia, ia)
1296 : ELSE
1297 : radial_hint(ia, ia, idim, jdim) = radial_hint(ia, ia, idim, jdim) + &
1298 : tb%dsedcn(n1 + iset)*tb%dcndL(idim, jdim, icol)
1299 : END IF
1300 : END DO
1301 : END DO
1302 : END IF
1303 : END DO
1304 : END DO
1305 : ELSE
1306 : !get off-diagonal F matrix
1307 : rr = SQRT(dr/(h0%rad(jkind) + h0%rad(ikind)))
1308 : n1 = tb%calc%bas%ish_at(icol)
1309 : DO iset = 1, nseta
1310 : sgfa = first_sgfa(1, iset)
1311 : n2 = tb%calc%bas%ish_at(irow)
1312 : DO jset = 1, nsetb
1313 : sgfb = first_sgfb(1, jset)
1314 : shpoly = (1.0_dp + h0%shpoly(iset, ikind)*rr) &
1315 : *(1.0_dp + h0%shpoly(jset, jkind)*rr)
1316 : dshpoly = ((1.0_dp + h0%shpoly(iset, ikind)*rr)*h0%shpoly(jset, jkind)*rr &
1317 : + (1.0_dp + h0%shpoly(jset, jkind)*rr)*h0%shpoly(iset, ikind)*rr) &
1318 : *0.5_dp/r2
1319 : hij_base = 0.5_dp*(tb%selfenergy(n1 + iset) + tb%selfenergy(n2 + jset)) &
1320 : *h0%hscale(iset, jset, ikind, jkind)
1321 : hij = hij_base*shpoly
1322 : DO ia = sgfa, sgfa + nsgfa(iset) - 1
1323 : DO ib = sgfb, sgfb + nsgfb(jset) - 1
1324 : hint(ia, ib, 1) = hij*sint(ia, ib, 1)
1325 : IF (calculate_forces) THEN
1326 : native_dot_weight = 2.0_dp
1327 : IF (icol == irow) native_dot_weight = 1.0_dp
1328 : native_cn_icol = native_cn_icol + native_dot_weight*0.5_dp* &
1329 : h0%hscale(iset, jset, ikind, jkind)*shpoly* &
1330 : tb%dsedcn(n1 + iset)*pblock(ib, ia)*sint(ia, ib, 1)
1331 : native_cn_irow = native_cn_irow + native_dot_weight*0.5_dp* &
1332 : h0%hscale(iset, jset, ikind, jkind)*shpoly* &
1333 : tb%dsedcn(n2 + jset)*pblock(ib, ia)*sint(ia, ib, 1)
1334 : native_radial_force = native_radial_force + &
1335 : hij_base*dshpoly*pblock(ib, ia)*sint(ia, ib, 1)*raw_rij
1336 : native_h0_overlap_force = native_h0_overlap_force + &
1337 : hij*pblock(ib, ia)*sint(ia, ib, 2:4)
1338 : DO jdim = 1, 3
1339 : DO idim = 1, 3
1340 : IF (nimg == 1) THEN
1341 : native_radial_dot(idim, jdim) = native_radial_dot(idim, jdim) + &
1342 : native_dot_weight*pblock(ib, ia)*( &
1343 : (-hij)*sint(ia, ib, idim + 1)*rij(jdim) + &
1344 : hij_base*dshpoly*sint(ia, ib, 1)*rij(idim)*rij(jdim) + &
1345 : 0.5_dp*h0%hscale(iset, jset, ikind, jkind)*shpoly*sint(ia, ib, 1)* &
1346 : (tb%dsedcn(n1 + iset)*tb%dcndL(idim, jdim, icol) + &
1347 : tb%dsedcn(n2 + jset)*tb%dcndL(idim, jdim, irow)))
1348 : ELSE
1349 : radial_hint(ia, ib, idim, jdim) = radial_hint(ia, ib, idim, jdim) + &
1350 : (-hij)*sint(ia, ib, idim + 1)*rij(jdim) + &
1351 : hij_base*dshpoly*sint(ia, ib, 1)*rij(idim)*rij(jdim) + &
1352 : 0.5_dp*h0%hscale(iset, jset, ikind, jkind)*shpoly*sint(ia, ib, 1)* &
1353 : (tb%dsedcn(n1 + iset)*tb%dcndL(idim, jdim, icol) + &
1354 : tb%dsedcn(n2 + jset)*tb%dcndL(idim, jdim, irow))
1355 : END IF
1356 : END DO
1357 : END DO
1358 : END IF
1359 : END DO
1360 : END DO
1361 : END DO
1362 : END DO
1363 : END IF
1364 :
1365 : ! update F matrix
1366 : !$ CALL omp_set_lock(locks(hash))
1367 : IF (icol <= irow) THEN
1368 : fblock(:, :) = fblock(:, :) + hint(:, :, 1)
1369 : IF (calculate_forces .AND. nimg > 1) THEN
1370 : DO jdim = 1, 3
1371 : DO idim = 1, 3
1372 : radial_blocks(idim, jdim)%block(:, :) = radial_blocks(idim, jdim)%block(:, :) + &
1373 : radial_hint(:, :, idim, jdim)
1374 : END DO
1375 : END DO
1376 : END IF
1377 : ELSE
1378 : fblock(:, :) = fblock(:, :) + TRANSPOSE(hint(:, :, 1))
1379 : IF (calculate_forces .AND. nimg > 1) THEN
1380 : DO jdim = 1, 3
1381 : DO idim = 1, 3
1382 : radial_blocks(idim, jdim)%block(:, :) = radial_blocks(idim, jdim)%block(:, :) + &
1383 : TRANSPOSE(radial_hint(:, :, idim, jdim))
1384 : END DO
1385 : END DO
1386 : END IF
1387 : END IF
1388 : !$ CALL omp_unset_lock(locks(hash))
1389 :
1390 : IF (calculate_forces) THEN
1391 : ff = 2.0_dp
1392 : !$OMP CRITICAL(tblite_native_radial_force)
1393 : native_radial_force_thread(:, raw_iatom) = &
1394 : native_radial_force_thread(:, raw_iatom) - ff*native_radial_force
1395 : native_radial_force_thread(:, raw_jatom) = &
1396 : native_radial_force_thread(:, raw_jatom) + ff*native_radial_force
1397 : native_radial_force_thread(:, icol) = &
1398 : native_radial_force_thread(:, icol) + ff*native_h0_overlap_force
1399 : native_radial_force_thread(:, irow) = &
1400 : native_radial_force_thread(:, irow) - ff*native_h0_overlap_force
1401 : native_cn_deriv_thread(icol) = native_cn_deriv_thread(icol) + native_cn_icol
1402 : native_cn_deriv_thread(irow) = native_cn_deriv_thread(irow) + native_cn_irow
1403 : !$OMP END CRITICAL(tblite_native_radial_force)
1404 : END IF
1405 :
1406 : DEALLOCATE (sint, hint)
1407 : IF (ALLOCATED(radial_hint)) DEALLOCATE (radial_hint)
1408 :
1409 : END DO
1410 : !$OMP END DO
1411 : DEALLOCATE (oint, owork)
1412 : !$OMP DO
1413 : !$ DO lock_num = 1, nlock
1414 : !$ CALL omp_destroy_lock(locks(lock_num))
1415 : !$ END DO
1416 : !$OMP END DO
1417 : !$OMP SINGLE
1418 : !$ DEALLOCATE (locks)
1419 : !$OMP END SINGLE NOWAIT
1420 : !$OMP END PARALLEL
1421 :
1422 2750 : IF (calculate_forces) THEN
1423 150 : IF (nimg > 1) THEN
1424 90 : native_radial_dot = 0.0_dp
1425 4932 : DO img = 1, nimg
1426 19458 : DO jdim = 1, 3
1427 62946 : DO idim = 1, 3
1428 43578 : CALL dbcsr_finalize(matrix_dh_native(idim + 3*(jdim - 1), img)%matrix)
1429 : CALL dbcsr_dot(matrix_dh_native(idim + 3*(jdim - 1), img)%matrix, &
1430 43578 : matrix_p(1, img)%matrix, native_dot_tmp)
1431 58104 : native_radial_dot(idim, jdim) = native_radial_dot(idim, jdim) + native_dot_tmp
1432 : END DO
1433 : END DO
1434 : END DO
1435 90 : CALL dbcsr_deallocate_matrix_set(matrix_dh_native)
1436 : ELSE
1437 60 : CALL para_env%sum(native_radial_dot)
1438 : END IF
1439 150 : CALL para_env%sum(native_cn_deriv_thread)
1440 3606 : tb%grad = 0.0_dp
1441 150 : CALL tb_add_grad(tb%grad, tb%dcndr, native_cn_deriv_thread, tb%mol%nat)
1442 150 : CALL tb_grad2force(qs_env, tb, para_env, 4)
1443 1014 : DO iatom = 1, SIZE(atom_of_kind)
1444 864 : ikind = kind_of(iatom)
1445 : force(ikind)%overlap(:, atom_of_kind(iatom)) = &
1446 3606 : force(ikind)%overlap(:, atom_of_kind(iatom)) + native_radial_force_thread(:, iatom)
1447 : END DO
1448 150 : IF (tb%use_virial) THEN
1449 1092 : virial%pv_overlap = virial%pv_overlap - native_radial_dot/para_env%num_pe
1450 1092 : virial%pv_virial = virial%pv_virial - native_radial_dot/para_env%num_pe
1451 : END IF
1452 : END IF
1453 :
1454 73724 : DO img = 1, nimg
1455 141948 : DO i = 1, SIZE(matrix_s, 1)
1456 141948 : CALL dbcsr_finalize(matrix_s(i, img)%matrix)
1457 : END DO
1458 144698 : DO i = 1, SIZE(matrix_h, 1)
1459 141948 : CALL dbcsr_finalize(matrix_h(i, img)%matrix)
1460 : END DO
1461 : END DO
1462 :
1463 2750 : IF (calculate_forces) THEN
1464 : CALL build_overlap_matrix(ks_env, matrixkp_s=matrix_s_native, &
1465 : matrix_name="OVERLAP MATRIX", nderivative=nderivatives, &
1466 : basis_type_a="ORB", basis_type_b="ORB", sab_nl=sab_orb, &
1467 150 : calculate_forces=.TRUE., matrixkp_p=matrix_q_native)
1468 150 : CALL dbcsr_deallocate_matrix_set(matrix_s_native)
1469 150 : CALL dbcsr_deallocate_matrix_set(matrix_q_native)
1470 : END IF
1471 :
1472 : !compute multipole moments for gfn2
1473 2750 : IF (dft_control%qs_control%xtb_control%tblite_method == gfn2xtb) THEN
1474 1368 : CALL tb_get_multipole(qs_env, tb)
1475 : END IF
1476 :
1477 : ! output overlap information
1478 2750 : NULLIFY (logger)
1479 2750 : logger => cp_get_default_logger()
1480 2750 : IF (.NOT. calculate_forces) THEN
1481 2600 : IF (cp_print_key_should_output(logger%iter_info, qs_env%input, &
1482 : "DFT%PRINT%OVERLAP_CONDITION") /= 0) THEN
1483 : iw = cp_print_key_unit_nr(logger, qs_env%input, "DFT%PRINT%OVERLAP_CONDITION", &
1484 2 : extension=".Log")
1485 2 : CALL section_vals_val_get(qs_env%input, "DFT%PRINT%OVERLAP_CONDITION%1-NORM", l_val=norml1)
1486 2 : CALL section_vals_val_get(qs_env%input, "DFT%PRINT%OVERLAP_CONDITION%DIAGONALIZATION", l_val=norml2)
1487 2 : CALL section_vals_val_get(qs_env%input, "DFT%PRINT%OVERLAP_CONDITION%ARNOLDI", l_val=use_arnoldi)
1488 2 : CALL get_qs_env(qs_env=qs_env, blacs_env=blacs_env)
1489 2 : CALL overlap_condnum(matrix_s, condnum, iw, norml1, norml2, use_arnoldi, blacs_env)
1490 : END IF
1491 : END IF
1492 :
1493 2750 : DEALLOCATE (basis_set_list)
1494 2750 : IF (ALLOCATED(native_cn_deriv_thread)) DEALLOCATE (native_cn_deriv_thread)
1495 2750 : IF (ALLOCATED(native_radial_force_thread)) DEALLOCATE (native_radial_force_thread)
1496 :
1497 2750 : CALL timestop(handle)
1498 :
1499 : #else
1500 : MARK_USED(qs_env)
1501 : MARK_USED(calculate_forces)
1502 : CPABORT("Built without TBLITE")
1503 : #endif
1504 :
1505 8250 : END SUBROUTINE build_tblite_matrices
1506 :
1507 : ! **************************************************************************************************
1508 : !> \brief ...
1509 : !> \param qs_env ...
1510 : !> \param dft_control ...
1511 : !> \param tb ...
1512 : !> \param calculate_forces ...
1513 : !> \param use_rho ...
1514 : ! **************************************************************************************************
1515 53206 : SUBROUTINE tb_update_charges(qs_env, dft_control, tb, calculate_forces, use_rho)
1516 :
1517 : TYPE(qs_environment_type), POINTER :: qs_env
1518 : TYPE(dft_control_type), POINTER :: dft_control
1519 : TYPE(tblite_type), POINTER :: tb
1520 : LOGICAL, INTENT(IN) :: calculate_forces
1521 : LOGICAL, INTENT(IN) :: use_rho
1522 :
1523 : #if defined(__TBLITE)
1524 :
1525 : INTEGER :: iatom, ikind, is, ns, atom_a, ii, im
1526 : INTEGER :: ispin, nspin
1527 : INTEGER :: nimg, nkind, nsgf, natorb, na, n_mix_cols, mix_offset
1528 : INTEGER :: n_atom, max_orb, max_shell
1529 : INTEGER :: raw_state_status, raw_state_unit
1530 : LOGICAL :: advance_native_mixer, discard_mixed_output, do_combined_mixing, &
1531 : do_dipole, do_quadrupole, native_sign_mixing, &
1532 : skip_charge_mixing, reuse_native_input, skip_scf_dispersion, &
1533 : seed_native_from_rho, use_native_mixer, use_no_mixer
1534 : REAL(KIND=dp) :: native_seed_charge, norm, new_charge, pao
1535 : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
1536 : INTEGER :: debug_status
1537 : CHARACTER(LEN=32) :: debug_value
1538 : #endif
1539 : CHARACTER(LEN=default_path_length) :: raw_state_file
1540 : INTEGER, DIMENSION(5) :: occ
1541 : INTEGER, DIMENSION(25) :: lao
1542 : INTEGER, DIMENSION(25) :: nao
1543 53206 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: ch_atom, ch_shell, ch_ref, ch_orb, mix_vars
1544 53206 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: aocg, ao_dip, ao_quad
1545 53206 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: aocg_spin, ao_dip_spin, ao_quad_spin, &
1546 53206 : ch_orb_spin, ch_shell_spin
1547 :
1548 53206 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1549 53206 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s, matrix_p
1550 53206 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: p_matrix
1551 : TYPE(dbcsr_type), POINTER :: s_matrix
1552 53206 : TYPE(error_type), ALLOCATABLE :: error
1553 : TYPE(mp_para_env_type), POINTER :: para_env
1554 53206 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1555 53206 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1556 : TYPE(qs_rho_type), POINTER :: rho
1557 : TYPE(qs_scf_env_type), POINTER :: scf_env
1558 : TYPE(scf_control_type), POINTER :: scf_control
1559 : TYPE(xtb_atom_type), POINTER :: xtb_kind
1560 :
1561 : ! compute mulliken charges required for charge update
1562 53206 : NULLIFY (particle_set, qs_kind_set, atomic_kind_set, scf_control, scf_env)
1563 : CALL get_qs_env(qs_env=qs_env, scf_env=scf_env, particle_set=particle_set, qs_kind_set=qs_kind_set, &
1564 : atomic_kind_set=atomic_kind_set, matrix_s_kp=matrix_s, rho=rho, para_env=para_env, &
1565 53206 : scf_control=scf_control)
1566 :
1567 : ! also compute multipoles needed by GFN2
1568 53206 : do_dipole = .FALSE.
1569 53206 : do_quadrupole = .FALSE.
1570 53206 : skip_scf_dispersion = .FALSE.
1571 : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
1572 : CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_DEBUG_SKIP_SCF_DISPERSION", debug_value, STATUS=debug_status)
1573 : IF (debug_status == 0) THEN
1574 : READ (debug_value, *, IOSTAT=debug_status) skip_scf_dispersion
1575 : IF (debug_status /= 0) skip_scf_dispersion = .FALSE.
1576 : END IF
1577 : #endif
1578 53206 : IF (dft_control%qs_control%do_ls_scf .OR. scf_control%use_ot) THEN
1579 : use_native_mixer = .FALSE.
1580 : use_no_mixer = .TRUE.
1581 : ELSE
1582 93192 : SELECT CASE (dft_control%qs_control%xtb_control%tblite_scc_mixer)
1583 : CASE (tblite_scc_mixer_auto)
1584 41484 : use_native_mixer = tb_native_scc_mixer_active(dft_control)
1585 41484 : use_no_mixer = .FALSE.
1586 : CASE (tblite_scc_mixer_tblite)
1587 : use_native_mixer = .TRUE.
1588 : use_no_mixer = .FALSE.
1589 : CASE (tblite_scc_mixer_cp2k)
1590 : use_native_mixer = .FALSE.
1591 : use_no_mixer = .FALSE.
1592 : CASE (tblite_scc_mixer_none)
1593 : use_native_mixer = .FALSE.
1594 0 : use_no_mixer = .TRUE.
1595 : CASE DEFAULT
1596 51708 : CPABORT("Unknown tblite SCC mixer")
1597 : END SELECT
1598 : END IF
1599 41484 : IF (use_native_mixer) THEN
1600 47088 : IF (.NOT. ASSOCIATED(scf_env)) CPABORT("tblite SCC mixer requires a QS SCF environment")
1601 47088 : IF (use_rho .AND. (.NOT. calculate_forces)) THEN
1602 24590 : IF (scf_env%iter_count > dft_control%qs_control%xtb_control%tblite_mixer_iterations) THEN
1603 0 : CPABORT("tblite SCC mixer exceeded TBLITE_MIXER/ITERATIONS")
1604 : END IF
1605 24590 : IF (scf_env%iter_count == 1) THEN
1606 : CALL tb_configure_mixer(tb, dft_control%qs_control%xtb_control%tblite_mixer_iterations, &
1607 : dft_control%qs_control%xtb_control%tblite_mixer_memory, &
1608 : dft_control%qs_control%xtb_control%tblite_mixer_damping, &
1609 : dft_control%qs_control%xtb_control%tblite_mixer_omega0, &
1610 : dft_control%qs_control%xtb_control%tblite_mixer_min_weight, &
1611 : dft_control%qs_control%xtb_control%tblite_mixer_max_weight, &
1612 : dft_control%qs_control%xtb_control%tblite_mixer_weight_factor, &
1613 2446 : dft_control%qs_control%xtb_control%tblite_mixer_solver)
1614 2446 : CALL tb_reset_mixer(tb)
1615 : END IF
1616 : END IF
1617 : END IF
1618 53206 : nspin = dft_control%nspins
1619 53206 : IF (nspin /= tb%wfn%nspin) CPABORT("CP2K/tblite spin channel mismatch")
1620 :
1621 53206 : NULLIFY (matrix_p)
1622 53206 : IF (use_rho) THEN
1623 28588 : CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
1624 24618 : ELSE IF (calculate_forces .AND. nspin > 1) THEN
1625 22 : IF (.NOT. ASSOCIATED(tb%rho_ao_kp_ref)) THEN
1626 0 : CPABORT("Missing converged tblite density for UKS/LSD forces")
1627 : END IF
1628 22 : matrix_p => tb%rho_ao_kp_ref
1629 : ELSE
1630 24596 : matrix_p => scf_env%p_mix_new
1631 : END IF
1632 53206 : IF (nspin > 1 .AND. (.NOT. calculate_forces)) CALL tb_store_density_ref(tb, matrix_p)
1633 53206 : IF (ASSOCIATED(tb%dipbra)) do_dipole = .TRUE.
1634 53206 : IF (ASSOCIATED(tb%quadbra)) do_quadrupole = .TRUE.
1635 53206 : reuse_native_input = .FALSE.
1636 53206 : IF (use_native_mixer) THEN
1637 47088 : IF (scf_env%iter_count == 1) THEN
1638 8534 : reuse_native_input = ANY(ABS(tb%wfn%qsh) > 1.0E-14_dp)
1639 4892 : IF (do_dipole) reuse_native_input = reuse_native_input .OR. &
1640 5920 : ANY(ABS(tb%wfn%dpat) > 1.0E-14_dp)
1641 4892 : IF (do_quadrupole) reuse_native_input = reuse_native_input .OR. &
1642 8506 : ANY(ABS(tb%wfn%qpat) > 1.0E-14_dp)
1643 : END IF
1644 : END IF
1645 53206 : n_atom = SIZE(particle_set)
1646 53206 : nkind = SIZE(atomic_kind_set)
1647 53206 : nimg = dft_control%nimages
1648 53206 : CALL get_qs_kind_set(qs_kind_set, maxsgf=nsgf)
1649 212824 : ALLOCATE (aocg(nsgf, n_atom))
1650 266030 : ALLOCATE (aocg_spin(nsgf, n_atom, nspin))
1651 53206 : aocg = 0.0_dp
1652 53206 : aocg_spin = 0.0_dp
1653 53206 : IF (do_dipole) THEN
1654 110712 : ALLOCATE (ao_dip(n_atom, dip_n))
1655 147616 : ALLOCATE (ao_dip_spin(n_atom, dip_n, nspin))
1656 36904 : ao_dip_spin = 0.0_dp
1657 : END IF
1658 53206 : IF (do_quadrupole) THEN
1659 110712 : ALLOCATE (ao_quad(n_atom, quad_n))
1660 147616 : ALLOCATE (ao_quad_spin(n_atom, quad_n, nspin))
1661 36904 : ao_quad_spin = 0.0_dp
1662 : END IF
1663 53206 : max_orb = 0
1664 53206 : max_shell = 0
1665 134490 : DO ikind = 1, nkind
1666 81284 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_kind)
1667 81284 : CALL get_xtb_atom_param(xtb_kind, natorb=natorb)
1668 134490 : max_orb = MAX(max_orb, natorb)
1669 : END DO
1670 308658 : DO is = 1, n_atom
1671 308658 : max_shell = MAX(max_shell, tb%calc%bas%nsh_at(is))
1672 : END DO
1673 372442 : ALLOCATE (ch_atom(n_atom, nspin), ch_shell(n_atom, max_shell))
1674 319236 : ALLOCATE (ch_orb(max_orb, n_atom), ch_ref(max_orb, n_atom))
1675 478854 : ALLOCATE (ch_orb_spin(max_orb, n_atom, nspin), ch_shell_spin(n_atom, max_shell, nspin))
1676 53206 : ch_atom = 0.0_dp
1677 53206 : ch_shell = 0.0_dp
1678 53206 : ch_orb = 0.0_dp
1679 53206 : ch_orb_spin = 0.0_dp
1680 53206 : ch_shell_spin = 0.0_dp
1681 53206 : ch_ref = 0.0_dp
1682 53206 : IF (nimg > 1) THEN
1683 50438 : DO ispin = 1, nspin
1684 25636 : CALL tb_ao_charges_kp_spin(matrix_p, matrix_s, aocg_spin(:, :, ispin), ispin, para_env)
1685 25636 : IF (do_dipole) THEN
1686 72184 : DO im = 1, dip_n
1687 : CALL tb_contract_dens_kp_spin(matrix_p, tb%dipbra, tb%dipket, im, dip_n, &
1688 72184 : ao_dip_spin(:, im, ispin), ispin, para_env)
1689 : END DO
1690 : END IF
1691 50438 : IF (do_quadrupole) THEN
1692 126322 : DO im = 1, quad_n
1693 : CALL tb_contract_dens_kp_spin(matrix_p, tb%quadbra, tb%quadket, im, quad_n, &
1694 126322 : ao_quad_spin(:, im, ispin), ispin, para_env)
1695 : END DO
1696 : END IF
1697 : END DO
1698 : ELSE
1699 : NULLIFY (p_matrix, s_matrix)
1700 28404 : p_matrix => matrix_p(:, 1)
1701 28404 : s_matrix => matrix_s(1, 1)%matrix
1702 61436 : DO ispin = 1, nspin
1703 33032 : CALL tb_ao_charges_matrix(matrix_p(ispin, 1)%matrix, s_matrix, aocg_spin(:, :, ispin), para_env)
1704 33032 : IF (do_dipole) THEN
1705 92472 : DO im = 1, dip_n
1706 : CALL tb_contract_dens_matrix(matrix_p(ispin, 1)%matrix, tb%dipbra(im)%matrix, &
1707 92472 : tb%dipket(im)%matrix, ao_dip_spin(:, im, ispin), para_env)
1708 : END DO
1709 : END IF
1710 61436 : IF (do_quadrupole) THEN
1711 161826 : DO im = 1, quad_n
1712 : CALL tb_contract_dens_matrix(matrix_p(ispin, 1)%matrix, tb%quadbra(im)%matrix, &
1713 161826 : tb%quadket(im)%matrix, ao_quad_spin(:, im, ispin), para_env)
1714 : END DO
1715 : END IF
1716 : END DO
1717 : END IF
1718 53206 : IF (nspin == 1) THEN
1719 2200922 : aocg(:, :) = aocg_spin(:, :, 1)
1720 632792 : IF (do_dipole) ao_dip(:, :) = ao_dip_spin(:, :, 1)
1721 1217840 : IF (do_quadrupole) ao_quad(:, :) = ao_quad_spin(:, :, 1)
1722 : ELSE
1723 79598 : aocg(:, :) = aocg_spin(:, :, 1) + aocg_spin(:, :, 2)
1724 5462 : IF (do_dipole) THEN
1725 17040 : DO im = 1, dip_n
1726 49212 : DO iatom = 1, n_atom
1727 32172 : pao = ao_dip_spin(iatom, im, 1)
1728 32172 : ao_dip_spin(iatom, im, 1) = pao + ao_dip_spin(iatom, im, 2)
1729 44952 : ao_dip_spin(iatom, im, 2) = pao - ao_dip_spin(iatom, im, 2)
1730 : END DO
1731 : END DO
1732 49212 : ao_dip(:, :) = ao_dip_spin(:, :, 1)
1733 : END IF
1734 5462 : IF (do_quadrupole) THEN
1735 29820 : DO im = 1, quad_n
1736 94164 : DO iatom = 1, n_atom
1737 64344 : pao = ao_quad_spin(iatom, im, 1)
1738 64344 : ao_quad_spin(iatom, im, 1) = pao + ao_quad_spin(iatom, im, 2)
1739 89904 : ao_quad_spin(iatom, im, 2) = pao - ao_quad_spin(iatom, im, 2)
1740 : END DO
1741 : END DO
1742 94164 : ao_quad(:, :) = ao_quad_spin(:, :, 1)
1743 : END IF
1744 : END IF
1745 53206 : NULLIFY (xtb_kind)
1746 134490 : DO ikind = 1, nkind
1747 81284 : CALL get_atomic_kind(atomic_kind_set(ikind), natom=na)
1748 81284 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_kind)
1749 81284 : CALL get_xtb_atom_param(xtb_kind, natorb=natorb, lao=lao, nao=nao, occupation=occ)
1750 471226 : DO iatom = 1, na
1751 255452 : atom_a = atomic_kind_set(ikind)%atom_list(iatom)
1752 2093796 : DO is = 1, natorb
1753 1838344 : ns = lao(is) + 1
1754 1838344 : norm = 2*lao(is) + 1
1755 1838344 : ch_ref(is, atom_a) = tb%calc%h0%refocc(nao(is), ikind)/norm
1756 1838344 : ch_orb(is, atom_a) = aocg(is, atom_a) - ch_ref(is, atom_a)
1757 1838344 : ch_orb_spin(is, atom_a, 1) = ch_orb(is, atom_a)
1758 1838344 : IF (nspin == 2) ch_orb_spin(is, atom_a, 2) = &
1759 49536 : aocg_spin(is, atom_a, 1) - aocg_spin(is, atom_a, 2)
1760 1838344 : ch_shell(atom_a, ns) = ch_orb(is, atom_a) + ch_shell(atom_a, ns)
1761 3981676 : DO ispin = 1, nspin
1762 : ch_shell_spin(atom_a, ns, ispin) = ch_orb_spin(is, atom_a, ispin) + &
1763 3726224 : ch_shell_spin(atom_a, ns, ispin)
1764 : END DO
1765 : END DO
1766 606936 : DO ispin = 1, nspin
1767 2556902 : ch_atom(atom_a, ispin) = SUM(ch_orb_spin(:, atom_a, ispin))
1768 : END DO
1769 : END DO
1770 : END DO
1771 308658 : native_seed_charge = -SUM(ch_atom(:, 1))
1772 : seed_native_from_rho = SUM(ABS(aocg_spin)) > 1.0E-10_dp .AND. &
1773 2413324 : ABS(native_seed_charge - REAL(dft_control%charge, dp)) < 1.0E-5_dp
1774 53206 : DEALLOCATE (aocg, aocg_spin)
1775 :
1776 53206 : raw_state_status = 1
1777 : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
1778 : CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_RAW_STATE_DUMP", raw_state_file, STATUS=raw_state_status)
1779 : #endif
1780 : IF (raw_state_status == 0) THEN
1781 : OPEN (NEWUNIT=raw_state_unit, FILE=TRIM(raw_state_file), STATUS="REPLACE", ACTION="WRITE")
1782 : WRITE (raw_state_unit, *) "qat"
1783 : DO iatom = 1, n_atom
1784 : WRITE (raw_state_unit, "(I0,1X,ES24.16)") iatom, -ch_atom(iatom, 1)
1785 : END DO
1786 : WRITE (raw_state_unit, *) "qsh"
1787 : DO iatom = 1, n_atom
1788 : DO is = 1, tb%calc%bas%nsh_at(iatom)
1789 : WRITE (raw_state_unit, "(I0,1X,ES24.16)") tb%calc%bas%ish_at(iatom) + is, -ch_shell(iatom, is)
1790 : END DO
1791 : END DO
1792 : IF (do_dipole) THEN
1793 : WRITE (raw_state_unit, *) "dpat"
1794 : DO iatom = 1, n_atom
1795 : WRITE (raw_state_unit, "(I0,3(1X,ES24.16))") iatom, -ao_dip(iatom, :)
1796 : END DO
1797 : END IF
1798 : IF (do_quadrupole) THEN
1799 : WRITE (raw_state_unit, *) "qpat"
1800 : DO iatom = 1, n_atom
1801 : WRITE (raw_state_unit, "(I0,6(1X,ES24.16))") iatom, -ao_quad(iatom, :)
1802 : END DO
1803 : END IF
1804 : CLOSE (raw_state_unit)
1805 : END IF
1806 :
1807 53206 : IF (use_native_mixer) THEN
1808 47088 : IF (.NOT. ALLOCATED(tb%mixer)) CPABORT("tblite mixer not initialized")
1809 47088 : advance_native_mixer = .FALSE.
1810 47088 : IF (use_rho .AND. (.NOT. calculate_forces)) THEN
1811 24590 : advance_native_mixer = scf_env%iter_count > 1
1812 : END IF
1813 24590 : IF (advance_native_mixer) THEN
1814 22144 : CALL tb%mixer%next(error)
1815 22144 : IF (ALLOCATED(error)) CPABORT("tblite native mixer failed")
1816 22144 : CALL tb%mixer%get(tb%wfn%qsh)
1817 161292 : tb%wfn%qat(:, :) = 0.0_dp
1818 132052 : DO iatom = 1, n_atom
1819 109908 : ii = tb%calc%bas%ish_at(iatom)
1820 247292 : DO ispin = 1, nspin
1821 : tb%wfn%qat(iatom, ispin) = &
1822 530706 : SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
1823 : END DO
1824 : END DO
1825 22144 : IF (do_dipole) THEN
1826 15124 : CALL tb%mixer%get(tb%wfn%dpat)
1827 15124 : DEALLOCATE (ao_dip)
1828 : END IF
1829 22144 : IF (do_quadrupole) THEN
1830 15124 : CALL tb%mixer%get(tb%wfn%qpat)
1831 15124 : DEALLOCATE (ao_quad)
1832 : END IF
1833 : ELSE
1834 24944 : IF (use_rho .AND. (.NOT. calculate_forces)) THEN
1835 2446 : IF (.NOT. reuse_native_input) THEN
1836 152 : IF (seed_native_from_rho) THEN
1837 : ! Seed the native tblite mixer from CP2K's current density so SCF_GUESS/RESTART
1838 : ! controls the initial SCC state.
1839 904 : DO iatom = 1, n_atom
1840 766 : ii = tb%calc%bas%ish_at(iatom)
1841 1710 : DO ispin = 1, nspin
1842 2640 : DO is = 1, tb%calc%bas%nsh_at(iatom)
1843 2640 : tb%wfn%qsh(ii + is, ispin) = -ch_shell_spin(iatom, is, ispin)
1844 : END DO
1845 : tb%wfn%qat(iatom, ispin) = &
1846 3406 : SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
1847 : END DO
1848 : END DO
1849 138 : IF (do_dipole) THEN
1850 420 : DO iatom = 1, n_atom
1851 802 : DO ispin = 1, nspin
1852 1886 : tb%wfn%dpat(:, iatom, ispin) = -ao_dip_spin(iatom, :, ispin)
1853 : END DO
1854 : END DO
1855 : END IF
1856 138 : IF (do_quadrupole) THEN
1857 420 : DO iatom = 1, n_atom
1858 802 : DO ispin = 1, nspin
1859 3032 : tb%wfn%qpat(:, iatom, ispin) = -ao_quad_spin(iatom, :, ispin)
1860 : END DO
1861 : END DO
1862 : END IF
1863 : ELSE
1864 242 : tb%wfn%qsh(:, :) = 0.0_dp
1865 102 : tb%wfn%qat(:, :) = 0.0_dp
1866 256 : IF (do_dipole) tb%wfn%dpat(:, :, :) = 0.0_dp
1867 430 : IF (do_quadrupole) tb%wfn%qpat(:, :, :) = 0.0_dp
1868 : END IF
1869 : END IF
1870 2446 : IF (do_dipole) DEALLOCATE (ao_dip)
1871 2446 : IF (do_quadrupole) DEALLOCATE (ao_quad)
1872 : ELSE
1873 22498 : IF ((.NOT. use_rho) .AND. (.NOT. calculate_forces)) THEN
1874 22358 : CALL tb%mixer%set(tb%wfn%qsh)
1875 22358 : IF (do_dipole) CALL tb%mixer%set(tb%wfn%dpat)
1876 22358 : IF (do_quadrupole) CALL tb%mixer%set(tb%wfn%qpat)
1877 : END IF
1878 134572 : DO iatom = 1, n_atom
1879 112074 : ii = tb%calc%bas%ish_at(iatom)
1880 252062 : DO ispin = 1, nspin
1881 428174 : DO is = 1, tb%calc%bas%nsh_at(iatom)
1882 428174 : tb%wfn%qsh(ii + is, ispin) = -ch_shell_spin(iatom, is, ispin)
1883 : END DO
1884 : tb%wfn%qat(iatom, ispin) = &
1885 540248 : SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
1886 : END DO
1887 : END DO
1888 22498 : IF (do_dipole) THEN
1889 91296 : DO iatom = 1, n_atom
1890 170862 : DO ispin = 1, nspin
1891 394290 : tb%wfn%dpat(:, iatom, ispin) = -ao_dip_spin(iatom, :, ispin)
1892 : END DO
1893 : END DO
1894 15270 : DEALLOCATE (ao_dip)
1895 : END IF
1896 22498 : IF (do_quadrupole) THEN
1897 91296 : DO iatom = 1, n_atom
1898 170862 : DO ispin = 1, nspin
1899 632988 : tb%wfn%qpat(:, iatom, ispin) = -ao_quad_spin(iatom, :, ispin)
1900 : END DO
1901 : END DO
1902 15270 : DEALLOCATE (ao_quad)
1903 : END IF
1904 22498 : IF ((.NOT. use_rho) .AND. (.NOT. calculate_forces)) THEN
1905 22358 : CALL tb%mixer%diff(tb%wfn%qsh)
1906 22358 : IF (do_dipole) CALL tb%mixer%diff(tb%wfn%dpat)
1907 22358 : IF (do_quadrupole) CALL tb%mixer%diff(tb%wfn%qpat)
1908 : END IF
1909 : END IF
1910 : END IF
1911 : ELSE
1912 : ! charge mixing
1913 6118 : native_sign_mixing = .FALSE.
1914 6118 : IF (.NOT. (dft_control%qs_control%do_ls_scf .OR. scf_control%use_ot)) THEN
1915 4620 : IF (.NOT. ASSOCIATED(scf_env)) CPABORT("CP2K SCC mixer requires a QS SCF environment")
1916 4620 : IF (.NOT. (do_dipole .OR. do_quadrupole) .AND. &
1917 : scf_env%mixing_method == modified_broyden_mixing_nr) THEN
1918 0 : CPABORT("MODIFIED_BROYDEN_MIXING with SCC_MIXER CP2K requires GFN2")
1919 : END IF
1920 : END IF
1921 6118 : IF (dft_control%qs_control%do_ls_scf .OR. scf_control%use_ot) THEN
1922 : ! LS_SCF and OT optimize the electronic variables directly. Use the
1923 : ! current shell/multipole response from that density without an
1924 : ! extra SCC variable mixing step.
1925 4620 : ELSE IF (nspin > 1) THEN
1926 1570 : n_mix_cols = nspin*max_shell
1927 1570 : IF (do_dipole) n_mix_cols = n_mix_cols + nspin*dip_n
1928 1570 : IF (do_quadrupole) n_mix_cols = n_mix_cols + nspin*quad_n
1929 6280 : ALLOCATE (mix_vars(n_atom, n_mix_cols))
1930 1570 : mix_vars = 0.0_dp
1931 :
1932 1570 : mix_offset = 0
1933 4710 : DO ispin = 1, nspin
1934 : mix_vars(:, mix_offset + 1:mix_offset + max_shell) = &
1935 21980 : -ch_shell_spin(:, 1:max_shell, ispin)
1936 4710 : mix_offset = mix_offset + max_shell
1937 : END DO
1938 1570 : IF (do_dipole) THEN
1939 4710 : DO ispin = 1, nspin
1940 : mix_vars(:, mix_offset + 1:mix_offset + dip_n) = &
1941 31400 : -ao_dip_spin(:, 1:dip_n, ispin)
1942 4710 : mix_offset = mix_offset + dip_n
1943 : END DO
1944 : END IF
1945 1570 : IF (do_quadrupole) THEN
1946 4710 : DO ispin = 1, nspin
1947 : mix_vars(:, mix_offset + 1:mix_offset + quad_n) = &
1948 59660 : -ao_quad_spin(:, 1:quad_n, ispin)
1949 4710 : mix_offset = mix_offset + quad_n
1950 : END DO
1951 : END IF
1952 :
1953 1570 : IF (.NOT. use_no_mixer) THEN
1954 : CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
1955 1570 : mix_vars, para_env, scf_env%iter_count)
1956 : END IF
1957 :
1958 1570 : mix_offset = 0
1959 4710 : DO ispin = 1, nspin
1960 : ch_shell_spin(:, 1:max_shell, ispin) = &
1961 21980 : -mix_vars(:, mix_offset + 1:mix_offset + max_shell)
1962 4710 : mix_offset = mix_offset + max_shell
1963 : END DO
1964 10990 : ch_shell(:, 1:max_shell) = ch_shell_spin(:, 1:max_shell, 1)
1965 1570 : IF (do_dipole) THEN
1966 4710 : DO ispin = 1, nspin
1967 : ao_dip_spin(:, 1:dip_n, ispin) = &
1968 31400 : -mix_vars(:, mix_offset + 1:mix_offset + dip_n)
1969 4710 : mix_offset = mix_offset + dip_n
1970 : END DO
1971 15700 : ao_dip(:, 1:dip_n) = ao_dip_spin(:, 1:dip_n, 1)
1972 : END IF
1973 1570 : IF (do_quadrupole) THEN
1974 4710 : DO ispin = 1, nspin
1975 : ao_quad_spin(:, 1:quad_n, ispin) = &
1976 59660 : -mix_vars(:, mix_offset + 1:mix_offset + quad_n)
1977 4710 : mix_offset = mix_offset + quad_n
1978 : END DO
1979 29830 : ao_quad(:, 1:quad_n) = ao_quad_spin(:, 1:quad_n, 1)
1980 : END IF
1981 1570 : DEALLOCATE (mix_vars)
1982 : ELSE
1983 3050 : do_combined_mixing = do_dipole .OR. do_quadrupole
1984 3050 : native_sign_mixing = do_dipole .OR. do_quadrupole
1985 3050 : discard_mixed_output = .FALSE.
1986 3050 : skip_charge_mixing = use_no_mixer
1987 3050 : IF (skip_charge_mixing) THEN
1988 : !
1989 3050 : ELSE IF (do_combined_mixing) THEN
1990 3050 : n_mix_cols = max_shell
1991 3050 : IF (do_dipole) n_mix_cols = n_mix_cols + dip_n
1992 3050 : IF (do_quadrupole) n_mix_cols = n_mix_cols + quad_n
1993 12200 : ALLOCATE (mix_vars(n_atom, n_mix_cols))
1994 : IF (native_sign_mixing) THEN
1995 27006 : mix_vars(:, 1:max_shell) = -ch_shell(:, 1:max_shell)
1996 : ELSE
1997 : mix_vars(:, 1:max_shell) = ch_shell(:, 1:max_shell)
1998 : END IF
1999 3050 : mix_offset = max_shell
2000 3050 : IF (do_dipole) THEN
2001 : IF (native_sign_mixing) THEN
2002 38984 : mix_vars(:, mix_offset + 1:mix_offset + dip_n) = -ao_dip(:, 1:dip_n)
2003 : ELSE
2004 : mix_vars(:, mix_offset + 1:mix_offset + dip_n) = ao_dip(:, 1:dip_n)
2005 : END IF
2006 : mix_offset = mix_offset + dip_n
2007 : END IF
2008 3050 : IF (do_quadrupole) THEN
2009 : IF (native_sign_mixing) THEN
2010 74918 : mix_vars(:, mix_offset + 1:mix_offset + quad_n) = -ao_quad(:, 1:quad_n)
2011 : ELSE
2012 : mix_vars(:, mix_offset + 1:mix_offset + quad_n) = ao_quad(:, 1:quad_n)
2013 : END IF
2014 : END IF
2015 : CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
2016 3050 : mix_vars, para_env, scf_env%iter_count)
2017 : IF (.NOT. discard_mixed_output) THEN
2018 : IF (native_sign_mixing) THEN
2019 27006 : ch_shell(:, 1:max_shell) = -mix_vars(:, 1:max_shell)
2020 : ELSE
2021 : ch_shell(:, 1:max_shell) = mix_vars(:, 1:max_shell)
2022 : END IF
2023 3050 : mix_offset = max_shell
2024 3050 : IF (do_dipole) THEN
2025 : IF (native_sign_mixing) THEN
2026 38984 : ao_dip(:, 1:dip_n) = -mix_vars(:, mix_offset + 1:mix_offset + dip_n)
2027 : ELSE
2028 : ao_dip(:, 1:dip_n) = mix_vars(:, mix_offset + 1:mix_offset + dip_n)
2029 : END IF
2030 : mix_offset = mix_offset + dip_n
2031 : END IF
2032 3050 : IF (do_quadrupole) THEN
2033 : IF (native_sign_mixing) THEN
2034 74918 : ao_quad(:, 1:quad_n) = -mix_vars(:, mix_offset + 1:mix_offset + quad_n)
2035 : ELSE
2036 : ao_quad(:, 1:quad_n) = mix_vars(:, mix_offset + 1:mix_offset + quad_n)
2037 : END IF
2038 : END IF
2039 : END IF
2040 3050 : DEALLOCATE (mix_vars)
2041 : ELSE
2042 : CALL charge_mixing(scf_env%mixing_method, scf_env%mixing_store, &
2043 0 : ch_shell, para_env, scf_env%iter_count)
2044 : END IF
2045 : END IF
2046 :
2047 : !setting new wave function
2048 6118 : CALL tb%pot%reset
2049 28760 : tb%e_es = 0.0_dp
2050 28760 : tb%e_scd = 0.0_dp
2051 6118 : IF (nspin > 1) THEN
2052 4884 : DO iatom = 1, n_atom
2053 3256 : ii = tb%calc%bas%ish_at(iatom)
2054 11396 : DO ispin = 1, nspin
2055 19536 : DO is = 1, tb%calc%bas%nsh_at(iatom)
2056 19536 : tb%wfn%qsh(ii + is, ispin) = -ch_shell_spin(iatom, is, ispin)
2057 : END DO
2058 : tb%wfn%qat(iatom, ispin) = &
2059 22792 : SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), ispin))
2060 : END DO
2061 : END DO
2062 1628 : IF (do_dipole) THEN
2063 4884 : DO iatom = 1, n_atom
2064 11396 : DO ispin = 1, nspin
2065 29304 : tb%wfn%dpat(:, iatom, ispin) = -ao_dip_spin(iatom, :, ispin)
2066 : END DO
2067 : END DO
2068 1628 : DEALLOCATE (ao_dip)
2069 : END IF
2070 1628 : IF (do_quadrupole) THEN
2071 4884 : DO iatom = 1, n_atom
2072 11396 : DO ispin = 1, nspin
2073 48840 : tb%wfn%qpat(:, iatom, ispin) = -ao_quad_spin(iatom, :, ispin)
2074 : END DO
2075 : END DO
2076 1628 : DEALLOCATE (ao_quad)
2077 : END IF
2078 : ELSE
2079 23876 : DO iatom = 1, n_atom
2080 19386 : ii = tb%calc%bas%ish_at(iatom)
2081 65512 : DO is = 1, tb%calc%bas%nsh_at(iatom)
2082 46126 : new_charge = -ch_shell(iatom, is)
2083 65512 : tb%wfn%qsh(ii + is, 1) = new_charge
2084 : END DO
2085 23876 : IF (native_sign_mixing) THEN
2086 23956 : tb%wfn%qat(iatom, 1) = SUM(tb%wfn%qsh(ii + 1:ii + tb%calc%bas%nsh_at(iatom), 1))
2087 : ELSE
2088 10458 : tb%wfn%qat(iatom, 1) = -ch_atom(iatom, 1)
2089 : END IF
2090 : END DO
2091 :
2092 4490 : IF (do_dipole) THEN
2093 17244 : DO iatom = 1, n_atom
2094 57768 : DO im = 1, dip_n
2095 54032 : tb%wfn%dpat(im, iatom, 1) = -ao_dip(iatom, im)
2096 : END DO
2097 : END DO
2098 3736 : DEALLOCATE (ao_dip)
2099 : END IF
2100 4490 : IF (do_quadrupole) THEN
2101 17244 : DO iatom = 1, n_atom
2102 98292 : DO im = 1, quad_n
2103 94556 : tb%wfn%qpat(im, iatom, 1) = -ao_quad(iatom, im)
2104 : END DO
2105 : END DO
2106 3736 : DEALLOCATE (ao_quad)
2107 : END IF
2108 : END IF
2109 : END IF
2110 :
2111 53206 : CALL tb%pot%reset
2112 308658 : tb%e_es = 0.0_dp
2113 308658 : tb%e_scd = 0.0_dp
2114 308658 : tb%e_int = 0.0_dp
2115 53206 : IF (ALLOCATED(tb%calc%coulomb)) THEN
2116 53206 : CALL tb%calc%coulomb%get_potential(tb%mol, tb%cache, tb%wfn, tb%pot)
2117 53206 : CALL tb%calc%coulomb%get_energy(tb%mol, tb%cache, tb%wfn, tb%e_es)
2118 : END IF
2119 53206 : IF (ALLOCATED(tb%calc%dispersion)) THEN
2120 : IF (.NOT. skip_scf_dispersion) THEN
2121 53206 : CALL tb%calc%dispersion%get_potential(tb%mol, tb%dcache, tb%wfn, tb%pot)
2122 53206 : CALL tb%calc%dispersion%get_energy(tb%mol, tb%dcache, tb%wfn, tb%e_scd)
2123 : END IF
2124 : END IF
2125 53206 : IF (ALLOCATED(tb%calc%interactions)) THEN
2126 5462 : CALL tb%calc%interactions%get_potential(tb%mol, tb%icache, tb%wfn, tb%pot)
2127 5462 : CALL tb%calc%interactions%get_energy(tb%mol, tb%icache, tb%wfn, tb%e_int)
2128 : END IF
2129 :
2130 53206 : IF (calculate_forces) THEN
2131 150 : IF (ALLOCATED(tb%calc%coulomb)) THEN
2132 3606 : tb%grad = 0.0_dp
2133 150 : CALL tb%calc%coulomb%get_gradient(tb%mol, tb%cache, tb%wfn, tb%grad, tb%sigma)
2134 150 : CALL tb_dump_sigma_component("after_coulomb", tb%sigma, para_env)
2135 150 : CALL tb_grad2force(qs_env, tb, para_env, 3)
2136 : END IF
2137 :
2138 150 : IF (ALLOCATED(tb%calc%dispersion) .AND. .NOT. skip_scf_dispersion) THEN
2139 3606 : tb%grad = 0.0_dp
2140 150 : CALL tb%calc%dispersion%get_gradient(tb%mol, tb%dcache, tb%wfn, tb%grad, tb%sigma)
2141 150 : CALL tb_dump_sigma_component("after_dispersion_scf", tb%sigma, para_env)
2142 150 : CALL tb_grad2force(qs_env, tb, para_env, 2)
2143 : END IF
2144 :
2145 150 : IF (ALLOCATED(tb%calc%interactions)) THEN
2146 230 : tb%grad = 0.0_dp
2147 22 : CALL tb%calc%interactions%get_gradient(tb%mol, tb%icache, tb%wfn, tb%grad, tb%sigma)
2148 22 : CALL tb_dump_sigma_component("after_interactions_scf", tb%sigma, para_env)
2149 22 : CALL tb_grad2force(qs_env, tb, para_env, 3)
2150 : END IF
2151 : END IF
2152 :
2153 53206 : IF (ALLOCATED(ao_dip_spin)) DEALLOCATE (ao_dip_spin)
2154 53206 : IF (ALLOCATED(ao_quad_spin)) DEALLOCATE (ao_quad_spin)
2155 53206 : DEALLOCATE (ch_atom, ch_shell, ch_orb, ch_ref, ch_orb_spin, ch_shell_spin)
2156 :
2157 : #else
2158 : MARK_USED(qs_env)
2159 : MARK_USED(tb)
2160 : MARK_USED(dft_control)
2161 : MARK_USED(calculate_forces)
2162 : MARK_USED(use_rho)
2163 : CPABORT("Built without TBLITE")
2164 : #endif
2165 :
2166 159618 : END SUBROUTINE tb_update_charges
2167 :
2168 : ! **************************************************************************************************
2169 : !> \brief ...
2170 : !> \param qs_env ...
2171 : !> \param tb ...
2172 : !> \param dft_control ...
2173 : ! **************************************************************************************************
2174 27902 : SUBROUTINE tb_ham_add_coulomb(qs_env, tb, dft_control)
2175 :
2176 : TYPE(qs_environment_type), POINTER :: qs_env
2177 : TYPE(tblite_type), POINTER :: tb
2178 : TYPE(dft_control_type), POINTER :: dft_control
2179 :
2180 : #if defined(__TBLITE)
2181 :
2182 : INTEGER :: ikind, jkind, iatom, jatom, icol, irow
2183 : INTEGER :: ic, id1, id2, id3, iq1, iq2, iq3, iq4, iq5, iq6, &
2184 : is, nimg, ni, nj, i, j, nspin
2185 : INTEGER :: la, lb, za, zb
2186 : LOGICAL :: found
2187 : INTEGER, DIMENSION(3) :: cellind
2188 : INTEGER, DIMENSION(25) :: naoa, naob
2189 : REAL(KIND=dp), DIMENSION(3) :: rij
2190 : REAL(KIND=dp) :: mpfac
2191 : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
2192 : INTEGER :: debug_status
2193 : CHARACTER(LEN=32) :: debug_value
2194 : #endif
2195 27902 : INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of, sum_shell
2196 27902 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: ashift, bshift
2197 27902 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: ksblock, sblock
2198 27902 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
2199 27902 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: dip_ket1, dip_ket2, dip_ket3, &
2200 27902 : dip_bra1, dip_bra2, dip_bra3
2201 27902 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: quad_ket1, quad_ket2, quad_ket3, &
2202 27902 : quad_ket4, quad_ket5, quad_ket6, &
2203 27902 : quad_bra1, quad_bra2, quad_bra3, &
2204 27902 : quad_bra4, quad_bra5, quad_bra6
2205 :
2206 27902 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2207 : TYPE(dbcsr_iterator_type) :: iter
2208 27902 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s
2209 27902 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: ks_matrix
2210 : TYPE(kpoint_type), POINTER :: kpoints
2211 : TYPE(neighbor_list_iterator_p_type), &
2212 27902 : DIMENSION(:), POINTER :: nl_iterator
2213 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2214 27902 : POINTER :: n_list
2215 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2216 27902 : POINTER :: kp_list
2217 27902 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2218 : TYPE(xtb_atom_type), POINTER :: xtb_atom_a, xtb_atom_b
2219 :
2220 27902 : nimg = dft_control%nimages
2221 27902 : mpfac = -0.5_dp
2222 :
2223 27902 : NULLIFY (matrix_s, ks_matrix, n_list, kp_list, qs_kind_set)
2224 : CALL get_qs_env(qs_env=qs_env, sab_orb=n_list, sab_kp=kp_list, &
2225 27902 : matrix_s_kp=matrix_s, matrix_ks_kp=ks_matrix, qs_kind_set=qs_kind_set)
2226 27902 : IF (nimg > 1) THEN
2227 12982 : IF (.NOT. ASSOCIATED(kp_list)) CPABORT("Missing k-point neighbor list for tblite Hamiltonian")
2228 12982 : n_list => kp_list
2229 : END IF
2230 27902 : nspin = SIZE(ks_matrix, 1)
2231 :
2232 : !creating sum of shell lists
2233 83706 : ALLOCATE (sum_shell(tb%mol%nat))
2234 161094 : i = 0
2235 161094 : DO j = 1, tb%mol%nat
2236 133192 : sum_shell(j) = i
2237 161094 : i = i + tb%calc%bas%nsh_at(j)
2238 : END DO
2239 :
2240 27902 : IF (nimg == 1) THEN
2241 : ! no k-points; all matrices have been transformed to periodic bsf
2242 14920 : CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set)
2243 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
2244 14920 : kind_of=kind_of)
2245 14920 : CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
2246 157152 : DO WHILE (dbcsr_iterator_blocks_left(iter))
2247 142232 : CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
2248 :
2249 142232 : ikind = kind_of(irow)
2250 142232 : jkind = kind_of(icol)
2251 :
2252 : ! atomic parameters
2253 142232 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
2254 142232 : CALL get_qs_kind(qs_kind_set(jkind), xtb_parameter=xtb_atom_b)
2255 142232 : CALL get_xtb_atom_param(xtb_atom_a, z=za, nao=naoa)
2256 142232 : CALL get_xtb_atom_param(xtb_atom_b, z=zb, nao=naob)
2257 :
2258 142232 : ni = SIZE(sblock, 1)
2259 568928 : ALLOCATE (ashift(ni, ni))
2260 :
2261 142232 : nj = SIZE(sblock, 2)
2262 568928 : ALLOCATE (bshift(nj, nj))
2263 :
2264 291678 : DO is = 1, nspin
2265 149446 : ashift = 0.0_dp
2266 1244365 : DO i = 1, ni
2267 1094919 : la = naoa(i) + sum_shell(irow)
2268 1244365 : ashift(i, i) = tb_spin_project(tb%pot%vsh(la, :), is)
2269 : END DO
2270 149446 : bshift = 0.0_dp
2271 1207925 : DO j = 1, nj
2272 1058479 : lb = naob(j) + sum_shell(icol)
2273 1207925 : bshift(j, j) = tb_spin_project(tb%pot%vsh(lb, :), is)
2274 : END DO
2275 149446 : NULLIFY (ksblock)
2276 : CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
2277 149446 : row=irow, col=icol, block=ksblock, found=found)
2278 149446 : CPASSERT(found)
2279 597784 : ksblock = ksblock - 0.5_dp*(MATMUL(ashift, sblock) &
2280 337046088 : + MATMUL(sblock, bshift))
2281 : ksblock = ksblock - 0.5_dp*(tb_spin_project(tb%pot%vat(irow, :), is) &
2282 20199032 : + tb_spin_project(tb%pot%vat(icol, :), is))*sblock
2283 : END DO
2284 441616 : DEALLOCATE (ashift, bshift)
2285 : END DO
2286 14920 : CALL dbcsr_iterator_stop(iter)
2287 :
2288 14920 : IF (ASSOCIATED(tb%dipbra)) THEN
2289 10248 : CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
2290 108599 : DO WHILE (dbcsr_iterator_blocks_left(iter))
2291 98351 : CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
2292 :
2293 98351 : NULLIFY (dip_bra1, dip_bra2, dip_bra3)
2294 : CALL dbcsr_get_block_p(matrix=tb%dipbra(1)%matrix, &
2295 98351 : row=irow, col=icol, BLOCK=dip_bra1, found=found)
2296 98351 : CPASSERT(found)
2297 : CALL dbcsr_get_block_p(matrix=tb%dipbra(2)%matrix, &
2298 98351 : row=irow, col=icol, BLOCK=dip_bra2, found=found)
2299 98351 : CPASSERT(found)
2300 : CALL dbcsr_get_block_p(matrix=tb%dipbra(3)%matrix, &
2301 98351 : row=irow, col=icol, BLOCK=dip_bra3, found=found)
2302 98351 : CPASSERT(found)
2303 98351 : NULLIFY (dip_ket1, dip_ket2, dip_ket3)
2304 : CALL dbcsr_get_block_p(matrix=tb%dipket(1)%matrix, &
2305 98351 : row=irow, col=icol, BLOCK=dip_ket1, found=found)
2306 98351 : CPASSERT(found)
2307 : CALL dbcsr_get_block_p(matrix=tb%dipket(2)%matrix, &
2308 98351 : row=irow, col=icol, BLOCK=dip_ket2, found=found)
2309 98351 : CPASSERT(found)
2310 : CALL dbcsr_get_block_p(matrix=tb%dipket(3)%matrix, &
2311 98351 : row=irow, col=icol, BLOCK=dip_ket3, found=found)
2312 98351 : CPASSERT(found)
2313 :
2314 211681 : DO is = 1, nspin
2315 103082 : NULLIFY (ksblock)
2316 : CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
2317 103082 : row=irow, col=icol, block=ksblock, found=found)
2318 103082 : CPASSERT(found)
2319 : ksblock = ksblock + mpfac*(dip_ket1*tb_spin_project(tb%pot%vdp(1, irow, :), is) &
2320 : + dip_ket2*tb_spin_project(tb%pot%vdp(2, irow, :), is) &
2321 : + dip_ket3*tb_spin_project(tb%pot%vdp(3, irow, :), is) &
2322 : + dip_bra1*tb_spin_project(tb%pot%vdp(1, icol, :), is) &
2323 : + dip_bra2*tb_spin_project(tb%pot%vdp(2, icol, :), is) &
2324 15239827 : + dip_bra3*tb_spin_project(tb%pot%vdp(3, icol, :), is))
2325 : END DO
2326 : END DO
2327 10248 : CALL dbcsr_iterator_stop(iter)
2328 : END IF
2329 :
2330 14920 : IF (ASSOCIATED(tb%quadbra)) THEN
2331 10248 : CALL dbcsr_iterator_start(iter, matrix_s(1, 1)%matrix)
2332 108599 : DO WHILE (dbcsr_iterator_blocks_left(iter))
2333 98351 : CALL dbcsr_iterator_next_block(iter, irow, icol, sblock)
2334 :
2335 98351 : NULLIFY (quad_bra1, quad_bra2, quad_bra3, quad_bra4, quad_bra5, quad_bra6)
2336 : CALL dbcsr_get_block_p(matrix=tb%quadbra(1)%matrix, &
2337 98351 : row=irow, col=icol, BLOCK=quad_bra1, found=found)
2338 98351 : CPASSERT(found)
2339 : CALL dbcsr_get_block_p(matrix=tb%quadbra(2)%matrix, &
2340 98351 : row=irow, col=icol, BLOCK=quad_bra2, found=found)
2341 98351 : CPASSERT(found)
2342 : CALL dbcsr_get_block_p(matrix=tb%quadbra(3)%matrix, &
2343 98351 : row=irow, col=icol, BLOCK=quad_bra3, found=found)
2344 98351 : CPASSERT(found)
2345 : CALL dbcsr_get_block_p(matrix=tb%quadbra(4)%matrix, &
2346 98351 : row=irow, col=icol, BLOCK=quad_bra4, found=found)
2347 98351 : CPASSERT(found)
2348 : CALL dbcsr_get_block_p(matrix=tb%quadbra(5)%matrix, &
2349 98351 : row=irow, col=icol, BLOCK=quad_bra5, found=found)
2350 98351 : CPASSERT(found)
2351 : CALL dbcsr_get_block_p(matrix=tb%quadbra(6)%matrix, &
2352 98351 : row=irow, col=icol, BLOCK=quad_bra6, found=found)
2353 98351 : CPASSERT(found)
2354 :
2355 98351 : NULLIFY (quad_ket1, quad_ket2, quad_ket3, quad_ket4, quad_ket5, quad_ket6)
2356 : CALL dbcsr_get_block_p(matrix=tb%quadket(1)%matrix, &
2357 98351 : row=irow, col=icol, BLOCK=quad_ket1, found=found)
2358 98351 : CPASSERT(found)
2359 : CALL dbcsr_get_block_p(matrix=tb%quadket(2)%matrix, &
2360 98351 : row=irow, col=icol, BLOCK=quad_ket2, found=found)
2361 98351 : CPASSERT(found)
2362 : CALL dbcsr_get_block_p(matrix=tb%quadket(3)%matrix, &
2363 98351 : row=irow, col=icol, BLOCK=quad_ket3, found=found)
2364 98351 : CPASSERT(found)
2365 : CALL dbcsr_get_block_p(matrix=tb%quadket(4)%matrix, &
2366 98351 : row=irow, col=icol, BLOCK=quad_ket4, found=found)
2367 98351 : CPASSERT(found)
2368 : CALL dbcsr_get_block_p(matrix=tb%quadket(5)%matrix, &
2369 98351 : row=irow, col=icol, BLOCK=quad_ket5, found=found)
2370 98351 : CPASSERT(found)
2371 : CALL dbcsr_get_block_p(matrix=tb%quadket(6)%matrix, &
2372 98351 : row=irow, col=icol, BLOCK=quad_ket6, found=found)
2373 98351 : CPASSERT(found)
2374 :
2375 211681 : DO is = 1, nspin
2376 103082 : NULLIFY (ksblock)
2377 : CALL dbcsr_get_block_p(matrix=ks_matrix(is, 1)%matrix, &
2378 103082 : row=irow, col=icol, block=ksblock, found=found)
2379 103082 : CPASSERT(found)
2380 :
2381 : ksblock = ksblock + mpfac*(quad_ket1*tb_spin_project(tb%pot%vqp(1, irow, :), is) &
2382 : + quad_ket2*tb_spin_project(tb%pot%vqp(2, irow, :), is) &
2383 : + quad_ket3*tb_spin_project(tb%pot%vqp(3, irow, :), is) &
2384 : + quad_ket4*tb_spin_project(tb%pot%vqp(4, irow, :), is) &
2385 : + quad_ket5*tb_spin_project(tb%pot%vqp(5, irow, :), is) &
2386 : + quad_ket6*tb_spin_project(tb%pot%vqp(6, irow, :), is) &
2387 : + quad_bra1*tb_spin_project(tb%pot%vqp(1, icol, :), is) &
2388 : + quad_bra2*tb_spin_project(tb%pot%vqp(2, icol, :), is) &
2389 : + quad_bra3*tb_spin_project(tb%pot%vqp(3, icol, :), is) &
2390 : + quad_bra4*tb_spin_project(tb%pot%vqp(4, icol, :), is) &
2391 : + quad_bra5*tb_spin_project(tb%pot%vqp(5, icol, :), is) &
2392 15239827 : + quad_bra6*tb_spin_project(tb%pot%vqp(6, icol, :), is))
2393 : END DO
2394 : END DO
2395 10248 : CALL dbcsr_iterator_stop(iter)
2396 : END IF
2397 :
2398 : ELSE
2399 12982 : NULLIFY (kpoints)
2400 12982 : CALL get_qs_env(qs_env=qs_env, kpoints=kpoints)
2401 12982 : NULLIFY (cell_to_index)
2402 12982 : CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
2403 :
2404 12982 : NULLIFY (nl_iterator)
2405 12982 : CALL neighbor_list_iterator_create(nl_iterator, n_list)
2406 2609855 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
2407 : CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
2408 2596873 : iatom=iatom, jatom=jatom, r=rij, cell=cellind)
2409 :
2410 2596873 : icol = MAX(iatom, jatom)
2411 2596873 : irow = MIN(iatom, jatom)
2412 :
2413 2596873 : IF (iatom > jatom) THEN
2414 1108618 : i = ikind
2415 1108618 : ikind = jkind
2416 1108618 : jkind = i
2417 : END IF
2418 :
2419 2596873 : ic = cell_to_index(cellind(1), cellind(2), cellind(3))
2420 2596873 : CPASSERT(ic > 0)
2421 :
2422 2596873 : NULLIFY (sblock)
2423 : CALL dbcsr_get_block_p(matrix=matrix_s(1, ic)%matrix, &
2424 2596873 : row=irow, col=icol, block=sblock, found=found)
2425 2596873 : CPASSERT(found)
2426 :
2427 : ! atomic parameters
2428 2596873 : CALL get_qs_kind(qs_kind_set(ikind), xtb_parameter=xtb_atom_a)
2429 2596873 : CALL get_qs_kind(qs_kind_set(jkind), xtb_parameter=xtb_atom_b)
2430 2596873 : CALL get_xtb_atom_param(xtb_atom_a, z=za, nao=naoa)
2431 2596873 : CALL get_xtb_atom_param(xtb_atom_b, z=zb, nao=naob)
2432 :
2433 2596873 : ni = SIZE(sblock, 1)
2434 10387492 : ALLOCATE (ashift(ni, ni))
2435 :
2436 2596873 : nj = SIZE(sblock, 2)
2437 10387492 : ALLOCATE (bshift(nj, nj))
2438 :
2439 5211296 : DO is = 1, nspin
2440 2614423 : ashift = 0.0_dp
2441 21567933 : DO i = 1, ni
2442 18953510 : la = naoa(i) + sum_shell(irow)
2443 21567933 : ashift(i, i) = tb_spin_project(tb%pot%vsh(la, :), is)
2444 : END DO
2445 2614423 : bshift = 0.0_dp
2446 21305273 : DO j = 1, nj
2447 18690850 : lb = naob(j) + sum_shell(icol)
2448 21305273 : bshift(j, j) = tb_spin_project(tb%pot%vsh(lb, :), is)
2449 : END DO
2450 2614423 : NULLIFY (ksblock)
2451 : CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
2452 2614423 : row=irow, col=icol, block=ksblock, found=found)
2453 2614423 : CPASSERT(found)
2454 10457692 : ksblock = ksblock - 0.5_dp*(MATMUL(ashift, sblock) &
2455 5992942041 : + MATMUL(sblock, bshift))
2456 : ksblock = ksblock - 0.5_dp*(tb_spin_project(tb%pot%vat(irow, :), is) &
2457 357091147 : + tb_spin_project(tb%pot%vat(icol, :), is))*sblock
2458 : END DO
2459 7803601 : DEALLOCATE (ashift, bshift)
2460 : END DO
2461 12982 : CALL neighbor_list_iterator_release(nl_iterator)
2462 :
2463 12982 : IF (ASSOCIATED(tb%dipbra)) THEN
2464 8872 : NULLIFY (nl_iterator)
2465 8872 : CALL neighbor_list_iterator_create(nl_iterator, n_list)
2466 1110523 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
2467 : CALL get_iterator_info(nl_iterator, &
2468 1101651 : iatom=iatom, jatom=jatom, cell=cellind)
2469 1101651 : icol = MAX(iatom, jatom)
2470 1101651 : irow = MIN(iatom, jatom)
2471 1101651 : ic = cell_to_index(cellind(1), cellind(2), cellind(3))
2472 1101651 : CPASSERT(ic > 0)
2473 1101651 : id1 = 1 + dip_n*(ic - 1)
2474 1101651 : id2 = 2 + dip_n*(ic - 1)
2475 1101651 : id3 = 3 + dip_n*(ic - 1)
2476 :
2477 1101651 : NULLIFY (dip_bra1, dip_bra2, dip_bra3)
2478 : CALL dbcsr_get_block_p(matrix=tb%dipbra(id1)%matrix, &
2479 1101651 : row=irow, col=icol, BLOCK=dip_bra1, found=found)
2480 1101651 : CPASSERT(found)
2481 : CALL dbcsr_get_block_p(matrix=tb%dipbra(id2)%matrix, &
2482 1101651 : row=irow, col=icol, BLOCK=dip_bra2, found=found)
2483 1101651 : CPASSERT(found)
2484 : CALL dbcsr_get_block_p(matrix=tb%dipbra(id3)%matrix, &
2485 1101651 : row=irow, col=icol, BLOCK=dip_bra3, found=found)
2486 1101651 : CPASSERT(found)
2487 1101651 : NULLIFY (dip_ket1, dip_ket2, dip_ket3)
2488 : CALL dbcsr_get_block_p(matrix=tb%dipket(id1)%matrix, &
2489 1101651 : row=irow, col=icol, BLOCK=dip_ket1, found=found)
2490 1101651 : CPASSERT(found)
2491 : CALL dbcsr_get_block_p(matrix=tb%dipket(id2)%matrix, &
2492 1101651 : row=irow, col=icol, BLOCK=dip_ket2, found=found)
2493 1101651 : CPASSERT(found)
2494 : CALL dbcsr_get_block_p(matrix=tb%dipket(id3)%matrix, &
2495 1101651 : row=irow, col=icol, BLOCK=dip_ket3, found=found)
2496 1101651 : CPASSERT(found)
2497 :
2498 2229724 : DO is = 1, nspin
2499 1119201 : NULLIFY (ksblock)
2500 : CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
2501 1119201 : row=irow, col=icol, block=ksblock, found=found)
2502 1119201 : CPASSERT(found)
2503 : ksblock = ksblock + mpfac*(dip_ket1*tb_spin_project(tb%pot%vdp(1, irow, :), is) &
2504 : + dip_ket2*tb_spin_project(tb%pot%vdp(2, irow, :), is) &
2505 : + dip_ket3*tb_spin_project(tb%pot%vdp(3, irow, :), is) &
2506 : + dip_bra1*tb_spin_project(tb%pot%vdp(1, icol, :), is) &
2507 : + dip_bra2*tb_spin_project(tb%pot%vdp(2, icol, :), is) &
2508 172535493 : + dip_bra3*tb_spin_project(tb%pot%vdp(3, icol, :), is))
2509 : END DO
2510 : END DO
2511 8872 : CALL neighbor_list_iterator_release(nl_iterator)
2512 : END IF
2513 :
2514 12982 : IF (ASSOCIATED(tb%quadbra)) THEN
2515 8872 : NULLIFY (nl_iterator)
2516 8872 : CALL neighbor_list_iterator_create(nl_iterator, n_list)
2517 1110523 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
2518 : CALL get_iterator_info(nl_iterator, &
2519 1101651 : iatom=iatom, jatom=jatom, cell=cellind)
2520 1101651 : icol = MAX(iatom, jatom)
2521 1101651 : irow = MIN(iatom, jatom)
2522 1101651 : ic = cell_to_index(cellind(1), cellind(2), cellind(3))
2523 1101651 : CPASSERT(ic > 0)
2524 1101651 : iq1 = 1 + quad_n*(ic - 1)
2525 1101651 : iq2 = 2 + quad_n*(ic - 1)
2526 1101651 : iq3 = 3 + quad_n*(ic - 1)
2527 1101651 : iq4 = 4 + quad_n*(ic - 1)
2528 1101651 : iq5 = 5 + quad_n*(ic - 1)
2529 1101651 : iq6 = 6 + quad_n*(ic - 1)
2530 :
2531 1101651 : NULLIFY (quad_bra1, quad_bra2, quad_bra3, quad_bra4, quad_bra5, quad_bra6)
2532 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq1)%matrix, &
2533 1101651 : row=irow, col=icol, BLOCK=quad_bra1, found=found)
2534 1101651 : CPASSERT(found)
2535 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq2)%matrix, &
2536 1101651 : row=irow, col=icol, BLOCK=quad_bra2, found=found)
2537 1101651 : CPASSERT(found)
2538 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq3)%matrix, &
2539 1101651 : row=irow, col=icol, BLOCK=quad_bra3, found=found)
2540 1101651 : CPASSERT(found)
2541 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq4)%matrix, &
2542 1101651 : row=irow, col=icol, BLOCK=quad_bra4, found=found)
2543 1101651 : CPASSERT(found)
2544 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq5)%matrix, &
2545 1101651 : row=irow, col=icol, BLOCK=quad_bra5, found=found)
2546 1101651 : CPASSERT(found)
2547 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq6)%matrix, &
2548 1101651 : row=irow, col=icol, BLOCK=quad_bra6, found=found)
2549 1101651 : CPASSERT(found)
2550 :
2551 1101651 : NULLIFY (quad_ket1, quad_ket2, quad_ket3, quad_ket4, quad_ket5, quad_ket6)
2552 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq1)%matrix, &
2553 1101651 : row=irow, col=icol, BLOCK=quad_ket1, found=found)
2554 1101651 : CPASSERT(found)
2555 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq2)%matrix, &
2556 1101651 : row=irow, col=icol, BLOCK=quad_ket2, found=found)
2557 1101651 : CPASSERT(found)
2558 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq3)%matrix, &
2559 1101651 : row=irow, col=icol, BLOCK=quad_ket3, found=found)
2560 1101651 : CPASSERT(found)
2561 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq4)%matrix, &
2562 1101651 : row=irow, col=icol, BLOCK=quad_ket4, found=found)
2563 1101651 : CPASSERT(found)
2564 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq5)%matrix, &
2565 1101651 : row=irow, col=icol, BLOCK=quad_ket5, found=found)
2566 1101651 : CPASSERT(found)
2567 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq6)%matrix, &
2568 1101651 : row=irow, col=icol, BLOCK=quad_ket6, found=found)
2569 1101651 : CPASSERT(found)
2570 :
2571 2229724 : DO is = 1, nspin
2572 1119201 : NULLIFY (ksblock)
2573 : CALL dbcsr_get_block_p(matrix=ks_matrix(is, ic)%matrix, &
2574 1119201 : row=irow, col=icol, block=ksblock, found=found)
2575 1119201 : CPASSERT(found)
2576 :
2577 : ksblock = ksblock + mpfac*(quad_ket1*tb_spin_project(tb%pot%vqp(1, irow, :), is) &
2578 : + quad_ket2*tb_spin_project(tb%pot%vqp(2, irow, :), is) &
2579 : + quad_ket3*tb_spin_project(tb%pot%vqp(3, irow, :), is) &
2580 : + quad_ket4*tb_spin_project(tb%pot%vqp(4, irow, :), is) &
2581 : + quad_ket5*tb_spin_project(tb%pot%vqp(5, irow, :), is) &
2582 : + quad_ket6*tb_spin_project(tb%pot%vqp(6, irow, :), is) &
2583 : + quad_bra1*tb_spin_project(tb%pot%vqp(1, icol, :), is) &
2584 : + quad_bra2*tb_spin_project(tb%pot%vqp(2, icol, :), is) &
2585 : + quad_bra3*tb_spin_project(tb%pot%vqp(3, icol, :), is) &
2586 : + quad_bra4*tb_spin_project(tb%pot%vqp(4, icol, :), is) &
2587 : + quad_bra5*tb_spin_project(tb%pot%vqp(5, icol, :), is) &
2588 172535493 : + quad_bra6*tb_spin_project(tb%pot%vqp(6, icol, :), is))
2589 : END DO
2590 : END DO
2591 8872 : CALL neighbor_list_iterator_release(nl_iterator)
2592 : END IF
2593 :
2594 : END IF
2595 :
2596 : #else
2597 : MARK_USED(qs_env)
2598 : MARK_USED(tb)
2599 : MARK_USED(dft_control)
2600 : CPABORT("Built without TBLITE")
2601 : #endif
2602 :
2603 55804 : END SUBROUTINE tb_ham_add_coulomb
2604 :
2605 : ! **************************************************************************************************
2606 : !> \brief ...
2607 : !> \param qs_env ...
2608 : !> \param tb ...
2609 : ! **************************************************************************************************
2610 1368 : SUBROUTINE tb_get_multipole(qs_env, tb)
2611 :
2612 : TYPE(qs_environment_type), POINTER :: qs_env
2613 : TYPE(tblite_type), POINTER :: tb
2614 :
2615 : #if defined(__TBLITE)
2616 :
2617 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tb_get_multipole'
2618 :
2619 : INTEGER :: ikind, jkind, iatom, jatom, icol, irow, iset, jset, ityp, jtyp
2620 : INTEGER :: ic, idx, id1, id2, id3, img, iq1, iq2, iq3, iq4, iq5, iq6
2621 : INTEGER :: nkind, natom, handle, nimg, i, inda, indb
2622 : INTEGER :: atom_a, atom_b, nseta, nsetb, ia, ib, ij
2623 : LOGICAL :: found
2624 : REAL(KIND=dp) :: r2
2625 : INTEGER, DIMENSION(3) :: cell
2626 1368 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
2627 : REAL(KIND=dp), DIMENSION(3) :: rij
2628 1368 : INTEGER, DIMENSION(:), POINTER :: la_max, lb_max
2629 1368 : INTEGER, DIMENSION(:), POINTER :: nsgfa, nsgfb
2630 1368 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
2631 1368 : INTEGER, ALLOCATABLE :: atom_of_kind(:)
2632 1368 : REAL(KIND=dp), ALLOCATABLE :: stmp(:)
2633 1368 : REAL(KIND=dp), ALLOCATABLE :: dtmp(:, :), qtmp(:, :), dtmpj(:, :), qtmpj(:, :)
2634 1368 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: dip_ket1, dip_ket2, dip_ket3, &
2635 1368 : dip_bra1, dip_bra2, dip_bra3
2636 1368 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: quad_ket1, quad_ket2, quad_ket3, &
2637 1368 : quad_ket4, quad_ket5, quad_ket6, &
2638 1368 : quad_bra1, quad_bra2, quad_bra3, &
2639 1368 : quad_bra4, quad_bra5, quad_bra6
2640 :
2641 1368 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
2642 1368 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_s
2643 : TYPE(dft_control_type), POINTER :: dft_control
2644 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
2645 1368 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
2646 : TYPE(kpoint_type), POINTER :: kpoints
2647 1368 : TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_orb
2648 1368 : TYPE(neighbor_list_set_p_type), DIMENSION(:), POINTER :: sab_kp
2649 : TYPE(neighbor_list_iterator_p_type), &
2650 1368 : DIMENSION(:), POINTER :: nl_iterator
2651 1368 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
2652 1368 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2653 :
2654 1368 : CALL timeset(routineN, handle)
2655 :
2656 : !get info from environment vaiarable
2657 1368 : NULLIFY (atomic_kind_set, qs_kind_set, sab_orb, sab_kp, particle_set)
2658 1368 : NULLIFY (dft_control, matrix_s, kpoints, cell_to_index)
2659 : CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, &
2660 : qs_kind_set=qs_kind_set, &
2661 : sab_orb=sab_orb, &
2662 : sab_kp=sab_kp, &
2663 : particle_set=particle_set, &
2664 : dft_control=dft_control, &
2665 : kpoints=kpoints, &
2666 1368 : matrix_s_kp=matrix_s)
2667 1368 : natom = SIZE(particle_set)
2668 1368 : nkind = SIZE(atomic_kind_set)
2669 1368 : nimg = dft_control%nimages
2670 1368 : IF (nimg > 1) THEN
2671 582 : IF (.NOT. ASSOCIATED(sab_kp)) CPABORT("Missing k-point neighbor list for tblite multipoles")
2672 582 : sab_orb => sab_kp
2673 582 : CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index)
2674 : END IF
2675 :
2676 1368 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, atom_of_kind=atom_of_kind)
2677 :
2678 : !set up basis set lists
2679 6138 : ALLOCATE (basis_set_list(nkind))
2680 1368 : CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
2681 :
2682 4104 : ALLOCATE (stmp(msao(tb%calc%bas%maxl)**2))
2683 4104 : ALLOCATE (dtmp(dip_n, msao(tb%calc%bas%maxl)**2))
2684 4104 : ALLOCATE (qtmp(quad_n, msao(tb%calc%bas%maxl)**2))
2685 2736 : ALLOCATE (dtmpj(dip_n, msao(tb%calc%bas%maxl)**2))
2686 2736 : ALLOCATE (qtmpj(quad_n, msao(tb%calc%bas%maxl)**2))
2687 :
2688 : ! allocate dipole/quadrupole moment matrix elemnts
2689 1368 : CALL dbcsr_allocate_matrix_set(tb%dipbra, dip_n*nimg)
2690 1368 : CALL dbcsr_allocate_matrix_set(tb%dipket, dip_n*nimg)
2691 1368 : CALL dbcsr_allocate_matrix_set(tb%quadbra, quad_n*nimg)
2692 1368 : CALL dbcsr_allocate_matrix_set(tb%quadket, quad_n*nimg)
2693 23328 : DO img = 1, nimg
2694 87840 : DO i = 1, dip_n
2695 65880 : idx = i + dip_n*(img - 1)
2696 65880 : ALLOCATE (tb%dipbra(idx)%matrix)
2697 65880 : ALLOCATE (tb%dipket(idx)%matrix)
2698 : CALL dbcsr_create(tb%dipbra(idx)%matrix, template=matrix_s(1, img)%matrix, &
2699 65880 : name="DIPOLE BRAMATRIX")
2700 : CALL dbcsr_create(tb%dipket(idx)%matrix, template=matrix_s(1, img)%matrix, &
2701 65880 : name="DIPOLE KETMATRIX")
2702 65880 : CALL cp_dbcsr_alloc_block_from_nbl(tb%dipbra(idx)%matrix, sab_orb)
2703 87840 : CALL cp_dbcsr_alloc_block_from_nbl(tb%dipket(idx)%matrix, sab_orb)
2704 : END DO
2705 155088 : DO i = 1, quad_n
2706 131760 : idx = i + quad_n*(img - 1)
2707 131760 : ALLOCATE (tb%quadbra(idx)%matrix)
2708 131760 : ALLOCATE (tb%quadket(idx)%matrix)
2709 : CALL dbcsr_create(tb%quadbra(idx)%matrix, template=matrix_s(1, img)%matrix, &
2710 131760 : name="QUADRUPOLE BRAMATRIX")
2711 : CALL dbcsr_create(tb%quadket(idx)%matrix, template=matrix_s(1, img)%matrix, &
2712 131760 : name="QUADRUPOLE KETMATRIX")
2713 131760 : CALL cp_dbcsr_alloc_block_from_nbl(tb%quadbra(idx)%matrix, sab_orb)
2714 153720 : CALL cp_dbcsr_alloc_block_from_nbl(tb%quadket(idx)%matrix, sab_orb)
2715 : END DO
2716 : END DO
2717 :
2718 : !loop over all atom pairs with a non-zero overlap (sab_orb)
2719 1368 : NULLIFY (nl_iterator)
2720 1368 : CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
2721 265701 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
2722 : CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
2723 264333 : iatom=iatom, jatom=jatom, r=rij, cell=cell)
2724 :
2725 1057332 : r2 = NORM2(rij(:))**2
2726 :
2727 264333 : icol = MAX(iatom, jatom)
2728 264333 : irow = MIN(iatom, jatom)
2729 :
2730 264333 : IF (iatom < jatom) THEN
2731 329176 : rij = -rij
2732 82294 : i = ikind
2733 82294 : ikind = jkind
2734 82294 : jkind = i
2735 : END IF
2736 :
2737 264333 : IF (nimg == 1) THEN
2738 : ic = 1
2739 : ELSE
2740 71810 : ic = cell_to_index(cell(1), cell(2), cell(3))
2741 71810 : CPASSERT(ic > 0)
2742 : END IF
2743 264333 : id1 = 1 + dip_n*(ic - 1)
2744 264333 : id2 = 2 + dip_n*(ic - 1)
2745 264333 : id3 = 3 + dip_n*(ic - 1)
2746 264333 : iq1 = 1 + quad_n*(ic - 1)
2747 264333 : iq2 = 2 + quad_n*(ic - 1)
2748 264333 : iq3 = 3 + quad_n*(ic - 1)
2749 264333 : iq4 = 4 + quad_n*(ic - 1)
2750 264333 : iq5 = 5 + quad_n*(ic - 1)
2751 264333 : iq6 = 6 + quad_n*(ic - 1)
2752 :
2753 264333 : ityp = tb%mol%id(icol)
2754 264333 : jtyp = tb%mol%id(irow)
2755 :
2756 264333 : NULLIFY (dip_bra1, dip_bra2, dip_bra3)
2757 : CALL dbcsr_get_block_p(matrix=tb%dipbra(id1)%matrix, &
2758 264333 : row=irow, col=icol, BLOCK=dip_bra1, found=found)
2759 264333 : CPASSERT(found)
2760 : CALL dbcsr_get_block_p(matrix=tb%dipbra(id2)%matrix, &
2761 264333 : row=irow, col=icol, BLOCK=dip_bra2, found=found)
2762 264333 : CPASSERT(found)
2763 : CALL dbcsr_get_block_p(matrix=tb%dipbra(id3)%matrix, &
2764 264333 : row=irow, col=icol, BLOCK=dip_bra3, found=found)
2765 264333 : CPASSERT(found)
2766 :
2767 264333 : NULLIFY (dip_ket1, dip_ket2, dip_ket3)
2768 : CALL dbcsr_get_block_p(matrix=tb%dipket(id1)%matrix, &
2769 264333 : row=irow, col=icol, BLOCK=dip_ket1, found=found)
2770 264333 : CPASSERT(found)
2771 : CALL dbcsr_get_block_p(matrix=tb%dipket(id2)%matrix, &
2772 264333 : row=irow, col=icol, BLOCK=dip_ket2, found=found)
2773 264333 : CPASSERT(found)
2774 : CALL dbcsr_get_block_p(matrix=tb%dipket(id3)%matrix, &
2775 264333 : row=irow, col=icol, BLOCK=dip_ket3, found=found)
2776 264333 : CPASSERT(found)
2777 :
2778 264333 : NULLIFY (quad_bra1, quad_bra2, quad_bra3, quad_bra4, quad_bra5, quad_bra6)
2779 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq1)%matrix, &
2780 264333 : row=irow, col=icol, BLOCK=quad_bra1, found=found)
2781 264333 : CPASSERT(found)
2782 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq2)%matrix, &
2783 264333 : row=irow, col=icol, BLOCK=quad_bra2, found=found)
2784 264333 : CPASSERT(found)
2785 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq3)%matrix, &
2786 264333 : row=irow, col=icol, BLOCK=quad_bra3, found=found)
2787 264333 : CPASSERT(found)
2788 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq4)%matrix, &
2789 264333 : row=irow, col=icol, BLOCK=quad_bra4, found=found)
2790 264333 : CPASSERT(found)
2791 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq5)%matrix, &
2792 264333 : row=irow, col=icol, BLOCK=quad_bra5, found=found)
2793 264333 : CPASSERT(found)
2794 : CALL dbcsr_get_block_p(matrix=tb%quadbra(iq6)%matrix, &
2795 264333 : row=irow, col=icol, BLOCK=quad_bra6, found=found)
2796 264333 : CPASSERT(found)
2797 :
2798 264333 : NULLIFY (quad_ket1, quad_ket2, quad_ket3, quad_ket4, quad_ket5, quad_ket6)
2799 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq1)%matrix, &
2800 264333 : row=irow, col=icol, BLOCK=quad_ket1, found=found)
2801 264333 : CPASSERT(found)
2802 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq2)%matrix, &
2803 264333 : row=irow, col=icol, BLOCK=quad_ket2, found=found)
2804 264333 : CPASSERT(found)
2805 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq3)%matrix, &
2806 264333 : row=irow, col=icol, BLOCK=quad_ket3, found=found)
2807 264333 : CPASSERT(found)
2808 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq4)%matrix, &
2809 264333 : row=irow, col=icol, BLOCK=quad_ket4, found=found)
2810 264333 : CPASSERT(found)
2811 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq5)%matrix, &
2812 264333 : row=irow, col=icol, BLOCK=quad_ket5, found=found)
2813 264333 : CPASSERT(found)
2814 : CALL dbcsr_get_block_p(matrix=tb%quadket(iq6)%matrix, &
2815 264333 : row=irow, col=icol, BLOCK=quad_ket6, found=found)
2816 264333 : CPASSERT(found)
2817 :
2818 : !get basis information
2819 264333 : basis_set_a => basis_set_list(ikind)%gto_basis_set
2820 264333 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
2821 264333 : basis_set_b => basis_set_list(jkind)%gto_basis_set
2822 264333 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
2823 264333 : atom_a = atom_of_kind(icol)
2824 264333 : atom_b = atom_of_kind(irow)
2825 : ! basis a
2826 264333 : first_sgfa => basis_set_a%first_sgf
2827 264333 : la_max => basis_set_a%lmax
2828 264333 : nseta = basis_set_a%nset
2829 264333 : nsgfa => basis_set_a%nsgf_set
2830 : ! basis b
2831 264333 : first_sgfb => basis_set_b%first_sgf
2832 264333 : lb_max => basis_set_b%lmax
2833 264333 : nsetb = basis_set_b%nset
2834 264333 : nsgfb => basis_set_b%nsgf_set
2835 :
2836 : ! --------- Hamiltonian
2837 : ! Periodic self-images are off-diagonal lattice contributions, not the on-site block.
2838 265701 : IF (icol == irow .AND. r2 < same_atom**2) THEN
2839 9951 : DO iset = 1, nseta
2840 29298 : DO jset = 1, nsetb
2841 : CALL multipole_cgto(tb%calc%bas%cgto(jset, ityp), tb%calc%bas%cgto(iset, ityp), &
2842 77388 : & r2, -rij, tb%calc%bas%intcut, stmp, dtmp, qtmp)
2843 :
2844 81199 : DO inda = 1, nsgfa(iset)
2845 54731 : ia = first_sgfa(1, iset) - first_sgfa(1, 1) + inda
2846 232373 : DO indb = 1, nsgfb(jset)
2847 158295 : ib = first_sgfb(1, jset) - first_sgfb(1, 1) + indb
2848 158295 : ij = indb + nsgfb(jset)*(inda - 1)
2849 :
2850 158295 : dip_ket1(ib, ia) = dip_ket1(ib, ia) + dtmp(1, ij)
2851 158295 : dip_ket2(ib, ia) = dip_ket2(ib, ia) + dtmp(2, ij)
2852 158295 : dip_ket3(ib, ia) = dip_ket3(ib, ia) + dtmp(3, ij)
2853 :
2854 158295 : quad_ket1(ib, ia) = quad_ket1(ib, ia) + qtmp(1, ij)
2855 158295 : quad_ket2(ib, ia) = quad_ket2(ib, ia) + qtmp(2, ij)
2856 158295 : quad_ket3(ib, ia) = quad_ket3(ib, ia) + qtmp(3, ij)
2857 158295 : quad_ket4(ib, ia) = quad_ket4(ib, ia) + qtmp(4, ij)
2858 158295 : quad_ket5(ib, ia) = quad_ket5(ib, ia) + qtmp(5, ij)
2859 158295 : quad_ket6(ib, ia) = quad_ket6(ib, ia) + qtmp(6, ij)
2860 :
2861 158295 : dip_bra1(ib, ia) = dip_bra1(ib, ia) + dtmp(1, ij)
2862 158295 : dip_bra2(ib, ia) = dip_bra2(ib, ia) + dtmp(2, ij)
2863 158295 : dip_bra3(ib, ia) = dip_bra3(ib, ia) + dtmp(3, ij)
2864 :
2865 158295 : quad_bra1(ib, ia) = quad_bra1(ib, ia) + qtmp(1, ij)
2866 158295 : quad_bra2(ib, ia) = quad_bra2(ib, ia) + qtmp(2, ij)
2867 158295 : quad_bra3(ib, ia) = quad_bra3(ib, ia) + qtmp(3, ij)
2868 158295 : quad_bra4(ib, ia) = quad_bra4(ib, ia) + qtmp(4, ij)
2869 158295 : quad_bra5(ib, ia) = quad_bra5(ib, ia) + qtmp(5, ij)
2870 213026 : quad_bra6(ib, ia) = quad_bra6(ib, ia) + qtmp(6, ij)
2871 : END DO
2872 : END DO
2873 : END DO
2874 : END DO
2875 : ELSE
2876 1025227 : DO iset = 1, nseta
2877 3278699 : DO jset = 1, nsetb
2878 : CALL multipole_cgto(tb%calc%bas%cgto(jset, jtyp), tb%calc%bas%cgto(iset, ityp), &
2879 9013888 : & r2, -rij, tb%calc%bas%intcut, stmp, dtmp, qtmp)
2880 :
2881 9733838 : DO inda = 1, nsgfa(iset)
2882 6716642 : ia = first_sgfa(1, iset) - first_sgfa(1, 1) + inda
2883 29028868 : DO indb = 1, nsgfb(jset)
2884 20058754 : ib = first_sgfb(1, jset) - first_sgfb(1, 1) + indb
2885 :
2886 20058754 : ij = indb + nsgfb(jset)*(inda - 1)
2887 : CALL tb_shift_multipole(-rij, stmp(ij), dtmp(:, ij), qtmp(:, ij), &
2888 80235016 : dtmpj(:, ij), qtmpj(:, ij))
2889 :
2890 20058754 : dip_bra1(ib, ia) = dip_bra1(ib, ia) + dtmp(1, ij)
2891 20058754 : dip_bra2(ib, ia) = dip_bra2(ib, ia) + dtmp(2, ij)
2892 20058754 : dip_bra3(ib, ia) = dip_bra3(ib, ia) + dtmp(3, ij)
2893 :
2894 20058754 : quad_bra1(ib, ia) = quad_bra1(ib, ia) + qtmp(1, ij)
2895 20058754 : quad_bra2(ib, ia) = quad_bra2(ib, ia) + qtmp(2, ij)
2896 20058754 : quad_bra3(ib, ia) = quad_bra3(ib, ia) + qtmp(3, ij)
2897 20058754 : quad_bra4(ib, ia) = quad_bra4(ib, ia) + qtmp(4, ij)
2898 20058754 : quad_bra5(ib, ia) = quad_bra5(ib, ia) + qtmp(5, ij)
2899 20058754 : quad_bra6(ib, ia) = quad_bra6(ib, ia) + qtmp(6, ij)
2900 :
2901 20058754 : dip_ket1(ib, ia) = dip_ket1(ib, ia) + dtmpj(1, ij)
2902 20058754 : dip_ket2(ib, ia) = dip_ket2(ib, ia) + dtmpj(2, ij)
2903 20058754 : dip_ket3(ib, ia) = dip_ket3(ib, ia) + dtmpj(3, ij)
2904 :
2905 20058754 : quad_ket1(ib, ia) = quad_ket1(ib, ia) + qtmpj(1, ij)
2906 20058754 : quad_ket2(ib, ia) = quad_ket2(ib, ia) + qtmpj(2, ij)
2907 20058754 : quad_ket3(ib, ia) = quad_ket3(ib, ia) + qtmpj(3, ij)
2908 20058754 : quad_ket4(ib, ia) = quad_ket4(ib, ia) + qtmpj(4, ij)
2909 20058754 : quad_ket5(ib, ia) = quad_ket5(ib, ia) + qtmpj(5, ij)
2910 26775396 : quad_ket6(ib, ia) = quad_ket6(ib, ia) + qtmpj(6, ij)
2911 : END DO
2912 : END DO
2913 : END DO
2914 : END DO
2915 : END IF
2916 : END DO
2917 1368 : CALL neighbor_list_iterator_release(nl_iterator)
2918 :
2919 67248 : DO i = 1, SIZE(tb%dipbra)
2920 65880 : CALL dbcsr_finalize(tb%dipbra(i)%matrix)
2921 67248 : CALL dbcsr_finalize(tb%dipket(i)%matrix)
2922 : END DO
2923 133128 : DO i = 1, SIZE(tb%quadbra)
2924 131760 : CALL dbcsr_finalize(tb%quadbra(i)%matrix)
2925 133128 : CALL dbcsr_finalize(tb%quadket(i)%matrix)
2926 : END DO
2927 :
2928 1368 : DEALLOCATE (basis_set_list)
2929 :
2930 1368 : CALL timestop(handle)
2931 :
2932 : #else
2933 : MARK_USED(qs_env)
2934 : MARK_USED(tb)
2935 : CPABORT("Built without TBLITE")
2936 : #endif
2937 :
2938 2736 : END SUBROUTINE tb_get_multipole
2939 :
2940 : ! **************************************************************************************************
2941 : !> \brief Shift a multipole operator from one center to the other.
2942 : !> \param vec displacement vector between the two centers
2943 : !> \param s overlap integral
2944 : !> \param di dipole integral on the original center
2945 : !> \param qi quadrupole integral on the original center
2946 : !> \param dj dipole integral on the shifted center
2947 : !> \param qj quadrupole integral on the shifted center
2948 : ! **************************************************************************************************
2949 20058754 : PURE SUBROUTINE tb_shift_multipole(vec, s, di, qi, dj, qj)
2950 :
2951 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: vec
2952 : REAL(KIND=dp), INTENT(IN) :: s
2953 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: di, qi
2954 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: dj, qj
2955 :
2956 : REAL(KIND=dp) :: tr
2957 :
2958 20058754 : dj(1) = di(1) + vec(1)*s
2959 20058754 : dj(2) = di(2) + vec(2)*s
2960 20058754 : dj(3) = di(3) + vec(3)*s
2961 :
2962 20058754 : qj(1) = 2*vec(1)*di(1) + vec(1)**2*s
2963 20058754 : qj(3) = 2*vec(2)*di(2) + vec(2)**2*s
2964 20058754 : qj(6) = 2*vec(3)*di(3) + vec(3)**2*s
2965 20058754 : qj(2) = vec(1)*di(2) + vec(2)*di(1) + vec(1)*vec(2)*s
2966 20058754 : qj(4) = vec(1)*di(3) + vec(3)*di(1) + vec(1)*vec(3)*s
2967 20058754 : qj(5) = vec(2)*di(3) + vec(3)*di(2) + vec(2)*vec(3)*s
2968 20058754 : tr = 0.5_dp*(qj(1) + qj(3) + qj(6))
2969 :
2970 20058754 : qj(1) = qi(1) + 1.5_dp*qj(1) - tr
2971 20058754 : qj(2) = qi(2) + 1.5_dp*qj(2)
2972 20058754 : qj(3) = qi(3) + 1.5_dp*qj(3) - tr
2973 20058754 : qj(4) = qi(4) + 1.5_dp*qj(4)
2974 20058754 : qj(5) = qi(5) + 1.5_dp*qj(5)
2975 20058754 : qj(6) = qi(6) + 1.5_dp*qj(6) - tr
2976 :
2977 20058754 : END SUBROUTINE tb_shift_multipole
2978 :
2979 : ! **************************************************************************************************
2980 : !> \brief compute the mulliken properties (AO resolved)
2981 : !> \param p_mat ...
2982 : !> \param s_matrix ...
2983 : !> \param charges ...
2984 : !> \param para_env ...
2985 : ! **************************************************************************************************
2986 1293384 : SUBROUTINE tb_ao_charges_matrix(p_mat, s_matrix, charges, para_env)
2987 : TYPE(dbcsr_type), POINTER :: p_mat, s_matrix
2988 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: charges
2989 : TYPE(mp_para_env_type), POINTER :: para_env
2990 :
2991 : INTEGER :: i, iblock_col, iblock_row, j
2992 : LOGICAL :: found
2993 1293384 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: p_block, s_block
2994 : TYPE(dbcsr_iterator_type) :: iter
2995 :
2996 55179774 : charges = 0.0_dp
2997 1293384 : CALL dbcsr_iterator_start(iter, s_matrix)
2998 14499562 : DO WHILE (dbcsr_iterator_blocks_left(iter))
2999 13206178 : NULLIFY (s_block, p_block)
3000 13206178 : CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, s_block)
3001 13206178 : CALL dbcsr_get_block_p(matrix=p_mat, row=iblock_row, col=iblock_col, BLOCK=p_block, found=found)
3002 13206178 : IF (.NOT. found) CYCLE
3003 13206178 : IF (.NOT. (ASSOCIATED(s_block) .AND. ASSOCIATED(p_block))) CYCLE
3004 :
3005 100889502 : DO j = 1, SIZE(p_block, 2)
3006 809262864 : DO i = 1, SIZE(p_block, 1)
3007 796056686 : charges(i, iblock_row) = charges(i, iblock_row) + p_block(i, j)*s_block(i, j)
3008 : END DO
3009 : END DO
3010 14499562 : IF (iblock_col /= iblock_row) THEN
3011 74544056 : DO j = 1, SIZE(p_block, 2)
3012 587433884 : DO i = 1, SIZE(p_block, 1)
3013 577312782 : charges(j, iblock_col) = charges(j, iblock_col) + p_block(i, j)*s_block(i, j)
3014 : END DO
3015 : END DO
3016 : END IF
3017 : END DO
3018 1293384 : CALL dbcsr_iterator_stop(iter)
3019 109066164 : CALL para_env%sum(charges)
3020 :
3021 1293384 : END SUBROUTINE tb_ao_charges_matrix
3022 :
3023 : ! **************************************************************************************************
3024 : !> \brief compute the AO-resolved Mulliken charges for one k-point spin channel.
3025 : !> \param p_matrix_kp ...
3026 : !> \param s_matrix_kp ...
3027 : !> \param charges ...
3028 : !> \param ispin ...
3029 : !> \param para_env ...
3030 : ! **************************************************************************************************
3031 25636 : SUBROUTINE tb_ao_charges_kp_spin(p_matrix_kp, s_matrix_kp, charges, ispin, para_env)
3032 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: p_matrix_kp, s_matrix_kp
3033 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: charges
3034 : INTEGER, INTENT(IN) :: ispin
3035 : TYPE(mp_para_env_type), POINTER :: para_env
3036 :
3037 : INTEGER :: ic
3038 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: image_charges
3039 : TYPE(dbcsr_type), POINTER :: p_mat, s_mat
3040 :
3041 978186 : charges = 0.0_dp
3042 102544 : ALLOCATE (image_charges(SIZE(charges, 1), SIZE(charges, 2)))
3043 1285988 : DO ic = 1, SIZE(s_matrix_kp, 2)
3044 : NULLIFY (p_mat, s_mat)
3045 1260352 : p_mat => p_matrix_kp(ispin, ic)%matrix
3046 1260352 : s_mat => s_matrix_kp(1, ic)%matrix
3047 1285988 : IF (ASSOCIATED(p_mat) .AND. ASSOCIATED(s_mat)) THEN
3048 1260352 : image_charges = 0.0_dp
3049 1260352 : CALL tb_ao_charges_matrix(p_mat, s_mat, image_charges, para_env)
3050 53797842 : charges(:, :) = charges(:, :) + image_charges(:, :)
3051 : END IF
3052 : END DO
3053 25636 : DEALLOCATE (image_charges)
3054 :
3055 25636 : END SUBROUTINE tb_ao_charges_kp_spin
3056 :
3057 : ! **************************************************************************************************
3058 : !> \brief compute the mulliken properties (AO resolved)
3059 : !> \param p_mat ...
3060 : !> \param bra_mat ...
3061 : !> \param ket_mat ...
3062 : !> \param output ...
3063 : !> \param para_env ...
3064 : ! **************************************************************************************************
3065 5717196 : SUBROUTINE tb_contract_dens_matrix(p_mat, bra_mat, ket_mat, output, para_env)
3066 : TYPE(dbcsr_type), POINTER :: p_mat, bra_mat, ket_mat
3067 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: output
3068 : TYPE(mp_para_env_type), POINTER :: para_env
3069 :
3070 : INTEGER :: i, iblock_col, iblock_row, j
3071 : LOGICAL :: found
3072 5717196 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: bra, ket, p_block
3073 : TYPE(dbcsr_iterator_type) :: iter
3074 :
3075 31817952 : output = 0.0_dp
3076 5717196 : CALL dbcsr_iterator_start(iter, bra_mat)
3077 58797117 : DO WHILE (dbcsr_iterator_blocks_left(iter))
3078 53079921 : NULLIFY (p_block, bra, ket)
3079 53079921 : CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, bra)
3080 53079921 : CALL dbcsr_get_block_p(matrix=p_mat, row=iblock_row, col=iblock_col, BLOCK=p_block, found=found)
3081 53079921 : IF (.NOT. found) CYCLE
3082 53079921 : CALL dbcsr_get_block_p(matrix=ket_mat, row=iblock_row, col=iblock_col, BLOCK=ket, found=found)
3083 53079921 : IF (.NOT. found) CPABORT("missing block")
3084 :
3085 53079921 : IF (.NOT. (ASSOCIATED(bra) .AND. ASSOCIATED(p_block))) CYCLE
3086 58797117 : IF (iblock_col == iblock_row) THEN
3087 118671120 : DO j = 1, SIZE(p_block, 1)
3088 1036895958 : DO i = 1, SIZE(p_block, 2)
3089 1023845580 : output(iblock_row) = output(iblock_row) + p_block(j, i)*bra(j, i)
3090 : END DO
3091 : END DO
3092 : ELSE
3093 300967092 : DO j = 1, SIZE(p_block, 1)
3094 2538367695 : DO i = 1, SIZE(p_block, 2)
3095 2498338152 : output(iblock_row) = output(iblock_row) + p_block(j, i)*ket(j, i)
3096 : END DO
3097 : END DO
3098 300967092 : DO j = 1, SIZE(p_block, 1)
3099 2538367695 : DO i = 1, SIZE(p_block, 2)
3100 2498338152 : output(iblock_col) = output(iblock_col) + p_block(j, i)*bra(j, i)
3101 : END DO
3102 : END DO
3103 : END IF
3104 : END DO
3105 5717196 : CALL dbcsr_iterator_stop(iter)
3106 57918708 : CALL para_env%sum(output)
3107 :
3108 5717196 : END SUBROUTINE tb_contract_dens_matrix
3109 :
3110 : ! **************************************************************************************************
3111 : !> \brief compute the AO-resolved density contraction for one k-point spin channel.
3112 : !> \param p_matrix ...
3113 : !> \param bra_mat ...
3114 : !> \param ket_mat ...
3115 : !> \param iop ...
3116 : !> \param nops ...
3117 : !> \param output ...
3118 : !> \param ispin ...
3119 : !> \param para_env ...
3120 : ! **************************************************************************************************
3121 162414 : SUBROUTINE tb_contract_dens_kp_spin(p_matrix, bra_mat, ket_mat, iop, nops, output, ispin, para_env)
3122 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: p_matrix
3123 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: bra_mat, ket_mat
3124 : INTEGER, INTENT(IN) :: iop, nops
3125 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: output
3126 : INTEGER, INTENT(IN) :: ispin
3127 : TYPE(mp_para_env_type), POINTER :: para_env
3128 :
3129 : INTEGER :: ic, idx, nimg
3130 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: image_output
3131 : TYPE(dbcsr_type), POINTER :: p_mat
3132 :
3133 162414 : nimg = SIZE(p_matrix, 2)
3134 799506 : output = 0.0_dp
3135 487242 : ALLOCATE (image_output(SIZE(output)))
3136 5671548 : DO ic = 1, nimg
3137 5509134 : idx = iop + nops*(ic - 1)
3138 5509134 : CPASSERT(idx <= SIZE(bra_mat))
3139 5509134 : CPASSERT(idx <= SIZE(ket_mat))
3140 : NULLIFY (p_mat)
3141 5509134 : p_mat => p_matrix(ispin, ic)%matrix
3142 5509134 : image_output = 0.0_dp
3143 5509134 : CALL tb_contract_dens_matrix(p_mat, bra_mat(idx)%matrix, ket_mat(idx)%matrix, image_output, para_env)
3144 30755016 : output = output + image_output
3145 : END DO
3146 162414 : DEALLOCATE (image_output)
3147 :
3148 162414 : END SUBROUTINE tb_contract_dens_kp_spin
3149 :
3150 : ! **************************************************************************************************
3151 : !> \brief compute the mulliken properties (AO resolved)
3152 : !> \param p_matrix ...
3153 : !> \param bra_mat ...
3154 : !> \param ket_mat ...
3155 : !> \param output ...
3156 : !> \param para_env ...
3157 : !> \par History
3158 : !> adapted from ao_charges_2
3159 : !> \note
3160 : ! **************************************************************************************************
3161 0 : SUBROUTINE contract_dens(p_matrix, bra_mat, ket_mat, output, para_env)
3162 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: p_matrix
3163 : TYPE(dbcsr_type), POINTER :: bra_mat, ket_mat
3164 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: output
3165 : TYPE(mp_para_env_type), POINTER :: para_env
3166 :
3167 : CHARACTER(len=*), PARAMETER :: routineN = 'contract_dens'
3168 :
3169 : INTEGER :: handle, i, iblock_col, iblock_row, &
3170 : ispin, j, nspin
3171 : LOGICAL :: found
3172 0 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: bra, ket, p_block
3173 : TYPE(dbcsr_iterator_type) :: iter
3174 :
3175 0 : CALL timeset(routineN, handle)
3176 :
3177 0 : nspin = SIZE(p_matrix)
3178 0 : output = 0.0_dp
3179 0 : DO ispin = 1, nspin
3180 0 : CALL dbcsr_iterator_start(iter, bra_mat)
3181 0 : DO WHILE (dbcsr_iterator_blocks_left(iter))
3182 0 : NULLIFY (p_block, bra, ket)
3183 :
3184 0 : CALL dbcsr_iterator_next_block(iter, iblock_row, iblock_col, bra)
3185 : CALL dbcsr_get_block_p(matrix=p_matrix(ispin)%matrix, &
3186 0 : row=iblock_row, col=iblock_col, BLOCK=p_block, found=found)
3187 0 : IF (.NOT. found) CYCLE
3188 : CALL dbcsr_get_block_p(matrix=ket_mat, &
3189 0 : row=iblock_row, col=iblock_col, BLOCK=ket, found=found)
3190 0 : IF (.NOT. found) CPABORT("missing block")
3191 :
3192 0 : IF (.NOT. (ASSOCIATED(bra) .AND. ASSOCIATED(p_block))) CYCLE
3193 0 : IF (iblock_col == iblock_row) THEN
3194 0 : DO j = 1, SIZE(p_block, 1)
3195 0 : DO i = 1, SIZE(p_block, 2)
3196 0 : output(iblock_row) = output(iblock_row) + p_block(j, i)*bra(j, i)
3197 : END DO
3198 : END DO
3199 : ELSE
3200 0 : DO j = 1, SIZE(p_block, 1)
3201 0 : DO i = 1, SIZE(p_block, 2)
3202 0 : output(iblock_row) = output(iblock_row) + p_block(j, i)*ket(j, i)
3203 : END DO
3204 : END DO
3205 0 : DO j = 1, SIZE(p_block, 1)
3206 0 : DO i = 1, SIZE(p_block, 2)
3207 0 : output(iblock_col) = output(iblock_col) + p_block(j, i)*bra(j, i)
3208 : END DO
3209 : END DO
3210 : END IF
3211 : END DO
3212 0 : CALL dbcsr_iterator_stop(iter)
3213 : END DO
3214 :
3215 0 : CALL para_env%sum(output)
3216 0 : CALL timestop(handle)
3217 :
3218 0 : END SUBROUTINE contract_dens
3219 :
3220 : ! **************************************************************************************************
3221 : !> \brief compute the AO-resolved density contraction for real-space k-point image matrices
3222 : !> \param p_matrix ...
3223 : !> \param bra_mat ...
3224 : !> \param ket_mat ...
3225 : !> \param iop ...
3226 : !> \param nops ...
3227 : !> \param output ...
3228 : !> \param para_env ...
3229 : ! **************************************************************************************************
3230 0 : SUBROUTINE contract_dens_kp(p_matrix, bra_mat, ket_mat, iop, nops, output, para_env)
3231 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: p_matrix
3232 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: bra_mat, ket_mat
3233 : INTEGER, INTENT(IN) :: iop, nops
3234 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: output
3235 : TYPE(mp_para_env_type), POINTER :: para_env
3236 :
3237 : INTEGER :: ic, idx, nimg
3238 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: image_output
3239 0 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: p_image
3240 :
3241 0 : nimg = SIZE(p_matrix, 2)
3242 0 : output = 0.0_dp
3243 0 : ALLOCATE (image_output(SIZE(output)))
3244 0 : DO ic = 1, nimg
3245 0 : idx = iop + nops*(ic - 1)
3246 0 : CPASSERT(idx <= SIZE(bra_mat))
3247 0 : CPASSERT(idx <= SIZE(ket_mat))
3248 : NULLIFY (p_image)
3249 0 : p_image => p_matrix(:, ic)
3250 0 : image_output = 0.0_dp
3251 0 : CALL contract_dens(p_image, bra_mat(idx)%matrix, ket_mat(idx)%matrix, image_output, para_env)
3252 0 : output = output + image_output
3253 : END DO
3254 0 : DEALLOCATE (image_output)
3255 :
3256 0 : END SUBROUTINE contract_dens_kp
3257 :
3258 : ! **************************************************************************************************
3259 : !> \brief save gradient to force
3260 : !> \param qs_env ...
3261 : !> \param tb ...
3262 : !> \param para_env ...
3263 : !> \param ityp ...
3264 : !> \note
3265 : ! **************************************************************************************************
3266 1006 : SUBROUTINE tb_grad2force(qs_env, tb, para_env, ityp)
3267 :
3268 : TYPE(qs_environment_type) :: qs_env
3269 : TYPE(tblite_type) :: tb
3270 : TYPE(mp_para_env_type) :: para_env
3271 : INTEGER :: ityp
3272 :
3273 : CHARACTER(len=*), PARAMETER :: routineN = 'tb_grad2force'
3274 :
3275 : CHARACTER(LEN=default_path_length) :: dump_file
3276 : INTEGER :: atoma, dump_status, dump_unit, handle, &
3277 : iatom, ikind, natom
3278 1006 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_of_kind, kind_of
3279 1006 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3280 1006 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3281 1006 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
3282 :
3283 1006 : CALL timeset(routineN, handle)
3284 :
3285 1006 : NULLIFY (force, atomic_kind_set)
3286 : CALL get_qs_env(qs_env=qs_env, force=force, particle_set=particle_set, &
3287 1006 : atomic_kind_set=atomic_kind_set)
3288 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
3289 1006 : atom_of_kind=atom_of_kind, kind_of=kind_of)
3290 :
3291 1006 : natom = SIZE(particle_set)
3292 :
3293 1006 : dump_status = 1
3294 : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
3295 : CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_FORCE_DUMP", dump_file, STATUS=dump_status)
3296 : #endif
3297 : IF (dump_status == 0) THEN
3298 : OPEN (NEWUNIT=dump_unit, FILE=TRIM(dump_file), STATUS="UNKNOWN", &
3299 : POSITION="APPEND", ACTION="WRITE")
3300 : WRITE (dump_unit, "(A,1X,I0)") "component", ityp
3301 : DO iatom = 1, natom
3302 : WRITE (dump_unit, "(I0,3(1X,ES24.16))") iatom, tb%grad(:, iatom)/para_env%num_pe
3303 : END DO
3304 : CLOSE (dump_unit)
3305 : END IF
3306 :
3307 1006 : SELECT CASE (ityp)
3308 : CASE DEFAULT
3309 0 : CPABORT("unknown force type")
3310 : CASE (0)
3311 696 : DO iatom = 1, natom
3312 612 : ikind = kind_of(iatom)
3313 612 : atoma = atom_of_kind(iatom)
3314 : force(ikind)%all_potential(:, atoma) = &
3315 2532 : force(ikind)%all_potential(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
3316 : END DO
3317 : CASE (1)
3318 1014 : DO iatom = 1, natom
3319 864 : ikind = kind_of(iatom)
3320 864 : atoma = atom_of_kind(iatom)
3321 : force(ikind)%repulsive(:, atoma) = &
3322 3606 : force(ikind)%repulsive(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
3323 : END DO
3324 : CASE (2)
3325 2028 : DO iatom = 1, natom
3326 1728 : ikind = kind_of(iatom)
3327 1728 : atoma = atom_of_kind(iatom)
3328 : force(ikind)%dispersion(:, atoma) = &
3329 7212 : force(ikind)%dispersion(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
3330 : END DO
3331 : CASE (3)
3332 1088 : DO iatom = 1, natom
3333 916 : ikind = kind_of(iatom)
3334 916 : atoma = atom_of_kind(iatom)
3335 : force(ikind)%rho_elec(:, atoma) = &
3336 3836 : force(ikind)%rho_elec(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
3337 : END DO
3338 : CASE (4)
3339 2028 : DO iatom = 1, natom
3340 1728 : ikind = kind_of(iatom)
3341 1728 : atoma = atom_of_kind(iatom)
3342 : force(ikind)%overlap(:, atoma) = &
3343 7212 : force(ikind)%overlap(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
3344 : END DO
3345 : CASE (5)
3346 1006 : DO iatom = 1, natom
3347 0 : ikind = kind_of(iatom)
3348 0 : atoma = atom_of_kind(iatom)
3349 : force(ikind)%efield(:, atoma) = &
3350 0 : force(ikind)%efield(:, atoma) + tb%grad(:, iatom)/para_env%num_pe
3351 : END DO
3352 : END SELECT
3353 :
3354 1006 : CALL timestop(handle)
3355 :
3356 2012 : END SUBROUTINE tb_grad2force
3357 :
3358 : ! **************************************************************************************************
3359 : !> \brief set gradient to zero
3360 : !> \param qs_env ...
3361 : !> \note
3362 : ! **************************************************************************************************
3363 150 : SUBROUTINE tb_zero_force(qs_env)
3364 :
3365 : TYPE(qs_environment_type) :: qs_env
3366 :
3367 : INTEGER :: iatom, ikind, natom
3368 150 : INTEGER, ALLOCATABLE, DIMENSION(:) :: kind_of
3369 150 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3370 150 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3371 150 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
3372 :
3373 150 : NULLIFY (force, atomic_kind_set)
3374 : CALL get_qs_env(qs_env=qs_env, force=force, particle_set=particle_set, &
3375 150 : atomic_kind_set=atomic_kind_set)
3376 : CALL get_atomic_kind_set(atomic_kind_set=atomic_kind_set, &
3377 150 : kind_of=kind_of)
3378 :
3379 150 : natom = SIZE(particle_set)
3380 :
3381 1014 : DO iatom = 1, natom
3382 864 : ikind = kind_of(iatom)
3383 17008 : force(ikind)%all_potential = 0.0_dp
3384 17008 : force(ikind)%repulsive = 0.0_dp
3385 17008 : force(ikind)%dispersion = 0.0_dp
3386 17008 : force(ikind)%rho_elec = 0.0_dp
3387 17008 : force(ikind)%overlap = 0.0_dp
3388 17158 : force(ikind)%efield = 0.0_dp
3389 : END DO
3390 :
3391 300 : END SUBROUTINE tb_zero_force
3392 :
3393 : ! **************************************************************************************************
3394 : !> \brief Add SCC-overlap and direct multipole Hamiltonian derivatives.
3395 : !> \param qs_env ...
3396 : !> \param use_rho ...
3397 : !> \param nimg ...
3398 : ! **************************************************************************************************
3399 150 : SUBROUTINE tb_derive_dH_off(qs_env, use_rho, nimg)
3400 :
3401 : TYPE(qs_environment_type), POINTER :: qs_env
3402 : LOGICAL, INTENT(IN) :: use_rho
3403 : INTEGER, INTENT(IN) :: nimg
3404 :
3405 : #if defined(__TBLITE)
3406 : INTEGER :: i, idim, ij, iatom, ic, icol, ikind, img, ispin, &
3407 : jdim, ni, nj, nkind, nel, &
3408 : ityp, jatom, jkind, jrow, jtyp, iset, jset, nseti, nsetj, &
3409 : ia, ib, inda, indb, sampled_axes, sampled_even_axes, &
3410 : sampled_gamma_axes, nspin, ikp_axis
3411 : INTEGER, DIMENSION(3) :: cellind, nkp_cellind, nkp_grid
3412 150 : INTEGER, DIMENSION(:), POINTER :: nsgfa, nsgfb
3413 150 : INTEGER, DIMENSION(:, :), POINTER :: first_sgfa, first_sgfb
3414 150 : INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
3415 : LOGICAL :: found, gamma_centered, gamma_sampled_image_pair, &
3416 : has_multipole_response, sampled_image_pair, &
3417 : use_matrix_scc_stress
3418 : LOGICAL, DIMENSION(3) :: mesh_has_gamma
3419 : REAL(KIND=dp) :: r2, dr, i_a_shift, j_a_shift, i_a_shift_mag, j_a_shift_mag, &
3420 : ishift, jshift, ishift_mag, jshift_mag, pij_charge, &
3421 : pij_magnet, mp_pair_scale, kpoint_coordinate, native_dot_tmp
3422 : REAL(KIND=dp), DIMENSION(3) :: kp_shift
3423 : REAL(KIND=dp), DIMENSION(3) :: rij, dgrad, dhgrad_charge, dhgrad_magnet, &
3424 : mpgrad_charge, mpgrad_magnet
3425 : REAL(KIND=dp), DIMENSION(3, 3) :: hsigma
3426 300 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: t_ov, idip, jdip, idip_mag, jdip_mag, &
3427 150 : iquad, jquad, iquad_mag, jquad_mag
3428 150 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: t_dip, t_quad, t_d_ov
3429 150 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: t_i_dip, t_i_quad, t_j_dip, t_j_quad
3430 150 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :, :, :) :: scc_strain_hint
3431 150 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: pblock, pblock_beta
3432 4050 : TYPE(block_p_type), DIMENSION(3, 3, 2) :: scc_strain_blocks
3433 :
3434 150 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3435 150 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_dh_scc, matrix_p
3436 150 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: basis_set_list
3437 : TYPE(gto_basis_set_type), POINTER :: basis_set_a, basis_set_b
3438 : TYPE(kpoint_type), POINTER :: kpoints
3439 : TYPE(mp_para_env_type), POINTER :: para_env
3440 : TYPE(neighbor_list_iterator_p_type), &
3441 150 : DIMENSION(:), POINTER :: nl_iterator
3442 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
3443 150 : POINTER :: sab_orb
3444 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
3445 150 : POINTER :: sab_kp
3446 150 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
3447 : TYPE(qs_rho_type), POINTER :: rho
3448 : TYPE(qs_scf_env_type), POINTER :: scf_env
3449 : TYPE(tblite_type), POINTER :: tb
3450 : TYPE(virial_type), POINTER :: virial
3451 :
3452 : ! compute mulliken charges required for charge update
3453 150 : NULLIFY (scf_env, rho, tb, sab_orb, sab_kp, para_env, kpoints, matrix_dh_scc, virial)
3454 : CALL get_qs_env(qs_env=qs_env, &
3455 : atomic_kind_set=atomic_kind_set, &
3456 : scf_env=scf_env, &
3457 : rho=rho, &
3458 : tb_tblite=tb, &
3459 : sab_orb=sab_orb, &
3460 : sab_kp=sab_kp, &
3461 : para_env=para_env, &
3462 : qs_kind_set=qs_kind_set, &
3463 150 : kpoints=kpoints)
3464 :
3465 150 : NULLIFY (cell_to_index)
3466 150 : IF (nimg > 1) THEN
3467 90 : IF (.NOT. ASSOCIATED(sab_kp)) CPABORT("Missing tblite k-point neighbor list")
3468 90 : sab_orb => sab_kp
3469 : CALL get_kpoint_info(kpoint=kpoints, cell_to_index=cell_to_index, nkp_grid=nkp_grid, &
3470 90 : kp_shift=kp_shift, gamma_centered=gamma_centered)
3471 : ELSE
3472 240 : nkp_grid = 1
3473 60 : kp_shift = 0.0_dp
3474 60 : gamma_centered = .TRUE.
3475 : END IF
3476 150 : mesh_has_gamma = .FALSE.
3477 600 : DO i = 1, 3
3478 1278 : DO ikp_axis = 1, nkp_grid(i)
3479 678 : IF (gamma_centered .AND. MODULO(nkp_grid(i), 2) == 0) THEN
3480 : kpoint_coordinate = REAL(2*ikp_axis - nkp_grid(i), KIND=dp)/ &
3481 0 : REAL(2*nkp_grid(i), KIND=dp) + kp_shift(i)
3482 : ELSE
3483 : kpoint_coordinate = REAL(2*ikp_axis - nkp_grid(i) - 1, KIND=dp)/ &
3484 678 : REAL(2*nkp_grid(i), KIND=dp) + kp_shift(i)
3485 : END IF
3486 1128 : IF (ABS(kpoint_coordinate - ANINT(kpoint_coordinate)) < 1.0e-12_dp) THEN
3487 318 : mesh_has_gamma(i) = .TRUE.
3488 : END IF
3489 : END DO
3490 : END DO
3491 150 : has_multipole_response = ASSOCIATED(tb%dipbra) .OR. ASSOCIATED(tb%quadbra)
3492 :
3493 150 : NULLIFY (matrix_p)
3494 150 : IF (use_rho) THEN
3495 128 : CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
3496 22 : ELSE IF (ASSOCIATED(tb%rho_ao_kp_ref)) THEN
3497 22 : matrix_p => tb%rho_ao_kp_ref
3498 : ELSE
3499 0 : matrix_p => scf_env%p_mix_new
3500 : END IF
3501 150 : nspin = SIZE(matrix_p, 1)
3502 384 : use_matrix_scc_stress = tb%use_virial .AND. nimg > 1 .AND. ALL(tb%mol%periodic)
3503 :
3504 : IF (use_matrix_scc_stress) THEN
3505 48 : CALL dbcsr_allocate_matrix_set(matrix_dh_scc, 9*nspin, nimg)
3506 3826 : DO img = 1, nimg
3507 7660 : DO ispin = 1, nspin
3508 19114 : DO jdim = 1, 3
3509 49842 : DO idim = 1, 3
3510 34506 : i = idim + 3*(jdim - 1) + 9*(ispin - 1)
3511 34506 : ALLOCATE (matrix_dh_scc(i, img)%matrix)
3512 : CALL dbcsr_create(matrix_dh_scc(i, img)%matrix, template=matrix_p(ispin, img)%matrix, &
3513 34506 : name="TBLITE SCC STRAIN DERIVATIVE")
3514 46008 : CALL cp_dbcsr_alloc_block_from_nbl(matrix_dh_scc(i, img)%matrix, sab_orb)
3515 : END DO
3516 : END DO
3517 : END DO
3518 : END DO
3519 : END IF
3520 :
3521 : ! set up basis set lists
3522 150 : nkind = SIZE(atomic_kind_set)
3523 742 : ALLOCATE (basis_set_list(nkind))
3524 150 : CALL basis_set_list_setup(basis_set_list, "ORB", qs_kind_set)
3525 :
3526 150 : nel = msao(tb%calc%bas%maxl)**2
3527 450 : ALLOCATE (t_ov(nel))
3528 450 : ALLOCATE (t_d_ov(3, nel))
3529 300 : ALLOCATE (t_dip(dip_n, nel))
3530 600 : ALLOCATE (t_i_dip(3, dip_n, nel), t_j_dip(3, dip_n, nel))
3531 450 : ALLOCATE (t_quad(quad_n, nel))
3532 600 : ALLOCATE (t_i_quad(3, quad_n, nel), t_j_quad(3, quad_n, nel))
3533 :
3534 150 : ALLOCATE (idip(dip_n), jdip(dip_n), idip_mag(dip_n), jdip_mag(dip_n))
3535 150 : ALLOCATE (iquad(quad_n), jquad(quad_n), iquad_mag(quad_n), jquad_mag(quad_n))
3536 :
3537 3606 : tb%grad = 0.0_dp
3538 150 : hsigma = 0.0_dp
3539 : ! loop over all atom pairs with a non-zero overlap (sab_orb)
3540 150 : NULLIFY (nl_iterator)
3541 150 : CALL neighbor_list_iterator_create(nl_iterator, sab_orb)
3542 63669 : DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
3543 : CALL get_iterator_info(nl_iterator, ikind=ikind, jkind=jkind, &
3544 63519 : iatom=iatom, jatom=jatom, r=rij, cell=cellind)
3545 :
3546 63519 : icol = MAX(iatom, jatom)
3547 63519 : jrow = MIN(iatom, jatom)
3548 :
3549 63519 : IF (iatom < jatom) THEN
3550 93784 : rij = -rij
3551 23446 : i = ikind
3552 23446 : ikind = jkind
3553 23446 : jkind = i
3554 : END IF
3555 :
3556 63519 : ityp = tb%mol%id(icol)
3557 63519 : jtyp = tb%mol%id(jrow)
3558 :
3559 254076 : r2 = DOT_PRODUCT(rij, rij)
3560 63519 : dr = SQRT(r2)
3561 63519 : IF (icol == jrow .AND. dr < same_atom) CYCLE
3562 :
3563 : !get basis information
3564 63087 : basis_set_a => basis_set_list(ikind)%gto_basis_set
3565 63087 : IF (.NOT. ASSOCIATED(basis_set_a)) CYCLE
3566 63087 : first_sgfa => basis_set_a%first_sgf
3567 63087 : nsgfa => basis_set_a%nsgf_set
3568 63087 : nseti = basis_set_a%nset
3569 63087 : basis_set_b => basis_set_list(jkind)%gto_basis_set
3570 63087 : IF (.NOT. ASSOCIATED(basis_set_b)) CYCLE
3571 63087 : first_sgfb => basis_set_b%first_sgf
3572 63087 : nsgfb => basis_set_b%nsgf_set
3573 63087 : nsetj = basis_set_b%nset
3574 :
3575 63087 : IF (nimg == 1) THEN
3576 : ic = 1
3577 : ELSE
3578 50260 : ic = cell_to_index(cellind(1), cellind(2), cellind(3))
3579 50260 : CPASSERT(ic > 0)
3580 : END IF
3581 63087 : nkp_cellind = 0
3582 252348 : DO i = 1, 3
3583 252348 : IF (nkp_grid(i) > 1) THEN
3584 150042 : nkp_cellind(i) = MODULO(cellind(i), nkp_grid(i))
3585 150042 : IF (2*nkp_cellind(i) > nkp_grid(i)) nkp_cellind(i) = nkp_cellind(i) - nkp_grid(i)
3586 : END IF
3587 : END DO
3588 63087 : sampled_axes = 0
3589 63087 : IF (nkp_cellind(1) /= 0) sampled_axes = sampled_axes + 1
3590 63087 : IF (nkp_cellind(2) /= 0) sampled_axes = sampled_axes + 1
3591 63087 : IF (nkp_cellind(3) /= 0) sampled_axes = sampled_axes + 1
3592 63087 : sampled_even_axes = 0
3593 63087 : sampled_gamma_axes = 0
3594 252348 : DO i = 1, 3
3595 189261 : IF (nkp_grid(i) > 1 .AND. MODULO(nkp_grid(i), 2) == 0 .AND. &
3596 63087 : ABS(2*nkp_cellind(i)) == nkp_grid(i)) THEN
3597 78936 : sampled_even_axes = sampled_even_axes + 1
3598 78936 : IF (mesh_has_gamma(i)) sampled_gamma_axes = sampled_gamma_axes + 1
3599 : END IF
3600 : END DO
3601 63087 : sampled_image_pair = sampled_axes > 0 .AND. sampled_even_axes > 0
3602 63087 : gamma_sampled_image_pair = sampled_image_pair .AND. sampled_gamma_axes == sampled_even_axes
3603 63087 : mp_pair_scale = 1.0_dp
3604 63087 : IF (icol == jrow .AND. sampled_image_pair .AND. has_multipole_response .AND. &
3605 724 : .NOT. gamma_sampled_image_pair) mp_pair_scale = -1.0_dp
3606 :
3607 63087 : NULLIFY (pblock, pblock_beta)
3608 : CALL dbcsr_get_block_p(matrix=matrix_p(1, ic)%matrix, &
3609 63087 : row=jrow, col=icol, BLOCK=pblock, found=found)
3610 63087 : IF (.NOT. found) CPABORT("pblock not found")
3611 63087 : IF (nspin > 1) THEN
3612 : CALL dbcsr_get_block_p(matrix=matrix_p(2, ic)%matrix, &
3613 171 : row=jrow, col=icol, BLOCK=pblock_beta, found=found)
3614 171 : IF (.NOT. found) CPABORT("pblock beta not found")
3615 : END IF
3616 63087 : IF (use_matrix_scc_stress) THEN
3617 338982 : ALLOCATE (scc_strain_hint(SIZE(pblock, 2), SIZE(pblock, 1), 3, 3, nspin))
3618 48426 : scc_strain_hint = 0.0_dp
3619 96928 : DO ispin = 1, nspin
3620 242434 : DO jdim = 1, 3
3621 630526 : DO idim = 1, 3
3622 436518 : NULLIFY (scc_strain_blocks(idim, jdim, ispin)%block)
3623 436518 : i = idim + 3*(jdim - 1) + 9*(ispin - 1)
3624 : CALL dbcsr_get_block_p(matrix=matrix_dh_scc(i, ic)%matrix, &
3625 : row=jrow, col=icol, &
3626 436518 : BLOCK=scc_strain_blocks(idim, jdim, ispin)%block, found=found)
3627 582024 : IF (.NOT. found) CPABORT("SCC strain derivative block not found")
3628 : END DO
3629 : END DO
3630 : END DO
3631 : END IF
3632 63087 : i_a_shift = tb%pot%vat(icol, 1)
3633 63087 : j_a_shift = tb%pot%vat(jrow, 1)
3634 63087 : i_a_shift_mag = 0.0_dp
3635 63087 : j_a_shift_mag = 0.0_dp
3636 63087 : IF (SIZE(tb%pot%vat, 2) > 1) THEN
3637 171 : i_a_shift_mag = tb%pot%vat(icol, 2)
3638 171 : j_a_shift_mag = tb%pot%vat(jrow, 2)
3639 : END IF
3640 252348 : idip(:) = tb%pot%vdp(:, icol, 1)
3641 252348 : jdip(:) = tb%pot%vdp(:, jrow, 1)
3642 63087 : idip_mag(:) = 0.0_dp
3643 63087 : jdip_mag(:) = 0.0_dp
3644 63087 : IF (SIZE(tb%pot%vdp, 3) > 1) THEN
3645 684 : idip_mag(:) = tb%pot%vdp(:, icol, 2)
3646 684 : jdip_mag(:) = tb%pot%vdp(:, jrow, 2)
3647 : END IF
3648 441609 : iquad(:) = tb%pot%vqp(:, icol, 1)
3649 441609 : jquad(:) = tb%pot%vqp(:, jrow, 1)
3650 63087 : iquad_mag(:) = 0.0_dp
3651 63087 : jquad_mag(:) = 0.0_dp
3652 63087 : IF (SIZE(tb%pot%vqp, 3) > 1) THEN
3653 1197 : iquad_mag(:) = tb%pot%vqp(:, icol, 2)
3654 1197 : jquad_mag(:) = tb%pot%vqp(:, jrow, 2)
3655 : END IF
3656 63087 : ni = tb%calc%bas%ish_at(icol)
3657 209808 : DO iset = 1, nseti
3658 146721 : ishift = i_a_shift + tb%pot%vsh(ni + iset, 1)
3659 146721 : ishift_mag = 0.0_dp
3660 146721 : IF (SIZE(tb%pot%vsh, 2) > 1) ishift_mag = i_a_shift_mag + tb%pot%vsh(ni + iset, 2)
3661 146721 : nj = tb%calc%bas%ish_at(jrow)
3662 564959 : DO jset = 1, nsetj
3663 355151 : jshift = j_a_shift + tb%pot%vsh(nj + jset, 1)
3664 355151 : jshift_mag = 0.0_dp
3665 355151 : IF (SIZE(tb%pot%vsh, 2) > 1) jshift_mag = j_a_shift_mag + tb%pot%vsh(nj + jset, 2)
3666 :
3667 : !get integrals and derivatives
3668 : CALL multipole_grad_cgto(tb%calc%bas%cgto(iset, ityp), tb%calc%bas%cgto(jset, jtyp), &
3669 : & r2, rij, tb%calc%bas%intcut, t_ov, t_dip, t_quad, t_d_ov, t_i_dip, t_i_quad, &
3670 355151 : & t_j_dip, t_j_quad)
3671 :
3672 355151 : dgrad = 0.0_dp
3673 1117212 : DO inda = 1, nsgfa(iset)
3674 762061 : ia = first_sgfa(1, iset) - first_sgfa(1, 1) + inda
3675 3138323 : DO indb = 1, nsgfb(jset)
3676 2021111 : ib = first_sgfb(1, jset) - first_sgfb(1, 1) + indb
3677 :
3678 2021111 : ij = inda + nsgfa(iset)*(indb - 1)
3679 :
3680 2021111 : pij_charge = pblock(ib, ia)
3681 2021111 : pij_magnet = 0.0_dp
3682 2021111 : IF (nspin > 1) THEN
3683 2638 : pij_charge = pij_charge + pblock_beta(ib, ia)
3684 2638 : pij_magnet = pblock(ib, ia) - pblock_beta(ib, ia)
3685 : END IF
3686 : mpgrad_charge = MATMUL(t_i_dip(:, :, ij), idip) &
3687 2021111 : + MATMUL(t_j_dip(:, :, ij), jdip) &
3688 2021111 : + MATMUL(t_i_quad(:, :, ij), iquad) &
3689 159667769 : + MATMUL(t_j_quad(:, :, ij), jquad)
3690 : mpgrad_magnet = MATMUL(t_i_dip(:, :, ij), idip_mag) &
3691 2021111 : + MATMUL(t_j_dip(:, :, ij), jdip_mag) &
3692 2021111 : + MATMUL(t_i_quad(:, :, ij), iquad_mag) &
3693 159667769 : + MATMUL(t_j_quad(:, :, ij), jquad_mag)
3694 8084444 : dhgrad_charge = -(ishift + jshift)*t_d_ov(:, ij) - mp_pair_scale*mpgrad_charge
3695 8084444 : dhgrad_magnet = -(ishift_mag + jshift_mag)*t_d_ov(:, ij) - mp_pair_scale*mpgrad_magnet
3696 : dgrad(:) = dgrad(:) - &
3697 : ((ishift + jshift)*pij_charge + &
3698 : (ishift_mag + jshift_mag)*pij_magnet)*t_d_ov(:, ij) - &
3699 8084444 : mp_pair_scale*(pij_charge*mpgrad_charge + pij_magnet*mpgrad_magnet)
3700 :
3701 2783172 : IF (ALLOCATED(scc_strain_hint)) THEN
3702 3652568 : DO jdim = 1, 3
3703 11870846 : DO idim = 1, 3
3704 : scc_strain_hint(ia, ib, idim, jdim, 1) = &
3705 : scc_strain_hint(ia, ib, idim, jdim, 1) &
3706 8218278 : + (dhgrad_charge(idim) + MERGE(dhgrad_magnet(idim), 0.0_dp, nspin > 1))*rij(jdim)
3707 10957704 : IF (nspin > 1) THEN
3708 : scc_strain_hint(ia, ib, idim, jdim, 2) = &
3709 : scc_strain_hint(ia, ib, idim, jdim, 2) &
3710 10944 : + (dhgrad_charge(idim) - dhgrad_magnet(idim))*rij(jdim)
3711 : END IF
3712 : END DO
3713 : END DO
3714 : END IF
3715 :
3716 : END DO
3717 : END DO
3718 1420604 : tb%grad(:, icol) = tb%grad(:, icol) - dgrad
3719 1420604 : tb%grad(:, jrow) = tb%grad(:, jrow) + dgrad
3720 501872 : IF (tb%use_virial .AND. .NOT. use_matrix_scc_stress) THEN
3721 114133 : IF (icol == jrow) THEN
3722 113600 : DO ia = 1, 3
3723 369200 : DO ib = 1, 3
3724 340800 : IF (sampled_image_pair .AND. .NOT. gamma_sampled_image_pair) THEN
3725 : hsigma(ia, ib) = hsigma(ia, ib) - 0.25_dp* &
3726 9792 : (rij(ia)*dgrad(ib) + rij(ib)*dgrad(ia))
3727 : ELSE
3728 : hsigma(ia, ib) = hsigma(ia, ib) + 0.25_dp* &
3729 245808 : (rij(ia)*dgrad(ib) + rij(ib)*dgrad(ia))
3730 : END IF
3731 : END DO
3732 : END DO
3733 : ELSE
3734 342932 : DO ia = 1, 3
3735 1114529 : DO ib = 1, 3
3736 1028796 : hsigma(ia, ib) = hsigma(ia, ib) + 0.50_dp*(rij(ia)*dgrad(ib) + rij(ib)*dgrad(ia))
3737 : END DO
3738 : END DO
3739 : END IF
3740 : END IF
3741 : END DO
3742 : END DO
3743 63237 : IF (ALLOCATED(scc_strain_hint)) THEN
3744 96928 : DO ispin = 1, nspin
3745 242434 : DO jdim = 1, 3
3746 630526 : DO idim = 1, 3
3747 582024 : IF (icol <= jrow) THEN
3748 : scc_strain_blocks(idim, jdim, ispin)%block(:, :) = &
3749 : scc_strain_blocks(idim, jdim, ispin)%block(:, :) &
3750 1972404 : + scc_strain_hint(:, :, idim, jdim, ispin)
3751 : ELSE
3752 : scc_strain_blocks(idim, jdim, ispin)%block(:, :) = &
3753 : scc_strain_blocks(idim, jdim, ispin)%block(:, :) &
3754 8163558 : + TRANSPOSE(scc_strain_hint(:, :, idim, jdim, ispin))
3755 : END IF
3756 : END DO
3757 : END DO
3758 : END DO
3759 48426 : DEALLOCATE (scc_strain_hint)
3760 : END IF
3761 : END DO
3762 150 : CALL neighbor_list_iterator_release(nl_iterator)
3763 :
3764 150 : IF (use_matrix_scc_stress) THEN
3765 48 : hsigma = 0.0_dp
3766 3826 : DO img = 1, nimg
3767 7660 : DO ispin = 1, nspin
3768 19114 : DO jdim = 1, 3
3769 49842 : DO idim = 1, 3
3770 34506 : i = idim + 3*(jdim - 1) + 9*(ispin - 1)
3771 34506 : CALL dbcsr_finalize(matrix_dh_scc(i, img)%matrix)
3772 34506 : CALL dbcsr_dot(matrix_dh_scc(i, img)%matrix, matrix_p(ispin, img)%matrix, native_dot_tmp)
3773 : ! Symmetric DBCSR storage represents both orientations of each assembled pair.
3774 46008 : hsigma(idim, jdim) = hsigma(idim, jdim) + 0.5_dp*native_dot_tmp
3775 : END DO
3776 : END DO
3777 : END DO
3778 : END DO
3779 48 : CALL dbcsr_deallocate_matrix_set(matrix_dh_scc)
3780 : ELSE
3781 102 : CALL para_env%sum(hsigma)
3782 : END IF
3783 150 : CALL para_env%sum(tb%grad)
3784 150 : CALL tb_grad2force(qs_env, tb, para_env, 4)
3785 :
3786 1374 : IF (.NOT. use_matrix_scc_stress) tb%sigma = tb%sigma + hsigma
3787 :
3788 150 : DEALLOCATE (basis_set_list)
3789 150 : DEALLOCATE (t_ov, t_d_ov)
3790 150 : DEALLOCATE (t_dip, t_i_dip, t_j_dip)
3791 150 : DEALLOCATE (t_quad, t_i_quad, t_j_quad)
3792 150 : DEALLOCATE (idip, jdip, idip_mag, jdip_mag, iquad, jquad, iquad_mag, jquad_mag)
3793 :
3794 150 : IF (tb%use_virial) THEN
3795 84 : CALL tb_add_stress(qs_env, tb, para_env)
3796 84 : IF (use_matrix_scc_stress) THEN
3797 48 : CALL get_qs_env(qs_env=qs_env, virial=virial)
3798 624 : virial%pv_virial = virial%pv_virial - hsigma/para_env%num_pe
3799 : END IF
3800 : END IF
3801 :
3802 : #else
3803 : MARK_USED(qs_env)
3804 : MARK_USED(use_rho)
3805 : MARK_USED(nimg)
3806 : CPABORT("Built without TBLITE")
3807 : #endif
3808 :
3809 300 : END SUBROUTINE tb_derive_dH_off
3810 :
3811 : ! **************************************************************************************************
3812 : !> \brief Run native tblite CLI and compare against CP2K/tblite.
3813 : !> \param qs_env ...
3814 : ! **************************************************************************************************
3815 150 : SUBROUTINE tb_reference_cli_compare(qs_env)
3816 :
3817 : TYPE(qs_environment_type), POINTER :: qs_env
3818 :
3819 : CHARACTER(LEN=*), PARAMETER :: routineN = 'tb_reference_cli_compare'
3820 :
3821 : CHARACTER(LEN=16) :: solvation_model_name
3822 : CHARACTER(LEN=32) :: acc_str, charge_str, efield_x_str, efield_y_str, efield_z_str, &
3823 : etemp_guess_val_str, etemp_str, iter_str, spin_str, spinpol_str
3824 : CHARACTER(LEN=4*default_path_length+16) :: efield_str, etemp_guess_str, param_str, &
3825 : post_processing_output_str, post_processing_str, restart_str, solvation_str, verbosity_str
3826 : CHARACTER(LEN=8) :: guess, method, solver
3827 : CHARACTER(LEN=8*default_path_length) :: command
3828 : CHARACTER(LEN=default_path_length) :: file_base, gen_file, grad_file, &
3829 : json_file, log_file, &
3830 : post_processing_output_file
3831 : INTEGER :: cmdstat, exitstat, handle, iounit, &
3832 : n_periodic, natom, nkp, &
3833 : reference_iterations, spin
3834 : INTEGER, DIMENSION(3) :: periodic
3835 : LOGICAL :: do_kpoints, have_energy, have_gradient, &
3836 : have_virial, too_large, &
3837 : unsupported_kpoints
3838 : REAL(KIND=dp) :: cli_energy, cp_energy, ediff, etemp, &
3839 : etemp_guess, fmax, fsum, vmax, vsum
3840 150 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: cli_gradient, cli_virial, cp_gradient
3841 150 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: xkp
3842 150 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
3843 : TYPE(cell_type), POINTER :: cell
3844 : TYPE(cp_logger_type), POINTER :: logger
3845 : TYPE(dft_control_type), POINTER :: dft_control
3846 : TYPE(kpoint_type), POINTER :: kpoints
3847 : TYPE(mp_para_env_type), POINTER :: para_env
3848 150 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3849 : TYPE(qs_energy_type), POINTER :: energy
3850 150 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
3851 : TYPE(scf_control_type), POINTER :: scf_control
3852 : TYPE(virial_type), POINTER :: virial
3853 : TYPE(xtb_reference_cli_type) :: ref
3854 :
3855 150 : CALL timeset(routineN, handle)
3856 :
3857 150 : NULLIFY (atomic_kind_set, cell, dft_control, energy, force, kpoints, logger, para_env, particle_set, &
3858 150 : scf_control, virial, xkp)
3859 : CALL get_qs_env(qs_env=qs_env, atomic_kind_set=atomic_kind_set, cell=cell, &
3860 : dft_control=dft_control, energy=energy, force=force, &
3861 : para_env=para_env, particle_set=particle_set, scf_control=scf_control, &
3862 150 : virial=virial, do_kpoints=do_kpoints, kpoints=kpoints)
3863 :
3864 150 : ref = dft_control%qs_control%xtb_control%reference_cli
3865 150 : IF (.NOT. ref%enabled) THEN
3866 148 : CALL timestop(handle)
3867 148 : RETURN
3868 : END IF
3869 2 : IF (.NOT. para_env%is_source()) THEN
3870 1 : CALL timestop(handle)
3871 1 : RETURN
3872 : END IF
3873 :
3874 1 : logger => cp_get_default_logger()
3875 1 : iounit = cp_logger_get_default_io_unit(logger)
3876 1 : verbosity_str = ""
3877 1 : IF (logger%iter_info%print_level == silent_print_level) THEN
3878 0 : verbosity_str = " --silent"
3879 1 : ELSE IF (logger%iter_info%print_level == high_print_level .OR. &
3880 : logger%iter_info%print_level == debug_print_level) THEN
3881 0 : verbosity_str = " --verbose"
3882 : END IF
3883 1 : IF (ref%solvation_active) THEN
3884 1 : periodic = 0
3885 1 : IF (ASSOCIATED(cell)) CALL get_cell(cell=cell, periodic=periodic)
3886 4 : n_periodic = COUNT(periodic == 1)
3887 1 : IF (n_periodic == 3) THEN
3888 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
3889 0 : "tblite reference CLI implicit solvation is not supported for PERIODIC XYZ."
3890 : WRITE (UNIT=iounit, FMT="(T2,A)") &
3891 0 : "Use PERIODIC NONE for molecular solvation diagnostics, or remove IMPLICIT_SOLVATION."
3892 0 : CPABORT("REFERENCE_CLI implicit solvation is incompatible with PERIODIC XYZ")
3893 1 : ELSE IF (n_periodic > 0) THEN
3894 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
3895 0 : "WARNING: tblite reference CLI implicit solvation with finite periodicity is diagnostic only."
3896 : WRITE (UNIT=iounit, FMT="(T2,A,I0,A)") &
3897 0 : "The generated native tblite reference geometry has ", n_periodic, &
3898 0 : " periodic direction(s); continuum-solvation conventions are primarily molecular."
3899 : END IF
3900 : END IF
3901 1 : unsupported_kpoints = .FALSE.
3902 1 : IF (do_kpoints .AND. ASSOCIATED(kpoints)) THEN
3903 0 : nkp = 0
3904 0 : CALL get_kpoint_info(kpoint=kpoints, nkp=nkp, xkp=xkp)
3905 0 : unsupported_kpoints = nkp > 1
3906 0 : IF (nkp == 1 .AND. ASSOCIATED(xkp)) unsupported_kpoints = ANY(ABS(xkp(:, 1)) > 1.0E-12_dp)
3907 : END IF
3908 0 : IF (unsupported_kpoints) THEN
3909 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
3910 0 : "tblite reference CLI check skipped: CP2K KPOINTS are active."
3911 : WRITE (UNIT=iounit, FMT="(T2,A)") &
3912 0 : "The native tblite CLI reference path does not reproduce CP2K multi-k-point sampling."
3913 0 : IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot check CP2K k-point calculations")
3914 0 : CALL timestop(handle)
3915 0 : RETURN
3916 : END IF
3917 1 : IF (dft_control%qs_control%xtb_control%tblite_scc_mixer == tblite_scc_mixer_cp2k) THEN
3918 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
3919 0 : "WARNING: tblite reference CLI cannot reproduce XTB/SCC_MIXER CP2K."
3920 : WRITE (UNIT=iounit, FMT="(T2,A)") &
3921 0 : "The external native tblite run uses tblite's own SCC mixer; only the converged result is compared."
3922 0 : IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce SCC_MIXER CP2K")
3923 : END IF
3924 1 : natom = SIZE(particle_set)
3925 1 : method = tb_reference_method_name(dft_control%qs_control%xtb_control%tblite_method)
3926 1 : guess = tb_reference_guess_name(ref%guess)
3927 1 : solver = tb_reference_solver_name(dft_control%qs_control%xtb_control%tblite_mixer_solver)
3928 1 : file_base = tb_join_path(ref%work_directory, ref%prefix)
3929 1 : gen_file = TRIM(file_base)//".gen"
3930 1 : grad_file = TRIM(file_base)//".grad"
3931 1 : json_file = TRIM(file_base)//".json"
3932 1 : log_file = TRIM(file_base)//".log"
3933 1 : post_processing_output_file = ""
3934 1 : IF (LEN_TRIM(ref%grad_file) > 0) grad_file = ref%grad_file
3935 1 : IF (LEN_TRIM(ref%json_file) > 0) json_file = ref%json_file
3936 1 : IF (LEN_TRIM(ref%post_processing_output_file) > 0) THEN
3937 1 : post_processing_output_file = ref%post_processing_output_file
3938 : END IF
3939 :
3940 1 : WRITE (charge_str, "(I0)") dft_control%charge
3941 1 : spin = MAX(0, dft_control%multiplicity - 1)
3942 1 : WRITE (spin_str, "(I0)") spin
3943 1 : WRITE (acc_str, "(ES16.8)") dft_control%qs_control%xtb_control%tblite_accuracy
3944 1 : reference_iterations = dft_control%qs_control%xtb_control%tblite_mixer_iterations
3945 1 : WRITE (iter_str, "(I0)") reference_iterations
3946 1 : efield_str = ""
3947 1 : IF (ref%efield_active) THEN
3948 1 : WRITE (efield_x_str, "(ES16.8)") ref%efield(1)
3949 1 : WRITE (efield_y_str, "(ES16.8)") ref%efield(2)
3950 1 : WRITE (efield_z_str, "(ES16.8)") ref%efield(3)
3951 : efield_str = " --efield "//TRIM(ADJUSTL(efield_x_str))//","// &
3952 1 : TRIM(ADJUSTL(efield_y_str))//","//TRIM(ADJUSTL(efield_z_str))
3953 : END IF
3954 1 : solvation_str = ""
3955 1 : solvation_model_name = ""
3956 1 : IF (ref%solvation_active) THEN
3957 2 : SELECT CASE (ref%solvation_model)
3958 : CASE (tblite_cli_solvation_alpb)
3959 1 : solvation_model_name = "ALPB"
3960 1 : solvation_str = " --alpb "
3961 : CASE (tblite_cli_solvation_gbsa)
3962 0 : solvation_model_name = "GBSA"
3963 0 : solvation_str = " --gbsa "
3964 : CASE (tblite_cli_solvation_gbe)
3965 0 : solvation_model_name = "GBE"
3966 0 : solvation_str = " --gbe "
3967 : CASE (tblite_cli_solvation_gb)
3968 0 : solvation_model_name = "GB"
3969 0 : solvation_str = " --gb "
3970 : CASE (tblite_cli_solvation_cpcm)
3971 0 : solvation_model_name = "CPCM"
3972 0 : solvation_str = " --cpcm "
3973 : CASE DEFAULT
3974 1 : CPABORT("Unknown tblite reference CLI implicit-solvation model")
3975 : END SELECT
3976 1 : solvation_str = TRIM(solvation_str)//" "//TRIM(tb_shell_quote(ref%solvation_solvent))
3977 2 : SELECT CASE (ref%solvation_born_kernel)
3978 : CASE (tblite_cli_born_kernel_auto)
3979 : CASE (tblite_cli_born_kernel_p16)
3980 1 : solvation_str = TRIM(solvation_str)//" --born-kernel p16"
3981 : CASE (tblite_cli_born_kernel_still)
3982 0 : solvation_str = TRIM(solvation_str)//" --born-kernel still"
3983 : CASE DEFAULT
3984 1 : CPABORT("Unknown tblite reference CLI Born kernel")
3985 : END SELECT
3986 2 : SELECT CASE (ref%solvation_state)
3987 : CASE (tblite_cli_solution_state_gsolv)
3988 : CASE (tblite_cli_solution_state_bar1mol)
3989 1 : solvation_str = TRIM(solvation_str)//" --solv-state bar1mol"
3990 : CASE (tblite_cli_solution_state_reference)
3991 0 : solvation_str = TRIM(solvation_str)//" --solv-state reference"
3992 : CASE DEFAULT
3993 1 : CPABORT("Unknown tblite reference CLI solution state")
3994 : END SELECT
3995 : END IF
3996 1 : IF (dft_control%qs_control%xtb_control%tblite_mixer_memory /= reference_iterations) THEN
3997 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
3998 0 : "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/MEMORY."
3999 : WRITE (UNIT=iounit, FMT="(T2,A,I0,A,I0,A)") &
4000 0 : "The native reference run uses tblite's internal mixer memory tied to --iterations (", &
4001 0 : reference_iterations, "), while CP2K uses MEMORY ", &
4002 0 : dft_control%qs_control%xtb_control%tblite_mixer_memory, "."
4003 0 : IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/MEMORY")
4004 : END IF
4005 1 : IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_damping - &
4006 : tblite_mixer_damping_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
4007 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
4008 0 : "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/DAMPING."
4009 : WRITE (UNIT=iounit, FMT="(T2,A,F8.4,A,F8.4,A)") &
4010 0 : "The native reference run uses tblite's library default ", tblite_mixer_damping_default, &
4011 0 : ", while CP2K uses DAMPING ", dft_control%qs_control%xtb_control%tblite_mixer_damping, "."
4012 0 : IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/DAMPING")
4013 : END IF
4014 1 : IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_omega0 - &
4015 : tblite_mixer_omega0_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
4016 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
4017 0 : "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/OMEGA0."
4018 : WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
4019 0 : "The native reference run uses tblite's library default ", tblite_mixer_omega0_default, &
4020 0 : ", while CP2K uses OMEGA0 ", dft_control%qs_control%xtb_control%tblite_mixer_omega0, "."
4021 0 : IF (ref%stop_on_error) CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/OMEGA0")
4022 : END IF
4023 1 : IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_min_weight - &
4024 : tblite_mixer_min_weight_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
4025 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
4026 0 : "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/MIN_WEIGHT."
4027 : WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
4028 0 : "The native reference run uses tblite's library default ", tblite_mixer_min_weight_default, &
4029 0 : ", while CP2K uses MIN_WEIGHT ", dft_control%qs_control%xtb_control%tblite_mixer_min_weight, "."
4030 0 : IF (ref%stop_on_error) THEN
4031 0 : CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/MIN_WEIGHT")
4032 : END IF
4033 : END IF
4034 1 : IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_max_weight - &
4035 : tblite_mixer_max_weight_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
4036 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
4037 0 : "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/MAX_WEIGHT."
4038 : WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
4039 0 : "The native reference run uses tblite's library default ", tblite_mixer_max_weight_default, &
4040 0 : ", while CP2K uses MAX_WEIGHT ", dft_control%qs_control%xtb_control%tblite_mixer_max_weight, "."
4041 0 : IF (ref%stop_on_error) THEN
4042 0 : CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/MAX_WEIGHT")
4043 : END IF
4044 : END IF
4045 1 : IF (ABS(dft_control%qs_control%xtb_control%tblite_mixer_weight_factor - &
4046 : tblite_mixer_weight_factor_default) > 10.0_dp*EPSILON(1.0_dp)) THEN
4047 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
4048 0 : "WARNING: tblite reference CLI cannot reproduce XTB/TBLITE_MIXER/WEIGHT_FACTOR."
4049 : WRITE (UNIT=iounit, FMT="(T2,A,ES12.4,A,ES12.4,A)") &
4050 0 : "The native reference run uses tblite's library default ", tblite_mixer_weight_factor_default, &
4051 0 : ", while CP2K uses WEIGHT_FACTOR ", &
4052 0 : dft_control%qs_control%xtb_control%tblite_mixer_weight_factor, "."
4053 0 : IF (ref%stop_on_error) THEN
4054 0 : CPABORT("tblite reference CLI cannot reproduce TBLITE_MIXER/WEIGHT_FACTOR")
4055 : END IF
4056 : END IF
4057 1 : etemp = 300.0_dp
4058 1 : IF (ASSOCIATED(scf_control)) THEN
4059 1 : IF (ASSOCIATED(scf_control%smear)) THEN
4060 1 : IF (scf_control%smear%do_smear) THEN
4061 1 : etemp = cp_unit_from_cp2k(scf_control%smear%electronic_temperature, "K")
4062 1 : IF (scf_control%smear%method /= smear_fermi_dirac) THEN
4063 : WRITE (UNIT=iounit, FMT="(/,T2,A,A,A)") &
4064 0 : "WARNING: tblite reference CLI cannot reproduce CP2K smearing method ", &
4065 0 : TRIM(tb_reference_smear_method_name(scf_control%smear%method)), "."
4066 : WRITE (UNIT=iounit, FMT="(T2,A,F12.3,A)") &
4067 0 : "The native reference run uses Fermi-Dirac electronic temperature ", etemp, " K instead."
4068 : END IF
4069 : END IF
4070 : END IF
4071 : END IF
4072 1 : WRITE (etemp_str, "(ES16.8)") etemp
4073 1 : etemp_guess = 0.0_dp
4074 1 : etemp_guess_str = ""
4075 1 : IF (ref%electronic_temperature_guess > 0.0_dp) THEN
4076 0 : etemp_guess = cp_unit_from_cp2k(ref%electronic_temperature_guess, "K")
4077 0 : WRITE (etemp_guess_val_str, "(ES16.8)") etemp_guess
4078 0 : etemp_guess_str = " --etemp-guess "//TRIM(ADJUSTL(etemp_guess_val_str))
4079 : END IF
4080 1 : param_str = ""
4081 1 : IF (LEN_TRIM(dft_control%qs_control%xtb_control%tblite_param_file) > 0) THEN
4082 0 : param_str = " --param "//TRIM(tb_shell_quote(dft_control%qs_control%xtb_control%tblite_param_file))
4083 : END IF
4084 1 : spinpol_str = ""
4085 1 : IF (dft_control%lsd) spinpol_str = " --spin-polarized"
4086 1 : post_processing_str = ""
4087 1 : IF (LEN_TRIM(ref%post_processing) > 0) THEN
4088 1 : post_processing_str = " --post-processing "//TRIM(tb_shell_quote(ref%post_processing))
4089 : END IF
4090 1 : post_processing_output_str = ""
4091 1 : IF (LEN_TRIM(post_processing_output_file) > 0) THEN
4092 : WRITE (UNIT=iounit, FMT="(/,T2,A)") &
4093 1 : "WARNING: tblite reference CLI POST_PROCESSING_OUTPUT was requested explicitly."
4094 : WRITE (UNIT=iounit, FMT="(T2,A)") &
4095 1 : "Some tblite 0.5.0 command-line builds document --post-processing-output but do not parse it."
4096 : post_processing_output_str = " --post-processing-output "// &
4097 1 : TRIM(tb_shell_quote(post_processing_output_file))
4098 : END IF
4099 1 : restart_str = " --no-restart"
4100 1 : IF (LEN_TRIM(ref%restart_file) > 0) THEN
4101 0 : restart_str = " --restart "//TRIM(tb_shell_quote(ref%restart_file))
4102 : END IF
4103 :
4104 1 : CALL tb_write_reference_gen(qs_env, TRIM(gen_file))
4105 :
4106 : command = TRIM(tb_shell_quote(ref%program_name))//" run --method "//TRIM(method)// &
4107 : TRIM(param_str)// &
4108 : TRIM(spinpol_str)// &
4109 : " --charge "//TRIM(ADJUSTL(charge_str))// &
4110 : " --spin "//TRIM(ADJUSTL(spin_str))// &
4111 : " --acc "//TRIM(ADJUSTL(acc_str))// &
4112 : " --guess "//TRIM(guess)// &
4113 : " --solver "//TRIM(solver)// &
4114 : " --iterations "//TRIM(ADJUSTL(iter_str))// &
4115 : " --etemp "//TRIM(ADJUSTL(etemp_str))// &
4116 : TRIM(etemp_guess_str)// &
4117 : TRIM(efield_str)// &
4118 : TRIM(solvation_str)// &
4119 : TRIM(post_processing_str)// &
4120 : TRIM(post_processing_output_str)// &
4121 : TRIM(restart_str)// &
4122 : TRIM(verbosity_str)//" --input "//TRIM(tb_shell_quote(ref%input_format))// &
4123 : " --grad "//TRIM(tb_shell_quote(grad_file))// &
4124 : " --json "//TRIM(tb_shell_quote(json_file))//" "//TRIM(tb_shell_quote(gen_file))// &
4125 1 : " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
4126 :
4127 1 : cmdstat = 0
4128 1 : exitstat = 0
4129 1 : CALL execute_command_line(TRIM(command), exitstat=exitstat, cmdstat=cmdstat)
4130 1 : IF (cmdstat /= 0 .OR. exitstat /= 0) THEN
4131 1 : WRITE (UNIT=iounit, FMT="(/,T2,A)") "tblite reference CLI check failed to run."
4132 1 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Command: ", TRIM(command)
4133 1 : WRITE (UNIT=iounit, FMT="(T2,A,I0,T32,A,I0)") "cmdstat:", cmdstat, "exitstat:", exitstat
4134 1 : IF (ref%stop_on_error) CPABORT("tblite reference CLI command failed")
4135 1 : CALL tb_reference_cleanup(ref, gen_file, grad_file, json_file, log_file, post_processing_output_file)
4136 1 : CALL timestop(handle)
4137 1 : RETURN
4138 : END IF
4139 :
4140 0 : ALLOCATE (cli_gradient(3, natom), cli_virial(3, 3))
4141 : CALL tb_read_reference_grad(TRIM(grad_file), natom, cli_energy, cli_gradient, cli_virial, &
4142 0 : have_energy, have_gradient, have_virial)
4143 :
4144 0 : WRITE (UNIT=iounit, FMT="(/,T2,A)") "tblite reference CLI check"
4145 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Executable: ", TRIM(ref%program_name)
4146 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Method: ", TRIM(method)
4147 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Guess: ", TRIM(guess)
4148 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Solver: ", TRIM(solver)
4149 0 : WRITE (UNIT=iounit, FMT="(T2,A,L1)") "Spin-pol.: ", dft_control%lsd
4150 0 : IF (ref%efield_active) THEN
4151 0 : WRITE (UNIT=iounit, FMT="(T2,A,3ES16.8,A)") "Efield: ", ref%efield, " V/Angstrom"
4152 : END IF
4153 0 : IF (ref%solvation_active) THEN
4154 0 : WRITE (UNIT=iounit, FMT="(T2,A,A,1X,A)") "Solvation: ", TRIM(solvation_model_name), &
4155 0 : TRIM(ref%solvation_solvent)
4156 : END IF
4157 0 : IF (LEN_TRIM(ref%post_processing) > 0) THEN
4158 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Post proc.: ", TRIM(ref%post_processing)
4159 : END IF
4160 0 : IF (LEN_TRIM(post_processing_output_file) > 0) THEN
4161 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "PP output: ", TRIM(post_processing_output_file)
4162 : END IF
4163 0 : IF (ref%electronic_temperature_guess > 0.0_dp) THEN
4164 0 : WRITE (UNIT=iounit, FMT="(T2,A,F12.3,A)") "Guess etemp:", etemp_guess, " K"
4165 : END IF
4166 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Grad file: ", TRIM(grad_file)
4167 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "JSON file: ", TRIM(json_file)
4168 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Log file: ", TRIM(log_file)
4169 :
4170 0 : too_large = .FALSE.
4171 0 : IF (ref%check_energy) THEN
4172 0 : IF (have_energy) THEN
4173 0 : cp_energy = energy%total
4174 0 : ediff = ABS(cp_energy - cli_energy)
4175 : WRITE (UNIT=iounit, FMT="(T2,A,3ES22.12)") &
4176 0 : "Energy CP2K/CLI/absdiff:", cp_energy, cli_energy, ediff
4177 0 : too_large = too_large .OR. ediff > ref%error_limit
4178 : ELSE
4179 0 : WRITE (UNIT=iounit, FMT="(T2,A)") "Energy check skipped: no CLI energy found."
4180 : END IF
4181 : END IF
4182 :
4183 0 : IF (ref%check_forces) THEN
4184 0 : IF (have_gradient .AND. ASSOCIATED(force)) THEN
4185 0 : ALLOCATE (cp_gradient(3, natom))
4186 0 : CALL total_qs_force(cp_gradient, force, atomic_kind_set)
4187 0 : fsum = SUM(ABS(cp_gradient - cli_gradient))
4188 0 : fmax = MAXVAL(ABS(cp_gradient - cli_gradient))
4189 0 : WRITE (UNIT=iounit, FMT="(T2,A,2ES22.12)") "Gradient diff sum/max:", fsum, fmax
4190 0 : too_large = too_large .OR. fmax > ref%error_limit
4191 0 : DEALLOCATE (cp_gradient)
4192 : ELSE
4193 0 : WRITE (UNIT=iounit, FMT="(T2,A)") "Gradient check skipped: no CLI gradient or CP2K force found."
4194 : END IF
4195 : END IF
4196 :
4197 0 : IF (ref%check_virial) THEN
4198 0 : IF (have_virial .AND. ASSOCIATED(virial)) THEN
4199 : ! Native tblite prints the positive cell derivative; CP2K stores the PV virial
4200 : ! with the opposite sign.
4201 0 : vsum = SUM(ABS(-virial%pv_virial - cli_virial))
4202 0 : vmax = MAXVAL(ABS(-virial%pv_virial - cli_virial))
4203 0 : WRITE (UNIT=iounit, FMT="(T2,A,2ES22.12)") "Virial diff sum/max:", vsum, vmax
4204 0 : too_large = too_large .OR. vmax > ref%error_limit
4205 : ELSE
4206 0 : WRITE (UNIT=iounit, FMT="(T2,A)") "Virial check skipped: no CLI virial or CP2K virial found."
4207 : END IF
4208 : END IF
4209 :
4210 0 : IF (too_large) THEN
4211 : WRITE (UNIT=iounit, FMT="(T2,A,ES12.4)") &
4212 0 : "tblite reference CLI deviation exceeded ERROR_LIMIT = ", ref%error_limit
4213 0 : IF (ref%stop_on_error) CPABORT("tblite reference CLI deviation exceeded ERROR_LIMIT")
4214 : END IF
4215 :
4216 0 : CALL tb_reference_cli_aux_commands(ref, dft_control, gen_file, file_base, verbosity_str, iounit)
4217 :
4218 0 : CALL tb_reference_cleanup(ref, gen_file, grad_file, json_file, log_file, post_processing_output_file)
4219 0 : DEALLOCATE (cli_gradient, cli_virial)
4220 :
4221 0 : CALL timestop(handle)
4222 :
4223 1200 : END SUBROUTINE tb_reference_cli_compare
4224 :
4225 : ! **************************************************************************************************
4226 : !> \brief Map CP2K tblite method id to native tblite CLI method name.
4227 : !> \param method_id ...
4228 : !> \return ...
4229 : ! **************************************************************************************************
4230 1 : FUNCTION tb_reference_method_name(method_id) RESULT(method)
4231 : INTEGER, INTENT(IN) :: method_id
4232 : CHARACTER(LEN=8) :: method
4233 :
4234 1 : SELECT CASE (method_id)
4235 : CASE (gfn1xtb)
4236 0 : method = "gfn1"
4237 : CASE (gfn2xtb)
4238 1 : method = "gfn2"
4239 : CASE (ipea1xtb)
4240 0 : method = "ipea1"
4241 : CASE DEFAULT
4242 1 : CPABORT("Unknown tblite reference CLI method")
4243 : END SELECT
4244 :
4245 1 : END FUNCTION tb_reference_method_name
4246 :
4247 : ! **************************************************************************************************
4248 : !> \brief Map CP2K tblite reference CLI guess id to native tblite CLI guess name.
4249 : !> \param guess_id ...
4250 : !> \return ...
4251 : ! **************************************************************************************************
4252 1 : FUNCTION tb_reference_guess_name(guess_id) RESULT(guess)
4253 : INTEGER, INTENT(IN) :: guess_id
4254 : CHARACTER(LEN=8) :: guess
4255 :
4256 2 : SELECT CASE (guess_id)
4257 : CASE (tblite_guess_sad)
4258 1 : guess = "sad"
4259 : CASE (tblite_guess_eeq)
4260 0 : guess = "eeq"
4261 : CASE (tblite_guess_ceh)
4262 0 : guess = "ceh"
4263 : CASE DEFAULT
4264 1 : CPABORT("Unknown tblite reference CLI guess")
4265 : END SELECT
4266 :
4267 1 : END FUNCTION tb_reference_guess_name
4268 :
4269 : ! **************************************************************************************************
4270 : !> \brief Map CP2K tblite solver id to native tblite CLI solver name.
4271 : !> \param solver_id ...
4272 : !> \return ...
4273 : ! **************************************************************************************************
4274 1 : FUNCTION tb_reference_solver_name(solver_id) RESULT(solver)
4275 : INTEGER, INTENT(IN) :: solver_id
4276 : CHARACTER(LEN=8) :: solver
4277 :
4278 2 : SELECT CASE (solver_id)
4279 : CASE (tblite_solver_gvd)
4280 1 : solver = "gvd"
4281 : CASE (tblite_solver_gvr)
4282 0 : solver = "gvr"
4283 : CASE DEFAULT
4284 1 : CPABORT("Unknown tblite reference CLI solver")
4285 : END SELECT
4286 :
4287 1 : END FUNCTION tb_reference_solver_name
4288 :
4289 : ! **************************************************************************************************
4290 : !> \brief Map CP2K smearing method id to a diagnostic label.
4291 : !> \param method_id ...
4292 : !> \return ...
4293 : ! **************************************************************************************************
4294 0 : FUNCTION tb_reference_smear_method_name(method_id) RESULT(method)
4295 : INTEGER, INTENT(IN) :: method_id
4296 : CHARACTER(LEN=24) :: method
4297 :
4298 0 : SELECT CASE (method_id)
4299 : CASE (smear_fermi_dirac)
4300 0 : method = "FERMI_DIRAC"
4301 : CASE (smear_energy_window)
4302 0 : method = "ENERGY_WINDOW"
4303 : CASE (smear_list)
4304 0 : method = "LIST"
4305 : CASE (smear_gaussian)
4306 0 : method = "GAUSSIAN"
4307 : CASE (smear_mp)
4308 0 : method = "METHFESSEL_PAXTON"
4309 : CASE (smear_mv)
4310 0 : method = "MARZARI_VANDERBILT"
4311 : CASE DEFAULT
4312 0 : method = "UNKNOWN"
4313 : END SELECT
4314 :
4315 0 : END FUNCTION tb_reference_smear_method_name
4316 :
4317 : ! **************************************************************************************************
4318 : !> \brief Run optional native tblite auxiliary subcommands.
4319 : !> \param ref ...
4320 : !> \param dft_control ...
4321 : !> \param gen_file ...
4322 : !> \param file_base ...
4323 : !> \param verbosity_str ...
4324 : !> \param iounit ...
4325 : ! **************************************************************************************************
4326 0 : SUBROUTINE tb_reference_cli_aux_commands(ref, dft_control, gen_file, file_base, verbosity_str, iounit)
4327 :
4328 : TYPE(xtb_reference_cli_type), INTENT(IN) :: ref
4329 : TYPE(dft_control_type), INTENT(IN) :: dft_control
4330 : CHARACTER(LEN=*), INTENT(IN) :: gen_file, file_base, verbosity_str
4331 : INTEGER, INTENT(IN) :: iounit
4332 :
4333 : CHARACTER(LEN=32) :: charge_str, efield_x_str, efield_y_str, &
4334 : efield_z_str, etemp_guess_val_str, &
4335 : spin_str
4336 : CHARACTER(LEN=4*default_path_length+16) :: copy_str, dry_run_str, efield_str, &
4337 : etemp_guess_str, grad_str, json_str, &
4338 : method_str, output_str
4339 : CHARACTER(LEN=8*default_path_length) :: command
4340 : CHARACTER(LEN=default_path_length) :: guess_input, log_file
4341 : INTEGER :: spin
4342 : REAL(KIND=dp) :: etemp_guess
4343 :
4344 0 : WRITE (charge_str, "(I0)") dft_control%charge
4345 0 : spin = MAX(0, dft_control%multiplicity - 1)
4346 0 : WRITE (spin_str, "(I0)") spin
4347 :
4348 0 : IF (ref%guess_cli%enabled) THEN
4349 0 : guess_input = ref%guess_cli%input_file
4350 0 : IF (LEN_TRIM(guess_input) == 0) guess_input = gen_file
4351 0 : etemp_guess_str = ""
4352 0 : IF (ref%guess_cli%electronic_temperature_guess > 0.0_dp) THEN
4353 0 : etemp_guess = cp_unit_from_cp2k(ref%guess_cli%electronic_temperature_guess, "K")
4354 0 : WRITE (etemp_guess_val_str, "(ES16.8)") etemp_guess
4355 0 : etemp_guess_str = " --etemp-guess "//TRIM(ADJUSTL(etemp_guess_val_str))
4356 : END IF
4357 0 : efield_str = ""
4358 0 : IF (ref%guess_cli%efield_active) THEN
4359 0 : WRITE (efield_x_str, "(ES16.8)") ref%guess_cli%efield(1)
4360 0 : WRITE (efield_y_str, "(ES16.8)") ref%guess_cli%efield(2)
4361 0 : WRITE (efield_z_str, "(ES16.8)") ref%guess_cli%efield(3)
4362 : efield_str = " --efield "//TRIM(ADJUSTL(efield_x_str))//","// &
4363 0 : TRIM(ADJUSTL(efield_y_str))//","//TRIM(ADJUSTL(efield_z_str))
4364 : END IF
4365 0 : grad_str = ""
4366 0 : IF (ref%guess_cli%grad) grad_str = " --grad"
4367 0 : json_str = ""
4368 0 : IF (LEN_TRIM(ref%guess_cli%json_file) > 0) THEN
4369 0 : json_str = " --json "//TRIM(tb_shell_quote(ref%guess_cli%json_file))
4370 : END IF
4371 0 : log_file = TRIM(file_base)//".guess.log"
4372 : command = TRIM(tb_shell_quote(ref%program_name))// &
4373 : " guess --charge "//TRIM(ADJUSTL(charge_str))// &
4374 : " --spin "//TRIM(ADJUSTL(spin_str))// &
4375 : " --method "//TRIM(tb_reference_guess_name(ref%guess_cli%method))// &
4376 : " --solver "//TRIM(tb_reference_solver_name(ref%guess_cli%solver))// &
4377 : TRIM(etemp_guess_str)// &
4378 : TRIM(efield_str)// &
4379 : TRIM(grad_str)// &
4380 : TRIM(json_str)// &
4381 : TRIM(verbosity_str)//" --input "//TRIM(tb_shell_quote(ref%guess_cli%input_format))// &
4382 : " "//TRIM(tb_shell_quote(guess_input))// &
4383 0 : " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
4384 0 : CALL tb_reference_cli_execute(ref, "guess", command, log_file, iounit)
4385 0 : IF (.NOT. ref%keep_files .AND. LEN_TRIM(ref%guess_cli%json_file) > 0) THEN
4386 0 : CALL tb_delete_file(ref%guess_cli%json_file)
4387 : END IF
4388 : END IF
4389 :
4390 0 : IF (ref%param_cli%enabled) THEN
4391 0 : method_str = ""
4392 0 : IF (ref%param_cli%method_explicit .OR. LEN_TRIM(ref%param_cli%input_file) == 0) THEN
4393 : method_str = " --method "// &
4394 : TRIM(tb_reference_method_name(MERGE(ref%param_cli%method, &
4395 : dft_control%qs_control%xtb_control%tblite_method, &
4396 0 : ref%param_cli%method_explicit)))
4397 : END IF
4398 0 : output_str = ""
4399 0 : IF (LEN_TRIM(ref%param_cli%output_file) > 0) THEN
4400 0 : output_str = " --output "//TRIM(tb_shell_quote(ref%param_cli%output_file))
4401 : END IF
4402 0 : log_file = TRIM(file_base)//".param.log"
4403 : command = TRIM(tb_shell_quote(ref%program_name))//" param"// &
4404 : TRIM(method_str)// &
4405 0 : TRIM(output_str)
4406 0 : IF (LEN_TRIM(ref%param_cli%input_file) > 0) THEN
4407 0 : command = TRIM(command)//" "//TRIM(tb_shell_quote(ref%param_cli%input_file))
4408 : END IF
4409 0 : command = TRIM(command)//" > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
4410 0 : CALL tb_reference_cli_execute(ref, "param", command, log_file, iounit)
4411 0 : IF (.NOT. ref%keep_files .AND. LEN_TRIM(ref%param_cli%output_file) > 0) THEN
4412 0 : CALL tb_delete_file(ref%param_cli%output_file)
4413 : END IF
4414 : END IF
4415 :
4416 0 : IF (ref%fit_cli%enabled) THEN
4417 0 : dry_run_str = ""
4418 0 : IF (ref%fit_cli%dry_run) dry_run_str = " --dry-run"
4419 0 : copy_str = ""
4420 0 : IF (LEN_TRIM(ref%fit_cli%copy_file) > 0) THEN
4421 0 : copy_str = " --copy "//TRIM(tb_shell_quote(ref%fit_cli%copy_file))
4422 : END IF
4423 0 : log_file = TRIM(file_base)//".fit.log"
4424 : command = TRIM(tb_shell_quote(ref%program_name))//" fit"// &
4425 : TRIM(dry_run_str)// &
4426 : TRIM(copy_str)// &
4427 : TRIM(verbosity_str)//" "//TRIM(tb_shell_quote(ref%fit_cli%param_file))// &
4428 : " "//TRIM(tb_shell_quote(ref%fit_cli%input_file))// &
4429 0 : " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
4430 0 : CALL tb_reference_cli_execute(ref, "fit", command, log_file, iounit)
4431 0 : IF (.NOT. ref%keep_files .AND. LEN_TRIM(ref%fit_cli%copy_file) > 0) THEN
4432 0 : CALL tb_delete_file(ref%fit_cli%copy_file)
4433 : END IF
4434 : END IF
4435 :
4436 0 : IF (ref%tagdiff_cli%enabled) THEN
4437 0 : method_str = ""
4438 0 : IF (ref%tagdiff_cli%fit) method_str = " --fit"
4439 0 : log_file = TRIM(file_base)//".tagdiff.log"
4440 : command = TRIM(tb_shell_quote(ref%program_name))//" tagdiff"// &
4441 : TRIM(method_str)//" "//TRIM(tb_shell_quote(ref%tagdiff_cli%actual_file))// &
4442 : " "//TRIM(tb_shell_quote(ref%tagdiff_cli%reference_file))// &
4443 0 : " > "//TRIM(tb_shell_quote(log_file))//" 2>&1"
4444 0 : CALL tb_reference_cli_execute(ref, "tagdiff", command, log_file, iounit)
4445 : END IF
4446 :
4447 0 : END SUBROUTINE tb_reference_cli_aux_commands
4448 :
4449 : ! **************************************************************************************************
4450 : !> \brief Execute one native tblite REFERENCE_CLI auxiliary command.
4451 : !> \param ref ...
4452 : !> \param label ...
4453 : !> \param command ...
4454 : !> \param log_file ...
4455 : !> \param iounit ...
4456 : ! **************************************************************************************************
4457 0 : SUBROUTINE tb_reference_cli_execute(ref, label, command, log_file, iounit)
4458 :
4459 : TYPE(xtb_reference_cli_type), INTENT(IN) :: ref
4460 : CHARACTER(LEN=*), INTENT(IN) :: label, command, log_file
4461 : INTEGER, INTENT(IN) :: iounit
4462 :
4463 : INTEGER :: cmdstat, exitstat
4464 :
4465 0 : cmdstat = 0
4466 0 : exitstat = 0
4467 0 : CALL execute_command_line(TRIM(command), exitstat=exitstat, cmdstat=cmdstat)
4468 0 : IF (cmdstat /= 0 .OR. exitstat /= 0) THEN
4469 0 : WRITE (UNIT=iounit, FMT="(/,T2,A,A)") "tblite reference CLI auxiliary command failed: ", &
4470 0 : TRIM(label)
4471 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Command: ", TRIM(command)
4472 0 : WRITE (UNIT=iounit, FMT="(T2,A,I0,T32,A,I0)") "cmdstat:", cmdstat, "exitstat:", exitstat
4473 0 : IF (ref%stop_on_error) CPABORT("tblite reference CLI auxiliary command failed")
4474 : ELSE
4475 0 : WRITE (UNIT=iounit, FMT="(/,T2,A,A)") "tblite reference CLI auxiliary command completed: ", &
4476 0 : TRIM(label)
4477 0 : WRITE (UNIT=iounit, FMT="(T2,A,A)") "Log file: ", TRIM(log_file)
4478 : END IF
4479 0 : IF (.NOT. ref%keep_files) CALL tb_delete_file(log_file)
4480 :
4481 0 : END SUBROUTINE tb_reference_cli_execute
4482 :
4483 : ! **************************************************************************************************
4484 : !> \brief Join directory and filename.
4485 : !> \param directory ...
4486 : !> \param filename ...
4487 : !> \return ...
4488 : ! **************************************************************************************************
4489 1 : FUNCTION tb_join_path(directory, filename) RESULT(path)
4490 : CHARACTER(LEN=*), INTENT(IN) :: directory, filename
4491 : CHARACTER(LEN=default_path_length) :: path
4492 :
4493 1 : IF (LEN_TRIM(directory) == 0 .OR. TRIM(directory) == ".") THEN
4494 1 : path = TRIM(filename)
4495 0 : ELSE IF (directory(LEN_TRIM(directory):LEN_TRIM(directory)) == "/") THEN
4496 0 : path = TRIM(directory)//TRIM(filename)
4497 : ELSE
4498 0 : path = TRIM(directory)//"/"//TRIM(filename)
4499 : END IF
4500 :
4501 1 : END FUNCTION tb_join_path
4502 :
4503 : ! **************************************************************************************************
4504 : !> \brief Shell-quote a filename or executable path.
4505 : !> \param text ...
4506 : !> \return ...
4507 : ! **************************************************************************************************
4508 9 : FUNCTION tb_shell_quote(text) RESULT(quoted)
4509 : CHARACTER(LEN=*), INTENT(IN) :: text
4510 : CHARACTER(LEN=4*default_path_length) :: quoted
4511 :
4512 : INTEGER :: i
4513 :
4514 9 : quoted = "'"
4515 150 : DO i = 1, LEN_TRIM(text)
4516 150 : IF (text(i:i) == "'") THEN
4517 0 : quoted = TRIM(quoted)//"'\\''"
4518 : ELSE
4519 141 : quoted = TRIM(quoted)//text(i:i)
4520 : END IF
4521 : END DO
4522 9 : quoted = TRIM(quoted)//"'"
4523 :
4524 9 : END FUNCTION tb_shell_quote
4525 :
4526 : ! **************************************************************************************************
4527 : !> \brief Write current CP2K geometry as DFTB+ gen format for native tblite.
4528 : !> \param qs_env ...
4529 : !> \param filename ...
4530 : ! **************************************************************************************************
4531 1 : SUBROUTINE tb_write_reference_gen(qs_env, filename)
4532 :
4533 : TYPE(qs_environment_type), POINTER :: qs_env
4534 : CHARACTER(LEN=*), INTENT(IN) :: filename
4535 :
4536 1 : CHARACTER(LEN=2), ALLOCATABLE, DIMENSION(:) :: symbols, unique_symbols
4537 : INTEGER :: iatom, ikind, ios, natom, nuniq, unit_nr
4538 1 : INTEGER, ALLOCATABLE, DIMENSION(:) :: species
4539 : INTEGER, DIMENSION(3) :: periodic
4540 : LOGICAL :: found
4541 : REAL(KIND=dp) :: to_angstrom
4542 : TYPE(cell_type), POINTER :: cell
4543 1 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
4544 :
4545 1 : NULLIFY (cell, particle_set)
4546 1 : CALL get_qs_env(qs_env=qs_env, cell=cell, particle_set=particle_set)
4547 :
4548 1 : natom = SIZE(particle_set)
4549 1 : to_angstrom = cp_unit_from_cp2k(1.0_dp, "angstrom")
4550 5 : ALLOCATE (symbols(natom), unique_symbols(natom), species(natom))
4551 1 : nuniq = 0
4552 5 : DO iatom = 1, natom
4553 4 : CALL get_atomic_kind(particle_set(iatom)%atomic_kind, element_symbol=symbols(iatom))
4554 4 : found = .FALSE.
4555 9 : DO ikind = 1, nuniq
4556 9 : IF (TRIM(unique_symbols(ikind)) == TRIM(symbols(iatom))) THEN
4557 : found = .TRUE.
4558 : EXIT
4559 : END IF
4560 : END DO
4561 4 : IF (.NOT. found) THEN
4562 3 : nuniq = nuniq + 1
4563 3 : unique_symbols(nuniq) = symbols(iatom)
4564 3 : ikind = nuniq
4565 : END IF
4566 5 : species(iatom) = ikind
4567 : END DO
4568 :
4569 : OPEN (NEWUNIT=unit_nr, FILE=TRIM(filename), STATUS="REPLACE", ACTION="WRITE", &
4570 1 : FORM="FORMATTED", IOSTAT=ios)
4571 1 : IF (ios /= 0) CPABORT("Could not open tblite reference CLI geometry file")
4572 :
4573 1 : CALL get_cell(cell=cell, periodic=periodic)
4574 4 : IF (ANY(periodic == 1)) THEN
4575 0 : WRITE (UNIT=unit_nr, FMT="(I0,1X,A)") natom, "S"
4576 : ELSE
4577 1 : WRITE (UNIT=unit_nr, FMT="(I0,1X,A)") natom, "C"
4578 : END IF
4579 4 : WRITE (UNIT=unit_nr, FMT="(*(A,1X))") (TRIM(unique_symbols(ikind)), ikind=1, nuniq)
4580 5 : DO iatom = 1, natom
4581 : WRITE (UNIT=unit_nr, FMT="(I0,1X,I0,3(1X,ES24.16))") &
4582 17 : iatom, species(iatom), particle_set(iatom)%r(:)*to_angstrom
4583 : END DO
4584 4 : IF (ANY(periodic == 1)) THEN
4585 0 : WRITE (UNIT=unit_nr, FMT="(3(1X,ES24.16))") 0.0_dp, 0.0_dp, 0.0_dp
4586 0 : DO ikind = 1, 3
4587 0 : WRITE (UNIT=unit_nr, FMT="(3(1X,ES24.16))") cell%hmat(:, ikind)*to_angstrom
4588 : END DO
4589 : END IF
4590 1 : CLOSE (unit_nr)
4591 :
4592 1 : DEALLOCATE (symbols, unique_symbols, species)
4593 :
4594 1 : END SUBROUTINE tb_write_reference_gen
4595 :
4596 : ! **************************************************************************************************
4597 : !> \brief Read native tblite gradient file.
4598 : !> \param filename ...
4599 : !> \param natom ...
4600 : !> \param energy ...
4601 : !> \param gradient ...
4602 : !> \param virial ...
4603 : !> \param have_energy ...
4604 : !> \param have_gradient ...
4605 : !> \param have_virial ...
4606 : ! **************************************************************************************************
4607 0 : SUBROUTINE tb_read_reference_grad(filename, natom, energy, gradient, virial, &
4608 : have_energy, have_gradient, have_virial)
4609 :
4610 : CHARACTER(LEN=*), INTENT(IN) :: filename
4611 : INTEGER, INTENT(IN) :: natom
4612 : REAL(KIND=dp), INTENT(OUT) :: energy
4613 : REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT) :: gradient, virial
4614 : LOGICAL, INTENT(OUT) :: have_energy, have_gradient, have_virial
4615 :
4616 : CHARACTER(LEN=1024) :: line
4617 : INTEGER :: ios, nread, unit_nr
4618 : LOGICAL :: exists
4619 0 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: values
4620 :
4621 0 : have_energy = .FALSE.
4622 0 : have_gradient = .FALSE.
4623 0 : have_virial = .FALSE.
4624 0 : energy = 0.0_dp
4625 0 : gradient = 0.0_dp
4626 0 : virial = 0.0_dp
4627 :
4628 0 : INQUIRE (FILE=TRIM(filename), EXIST=exists)
4629 0 : IF (.NOT. exists) RETURN
4630 :
4631 : OPEN (NEWUNIT=unit_nr, FILE=TRIM(filename), STATUS="OLD", ACTION="READ", &
4632 0 : FORM="FORMATTED", IOSTAT=ios)
4633 0 : IF (ios /= 0) RETURN
4634 :
4635 : DO
4636 0 : READ (UNIT=unit_nr, FMT="(A)", IOSTAT=ios) line
4637 0 : IF (ios /= 0) EXIT
4638 0 : IF (INDEX(line, "energy :real:0:") > 0) THEN
4639 0 : READ (UNIT=unit_nr, FMT="(A)", IOSTAT=ios) line
4640 0 : IF (ios == 0) THEN
4641 0 : READ (line, *, IOSTAT=ios) energy
4642 0 : have_energy = ios == 0
4643 : END IF
4644 0 : ELSE IF (INDEX(line, "gradient :real:2:3,") > 0) THEN
4645 0 : ALLOCATE (values(3*natom))
4646 0 : CALL tb_read_real_values(unit_nr, values, nread)
4647 0 : IF (nread == 3*natom) THEN
4648 0 : CALL tb_values_to_matrix(values, gradient)
4649 0 : have_gradient = .TRUE.
4650 : END IF
4651 0 : DEALLOCATE (values)
4652 0 : ELSE IF (INDEX(line, "virial :real:2:3,3") > 0) THEN
4653 0 : ALLOCATE (values(9))
4654 0 : CALL tb_read_real_values(unit_nr, values, nread)
4655 0 : IF (nread == 9) THEN
4656 0 : CALL tb_values_to_matrix(values, virial)
4657 0 : have_virial = .TRUE.
4658 : END IF
4659 0 : DEALLOCATE (values)
4660 : END IF
4661 : END DO
4662 0 : CLOSE (unit_nr)
4663 :
4664 0 : END SUBROUTINE tb_read_reference_grad
4665 :
4666 : ! **************************************************************************************************
4667 : !> \brief Read a fixed number of real values from following lines.
4668 : !> \param unit_nr ...
4669 : !> \param values ...
4670 : !> \param nread ...
4671 : ! **************************************************************************************************
4672 0 : SUBROUTINE tb_read_real_values(unit_nr, values, nread)
4673 :
4674 : INTEGER, INTENT(IN) :: unit_nr
4675 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: values
4676 : INTEGER, INTENT(OUT) :: nread
4677 :
4678 : CHARACTER(LEN=1024) :: line
4679 : INTEGER :: ios
4680 :
4681 0 : nread = 0
4682 0 : DO WHILE (nread < SIZE(values))
4683 0 : READ (UNIT=unit_nr, FMT="(A)", IOSTAT=ios) line
4684 0 : IF (ios /= 0) EXIT
4685 0 : CALL tb_parse_real_line(line, values, nread)
4686 : END DO
4687 :
4688 0 : END SUBROUTINE tb_read_real_values
4689 :
4690 : ! **************************************************************************************************
4691 : !> \brief Parse real values from one text line.
4692 : !> \param line ...
4693 : !> \param values ...
4694 : !> \param nread ...
4695 : ! **************************************************************************************************
4696 0 : SUBROUTINE tb_parse_real_line(line, values, nread)
4697 :
4698 : CHARACTER(LEN=*), INTENT(IN) :: line
4699 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: values
4700 : INTEGER, INTENT(INOUT) :: nread
4701 :
4702 : CHARACTER(LEN=128) :: token
4703 : INTEGER :: first, ios, last, pos
4704 :
4705 0 : pos = 1
4706 0 : DO WHILE (pos <= LEN_TRIM(line) .AND. nread < SIZE(values))
4707 0 : DO WHILE (pos <= LEN_TRIM(line) .AND. INDEX(" ,[]", line(pos:pos)) > 0)
4708 0 : pos = pos + 1
4709 : END DO
4710 0 : IF (pos > LEN_TRIM(line)) EXIT
4711 : first = pos
4712 0 : DO WHILE (pos <= LEN_TRIM(line) .AND. INDEX(" ,[]", line(pos:pos)) == 0)
4713 0 : pos = pos + 1
4714 : END DO
4715 0 : last = pos - 1
4716 0 : token = line(first:last)
4717 0 : READ (token, *, IOSTAT=ios) values(nread + 1)
4718 0 : IF (ios == 0) nread = nread + 1
4719 : END DO
4720 :
4721 0 : END SUBROUTINE tb_parse_real_line
4722 :
4723 : ! **************************************************************************************************
4724 : !> \brief Convert flat native tblite values to CP2K atom-major matrix layout.
4725 : !> \param values ...
4726 : !> \param matrix ...
4727 : ! **************************************************************************************************
4728 0 : SUBROUTINE tb_values_to_matrix(values, matrix)
4729 :
4730 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: values
4731 : REAL(KIND=dp), DIMENSION(:, :), INTENT(OUT) :: matrix
4732 :
4733 : INTEGER :: i, j, n
4734 :
4735 0 : n = 0
4736 0 : DO j = 1, SIZE(matrix, 2)
4737 0 : DO i = 1, SIZE(matrix, 1)
4738 0 : n = n + 1
4739 0 : matrix(i, j) = values(n)
4740 : END DO
4741 : END DO
4742 :
4743 0 : END SUBROUTINE tb_values_to_matrix
4744 :
4745 : ! **************************************************************************************************
4746 : !> \brief Delete temporary files unless requested otherwise.
4747 : !> \param ref ...
4748 : !> \param gen_file ...
4749 : !> \param grad_file ...
4750 : !> \param json_file ...
4751 : !> \param log_file ...
4752 : !> \param post_processing_output_file ...
4753 : ! **************************************************************************************************
4754 1 : SUBROUTINE tb_reference_cleanup(ref, gen_file, grad_file, json_file, log_file, post_processing_output_file)
4755 :
4756 : TYPE(xtb_reference_cli_type), INTENT(IN) :: ref
4757 : CHARACTER(LEN=*), INTENT(IN) :: gen_file, grad_file, json_file, &
4758 : log_file, post_processing_output_file
4759 :
4760 1 : IF (ref%keep_files) RETURN
4761 1 : CALL tb_delete_file(gen_file)
4762 1 : CALL tb_delete_file(grad_file)
4763 1 : CALL tb_delete_file(json_file)
4764 1 : CALL tb_delete_file(log_file)
4765 1 : IF (LEN_TRIM(post_processing_output_file) > 0) THEN
4766 1 : CALL tb_delete_file(post_processing_output_file)
4767 : END IF
4768 :
4769 : END SUBROUTINE tb_reference_cleanup
4770 :
4771 : ! **************************************************************************************************
4772 : !> \brief Delete a file if it exists.
4773 : !> \param filename ...
4774 : ! **************************************************************************************************
4775 5 : SUBROUTINE tb_delete_file(filename)
4776 :
4777 : CHARACTER(LEN=*), INTENT(IN) :: filename
4778 :
4779 : INTEGER :: ios, unit_nr
4780 : LOGICAL :: exists
4781 :
4782 5 : INQUIRE (FILE=TRIM(filename), EXIST=exists)
4783 5 : IF (.NOT. exists) RETURN
4784 2 : OPEN (NEWUNIT=unit_nr, FILE=TRIM(filename), STATUS="OLD", IOSTAT=ios)
4785 2 : IF (ios == 0) CLOSE (unit_nr, STATUS="DELETE")
4786 :
4787 : END SUBROUTINE tb_delete_file
4788 :
4789 : ! **************************************************************************************************
4790 : !> \brief Dump cumulative tblite virial pieces for local debugging.
4791 : !> \param label ...
4792 : !> \param sigma ...
4793 : !> \param para_env ...
4794 : ! **************************************************************************************************
4795 0 : SUBROUTINE tb_dump_sigma_component(label, sigma, para_env)
4796 :
4797 : CHARACTER(LEN=*), INTENT(IN) :: label
4798 : REAL(KIND=dp), DIMENSION(:, :), INTENT(IN) :: sigma
4799 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
4800 :
4801 : CHARACTER(LEN=default_path_length) :: dump_file
4802 : INTEGER :: dump_status, dump_unit, i
4803 :
4804 0 : dump_status = 1
4805 : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
4806 : CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_SIGMA_COMPONENT_DUMP", dump_file, STATUS=dump_status)
4807 : #endif
4808 : IF (dump_status /= 0) RETURN
4809 :
4810 : OPEN (NEWUNIT=dump_unit, FILE=TRIM(dump_file), STATUS="UNKNOWN", &
4811 : POSITION="APPEND", ACTION="WRITE")
4812 : WRITE (dump_unit, "(A)") TRIM(label)
4813 : DO i = 1, 3
4814 : WRITE (dump_unit, "(3(1X,ES24.16))") sigma(i, :)/para_env%num_pe
4815 : END DO
4816 : CLOSE (dump_unit)
4817 :
4818 : END SUBROUTINE tb_dump_sigma_component
4819 :
4820 : ! **************************************************************************************************
4821 : !> \brief save stress tensor
4822 : !> \param qs_env ...
4823 : !> \param tb ...
4824 : !> \param para_env ...
4825 : ! **************************************************************************************************
4826 84 : SUBROUTINE tb_add_stress(qs_env, tb, para_env)
4827 :
4828 : TYPE(qs_environment_type) :: qs_env
4829 : TYPE(tblite_type) :: tb
4830 : TYPE(mp_para_env_type) :: para_env
4831 :
4832 : CHARACTER(LEN=default_path_length) :: dump_file
4833 : INTEGER :: dump_status, dump_unit, i
4834 : INTEGER, DIMENSION(3) :: periodic
4835 : TYPE(cell_type), POINTER :: cell
4836 : TYPE(virial_type), POINTER :: virial
4837 :
4838 84 : NULLIFY (virial, cell)
4839 84 : CALL get_qs_env(qs_env=qs_env, virial=virial, cell=cell)
4840 84 : CALL get_cell(cell=cell, periodic=periodic)
4841 :
4842 106 : IF (ALL(periodic == 0)) THEN
4843 : CALL cp_warn(__LOCATION__, &
4844 : "tblite stress tensor requested for an isolated system. "// &
4845 : "The reported virial is useful for finite-difference checks, "// &
4846 4 : "but it is not a physically meaningful bulk stress for an isolated molecule.")
4847 : END IF
4848 :
4849 84 : dump_status = 1
4850 : #if defined(__TBLITE_DEBUG_DIAGNOSTICS)
4851 : CALL GET_ENVIRONMENT_VARIABLE("CP2K_TBLITE_VIRIAL_DUMP", dump_file, STATUS=dump_status)
4852 : #endif
4853 : IF (dump_status == 0) THEN
4854 : OPEN (NEWUNIT=dump_unit, FILE=TRIM(dump_file), STATUS="UNKNOWN", &
4855 : POSITION="APPEND", ACTION="WRITE")
4856 : WRITE (dump_unit, "(A)") "sigma"
4857 : DO i = 1, 3
4858 : WRITE (dump_unit, "(3(1X,ES24.16))") tb%sigma(i, :)/para_env%num_pe
4859 : END DO
4860 : CLOSE (dump_unit)
4861 : END IF
4862 :
4863 1092 : virial%pv_virial = virial%pv_virial - tb%sigma/para_env%num_pe
4864 :
4865 84 : END SUBROUTINE tb_add_stress
4866 :
4867 : ! **************************************************************************************************
4868 : !> \brief add contrib. to gradient
4869 : !> \param grad ...
4870 : !> \param deriv ...
4871 : !> \param dE ...
4872 : !> \param natom ...
4873 : ! **************************************************************************************************
4874 150 : SUBROUTINE tb_add_grad(grad, deriv, dE, natom)
4875 :
4876 : REAL(KIND=dp), DIMENSION(:, :) :: grad
4877 : REAL(KIND=dp), DIMENSION(:, :, :) :: deriv
4878 : REAL(KIND=dp), DIMENSION(:) :: dE
4879 : INTEGER :: natom
4880 :
4881 : INTEGER :: i, j
4882 :
4883 1014 : DO i = 1, natom
4884 9430 : DO j = 1, natom
4885 34528 : grad(:, i) = grad(:, i) + deriv(:, i, j)*dE(j)
4886 : END DO
4887 : END DO
4888 :
4889 150 : END SUBROUTINE tb_add_grad
4890 :
4891 : ! **************************************************************************************************
4892 : !> \brief add contrib. to sigma
4893 : !> \param sig ...
4894 : !> \param deriv ...
4895 : !> \param dE ...
4896 : !> \param natom ...
4897 : ! **************************************************************************************************
4898 0 : SUBROUTINE tb_add_sig(sig, deriv, dE, natom)
4899 :
4900 : REAL(KIND=dp), DIMENSION(:, :) :: sig
4901 : REAL(KIND=dp), DIMENSION(:, :, :) :: deriv
4902 : REAL(KIND=dp), DIMENSION(:) :: dE
4903 : INTEGER :: natom
4904 :
4905 : INTEGER :: i, j
4906 :
4907 0 : DO i = 1, 3
4908 0 : DO j = 1, natom
4909 0 : sig(:, i) = sig(:, i) + deriv(:, i, j)*dE(j)
4910 : END DO
4911 : END DO
4912 :
4913 0 : END SUBROUTINE tb_add_sig
4914 :
4915 6806091 : END MODULE tblite_interface
|