(git:936074a)
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 ! initialize src matrix
399 NULLIFY (scrm)
400 CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
401 ALLOCATE (scrm(1, 1)%matrix)
402 CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_p(1, 1)%matrix)
403 CALL get_qs_env(qs_env=qs_env, sab_orb=sab_orb)
404 CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
405
406 ! kinetic energy
407 CALL kinetic_energy_matrix(qs_env, matrixkp_t=scrm, matrix_p=matrix_p, &
408 calculate_forces=calculate_forces, &
409 debug_forces=debug_forces, debug_stress=debug_stress)
410
411 nder = 1
412 CALL core_matrices(qs_env, scrm, matrix_p, calculate_forces, nder, &
413 debug_forces=debug_forces, debug_stress=debug_stress)
414
415 IF (debug_stress .AND. use_virial) THEN
416 stdeb = fconv*(virial%pv_virial - sttot)
417 CALL para_env%sum(stdeb)
418 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
419 'STRESS| Stress Pout*dHcore ', one_third_sum_diag(stdeb), det_3x3(stdeb)
420 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") ' '
421 END IF
422
423 ! delete scr matrix
425
426 CALL timestop(handle)
427
428 END SUBROUTINE ec_debug_force
429
430! **************************************************************************************************
431
432! **************************************************************************************************
433!> \brief ...
434!> \param qs_env ...
435!> \param ec_env ...
436!> \param calc_forces ...
437!> \param unit_nr ...
438! **************************************************************************************************
439 SUBROUTINE ec_ext_setup(qs_env, ec_env, calc_forces, unit_nr)
440 TYPE(qs_environment_type), POINTER :: qs_env
441 TYPE(energy_correction_type), POINTER :: ec_env
442 LOGICAL, INTENT(IN) :: calc_forces
443 INTEGER, INTENT(IN) :: unit_nr
444
445 CHARACTER(LEN=*), PARAMETER :: routinen = 'ec_ext_setup'
446
447 CHARACTER(LEN=default_string_length) :: headline
448 INTEGER :: handle, ispin, nao, nocc, nspins
449 REAL(kind=dp) :: a_max, c_max
450 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
451 TYPE(cp_fm_type) :: emat, ksmo, smo
452 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_h, matrix_ks, matrix_p, matrix_s
453 TYPE(dft_control_type), POINTER :: dft_control
454 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
455 POINTER :: sab_orb
456 TYPE(qs_rho_type), POINTER :: rho
457
458 CALL timeset(routinen, handle)
459
460 CALL get_qs_env(qs_env=qs_env, &
461 dft_control=dft_control, &
462 sab_orb=sab_orb, &
463 rho=rho, &
464 matrix_s_kp=matrix_s, &
465 matrix_ks_kp=matrix_ks, &
466 matrix_h_kp=matrix_h)
467
468 nspins = dft_control%nspins
469
470 ! KS Hamiltonian matrix
471 IF (ASSOCIATED(ec_env%matrix_ks)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_ks)
472 CALL dbcsr_allocate_matrix_set(ec_env%matrix_ks, nspins, 1)
473 headline = "HAMILTONIAN MATRIX"
474 DO ispin = 1, nspins
475 ALLOCATE (ec_env%matrix_ks(ispin, 1)%matrix)
476 CALL dbcsr_create(ec_env%matrix_ks(ispin, 1)%matrix, name=trim(headline), &
477 template=matrix_ks(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
478 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_ks(ispin, 1)%matrix, sab_orb)
479 CALL dbcsr_copy(ec_env%matrix_ks(ispin, 1)%matrix, matrix_ks(ispin, 1)%matrix)
480 END DO
481
482 ! Overlap matrix
483 IF (ASSOCIATED(ec_env%matrix_s)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_s)
484 CALL dbcsr_allocate_matrix_set(ec_env%matrix_s, 1, 1)
485 headline = "OVERLAP MATRIX"
486 ALLOCATE (ec_env%matrix_s(1, 1)%matrix)
487 CALL dbcsr_create(ec_env%matrix_s(1, 1)%matrix, name=trim(headline), &
488 template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
489 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_s(1, 1)%matrix, sab_orb)
490 CALL dbcsr_copy(ec_env%matrix_s(1, 1)%matrix, matrix_s(1, 1)%matrix)
491
492 ! density matrix
493 ! Get density matrix of reference calculation
494 CALL qs_rho_get(rho, rho_ao_kp=matrix_p)
495 IF (ASSOCIATED(ec_env%matrix_p)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_p)
496 CALL dbcsr_allocate_matrix_set(ec_env%matrix_p, nspins, 1)
497 headline = "DENSITY MATRIX"
498 DO ispin = 1, nspins
499 ALLOCATE (ec_env%matrix_p(ispin, 1)%matrix)
500 CALL dbcsr_create(ec_env%matrix_p(ispin, 1)%matrix, name=trim(headline), &
501 template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
502 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_p(ispin, 1)%matrix, sab_orb)
503 CALL dbcsr_copy(ec_env%matrix_p(ispin, 1)%matrix, matrix_p(ispin, 1)%matrix)
504 END DO
505
506 IF (calc_forces) THEN
507 ! energy weighted density matrix
508 ! for security, we recalculate W here (stored in qs_env)
509 IF (ASSOCIATED(ec_env%matrix_w)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_w)
510 CALL dbcsr_allocate_matrix_set(ec_env%matrix_w, nspins, 1)
511 headline = "ENERGY WEIGHTED DENSITY MATRIX"
512 DO ispin = 1, nspins
513 ALLOCATE (ec_env%matrix_w(ispin, 1)%matrix)
514 CALL dbcsr_create(ec_env%matrix_w(ispin, 1)%matrix, name=trim(headline), &
515 template=matrix_p(ispin, 1)%matrix, matrix_type=dbcsr_type_symmetric)
516 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_w(ispin, 1)%matrix, sab_orb)
517 CALL dbcsr_set(ec_env%matrix_w(ispin, 1)%matrix, 0.0_dp)
518 END DO
519
520 ! hz matrix
521 IF (ASSOCIATED(ec_env%matrix_hz)) CALL dbcsr_deallocate_matrix_set(ec_env%matrix_hz)
522 CALL dbcsr_allocate_matrix_set(ec_env%matrix_hz, nspins)
523 headline = "Hz MATRIX"
524 DO ispin = 1, nspins
525 ALLOCATE (ec_env%matrix_hz(ispin)%matrix)
526 CALL dbcsr_create(ec_env%matrix_hz(ispin)%matrix, name=trim(headline), &
527 template=matrix_s(1, 1)%matrix, matrix_type=dbcsr_type_symmetric)
528 CALL cp_dbcsr_alloc_block_from_nbl(ec_env%matrix_hz(ispin)%matrix, sab_orb)
529 CALL dbcsr_set(ec_env%matrix_hz(ispin)%matrix, 0.0_dp)
530 END DO
531
532 ! Test for consistency of orbitals and KS matrix
533 DO ispin = 1, nspins
534 mat_struct => ec_env%mo_occ(ispin)%matrix_struct
535 CALL cp_fm_create(ksmo, mat_struct)
536 CALL cp_fm_get_info(ksmo, nrow_global=nao, ncol_global=nocc)
537 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_ks(ispin, 1)%matrix, ec_env%mo_occ(ispin), &
538 ksmo, nocc, alpha=1.0_dp, beta=0.0_dp)
539 CALL cp_fm_create(smo, mat_struct)
540 CALL cp_dbcsr_sm_fm_multiply(ec_env%matrix_s(1, 1)%matrix, ec_env%mo_occ(ispin), &
541 smo, nocc, alpha=1.0_dp, beta=0.0_dp)
542 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
543 template_fmstruct=mat_struct)
544 CALL cp_fm_create(emat, fm_struct)
545 CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, ec_env%mo_occ(ispin), ksmo, 0.0_dp, emat)
546 CALL parallel_gemm('N', 'N', nao, nocc, nocc, -1.0_dp, smo, emat, 1.0_dp, ksmo)
547 CALL cp_fm_maxabsval(ksmo, a_max)
548 CALL cp_fm_struct_release(fm_struct)
549 CALL cp_fm_release(smo)
550 CALL cp_fm_release(ksmo)
551 CALL cp_fm_release(emat)
552 CALL cp_fm_maxabsval(ec_env%mo_occ(ispin), c_max)
553 IF (unit_nr > 0) THEN
554 WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO coeficients", ispin, c_max
555 WRITE (unit_nr, "(T3,A,T50,I2,T61,F20.12)") "External:: Max value of MO gradients", ispin, a_max
556 END IF
557 END DO
558 END IF
559
560 CALL timestop(handle)
561
562 END SUBROUTINE ec_ext_setup
563
564! **************************************************************************************************
565!> \brief ...
566!> \param cpmos ...
567!> \param mo_ref ...
568!> \param mo_occ ...
569!> \param matrix_s ...
570!> \param unit_nr ...
571! **************************************************************************************************
572 SUBROUTINE align_vectors(cpmos, mo_ref, mo_occ, matrix_s, unit_nr)
573 TYPE(cp_fm_type), INTENT(IN) :: cpmos, mo_ref, mo_occ
574 TYPE(dbcsr_type), POINTER :: matrix_s
575 INTEGER, INTENT(IN) :: unit_nr
576
577 CHARACTER(LEN=*), PARAMETER :: routinen = 'align_vectors'
578
579 INTEGER :: handle, i, nao, nocc, scg
580 REAL(kind=dp) :: a_max
581 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: diag
582 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
583 TYPE(cp_fm_type) :: emat, smo
584
585 CALL timeset(routinen, handle)
586
587 mat_struct => cpmos%matrix_struct
588 CALL cp_fm_create(smo, mat_struct)
589 CALL cp_fm_get_info(smo, nrow_global=nao, ncol_global=nocc)
590 CALL cp_dbcsr_sm_fm_multiply(matrix_s, mo_occ, smo, nocc, alpha=1.0_dp, beta=0.0_dp)
591 CALL cp_fm_struct_create(fm_struct, ncol_global=nocc, nrow_global=nocc, &
592 template_fmstruct=mat_struct)
593 CALL cp_fm_create(emat, fm_struct)
594 CALL parallel_gemm('T', 'N', nocc, nocc, nao, 1.0_dp, mo_ref, smo, 0.0_dp, emat)
595 CALL parallel_gemm('N', 'N', nao, nocc, nocc, 1.0_dp, cpmos, emat, 0.0_dp, smo)
596 CALL cp_fm_to_fm(smo, cpmos)
597 CALL cp_fm_to_fm(mo_occ, mo_ref)
598 !
599 ALLOCATE (diag(nocc))
600 CALL cp_fm_get_diag(emat, diag)
601 a_max = nocc - sum(diag)
602 scg = 0
603 DO i = 1, nocc
604 IF (abs(diag(i) + 1.0_dp) < 0.001) scg = scg + 1
605 END DO
606 IF (unit_nr > 0) THEN
607 WRITE (unit_nr, "(T3,A,T61,F20.8)") "External:: Orbital rotation index", a_max
608 WRITE (unit_nr, "(T3,A,T71,I10)") "External:: Number of orbital phase changes", scg
609 END IF
610
611 DEALLOCATE (diag)
612 CALL cp_fm_struct_release(fm_struct)
613 CALL cp_fm_release(smo)
614 CALL cp_fm_release(emat)
615
616 CALL timestop(handle)
617
618 END SUBROUTINE align_vectors
619
620! **************************************************************************************************
621!> \brief ...
622!> \param qs_env ...
623!> \param matrix_w ...
624!> \param unit_nr ...
625! **************************************************************************************************
626 SUBROUTINE matrix_w_forces(qs_env, matrix_w, unit_nr)
627 TYPE(qs_environment_type), POINTER :: qs_env
628 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_w
629 INTEGER, INTENT(IN) :: unit_nr
630
631 CHARACTER(LEN=*), PARAMETER :: routinen = 'matrix_w_forces'
632
633 INTEGER :: handle, iounit, nder, nimages
634 LOGICAL :: debug_forces, debug_stress, use_virial
635 REAL(kind=dp) :: fconv
636 REAL(kind=dp), DIMENSION(3) :: fodeb
637 REAL(kind=dp), DIMENSION(3, 3) :: stdeb, sttot
638 TYPE(cell_type), POINTER :: cell
639 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: scrm
640 TYPE(dft_control_type), POINTER :: dft_control
641 TYPE(mp_para_env_type), POINTER :: para_env
642 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
643 POINTER :: sab_orb
644 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
645 TYPE(qs_ks_env_type), POINTER :: ks_env
646 TYPE(virial_type), POINTER :: virial
647
648 CALL timeset(routinen, handle)
649
650 debug_forces = .true.
651 debug_stress = .true.
652
653 iounit = unit_nr
654
655 ! no k-points possible
656 CALL get_qs_env(qs_env=qs_env, &
657 cell=cell, &
658 dft_control=dft_control, &
659 force=force, &
660 ks_env=ks_env, &
661 sab_orb=sab_orb, &
662 para_env=para_env, &
663 virial=virial)
664 nimages = dft_control%nimages
665 IF (nimages /= 1) THEN
666 cpabort("K-points not implemented")
667 END IF
668
669 ! check for virial
670 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
671
672 fconv = 1.0e-9_dp*pascal/cell%deth
673 IF (debug_stress .AND. use_virial) THEN
674 sttot = virial%pv_virial
675 END IF
676
677 ! initialize src matrix
678 NULLIFY (scrm)
679 CALL dbcsr_allocate_matrix_set(scrm, 1, 1)
680 ALLOCATE (scrm(1, 1)%matrix)
681 CALL dbcsr_create(scrm(1, 1)%matrix, template=matrix_w(1, 1)%matrix)
682 CALL cp_dbcsr_alloc_block_from_nbl(scrm(1, 1)%matrix, sab_orb)
683
684 nder = 1
685 IF (SIZE(matrix_w, 1) == 2) THEN
686 CALL dbcsr_add(matrix_w(1, 1)%matrix, matrix_w(2, 1)%matrix, &
687 alpha_scalar=1.0_dp, beta_scalar=1.0_dp)
688 END IF
689
690 ! Overlap and kinetic energy matrices
691 IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
692 IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
693 CALL build_overlap_matrix(ks_env, matrixkp_s=scrm, &
694 matrix_name="OVERLAP MATRIX", &
695 basis_type_a="ORB", &
696 basis_type_b="ORB", &
697 sab_nl=sab_orb, calculate_forces=.true., &
698 matrixkp_p=matrix_w)
699
700 IF (debug_forces) THEN
701 fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
702 CALL para_env%sum(fodeb)
703 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wout*dS ", fodeb
704 END IF
705 IF (debug_stress .AND. use_virial) THEN
706 stdeb = fconv*(virial%pv_overlap - stdeb)
707 CALL para_env%sum(stdeb)
708 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
709 'STRESS| Wout*dS', one_third_sum_diag(stdeb), det_3x3(stdeb)
710 END IF
711 IF (SIZE(matrix_w, 1) == 2) THEN
712 CALL dbcsr_add(matrix_w(1, 1)%matrix, matrix_w(2, 1)%matrix, &
713 alpha_scalar=1.0_dp, beta_scalar=-1.0_dp)
714 END IF
715
716 ! delete scrm matrix
718
719 CALL timestop(handle)
720
721 END SUBROUTINE matrix_w_forces
722
723! **************************************************************************************************
724!> \brief ...
725!> \param qs_env ...
726!> \param cpmos ...
727!> \param mo_occ ...
728!> \param matrix_r ...
729!> \param unit_nr ...
730! **************************************************************************************************
731 SUBROUTINE matrix_r_forces(qs_env, cpmos, mo_occ, matrix_r, unit_nr)
732 TYPE(qs_environment_type), POINTER :: qs_env
733 TYPE(cp_fm_type), DIMENSION(:), POINTER :: cpmos, mo_occ
734 TYPE(dbcsr_type), POINTER :: matrix_r
735 INTEGER, INTENT(IN) :: unit_nr
736
737 CHARACTER(LEN=*), PARAMETER :: routinen = 'matrix_r_forces'
738
739 INTEGER :: handle, iounit, ispin, nao, nocc, nspins
740 LOGICAL :: debug_forces, debug_stress, use_virial
741 REAL(kind=dp) :: fconv, focc
742 REAL(kind=dp), DIMENSION(3) :: fodeb
743 REAL(kind=dp), DIMENSION(3, 3) :: stdeb
744 TYPE(cell_type), POINTER :: cell
745 TYPE(cp_fm_struct_type), POINTER :: fm_struct, mat_struct
746 TYPE(cp_fm_type) :: chcmat, rcvec
747 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: scrm
748 TYPE(dft_control_type), POINTER :: dft_control
749 TYPE(mp_para_env_type), POINTER :: para_env
750 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
751 POINTER :: sab_orb
752 TYPE(qs_force_type), DIMENSION(:), POINTER :: force
753 TYPE(qs_ks_env_type), POINTER :: ks_env
754 TYPE(virial_type), POINTER :: virial
755
756 CALL timeset(routinen, handle)
757
758 debug_forces = .true.
759 debug_stress = .true.
760 iounit = unit_nr
761
762 nspins = SIZE(mo_occ)
763 focc = 1.0_dp
764 IF (nspins == 1) focc = 2.0_dp
765 focc = 0.25_dp*focc
766
767 CALL dbcsr_set(matrix_r, 0.0_dp)
768 DO ispin = 1, nspins
769 CALL cp_fm_get_info(cpmos(ispin), matrix_struct=fm_struct, nrow_global=nao, ncol_global=nocc)
770 CALL cp_fm_create(rcvec, fm_struct)
771 CALL cp_fm_struct_create(mat_struct, nrow_global=nocc, ncol_global=nocc, template_fmstruct=fm_struct)
772 CALL cp_fm_create(chcmat, mat_struct)
773 CALL parallel_gemm("T", "N", nocc, nocc, nao, 1.0_dp, mo_occ(ispin), cpmos(ispin), 0.0_dp, chcmat)
774 CALL parallel_gemm("N", "N", nao, nocc, nocc, 1.0_dp, mo_occ(ispin), chcmat, 0.0_dp, rcvec)
775 CALL cp_dbcsr_plus_fm_fm_t(matrix_r, matrix_v=rcvec, matrix_g=mo_occ(ispin), ncol=nocc, alpha=focc)
776 CALL cp_fm_struct_release(mat_struct)
777 CALL cp_fm_release(rcvec)
778 CALL cp_fm_release(chcmat)
779 END DO
780
781 CALL get_qs_env(qs_env=qs_env, &
782 cell=cell, &
783 dft_control=dft_control, &
784 force=force, &
785 ks_env=ks_env, &
786 sab_orb=sab_orb, &
787 para_env=para_env, &
788 virial=virial)
789 ! check for virial
790 use_virial = virial%pv_availability .AND. (.NOT. virial%pv_numer)
791 fconv = 1.0e-9_dp*pascal/cell%deth
792
793 IF (debug_forces) fodeb(1:3) = force(1)%overlap(1:3, 1)
794 IF (debug_stress .AND. use_virial) stdeb = virial%pv_overlap
795 NULLIFY (scrm)
796 CALL build_overlap_matrix(ks_env, matrix_s=scrm, &
797 matrix_name="OVERLAP MATRIX", &
798 basis_type_a="ORB", basis_type_b="ORB", &
799 sab_nl=sab_orb, calculate_forces=.true., &
800 matrix_p=matrix_r)
801 IF (debug_forces) THEN
802 fodeb(1:3) = force(1)%overlap(1:3, 1) - fodeb(1:3)
803 CALL para_env%sum(fodeb)
804 IF (iounit > 0) WRITE (iounit, "(T3,A,T33,3F16.8)") "DEBUG:: Wz*dS ", fodeb
805 END IF
806 IF (debug_stress .AND. use_virial) THEN
807 stdeb = fconv*(virial%pv_overlap - stdeb)
808 CALL para_env%sum(stdeb)
809 IF (iounit > 0) WRITE (unit=iounit, fmt="(T2,A,T41,2(1X,ES19.11))") &
810 'STRESS| Wz ', one_third_sum_diag(stdeb), det_3x3(stdeb)
811 END IF
813
814 CALL timestop(handle)
815
816 END SUBROUTINE matrix_r_forces
817
818END 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_create(matrix, matrix_struct, name, use_sp, set_zero)
creates a new full matrix with the given structure
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
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:1503
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, 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, 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.