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