(git:b06d3a9)
Loading...
Searching...
No Matches
ec_external.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines for an external energy correction on top of a Kohn-Sham calculation
10!> \par History
11!> 10.2024 created
12!> \author JGH
13! **************************************************************************************************
15 USE cell_types, ONLY: cell_type
17 USE cp_dbcsr_api, ONLY: dbcsr_copy,&
20 dbcsr_set,&
22 dbcsr_type_symmetric
29 USE cp_files, ONLY: close_file,&
34 USE cp_fm_types, ONLY: &
41 USE kinds, ONLY: default_string_length,&
42 dp
43 USE mathlib, ONLY: det_3x3
46 USE physcon, ONLY: pascal
59 USE qs_rho_types, ONLY: qs_rho_get,&
61 USE trexio_utils, ONLY: read_trexio
63 USE virial_types, ONLY: virial_type
64#include "./base/base_uses.f90"
65
66 IMPLICIT NONE
67
68 PRIVATE
69
70! *** Global parameters ***
71
72 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ec_external'
73
75
76CONTAINS
77
78! **************************************************************************************************
79!> \brief External energy method
80!> \param qs_env ...
81!> \param ec_env ...
82!> \param calculate_forces ...
83!> \par History
84!> 10.2024 created
85!> \author JGH
86! **************************************************************************************************
87 SUBROUTINE ec_ext_energy(qs_env, ec_env, calculate_forces)
88 TYPE(qs_environment_type), POINTER :: qs_env
89 TYPE(energy_correction_type), POINTER :: ec_env
90 LOGICAL, INTENT(IN) :: calculate_forces
91
92 CHARACTER(len=*), PARAMETER :: routinen = 'ec_ext_energy'
93
94 INTEGER :: funit, handle, ia, ispin, iter, nao, &
95 nocc, ns, nsample, nspins, unit_nr
96 INTEGER, ALLOCATABLE, DIMENSION(:) :: state
97 REAL(kind=dp) :: focc
98 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: hmat, hnum, rnum
99 TYPE(cp_fm_struct_type), POINTER :: fm_struct, h_struct
100 TYPE(cp_fm_type) :: h_fm
101 TYPE(cp_fm_type), DIMENSION(:), POINTER :: cpmos, mo_occ, mo_ref
102 TYPE(cp_fm_type), POINTER :: mo_coeff
103 TYPE(cp_logger_type), POINTER :: logger
104 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
105 TYPE(dft_control_type), POINTER :: dft_control
106 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
107
108 CALL timeset(routinen, handle)
109
110 CALL get_qs_env(qs_env, dft_control=dft_control)
111 nspins = dft_control%nspins
112
113 logger => cp_get_default_logger()
114 IF (logger%para_env%is_source()) THEN
115 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
116 ELSE
117 unit_nr = -1
118 END IF
119
120 ec_env%etotal = 0.0_dp
121 ec_env%ex = 0.0_dp
122 ec_env%exc = 0.0_dp
123 ec_env%ehartree = 0.0_dp
124
125 CALL get_qs_env(qs_env, mos=mos)
126 ALLOCATE (cpmos(nspins), mo_ref(nspins), mo_occ(nspins))
127
128 CALL cp_fm_release(ec_env%mo_occ)
129 CALL cp_fm_release(ec_env%cpmos)
130 IF (ec_env%debug_external) THEN
131 !
132 DO ispin = 1, nspins
133 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
134 NULLIFY (fm_struct)
135 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, &
136 template_fmstruct=mo_coeff%matrix_struct)
137 CALL cp_fm_create(cpmos(ispin), fm_struct)
138 CALL cp_fm_set_all(cpmos(ispin), 0.0_dp)
139 CALL cp_fm_create(mo_ref(ispin), fm_struct)
140 CALL cp_fm_set_all(mo_ref(ispin), 0.0_dp)
141 CALL cp_fm_create(mo_occ(ispin), fm_struct)
142 CALL cp_fm_to_fm(mo_coeff, mo_occ(ispin), nocc)
143 CALL cp_fm_struct_release(fm_struct)
144 END DO
145 !
146 ec_env%mo_occ => mo_ref
147 CALL ec_ext_debug(qs_env, ec_env, calculate_forces, unit_nr)
148 !
149 IF (ec_env%do_error) THEN
150 CALL cp_fm_get_info(cpmos(1), nrow_global=nao)
151 CALL cp_fm_struct_create(h_struct, nrow_global=nao, ncol_global=nao, &
152 template_fmstruct=cpmos(1)%matrix_struct)
153 CALL cp_fm_create(h_fm, h_struct)
154 CALL copy_dbcsr_to_fm(ec_env%matrix_h(1, 1)%matrix, h_fm)
155 CALL cp_fm_struct_release(h_struct)
156 ALLOCATE (hmat(nao, nao))
157 CALL cp_fm_get_submatrix(h_fm, hmat, 1, 1, nao, nao)
158 CALL cp_fm_release(h_fm)
159 IF (unit_nr > 1) THEN
160 nsample = 5
161 WRITE (unit_nr, '(/,T2,A)') &
162 " Write EXTERNAL Response Error file: "//trim(ec_env%exresperr_fn)
163 WRITE (unit_nr, '(T2,A,I6)') " Number of Error samples is: ", nsample
164 CALL open_file(ec_env%exresperr_fn, file_status="REPLACE", file_action="WRITE", &
165 file_form="FORMATTED", unit_number=funit)
166 ALLOCATE (rnum(nao, nao), hnum(nao, nao))
167 WRITE (funit, '(A)') " CP2K "
168 WRITE (funit, *) nsample
169 CALL random_seed(size=ns)
170 ALLOCATE (state(ns))
171 DO ia = 1, ns
172 state(ia) = nint(271808156._dp*sin(5.357_dp*ia))
173 END DO
174 CALL random_seed(put=state)
175 CALL random_number(rnum)
176 DO iter = 1, nsample
177 DO ispin = 1, nspins
178 WRITE (funit, *) nao, nao
179 CALL random_number(rnum)
180 hnum(1:nao, 1:nao) = rnum(1:nao, 1:nao) + transpose(rnum(1:nao, 1:nao))
181 hnum(1:nao, 1:nao) = (hnum(1:nao, 1:nao) - 1.0_dp)*1.0e-3_dp
182 rnum(1:nao, 1:nao) = hnum(1:nao, 1:nao) + hmat(1:nao, 1:nao)
183 DO ia = 1, nao
184 WRITE (funit, *) rnum(ia, 1:nao)
185 END DO
186 END DO
187 END DO
188 DEALLOCATE (rnum, hnum, state)
189 CALL close_file(funit)
190 END IF
191 DEALLOCATE (hmat)
192 END IF
193 !
194 IF (calculate_forces) THEN
195 focc = 2.0_dp
196 IF (nspins == 1) focc = 4.0_dp
197 DO ispin = 1, nspins
198 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
199 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_h(1, 1)%matrix, ec_env%mo_occ(ispin), &
200 cpmos(ispin), nocc, &
201 alpha=focc, beta=0.0_dp)
202 END DO
203 END IF
204 ec_env%cpmos => cpmos
205 ELSE
206 DO ispin = 1, nspins
207 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
208 NULLIFY (fm_struct)
209 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, &
210 template_fmstruct=mo_coeff%matrix_struct)
211 CALL cp_fm_create(cpmos(ispin), fm_struct)
212 CALL cp_fm_set_all(cpmos(ispin), 0.0_dp)
213 CALL cp_fm_create(mo_occ(ispin), fm_struct)
214 CALL cp_fm_to_fm(mo_coeff, mo_occ(ispin), nocc)
215 CALL cp_fm_create(mo_ref(ispin), fm_struct)
216 CALL cp_fm_set_all(mo_ref(ispin), 0.0_dp)
217 CALL cp_fm_struct_release(fm_struct)
218 END DO
219
220 ! get external information
221 CALL ec_ext_interface(qs_env, ec_env%exresp_fn, mo_occ, mo_ref, cpmos, calculate_forces, unit_nr)
222 ec_env%mo_occ => mo_ref
223 ec_env%cpmos => cpmos
224 END IF
225
226 IF (calculate_forces) THEN
227 ! check for orbital rotations
228 CALL get_qs_env(qs_env, matrix_s=matrix_s)
229 DO ispin = 1, nspins
230 CALL align_vectors(ec_env%cpmos(ispin), ec_env%mo_occ(ispin), mo_occ(ispin), &
231 matrix_s(1)%matrix, ec_env%orbrot_index, ec_env%phase_index, unit_nr)
232 END DO
233 ! set up matrices for response
234 CALL ec_ext_setup(qs_env, ec_env, .true., unit_nr)
235 ELSE
236 CALL ec_ext_setup(qs_env, ec_env, .false., unit_nr)
237 END IF
238
239 CALL cp_fm_release(mo_occ)
240
241 CALL timestop(handle)
242
243 END SUBROUTINE ec_ext_energy
244
245! **************************************************************************************************
246
247! **************************************************************************************************
248!> \brief ...
249!> \param qs_env ...
250!> \param trexio_fn ...
251!> \param mo_occ ...
252!> \param mo_ref ...
253!> \param cpmos ...
254!> \param calculate_forces ...
255!> \param unit_nr ...
256! **************************************************************************************************
257 SUBROUTINE ec_ext_interface(qs_env, trexio_fn, mo_occ, mo_ref, cpmos, calculate_forces, unit_nr)
258 TYPE(qs_environment_type), POINTER :: qs_env
259 CHARACTER(LEN=*) :: trexio_fn
260 TYPE(cp_fm_type), DIMENSION(:), POINTER :: mo_occ, mo_ref, cpmos
261 LOGICAL, INTENT(IN) :: calculate_forces
262 INTEGER, INTENT(IN) :: unit_nr
263
264 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_ext_interface'
265
266 INTEGER :: handle, ispin, nao, nmos, nocc(2), nspins
267 REAL(kind=dp) :: focc
268 TYPE(cp_fm_type), POINTER :: mo_coeff
269 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: energy_derivative
270 TYPE(dft_control_type), POINTER :: dft_control
271 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos_trexio
272 TYPE(mp_para_env_type), POINTER :: para_env
273
274 CALL timeset(routinen, handle)
275
276 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, para_env=para_env)
277
278 nspins = dft_control%nspins
279 nocc = 0
280 DO ispin = 1, nspins
281 CALL cp_fm_get_info(mo_occ(ispin), nrow_global=nao, ncol_global=nocc(ispin))
282 END DO
283
284 IF (unit_nr > 0) THEN
285 WRITE (unit_nr, '(T2,A)') " Read EXTERNAL Response from file: "//trim(trexio_fn)
286 END IF
287 ALLOCATE (mos_trexio(nspins))
288 IF (calculate_forces) THEN
289 NULLIFY (energy_derivative)
290 CALL dbcsr_allocate_matrix_set(energy_derivative, nspins)
291 !
292 CALL read_trexio(qs_env, trexio_filename=trexio_fn, &
293 mo_set_trexio=mos_trexio, &
294 energy_derivative=energy_derivative)
295 !
296 focc = 2.0_dp
297 IF (nspins == 1) focc = 4.0_dp
298 DO ispin = 1, nspins
299 CALL get_mo_set(mo_set=mos_trexio(ispin), mo_coeff=mo_coeff, homo=nmos)
300 CALL cp_dbcsr_sm_fm_multiply(energy_derivative(ispin)%matrix, mo_coeff, &
301 cpmos(ispin), ncol=nmos, alpha=focc, beta=0.0_dp)
302 END DO
303 !
304 CALL dbcsr_deallocate_matrix_set(energy_derivative)
305 ELSE
306 CALL read_trexio(qs_env, trexio_filename=trexio_fn, &
307 mo_set_trexio=mos_trexio)
308 END IF
309 !
310 DO ispin = 1, nspins
311 CALL get_mo_set(mo_set=mos_trexio(ispin), mo_coeff=mo_coeff, homo=nmos)
312 CALL cp_fm_to_fm(mo_coeff, mo_ref(ispin), nmos)
313 CALL deallocate_mo_set(mos_trexio(ispin))
314 END DO
315 DEALLOCATE (mos_trexio)
316
317 CALL timestop(handle)
318
319 END SUBROUTINE ec_ext_interface
320
321! **************************************************************************************************
322
323! **************************************************************************************************
324!> \brief ...
325!> \param qs_env ...
326!> \param ec_env ...
327!> \param calculate_forces ...
328!> \param unit_nr ...
329! **************************************************************************************************
330 SUBROUTINE ec_ext_debug(qs_env, ec_env, calculate_forces, unit_nr)
331 TYPE(qs_environment_type), POINTER :: qs_env
332 TYPE(energy_correction_type), POINTER :: ec_env
333 LOGICAL, INTENT(IN) :: calculate_forces
334 INTEGER, INTENT(IN) :: unit_nr
335
336 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_ext_debug'
337
338 CHARACTER(LEN=default_string_length) :: headline
339 INTEGER :: handle, ispin, nocc, nspins
340 TYPE(cp_fm_type), POINTER :: mo_coeff
341 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_p, matrix_s
342 TYPE(dft_control_type), POINTER :: dft_control
343 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
344 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
345 POINTER :: sab_orb
346 TYPE(qs_rho_type), POINTER :: rho
347
348 CALL timeset(routinen, handle)
349
350 CALL get_qs_env(qs_env=qs_env, &
351 dft_control=dft_control, &
352 sab_orb=sab_orb, &
353 rho=rho, &
354 matrix_s_kp=matrix_s, &
355 matrix_h_kp=matrix_h)
356
357 nspins = dft_control%nspins
358 CALL get_qs_env(qs_env, mos=mos)
359 DO ispin = 1, nspins
360 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
361 CALL cp_fm_to_fm(mo_coeff, ec_env%mo_occ(ispin), nocc)
362 END DO
363
364 ! Core Hamiltonian matrix
365 IF (ASSOCIATED(ec_env%matrix_h)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_h)
366 CALL dbcsr_allocate_matrix_set(ec_env%matrix_h, 1, 1)
367 headline = "CORE HAMILTONIAN MATRIX"
368 ALLOCATE (ec_env%matrix_h(1, 1)%matrix)
369 CALL dbcsr_create(ec_env%matrix_h(1, 1)%matrix, name=trim(headline), &
370 template=matrix_h(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
371 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_h(1, 1)%matrix, sab_orb)
372 CALL dbcsr_copy(ec_env%matrix_h(1, 1)%matrix, matrix_h(1, 1)%matrix)
373
374 ! Get density matrix of reference calculation
375 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
376 ! Use Core energy as model energy
377 CALL calculate_ptrace(ec_env%matrix_h, matrix_p, ec_env%ex, nspins)
378
379 IF (calculate_forces) THEN
380 ! force of model energy
381 CALL ec_debug_force(qs_env, matrix_p, unit_nr)
382 END IF
383
384 CALL timestop(handle)
385
386 END SUBROUTINE ec_ext_debug
387
388! **************************************************************************************************
389!> \brief ...
390!> \param qs_env ...
391!> \param matrix_p ...
392!> \param unit_nr ...
393! **************************************************************************************************
394 SUBROUTINE ec_debug_force(qs_env, matrix_p, unit_nr)
395 TYPE(qs_environment_type), POINTER :: qs_env
396 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p
397 INTEGER, INTENT(IN) :: unit_nr
398
399 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_debug_force'
400
401 INTEGER :: handle, iounit, nder, nimages
402 LOGICAL :: calculate_forces, debug_forces, &
403 debug_stress, use_virial
404 REAL(kind=dp) :: fconv
405 REAL(kind=dp), DIMENSION(3, 3) :: stdeb, sttot
406 TYPE(cell_type), POINTER :: cell
407 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: scrm
408 TYPE(dft_control_type), POINTER :: dft_control
409 TYPE(mp_para_env_type), POINTER :: para_env
410 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
411 POINTER :: sab_orb
412 TYPE(virial_type), POINTER :: virial
413
414 CALL timeset(routinen, handle)
415
416 debug_forces = .true.
417 debug_stress = .true.
418 iounit = unit_nr
419
420 calculate_forces = .true.
421
422 ! no k-points possible
423 CALL get_qs_env(qs_env=qs_env, &
424 cell=cell, &
425 dft_control=dft_control, &
426 para_env=para_env, &
427 virial=virial)
428 nimages = dft_control%nimages
429 IF (nimages /= 1) THEN
430 cpabort("K-points not implemented")
431 END IF
432
433 ! check for virial
434 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
435
436 fconv = 1.0e-9_dp*pascal/cell%deth
437 IF (debug_stress .AND. use_virial) THEN
438 sttot = virial%pv_virial
439 END IF
440
441 ! initialize src matrix
442 NULLIFY (scrm)
443 CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
444 ALLOCATE (scrm(1, 1)%matrix)
445 CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_p(1, 1)%matrix)
446 CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
447 CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
448
449 ! kinetic energy
450 CALL kinetic_energy_matrix(qs_env, matrixkp_t=scrm, matrix_p=matrix_p, &
451 calculate_forces=calculate_forces, &
452 debug_forces=debug_forces, debug_stress=debug_stress)
453
454 nder = 1
455 CALL core_matrices(qs_env, scrm, matrix_p, calculate_forces, nder, &
456 debug_forces=debug_forces, debug_stress=debug_stress)
457
458 IF (debug_stress .AND. use_virial) THEN
459 stdeb = fconv*(virial%pv_virial - sttot)
460 CALL para_env%sum(stdeb)
461 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
462 'STRESS| Stress Pout*dHcore ', one_third_sum_diag(stdeb), det_3x3(stdeb)
463 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") ' '
464 END IF
465
466 ! delete scr matrix
468
469 CALL timestop(handle)
470
471 END SUBROUTINE ec_debug_force
472
473! **************************************************************************************************
474
475! **************************************************************************************************
476!> \brief ...
477!> \param qs_env ...
478!> \param ec_env ...
479!> \param calc_forces ...
480!> \param unit_nr ...
481! **************************************************************************************************
482 SUBROUTINE ec_ext_setup(qs_env, ec_env, calc_forces, unit_nr)
483 TYPE(qs_environment_type), POINTER :: qs_env
484 TYPE(energy_correction_type), POINTER :: ec_env
485 LOGICAL, INTENT(IN) :: calc_forces
486 INTEGER, INTENT(IN) :: unit_nr
487
488 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_ext_setup'
489
490 CHARACTER(LEN=default_string_length) :: headline
491 INTEGER :: handle, ispin, nao, nocc, nspins
492 REAL(kind=dp) :: a_max, c_max
493 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
494 TYPE(cp_fm_type) :: emat, ksmo, smo
495 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_ks, matrix_p, matrix_s
496 TYPE(dft_control_type), POINTER :: dft_control
497 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
498 POINTER :: sab_orb
499 TYPE(qs_rho_type), POINTER :: rho
500
501 CALL timeset(routinen, handle)
502
503 CALL get_qs_env(qs_env=qs_env, &
504 dft_control=dft_control, &
505 sab_orb=sab_orb, &
506 rho=rho, &
507 matrix_s_kp=matrix_s, &
508 matrix_ks_kp=matrix_ks, &
509 matrix_h_kp=matrix_h)
510
511 nspins = dft_control%nspins
512
513 ! KS Hamiltonian matrix
514 IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
515 CALL dbcsr_allocate_matrix_set(ec_env%matrix_ks, nspins, 1)
516 headline = "HAMILTONIAN MATRIX"
517 DO ispin = 1, nspins
518 ALLOCATE (ec_env%matrix_ks(ispin, 1)%matrix)
519 CALL dbcsr_create(ec_env%matrix_ks(ispin, 1)%matrix, name=trim(headline), &
520 template=matrix_ks(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
521 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_ks(ispin, 1)%matrix, sab_orb)
522 CALL dbcsr_copy(ec_env%matrix_ks(ispin, 1)%matrix, matrix_ks(ispin, 1)%matrix)
523 END DO
524
525 ! Overlap matrix
526 IF (ASSOCIATED(ec_env%matrix_s)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_s)
527 CALL dbcsr_allocate_matrix_set(ec_env%matrix_s, 1, 1)
528 headline = "OVERLAP MATRIX"
529 ALLOCATE (ec_env%matrix_s(1, 1)%matrix)
530 CALL dbcsr_create(ec_env%matrix_s(1, 1)%matrix, name=trim(headline), &
531 template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
532 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_s(1, 1)%matrix, sab_orb)
533 CALL dbcsr_copy(ec_env%matrix_s(1, 1)%matrix, matrix_s(1, 1)%matrix)
534
535 ! density matrix
536 ! Get density matrix of reference calculation
537 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
538 IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
539 CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, 1)
540 headline = "DENSITY MATRIX"
541 DO ispin = 1, nspins
542 ALLOCATE (ec_env%matrix_p(ispin, 1)%matrix)
543 CALL dbcsr_create(ec_env%matrix_p(ispin, 1)%matrix, name=trim(headline), &
544 template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
545 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, 1)%matrix, sab_orb)
546 CALL dbcsr_copy(ec_env%matrix_p(ispin, 1)%matrix, matrix_p(ispin, 1)%matrix)
547 END DO
548
549 IF (calc_forces) THEN
550 ! energy weighted density matrix
551 ! for security, we recalculate W here (stored in qs_env)
552 IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
553 CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, 1)
554 headline = "ENERGY WEIGHTED DENSITY MATRIX"
555 DO ispin = 1, nspins
556 ALLOCATE (ec_env%matrix_w(ispin, 1)%matrix)
557 CALL dbcsr_create(ec_env%matrix_w(ispin, 1)%matrix, name=trim(headline), &
558 template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
559 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, 1)%matrix, sab_orb)
560 CALL dbcsr_set(ec_env%matrix_w(ispin, 1)%matrix, 0.0_dp)
561 END DO
562
563 ! hz matrix
564 IF (ASSOCIATED(ec_env%matrix_hz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_hz)
565 CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
566 headline = "Hz MATRIX"
567 DO ispin = 1, nspins
568 ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
569 CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, name=trim(headline), &
570 template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
571 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_hz(ispin)%matrix, sab_orb)
572 CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
573 END DO
574
575 ! Test for consistency of orbitals and KS matrix
576 DO ispin = 1, nspins
577 mat_struct => ec_env%mo_occ(ispin)%matrix_struct
578 CALL cp_fm_create(ksmo, mat_struct)
579 CALL cp_fm_get_info(ksmo, nrow_global=nao, ncol_global=nocc)
580 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_ks(ispin, 1)%matrix, ec_env%mo_occ(ispin), &
581 ksmo, nocc, alpha=1.0_dp, beta=0.0_dp)
582 CALL cp_fm_create(smo, mat_struct)
583 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_s(1, 1)%matrix, ec_env%mo_occ(ispin), &
584 smo, nocc, alpha=1.0_dp, beta=0.0_dp)
585 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
586 template_fmstruct=mat_struct)
587 CALL cp_fm_create(emat, fm_struct)
588 CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, ec_env%mo_occ(ispin), ksmo, 0.0_dp, emat)
589 CALL parallel_gemm('N', 'N', nao, nocc, nocc, -1.0_dp, smo, emat, 1.0_dp, ksmo)
590 CALL cp_fm_maxabsval(ksmo, a_max)
591 CALL cp_fm_struct_release(fm_struct)
592 CALL cp_fm_release(smo)
593 CALL cp_fm_release(ksmo)
594 CALL cp_fm_release(emat)
595 CALL cp_fm_maxabsval(ec_env%mo_occ(ispin), c_max)
596 IF (unit_nr > 0) THEN
597 WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO coeficients", ispin, c_max
598 WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO gradients", ispin, a_max
599 END IF
600 END DO
601 END IF
602
603 CALL timestop(handle)
604
605 END SUBROUTINE ec_ext_setup
606
607! **************************************************************************************************
608!> \brief ...
609!> \param cpmos ...
610!> \param mo_ref ...
611!> \param mo_occ ...
612!> \param matrix_s ...
613!> \param orbrot_index ...
614!> \param phase_index ...
615!> \param unit_nr ...
616! **************************************************************************************************
617 SUBROUTINE align_vectors(cpmos, mo_ref, mo_occ, matrix_s, orbrot_index, phase_index, unit_nr)
618 TYPE(cp_fm_type), INTENT(IN) :: cpmos, mo_ref, mo_occ
619 TYPE(dbcsr_type), POINTER :: matrix_s
620 REAL(kind=dp), INTENT(OUT) :: orbrot_index, phase_index
621 INTEGER, INTENT(IN) :: unit_nr
622
623 CHARACTER(LEN=*), PARAMETER :: routinen = 'align_vectors'
624
625 INTEGER :: handle, i, nao, nocc, scg
626 REAL(kind=dp) :: a_max
627 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: diag
628 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
629 TYPE(cp_fm_type) :: emat, smo
630
631 CALL timeset(routinen, handle)
632
633 mat_struct => cpmos%matrix_struct
634 CALL cp_fm_create(smo, mat_struct)
635 CALL cp_fm_get_info(smo, nrow_global=nao, ncol_global=nocc)
636 CALL cp_dbcsr_sm_fm_multiply(matrix_s, mo_occ, smo, nocc, alpha=1.0_dp, beta=0.0_dp)
637 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
638 template_fmstruct=mat_struct)
639 CALL cp_fm_create(emat, fm_struct)
640 CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, mo_ref, smo, 0.0_dp, emat)
641 CALL parallel_gemm('N', 'N', nao, nocc, nocc, 1.0_dp, cpmos, emat, 0.0_dp, smo)
642 CALL cp_fm_to_fm(smo, cpmos)
643 CALL cp_fm_to_fm(mo_occ, mo_ref)
644 !
645 ALLOCATE (diag(nocc))
646 CALL cp_fm_get_diag(emat, diag)
647 a_max = nocc - sum(diag)
648 scg = 0
649 DO i = 1, nocc
650 IF (abs(diag(i) + 1.0_dp) < 0.001) scg = scg + 1
651 END DO
652 IF (unit_nr > 0) THEN
653 WRITE (unit_nr, "(T3,A,T61,F20.8)") "External:: Orbital rotation index", a_max
654 WRITE (unit_nr, "(T3,A,T71,I10)") "External:: Number of orbital phase changes", scg
655 END IF
656 orbrot_index = a_max
657 phase_index = real(scg, kind=dp)
658
659 DEALLOCATE (diag)
660 CALL cp_fm_struct_release(fm_struct)
661 CALL cp_fm_release(smo)
662 CALL cp_fm_release(emat)
663
664 CALL timestop(handle)
665
666 END SUBROUTINE align_vectors
667
668! **************************************************************************************************
669!> \brief ...
670!> \param qs_env ...
671!> \param cpmos ...
672!> \param mo_occ ...
673!> \param matrix_r ...
674!> \param unit_nr ...
675!> \param debug_forces ...
676!> \param debug_stress ...
677! **************************************************************************************************
678 SUBROUTINE matrix_r_forces(qs_env, cpmos, mo_occ, matrix_r, unit_nr, &
679 debug_forces, debug_stress)
680 TYPE(qs_environment_type), POINTER :: qs_env
681 TYPE(cp_fm_type), DIMENSION(:), POINTER :: cpmos, mo_occ
682 TYPE(dbcsr_type), POINTER :: matrix_r
683 INTEGER, INTENT(IN) :: unit_nr
684 LOGICAL, INTENT(IN), OPTIONAL :: debug_forces, debug_stress
685
686 CHARACTER(LEN=*), PARAMETER :: routinen = 'matrix_r_forces'
687
688 INTEGER :: handle, iounit, ispin, nao, nocc, nspins
689 LOGICAL :: my_debug_forces, my_debug_stress, &
690 use_virial
691 REAL(kind=dp) :: fconv, focc
692 REAL(kind=dp), DIMENSION(3) :: fodeb
693 REAL(kind=dp), DIMENSION(3, 3) :: stdeb
694 TYPE(cell_type), POINTER :: cell
695 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
696 TYPE(cp_fm_type) :: chcmat, rcvec
697 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: scrm
698 TYPE(dft_control_type), POINTER :: dft_control
699 TYPE(mp_para_env_type), POINTER :: para_env
700 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
701 POINTER :: sab_orb
702 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
703 TYPE(qs_ks_env_type), POINTER :: ks_env
704 TYPE(virial_type), POINTER :: virial
705
706 CALL timeset(routinen, handle)
707
708 my_debug_forces = .true.
709 my_debug_stress = .true.
710 IF (PRESENT(debug_forces)) my_debug_forces = debug_forces
711 IF (PRESENT(debug_stress)) my_debug_stress = debug_stress
712 iounit = unit_nr
713
714 nspins = SIZE(mo_occ)
715 focc = 1.0_dp
716 IF (nspins == 1) focc = 2.0_dp
717 focc = 0.25_dp*focc
718
719 CALL dbcsr_set(matrix_r, 0.0_dp)
720 DO ispin = 1, nspins
721 CALL cp_fm_get_info(cpmos(ispin), matrix_struct=fm_struct, nrow_global=nao, ncol_global=nocc)
722 CALL cp_fm_create(rcvec, fm_struct)
723 CALL cp_fm_struct_create(mat_struct, nrow_global=nocc, ncol_global=nocc, template_fmstruct=fm_struct)
724 CALL cp_fm_create(chcmat, mat_struct)
725 CALL parallel_gemm("T", "N", nocc, nocc, nao, 1.0_dp, mo_occ(ispin), cpmos(ispin), 0.0_dp, chcmat)
726 CALL parallel_gemm("N", "N", nao, nocc, nocc, 1.0_dp, mo_occ(ispin), chcmat, 0.0_dp, rcvec)
727 CALL cp_dbcsr_plus_fm_fm_t(matrix_r, matrix_v=rcvec, matrix_g=mo_occ(ispin), ncol=nocc, alpha=focc)
728 CALL cp_fm_struct_release(mat_struct)
729 CALL cp_fm_release(rcvec)
730 CALL cp_fm_release(chcmat)
731 END DO
732
733 CALL get_qs_env(qs_env=qs_env, &
734 cell=cell, &
735 dft_control=dft_control, &
736 force=force, &
737 ks_env=ks_env, &
738 sab_orb=sab_orb, &
739 para_env=para_env, &
740 virial=virial)
741 ! check for virial
742 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
743 fconv = 1.0e-9_dp*pascal/cell%deth
744
745 IF (my_debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
746 IF (my_debug_stress .AND. use_virial) stdeb = virial%pv_overlap
747 NULLIFY (scrm)
748 CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
749 matrix_name="OVERLAP MATRIX", &
750 basis_type_a="ORB", basis_type_b="ORB", &
751 sab_nl=sab_orb, calculate_forces=.true., &
752 matrix_p=matrix_r)
753 IF (my_debug_forces) THEN
754 fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
755 CALL para_env%sum(fodeb)
756 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wz*dS ", fodeb
757 END IF
758 IF (my_debug_stress .AND. use_virial) THEN
759 stdeb = fconv*(virial%pv_overlap - stdeb)
760 CALL para_env%sum(stdeb)
761 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
762 'STRESS| Wz ', one_third_sum_diag(stdeb), det_3x3(stdeb)
763 END IF
765
766 CALL timestop(handle)
767
768 END SUBROUTINE matrix_r_forces
769
770END MODULE ec_external
Handles all functions related to the CELL.
Definition cell_types.F:15
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_set(matrix, alpha)
...
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
subroutine, public copy_dbcsr_to_fm(matrix, fm)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public cp_dbcsr_plus_fm_fm_t(sparse_matrix, matrix_v, matrix_g, ncol, alpha, keep_sparsity, symmetry_mode)
performs the multiplication sparse_matrix+dense_mat*dens_mat^T if matrix_g is not explicitly given,...
Utility routines to open and close files. Tracking of preconnections.
Definition cp_files.F:16
subroutine, public open_file(file_name, file_status, file_form, file_action, file_position, file_pad, unit_number, debug, skip_get_unit_number, file_access)
Opens the requested file using a free unit number.
Definition cp_files.F:311
subroutine, public close_file(unit_number, file_status, keep_preconnection)
Close an open file given by its logical unit number. Optionally, keep the file and unit preconnected.
Definition cp_files.F:122
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_diag(matrix, diag)
returns the diagonal elements of a fm
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp, nrow, ncol, set_zero)
creates a new full matrix with the given structure
subroutine, public cp_fm_maxabsval(matrix, a_max, ir_max, ic_max)
find the maximum absolute value of the matrix element maxval(abs(matrix))
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_get_submatrix(fm, target_m, start_row, start_col, n_rows, n_cols, transpose)
gets a submatrix of a full matrix op(target_m)(1:n_rows,1:n_cols) =fm(start_row:start_row+n_rows,...
various routines to log and control the output. The idea is that decisions about where to log should ...
recursive integer function, public cp_logger_get_default_unit_nr(logger, local, skip_not_ionode)
asks the default unit number of the given logger. try to use cp_logger_get_unit_nr
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
Types needed for a for a Energy Correction.
Routines for an external energy correction on top of a Kohn-Sham calculation.
Definition ec_external.F:14
subroutine, public ec_ext_energy(qs_env, ec_env, calculate_forces)
External energy method.
Definition ec_external.F:88
subroutine, public matrix_r_forces(qs_env, cpmos, mo_occ, matrix_r, unit_nr, debug_forces, debug_stress)
...
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
integer, parameter, public default_string_length
Definition kinds.F:57
Collection of simple mathematical functions and subroutines.
Definition mathlib.F:15
subroutine, public diag(n, a, d, v)
Diagonalize matrix a. The eigenvalues are returned in vector d and the eigenvectors are returned in m...
Definition mathlib.F:1504
Interface to the message passing library MPI.
basic linear algebra operations for full matrixes
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public pascal
Definition physcon.F:174
Calculation of the energies concerning the core charge distribution.
Calculation of the core Hamiltonian integral matrix <a|H|b> over Cartesian Gaussian-type functions.
subroutine, public kinetic_energy_matrix(qs_env, matrixkp_t, matrix_t, matrix_p, matrix_name, calculate_forces, nderivative, sab_orb, eps_filter, basis_type, debug_forces, debug_stress)
Calculate kinetic energy matrix and possible relativistic correction.
subroutine, public core_matrices(qs_env, matrix_h, matrix_p, calculate_forces, nder, ec_env, dcdr_env, ec_env_matrices, basis_type, debug_forces, debug_stress, atcore)
...
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
subroutine, public deallocate_mo_set(mo_set)
Deallocate a wavefunction data structure.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Define the neighbor list data types and the corresponding functionality.
Calculation of overlap matrix, its derivatives and forces.
Definition qs_overlap.F:19
subroutine, public build_overlap_matrix(ks_env, matrix_s, matrixkp_s, matrix_name, nderivative, basis_type_a, basis_type_b, sab_nl, calculate_forces, matrix_p, matrixkp_p)
Calculation of the overlap matrix over Cartesian Gaussian functions.
Definition qs_overlap.F:120
superstucture that hold various representations of the density and keeps track of which ones are vali...
subroutine, public qs_rho_get(rho_struct, rho_ao, rho_ao_im, rho_ao_kp, rho_ao_im_kp, rho_r, drho_r, rho_g, drho_g, tau_r, tau_g, rho_r_valid, drho_r_valid, rho_g_valid, drho_g_valid, tau_r_valid, tau_g_valid, tot_rho_r, tot_rho_g, rho_r_sccs, soft_valid, complex_rho_ao)
returns info about the density described by this object. If some representation is not available an e...
The module to read/write TREX IO files for interfacing CP2K with other programs.
subroutine, public read_trexio(qs_env, trexio_filename, mo_set_trexio, energy_derivative)
Read a trexio file.
pure real(kind=dp) function, public one_third_sum_diag(a)
...
Type defining parameters related to the simulation cell.
Definition cell_types.F:60
keeps the information about the structure of a full matrix
represent a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
Contains information on the energy correction functional for KG.
stores all the informations relevant to an mpi environment
calculation environment to calculate the ks matrix, holds all the needed vars. assumes that the core ...
keeps the density in various representations, keeping track of which ones are valid.