(git:97501a3)
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-2025 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_add,&
21 dbcsr_set,&
23 dbcsr_type_symmetric
32 USE cp_fm_types, ONLY: cp_fm_create,&
44 USE kinds, ONLY: default_string_length,&
45 dp
46 USE mathlib, ONLY: det_3x3
49 USE physcon, ONLY: pascal
62 USE qs_rho_types, ONLY: qs_rho_get,&
64 USE trexio_utils, ONLY: read_trexio
66 USE virial_types, ONLY: virial_type
67#include "./base/base_uses.f90"
68
69 IMPLICIT NONE
70
71 PRIVATE
72
73! *** Global parameters ***
74
75 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'ec_external'
76
77 PUBLIC :: ec_ext_energy
78
79CONTAINS
80
81! **************************************************************************************************
82!> \brief External energy method
83!> \param qs_env ...
84!> \param ec_env ...
85!> \param calculate_forces ...
86!> \par History
87!> 10.2024 created
88!> \author JGH
89! **************************************************************************************************
90 SUBROUTINE ec_ext_energy(qs_env, ec_env, calculate_forces)
91 TYPE(qs_environment_type), POINTER :: qs_env
92 TYPE(energy_correction_type), POINTER :: ec_env
93 LOGICAL, INTENT(IN) :: calculate_forces
94
95 CHARACTER(len=*), PARAMETER :: routinen = 'ec_ext_energy'
96
97 INTEGER :: handle, ispin, nocc, nspins, unit_nr
98 REAL(kind=dp) :: focc
99 TYPE(cp_fm_struct_type), POINTER :: fm_struct
100 TYPE(cp_fm_type), DIMENSION(:), POINTER :: cpmos, mo_occ, mo_ref
101 TYPE(cp_fm_type), POINTER :: mo_coeff
102 TYPE(cp_logger_type), POINTER :: logger
103 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
104 TYPE(dft_control_type), POINTER :: dft_control
105 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
106
107 CALL timeset(routinen, handle)
108
109 CALL get_qs_env(qs_env, dft_control=dft_control)
110 nspins = dft_control%nspins
111
112 logger => cp_get_default_logger()
113 IF (logger%para_env%is_source()) THEN
114 unit_nr = cp_logger_get_default_unit_nr(logger, local=.true.)
115 ELSE
116 unit_nr = -1
117 END IF
118
119 ec_env%etotal = 0.0_dp
120 ec_env%ex = 0.0_dp
121 ec_env%exc = 0.0_dp
122 ec_env%ehartree = 0.0_dp
123
124 CALL get_qs_env(qs_env, mos=mos)
125 ALLOCATE (cpmos(nspins), mo_ref(nspins), mo_occ(nspins))
126
127 CALL cp_fm_release(ec_env%mo_occ)
128 CALL cp_fm_release(ec_env%cpmos)
129 IF (ec_env%debug_external) THEN
130 !
131 DO ispin = 1, nspins
132 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
133 NULLIFY (fm_struct)
134 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, &
135 template_fmstruct=mo_coeff%matrix_struct)
136 CALL cp_fm_create(cpmos(ispin), fm_struct)
137 CALL cp_fm_set_all(cpmos(ispin), 0.0_dp)
138 CALL cp_fm_create(mo_ref(ispin), fm_struct)
139 CALL cp_fm_set_all(mo_ref(ispin), 0.0_dp)
140 CALL cp_fm_create(mo_occ(ispin), fm_struct)
141 CALL cp_fm_to_fm(mo_coeff, mo_occ(ispin), nocc)
142 CALL cp_fm_struct_release(fm_struct)
143 END DO
144 !
145 ec_env%mo_occ => mo_ref
146 CALL ec_ext_debug(qs_env, ec_env, calculate_forces, unit_nr)
147 !
148 IF (calculate_forces) THEN
149 focc = 2.0_dp
150 IF (nspins == 1) focc = 4.0_dp
151 DO ispin = 1, nspins
152 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
153 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_h(1, 1)%matrix, ec_env%mo_occ(ispin), &
154 cpmos(ispin), nocc, &
155 alpha=focc, beta=0.0_dp)
156 END DO
157 END IF
158 ec_env%cpmos => cpmos
159 ELSE
160 DO ispin = 1, nspins
161 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
162 NULLIFY (fm_struct)
163 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, &
164 template_fmstruct=mo_coeff%matrix_struct)
165 CALL cp_fm_create(cpmos(ispin), fm_struct)
166 CALL cp_fm_set_all(cpmos(ispin), 0.0_dp)
167 CALL cp_fm_create(mo_occ(ispin), fm_struct)
168 CALL cp_fm_to_fm(mo_coeff, mo_occ(ispin), nocc)
169 CALL cp_fm_create(mo_ref(ispin), fm_struct)
170 CALL cp_fm_set_all(mo_ref(ispin), 0.0_dp)
171 CALL cp_fm_struct_release(fm_struct)
172 END DO
173
174 ! get external information
175 CALL ec_ext_interface(qs_env, ec_env%exresp_fn, mo_occ, mo_ref, cpmos, calculate_forces, unit_nr)
176 ec_env%mo_occ => mo_ref
177 ec_env%cpmos => cpmos
178 END IF
179
180 IF (calculate_forces) THEN
181 ! check for orbital rotations
182 CALL get_qs_env(qs_env, matrix_s=matrix_s)
183 DO ispin = 1, nspins
184 CALL align_vectors(ec_env%cpmos(ispin), ec_env%mo_occ(ispin), mo_occ(ispin), &
185 matrix_s(1)%matrix, unit_nr)
186 END DO
187 ! set up matrices for response
188 CALL ec_ext_setup(qs_env, ec_env, .true., unit_nr)
189 ! orthogonality force
190 CALL matrix_r_forces(qs_env, ec_env%cpmos, ec_env%mo_occ, &
191 ec_env%matrix_w(1, 1)%matrix, unit_nr)
192 ELSE
193 CALL ec_ext_setup(qs_env, ec_env, .false., unit_nr)
194 END IF
195
196 CALL cp_fm_release(mo_occ)
197
198 CALL timestop(handle)
199
200 END SUBROUTINE ec_ext_energy
201
202! **************************************************************************************************
203
204! **************************************************************************************************
205!> \brief ...
206!> \param qs_env ...
207!> \param trexio_fn ...
208!> \param mo_occ ...
209!> \param mo_ref ...
210!> \param cpmos ...
211!> \param calculate_forces ...
212!> \param unit_nr ...
213! **************************************************************************************************
214 SUBROUTINE ec_ext_interface(qs_env, trexio_fn, mo_occ, mo_ref, cpmos, calculate_forces, unit_nr)
215 TYPE(qs_environment_type), POINTER :: qs_env
216 CHARACTER(LEN=*) :: trexio_fn
217 TYPE(cp_fm_type), DIMENSION(:), POINTER :: mo_occ, mo_ref, cpmos
218 LOGICAL, INTENT(IN) :: calculate_forces
219 INTEGER, INTENT(IN) :: unit_nr
220
221 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_ext_interface'
222
223 INTEGER :: handle, ispin, nao, nmos, nocc(2), nspins
224 REAL(kind=dp) :: focc
225 TYPE(cp_fm_type), POINTER :: mo_coeff
226 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: energy_derivative
227 TYPE(dft_control_type), POINTER :: dft_control
228 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos_trexio
229 TYPE(mp_para_env_type), POINTER :: para_env
230
231 CALL timeset(routinen, handle)
232
233 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, para_env=para_env)
234
235 nspins = dft_control%nspins
236 nocc = 0
237 DO ispin = 1, nspins
238 CALL cp_fm_get_info(mo_occ(ispin), nrow_global=nao, ncol_global=nocc(ispin))
239 END DO
240
241 IF (unit_nr > 0) THEN
242 WRITE (unit_nr, '(T2,A)') " Read EXTERNAL Response from file: "//trim(trexio_fn)
243 END IF
244 ALLOCATE (mos_trexio(nspins))
245 IF (calculate_forces) THEN
246 NULLIFY (energy_derivative)
247 CALL dbcsr_allocate_matrix_set(energy_derivative, nspins)
248 !
249 CALL read_trexio(qs_env, trexio_filename=trexio_fn, &
250 mo_set_trexio=mos_trexio, &
251 energy_derivative=energy_derivative)
252 !
253 focc = 2.0_dp
254 IF (nspins == 1) focc = 4.0_dp
255 DO ispin = 1, nspins
256 CALL get_mo_set(mo_set=mos_trexio(ispin), mo_coeff=mo_coeff, homo=nmos)
257 CALL cp_dbcsr_sm_fm_multiply(energy_derivative(ispin)%matrix, mo_coeff, &
258 cpmos(ispin), ncol=nmos, alpha=focc, beta=0.0_dp)
259 END DO
260 !
261 CALL dbcsr_deallocate_matrix_set(energy_derivative)
262 ELSE
263 CALL read_trexio(qs_env, trexio_filename=trexio_fn, &
264 mo_set_trexio=mos_trexio)
265 END IF
266 !
267 DO ispin = 1, nspins
268 CALL get_mo_set(mo_set=mos_trexio(ispin), mo_coeff=mo_coeff, homo=nmos)
269 CALL cp_fm_to_fm(mo_coeff, mo_ref(ispin), nmos)
270 CALL deallocate_mo_set(mos_trexio(ispin))
271 END DO
272 DEALLOCATE (mos_trexio)
273
274 CALL timestop(handle)
275
276 END SUBROUTINE ec_ext_interface
277
278! **************************************************************************************************
279
280! **************************************************************************************************
281!> \brief ...
282!> \param qs_env ...
283!> \param ec_env ...
284!> \param calculate_forces ...
285!> \param unit_nr ...
286! **************************************************************************************************
287 SUBROUTINE ec_ext_debug(qs_env, ec_env, calculate_forces, unit_nr)
288 TYPE(qs_environment_type), POINTER :: qs_env
289 TYPE(energy_correction_type), POINTER :: ec_env
290 LOGICAL, INTENT(IN) :: calculate_forces
291 INTEGER, INTENT(IN) :: unit_nr
292
293 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_ext_debug'
294
295 CHARACTER(LEN=default_string_length) :: headline
296 INTEGER :: handle, ispin, nocc, nspins
297 TYPE(cp_fm_type), POINTER :: mo_coeff
298 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_p, matrix_s
299 TYPE(dft_control_type), POINTER :: dft_control
300 TYPE(mo_set_type), DIMENSION(:), POINTER :: mos
301 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
302 POINTER :: sab_orb
303 TYPE(qs_rho_type), POINTER :: rho
304
305 CALL timeset(routinen, handle)
306
307 CALL get_qs_env(qs_env=qs_env, &
308 dft_control=dft_control, &
309 sab_orb=sab_orb, &
310 rho=rho, &
311 matrix_s_kp=matrix_s, &
312 matrix_h_kp=matrix_h)
313
314 nspins = dft_control%nspins
315 CALL get_qs_env(qs_env, mos=mos)
316 DO ispin = 1, nspins
317 CALL get_mo_set(mo_set=mos(ispin), mo_coeff=mo_coeff, homo=nocc)
318 CALL cp_fm_to_fm(mo_coeff, ec_env%mo_occ(ispin), nocc)
319 END DO
320
321 ! Core Hamiltonian matrix
322 IF (ASSOCIATED(ec_env%matrix_h)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_h)
323 CALL dbcsr_allocate_matrix_set(ec_env%matrix_h, 1, 1)
324 headline = "CORE HAMILTONIAN MATRIX"
325 ALLOCATE (ec_env%matrix_h(1, 1)%matrix)
326 CALL dbcsr_create(ec_env%matrix_h(1, 1)%matrix, name=trim(headline), &
327 template=matrix_h(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
328 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_h(1, 1)%matrix, sab_orb)
329 CALL dbcsr_copy(ec_env%matrix_h(1, 1)%matrix, matrix_h(1, 1)%matrix)
330
331 ! Get density matrix of reference calculation
332 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
333 ! Use Core energy as model energy
334 CALL calculate_ptrace(ec_env%matrix_h, matrix_p, ec_env%ex, nspins)
335
336 IF (calculate_forces) THEN
337 ! force of model energy
338 CALL ec_debug_force(qs_env, matrix_p, unit_nr)
339 END IF
340
341 CALL timestop(handle)
342
343 END SUBROUTINE ec_ext_debug
344
345! **************************************************************************************************
346!> \brief ...
347!> \param qs_env ...
348!> \param matrix_p ...
349!> \param unit_nr ...
350! **************************************************************************************************
351 SUBROUTINE ec_debug_force(qs_env, matrix_p, unit_nr)
352 TYPE(qs_environment_type), POINTER :: qs_env
353 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_p
354 INTEGER, INTENT(IN) :: unit_nr
355
356 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_debug_force'
357
358 INTEGER :: handle, iounit, nder, nimages
359 LOGICAL :: calculate_forces, debug_forces, &
360 debug_stress, use_virial
361 REAL(kind=dp) :: fconv
362 REAL(kind=dp), DIMENSION(3, 3) :: stdeb, sttot
363 TYPE(cell_type), POINTER :: cell
364 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: scrm
365 TYPE(dft_control_type), POINTER :: dft_control
366 TYPE(mp_para_env_type), POINTER :: para_env
367 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
368 POINTER :: sab_orb
369 TYPE(virial_type), POINTER :: virial
370
371 CALL timeset(routinen, handle)
372
373 debug_forces = .true.
374 debug_stress = .true.
375 iounit = unit_nr
376
377 calculate_forces = .true.
378
379 ! no k-points possible
380 CALL get_qs_env(qs_env=qs_env, &
381 cell=cell, &
382 dft_control=dft_control, &
383 para_env=para_env, &
384 virial=virial)
385 nimages = dft_control%nimages
386 IF (nimages /= 1) THEN
387 cpabort("K-points not implemented")
388 END IF
389
390 ! check for virial
391 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
392
393 fconv = 1.0e-9_dp*pascal/cell%deth
394 IF (debug_stress .AND. use_virial) THEN
395 sttot = virial%pv_virial
396 END IF
397
398 ! check for GAPW/GAPW_XC
399 IF (dft_control%qs_control%gapw .OR. dft_control%qs_control%gapw_xc) THEN
400 cpabort("GAPW not implemented")
401 END IF
402
403 ! initialize src matrix
404 NULLIFY (scrm)
405 CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
406 ALLOCATE (scrm(1, 1)%matrix)
407 CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_p(1, 1)%matrix)
408 CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
409 CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
410
411 ! kinetic energy
412 CALL kinetic_energy_matrix(qs_env, matrixkp_t=scrm, matrix_p=matrix_p, &
413 calculate_forces=calculate_forces, &
414 debug_forces=debug_forces, debug_stress=debug_stress)
415
416 nder = 1
417 CALL core_matrices(qs_env, scrm, matrix_p, calculate_forces, nder, &
418 debug_forces=debug_forces, debug_stress=debug_stress)
419
420 IF (debug_stress .AND. use_virial) THEN
421 stdeb = fconv*(virial%pv_virial - sttot)
422 CALL para_env%sum(stdeb)
423 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
424 'STRESS| Stress Pout*dHcore ', one_third_sum_diag(stdeb), det_3x3(stdeb)
425 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") ' '
426 END IF
427
428 ! delete scr matrix
430
431 CALL timestop(handle)
432
433 END SUBROUTINE ec_debug_force
434
435! **************************************************************************************************
436
437! **************************************************************************************************
438!> \brief ...
439!> \param qs_env ...
440!> \param ec_env ...
441!> \param calc_forces ...
442!> \param unit_nr ...
443! **************************************************************************************************
444 SUBROUTINE ec_ext_setup(qs_env, ec_env, calc_forces, unit_nr)
445 TYPE(qs_environment_type), POINTER :: qs_env
446 TYPE(energy_correction_type), POINTER :: ec_env
447 LOGICAL, INTENT(IN) :: calc_forces
448 INTEGER, INTENT(IN) :: unit_nr
449
450 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_ext_setup'
451
452 CHARACTER(LEN=default_string_length) :: headline
453 INTEGER :: handle, ispin, nao, nocc, nspins
454 REAL(kind=dp) :: a_max, c_max
455 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
456 TYPE(cp_fm_type) :: emat, ksmo, smo
457 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_ks, matrix_p, matrix_s
458 TYPE(dft_control_type), POINTER :: dft_control
459 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
460 POINTER :: sab_orb
461 TYPE(qs_rho_type), POINTER :: rho
462
463 CALL timeset(routinen, handle)
464
465 CALL get_qs_env(qs_env=qs_env, &
466 dft_control=dft_control, &
467 sab_orb=sab_orb, &
468 rho=rho, &
469 matrix_s_kp=matrix_s, &
470 matrix_ks_kp=matrix_ks, &
471 matrix_h_kp=matrix_h)
472
473 nspins = dft_control%nspins
474
475 ! KS Hamiltonian matrix
476 IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
477 CALL dbcsr_allocate_matrix_set(ec_env%matrix_ks, nspins, 1)
478 headline = "HAMILTONIAN MATRIX"
479 DO ispin = 1, nspins
480 ALLOCATE (ec_env%matrix_ks(ispin, 1)%matrix)
481 CALL dbcsr_create(ec_env%matrix_ks(ispin, 1)%matrix, name=trim(headline), &
482 template=matrix_ks(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
483 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_ks(ispin, 1)%matrix, sab_orb)
484 CALL dbcsr_copy(ec_env%matrix_ks(ispin, 1)%matrix, matrix_ks(ispin, 1)%matrix)
485 END DO
486
487 ! Overlap matrix
488 IF (ASSOCIATED(ec_env%matrix_s)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_s)
489 CALL dbcsr_allocate_matrix_set(ec_env%matrix_s, 1, 1)
490 headline = "OVERLAP MATRIX"
491 ALLOCATE (ec_env%matrix_s(1, 1)%matrix)
492 CALL dbcsr_create(ec_env%matrix_s(1, 1)%matrix, name=trim(headline), &
493 template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
494 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_s(1, 1)%matrix, sab_orb)
495 CALL dbcsr_copy(ec_env%matrix_s(1, 1)%matrix, matrix_s(1, 1)%matrix)
496
497 ! density matrix
498 ! Get density matrix of reference calculation
499 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
500 IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
501 CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, 1)
502 headline = "DENSITY MATRIX"
503 DO ispin = 1, nspins
504 ALLOCATE (ec_env%matrix_p(ispin, 1)%matrix)
505 CALL dbcsr_create(ec_env%matrix_p(ispin, 1)%matrix, name=trim(headline), &
506 template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
507 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, 1)%matrix, sab_orb)
508 CALL dbcsr_copy(ec_env%matrix_p(ispin, 1)%matrix, matrix_p(ispin, 1)%matrix)
509 END DO
510
511 IF (calc_forces) THEN
512 ! energy weighted density matrix
513 ! for security, we recalculate W here (stored in qs_env)
514 IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
515 CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, 1)
516 headline = "ENERGY WEIGHTED DENSITY MATRIX"
517 DO ispin = 1, nspins
518 ALLOCATE (ec_env%matrix_w(ispin, 1)%matrix)
519 CALL dbcsr_create(ec_env%matrix_w(ispin, 1)%matrix, name=trim(headline), &
520 template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
521 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, 1)%matrix, sab_orb)
522 CALL dbcsr_set(ec_env%matrix_w(ispin, 1)%matrix, 0.0_dp)
523 END DO
524
525 ! hz matrix
526 IF (ASSOCIATED(ec_env%matrix_hz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_hz)
527 CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
528 headline = "Hz MATRIX"
529 DO ispin = 1, nspins
530 ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
531 CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, name=trim(headline), &
532 template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
533 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_hz(ispin)%matrix, sab_orb)
534 CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
535 END DO
536
537 ! Test for consistency of orbitals and KS matrix
538 DO ispin = 1, nspins
539 mat_struct => ec_env%mo_occ(ispin)%matrix_struct
540 CALL cp_fm_create(ksmo, mat_struct)
541 CALL cp_fm_get_info(ksmo, nrow_global=nao, ncol_global=nocc)
542 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_ks(ispin, 1)%matrix, ec_env%mo_occ(ispin), &
543 ksmo, nocc, alpha=1.0_dp, beta=0.0_dp)
544 CALL cp_fm_create(smo, mat_struct)
545 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_s(1, 1)%matrix, ec_env%mo_occ(ispin), &
546 smo, nocc, alpha=1.0_dp, beta=0.0_dp)
547 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
548 template_fmstruct=mat_struct)
549 CALL cp_fm_create(emat, fm_struct)
550 CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, ec_env%mo_occ(ispin), ksmo, 0.0_dp, emat)
551 CALL parallel_gemm('N', 'N', nao, nocc, nocc, -1.0_dp, smo, emat, 1.0_dp, ksmo)
552 CALL cp_fm_maxabsval(ksmo, a_max)
553 CALL cp_fm_struct_release(fm_struct)
554 CALL cp_fm_release(smo)
555 CALL cp_fm_release(ksmo)
556 CALL cp_fm_release(emat)
557 CALL cp_fm_maxabsval(ec_env%mo_occ(ispin), c_max)
558 IF (unit_nr > 0) THEN
559 WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO coeficients", ispin, c_max
560 WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO gradients", ispin, a_max
561 END IF
562 END DO
563 END IF
564
565 CALL timestop(handle)
566
567 END SUBROUTINE ec_ext_setup
568
569! **************************************************************************************************
570!> \brief ...
571!> \param cpmos ...
572!> \param mo_ref ...
573!> \param mo_occ ...
574!> \param matrix_s ...
575!> \param unit_nr ...
576! **************************************************************************************************
577 SUBROUTINE align_vectors(cpmos, mo_ref, mo_occ, matrix_s, unit_nr)
578 TYPE(cp_fm_type), INTENT(IN) :: cpmos, mo_ref, mo_occ
579 TYPE(dbcsr_type), POINTER :: matrix_s
580 INTEGER, INTENT(IN) :: unit_nr
581
582 CHARACTER(LEN=*), PARAMETER :: routinen = 'align_vectors'
583
584 INTEGER :: handle, i, nao, nocc, scg
585 REAL(kind=dp) :: a_max
586 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: diag
587 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
588 TYPE(cp_fm_type) :: emat, smo
589
590 CALL timeset(routinen, handle)
591
592 mat_struct => cpmos%matrix_struct
593 CALL cp_fm_create(smo, mat_struct)
594 CALL cp_fm_get_info(smo, nrow_global=nao, ncol_global=nocc)
595 CALL cp_dbcsr_sm_fm_multiply(matrix_s, mo_occ, smo, nocc, alpha=1.0_dp, beta=0.0_dp)
596 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
597 template_fmstruct=mat_struct)
598 CALL cp_fm_create(emat, fm_struct)
599 CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, mo_ref, smo, 0.0_dp, emat)
600 CALL parallel_gemm('N', 'N', nao, nocc, nocc, 1.0_dp, cpmos, emat, 0.0_dp, smo)
601 CALL cp_fm_to_fm(smo, cpmos)
602 CALL cp_fm_to_fm(mo_occ, mo_ref)
603 !
604 ALLOCATE (diag(nocc))
605 CALL cp_fm_get_diag(emat, diag)
606 a_max = nocc - sum(diag)
607 scg = 0
608 DO i = 1, nocc
609 IF (abs(diag(i) + 1.0_dp) < 0.001) scg = scg + 1
610 END DO
611 IF (unit_nr > 0) THEN
612 WRITE (unit_nr, "(T3,A,T61,F20.8)") "External:: Orbital rotation index", a_max
613 WRITE (unit_nr, "(T3,A,T71,I10)") "External:: Number of orbital phase changes", scg
614 END IF
615
616 DEALLOCATE (diag)
617 CALL cp_fm_struct_release(fm_struct)
618 CALL cp_fm_release(smo)
619 CALL cp_fm_release(emat)
620
621 CALL timestop(handle)
622
623 END SUBROUTINE align_vectors
624
625! **************************************************************************************************
626!> \brief ...
627!> \param qs_env ...
628!> \param matrix_w ...
629!> \param unit_nr ...
630! **************************************************************************************************
631 SUBROUTINE matrix_w_forces(qs_env, matrix_w, unit_nr)
632 TYPE(qs_environment_type), POINTER :: qs_env
633 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_w
634 INTEGER, INTENT(IN) :: unit_nr
635
636 CHARACTER(LEN=*), PARAMETER :: routinen = 'matrix_w_forces'
637
638 INTEGER :: handle, iounit, nder, nimages
639 LOGICAL :: debug_forces, debug_stress, use_virial
640 REAL(kind=dp) :: fconv
641 REAL(kind=dp), DIMENSION(3) :: fodeb
642 REAL(kind=dp), DIMENSION(3, 3) :: stdeb, sttot
643 TYPE(cell_type), POINTER :: cell
644 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: scrm
645 TYPE(dft_control_type), POINTER :: dft_control
646 TYPE(mp_para_env_type), POINTER :: para_env
647 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
648 POINTER :: sab_orb
649 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
650 TYPE(qs_ks_env_type), POINTER :: ks_env
651 TYPE(virial_type), POINTER :: virial
652
653 CALL timeset(routinen, handle)
654
655 debug_forces = .true.
656 debug_stress = .true.
657
658 iounit = unit_nr
659
660 ! no k-points possible
661 CALL get_qs_env(qs_env=qs_env, &
662 cell=cell, &
663 dft_control=dft_control, &
664 force=force, &
665 ks_env=ks_env, &
666 sab_orb=sab_orb, &
667 para_env=para_env, &
668 virial=virial)
669 nimages = dft_control%nimages
670 IF (nimages /= 1) THEN
671 cpabort("K-points not implemented")
672 END IF
673
674 ! check for virial
675 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
676
677 fconv = 1.0e-9_dp*pascal/cell%deth
678 IF (debug_stress .AND. use_virial) THEN
679 sttot = virial%pv_virial
680 END IF
681
682 ! initialize src matrix
683 NULLIFY (scrm)
684 CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
685 ALLOCATE (scrm(1, 1)%matrix)
686 CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_w(1, 1)%matrix)
687 CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
688
689 nder = 1
690 IF (SIZE(matrix_w, 1) == 2) THEN
691 CALL dbcsr_add(matrix_w(1, 1)%matrix, matrix_w(2, 1)%matrix, &
692 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
693 END IF
694
695 ! Overlap and kinetic energy matrices
696 IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
697 IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
698 CALL build_overlap_matrix(ks_env, matrixkp_s=scrm, &
699 matrix_name="OVERLAP MATRIX", &
700 basis_type_a="ORB", &
701 basis_type_b="ORB", &
702 sab_nl=sab_orb, calculate_forces=.true., &
703 matrixkp_p=matrix_w)
704
705 IF (debug_forces) THEN
706 fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
707 CALL para_env%sum(fodeb)
708 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wout*dS ", fodeb
709 END IF
710 IF (debug_stress .AND. use_virial) THEN
711 stdeb = fconv*(virial%pv_overlap - stdeb)
712 CALL para_env%sum(stdeb)
713 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
714 'STRESS| Wout*dS', one_third_sum_diag(stdeb), det_3x3(stdeb)
715 END IF
716 IF (SIZE(matrix_w, 1) == 2) THEN
717 CALL dbcsr_add(matrix_w(1, 1)%matrix, matrix_w(2, 1)%matrix, &
718 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
719 END IF
720
721 ! delete scrm matrix
723
724 CALL timestop(handle)
725
726 END SUBROUTINE matrix_w_forces
727
728! **************************************************************************************************
729!> \brief ...
730!> \param qs_env ...
731!> \param cpmos ...
732!> \param mo_occ ...
733!> \param matrix_r ...
734!> \param unit_nr ...
735! **************************************************************************************************
736 SUBROUTINE matrix_r_forces(qs_env, cpmos, mo_occ, matrix_r, unit_nr)
737 TYPE(qs_environment_type), POINTER :: qs_env
738 TYPE(cp_fm_type), DIMENSION(:), POINTER :: cpmos, mo_occ
739 TYPE(dbcsr_type), POINTER :: matrix_r
740 INTEGER, INTENT(IN) :: unit_nr
741
742 CHARACTER(LEN=*), PARAMETER :: routinen = 'matrix_r_forces'
743
744 INTEGER :: handle, iounit, ispin, nao, nocc, nspins
745 LOGICAL :: debug_forces, debug_stress, use_virial
746 REAL(kind=dp) :: fconv, focc
747 REAL(kind=dp), DIMENSION(3) :: fodeb
748 REAL(kind=dp), DIMENSION(3, 3) :: stdeb
749 TYPE(cell_type), POINTER :: cell
750 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
751 TYPE(cp_fm_type) :: chcmat, rcvec
752 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: scrm
753 TYPE(dft_control_type), POINTER :: dft_control
754 TYPE(mp_para_env_type), POINTER :: para_env
755 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
756 POINTER :: sab_orb
757 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
758 TYPE(qs_ks_env_type), POINTER :: ks_env
759 TYPE(virial_type), POINTER :: virial
760
761 CALL timeset(routinen, handle)
762
763 debug_forces = .true.
764 debug_stress = .true.
765 iounit = unit_nr
766
767 nspins = SIZE(mo_occ)
768 focc = 1.0_dp
769 IF (nspins == 1) focc = 2.0_dp
770 focc = 0.25_dp*focc
771
772 CALL dbcsr_set(matrix_r, 0.0_dp)
773 DO ispin = 1, nspins
774 CALL cp_fm_get_info(cpmos(ispin), matrix_struct=fm_struct, nrow_global=nao, ncol_global=nocc)
775 CALL cp_fm_create(rcvec, fm_struct)
776 CALL cp_fm_struct_create(mat_struct, nrow_global=nocc, ncol_global=nocc, template_fmstruct=fm_struct)
777 CALL cp_fm_create(chcmat, mat_struct)
778 CALL parallel_gemm("T", "N", nocc, nocc, nao, 1.0_dp, mo_occ(ispin), cpmos(ispin), 0.0_dp, chcmat)
779 CALL parallel_gemm("N", "N", nao, nocc, nocc, 1.0_dp, mo_occ(ispin), chcmat, 0.0_dp, rcvec)
780 CALL cp_dbcsr_plus_fm_fm_t(matrix_r, matrix_v=rcvec, matrix_g=mo_occ(ispin), ncol=nocc, alpha=focc)
781 CALL cp_fm_struct_release(mat_struct)
782 CALL cp_fm_release(rcvec)
783 CALL cp_fm_release(chcmat)
784 END DO
785
786 CALL get_qs_env(qs_env=qs_env, &
787 cell=cell, &
788 dft_control=dft_control, &
789 force=force, &
790 ks_env=ks_env, &
791 sab_orb=sab_orb, &
792 para_env=para_env, &
793 virial=virial)
794 ! check for virial
795 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
796 fconv = 1.0e-9_dp*pascal/cell%deth
797
798 IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
799 IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
800 NULLIFY (scrm)
801 CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
802 matrix_name="OVERLAP MATRIX", &
803 basis_type_a="ORB", basis_type_b="ORB", &
804 sab_nl=sab_orb, calculate_forces=.true., &
805 matrix_p=matrix_r)
806 IF (debug_forces) THEN
807 fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
808 CALL para_env%sum(fodeb)
809 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wz*dS ", fodeb
810 END IF
811 IF (debug_stress .AND. use_virial) THEN
812 stdeb = fconv*(virial%pv_overlap - stdeb)
813 CALL para_env%sum(stdeb)
814 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
815 'STRESS| Wz ', one_third_sum_diag(stdeb), det_3x3(stdeb)
816 END IF
818
819 CALL timestop(handle)
820
821 END SUBROUTINE matrix_r_forces
822
823END 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)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
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 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,...
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_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_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
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:91
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:1496
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, 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, 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, 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, ecoul_1c, rho0_s_rs, rho0_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:55
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.