(git:744416f)
Loading...
Searching...
No Matches
rpa_gw_sigma_x.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 to calculate EXX within GW
10!> \par History
11!> 07.2020 separated from mp2.F [F. Stein, code by Jan Wilhelm]
12!> 07.2024 determine number of corrected MOs from BSE cutoffs [Maximilian Graml]
13!> \author Jan Wilhelm, Frederick Stein
14! **************************************************************************************************
17 USE admm_types, ONLY: admm_type,&
20 USE cp_cfm_types, ONLY: cp_cfm_create,&
25 USE cp_dbcsr_api, ONLY: &
27 dbcsr_release, dbcsr_release_p, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, &
28 dbcsr_type_symmetric
35 USE cp_files, ONLY: close_file,&
38 USE cp_fm_types, ONLY: cp_fm_create,&
46 USE hfx_ri, ONLY: hfx_ri_update_ks
57 USE kinds, ONLY: dp
59 USE kpoint_types, ONLY: get_kpoint_info,&
62 USE machine, ONLY: m_walltime
63 USE mathconstants, ONLY: gaussi,&
64 z_one,&
65 z_zero
71 USE mp2_types, ONLY: mp2_type
73 USE physcon, ONLY: evolt
79 USE qs_mo_types, ONLY: get_mo_set,&
82 USE qs_rho_types, ONLY: qs_rho_get,&
87
88!$ USE OMP_LIB, ONLY: omp_get_max_threads, omp_get_thread_num, omp_get_num_threads
89
90#include "./base/base_uses.f90"
91
92 IMPLICIT NONE
93
94 PRIVATE
95
96 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rpa_gw_sigma_x'
97
99
100CONTAINS
101
102! **************************************************************************************************
103!> \brief ...
104!> \param qs_env ...
105!> \param mp2_env ...
106!> \param mos_mp2 ...
107!> \param energy_ex ...
108!> \param energy_xc_admm ...
109!> \param t3 ...
110!> \param unit_nr ...
111!> \par History
112!> 04.2015 created
113!> \author Jan Wilhelm
114! **************************************************************************************************
115 SUBROUTINE compute_vec_sigma_x_minus_vxc_gw(qs_env, mp2_env, mos_mp2, energy_ex, energy_xc_admm, t3, unit_nr)
116 TYPE(qs_environment_type), POINTER :: qs_env
117 TYPE(mp2_type) :: mp2_env
118 TYPE(mo_set_type), DIMENSION(:), INTENT(IN) :: mos_mp2
119 REAL(kind=dp), INTENT(OUT) :: energy_ex, energy_xc_admm(2), t3
120 INTEGER, INTENT(IN) :: unit_nr
121
122 CHARACTER(len=*), PARAMETER :: routinen = 'compute_vec_Sigma_x_minus_vxc_gw'
123
124 CHARACTER(4) :: occ_virt
125 CHARACTER(LEN=40) :: line
126 INTEGER :: dimen, gw_corr_lev_occ, gw_corr_lev_tot, gw_corr_lev_virt, handle, homo, &
127 homo_reduced_bse, i_img, ikp, irep, ispin, iunit, max_corr_lev_occ, max_corr_lev_virt, &
128 myfun, myfun_aux, myfun_prim, n_level_gw, n_level_gw_ref, n_rep_hf, nkp, nkp_sigma, nmo, &
129 nspins, print_exx, virtual_reduced_bse
130 LOGICAL :: calc_ints, charge_constrain_tmp, do_admm_rpa, do_hfx, do_kpoints_cubic_rpa, &
131 do_kpoints_from_gamma, do_ri_sigma_x, really_read_line
132 REAL(kind=dp) :: e_gap_gw, e_homo_gw, e_lumo_gw, eh1, ehfx, eigval_dft, eigval_hf_at_dft, &
133 energy_exc, energy_exc1, energy_exc1_aux_fit, energy_exc_aux_fit, energy_total, &
134 exx_minus_vxc, hfx_fraction, min_direct_hf_at_dft_gap, t1, t2, tmp
135 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: matrix_tmp_2_diag
136 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :) :: eigenval_kp_hf_at_dft, vec_sigma_x
137 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: eigenval_kp, vec_sigma_x_minus_vxc_gw, &
138 vec_sigma_x_minus_vxc_gw_im
139 REAL(kind=dp), DIMENSION(:), POINTER :: mo_eigenvalues
140 TYPE(admm_type), POINTER :: admm_env
141 TYPE(cp_fm_type), POINTER :: mo_coeff
142 TYPE(dbcsr_p_type), ALLOCATABLE, DIMENSION(:) :: mat_exchange_for_kp_from_gamma
143 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_ks, matrix_ks_aux_fit, &
144 matrix_ks_aux_fit_hfx, rho_ao, &
145 rho_ao_aux_fit
146 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_2d, matrix_ks_kp_im, &
147 matrix_ks_kp_re, matrix_ks_transl, matrix_sigma_x_minus_vxc, matrix_sigma_x_minus_vxc_im, &
148 rho_ao_2d
149 TYPE(dbcsr_type) :: matrix_tmp, matrix_tmp_2, mo_coeff_b
150 TYPE(dft_control_type), POINTER :: dft_control
151 TYPE(kpoint_type), POINTER :: kpoints, kpoints_sigma
152 TYPE(mo_window_type) :: bse_window
153 TYPE(mp_para_env_type), POINTER :: para_env
154 TYPE(qs_energy_type), POINTER :: energy
155 TYPE(qs_ks_env_type), POINTER :: ks_env
156 TYPE(qs_rho_type), POINTER :: rho, rho_aux_fit
157 TYPE(section_vals_type), POINTER :: hfx_sections, input, xc_section, &
158 xc_section_admm_aux, &
159 xc_section_admm_prim
160
161 NULLIFY (admm_env, matrix_ks, matrix_ks_aux_fit, rho_ao, matrix_sigma_x_minus_vxc, input, &
162 xc_section, xc_section_admm_aux, xc_section_admm_prim, hfx_sections, rho, &
163 dft_control, para_env, ks_env, mo_coeff, matrix_sigma_x_minus_vxc_im, matrix_ks_aux_fit_hfx, &
164 rho_aux_fit, rho_ao_aux_fit)
165
166 CALL timeset(routinen, handle)
167
168 t1 = m_walltime()
169
170 do_admm_rpa = mp2_env%ri_rpa%do_admm
171 do_ri_sigma_x = mp2_env%ri_g0w0%do_ri_Sigma_x
172 do_kpoints_cubic_rpa = qs_env%mp2_env%ri_rpa_im_time%do_im_time_kpoints
173 do_kpoints_from_gamma = qs_env%mp2_env%ri_rpa_im_time%do_kpoints_from_Gamma
174 print_exx = mp2_env%ri_g0w0%print_exx
175
176 IF (do_kpoints_cubic_rpa) THEN
177 cpassert(do_ri_sigma_x)
178 END IF
179
180 IF (do_kpoints_cubic_rpa) THEN
181
182 CALL get_qs_env(qs_env, &
183 admm_env=admm_env, &
184 matrix_ks_kp=matrix_ks_transl, &
185 rho=rho, &
186 input=input, &
187 dft_control=dft_control, &
188 para_env=para_env, &
189 kpoints=kpoints, &
190 ks_env=ks_env, &
191 energy=energy)
192 nkp = kpoints%nkp
193
194 ELSE
195
196 CALL get_qs_env(qs_env, &
197 admm_env=admm_env, &
198 matrix_ks=matrix_ks, &
199 rho=rho, &
200 input=input, &
201 dft_control=dft_control, &
202 para_env=para_env, &
203 ks_env=ks_env, &
204 energy=energy)
205 nkp = 1
206 CALL qs_rho_get(rho, rho_ao=rho_ao)
207
208 IF (do_admm_rpa) THEN
209 CALL get_admm_env(admm_env, matrix_ks_aux_fit=matrix_ks_aux_fit, rho_aux_fit=rho_aux_fit, &
210 matrix_ks_aux_fit_hfx=matrix_ks_aux_fit_hfx)
211 CALL qs_rho_get(rho_aux_fit, rho_ao=rho_ao_aux_fit)
212
213 ! RPA/GW with ADMM for EXX or the exchange self-energy only implemented for
214 ! ADMM_PURIFICATION_METHOD NONE
215 ! METHOD BASIS_PROJECTION
216 ! in the admm section
217 cpassert(admm_env%purification_method == do_admm_purify_none)
218 cpassert(dft_control%admm_control%method == do_admm_basis_projection)
219 END IF
220 END IF
221
222 nspins = dft_control%nspins
223
224 ! safe ks matrix for later: we will transform matrix_ks
225 ! to T-cell index and then to k-points for band structure calculation
226 IF (do_kpoints_from_gamma) THEN
227 ! not yet there: open shell
228 ALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_ks(nspins))
229 DO ispin = 1, nspins
230 NULLIFY (qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix)
231 ALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix)
232 CALL dbcsr_create(qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix, &
233 template=matrix_ks(ispin)%matrix)
234 CALL dbcsr_desymmetrize(matrix_ks(ispin)%matrix, &
235 qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix)
236
237 END DO
238 END IF
239
240 IF (do_kpoints_cubic_rpa) THEN
241
242 CALL allocate_matrix_ks_kp(matrix_ks_transl, matrix_ks_kp_re, matrix_ks_kp_im, kpoints)
243 CALL transform_matrix_ks_to_kp(matrix_ks_transl, matrix_ks_kp_re, matrix_ks_kp_im, kpoints)
244
245 DO ispin = 1, nspins
246 DO i_img = 1, SIZE(matrix_ks_transl, 2)
247 CALL dbcsr_set(matrix_ks_transl(ispin, i_img)%matrix, 0.0_dp)
248 END DO
249 END DO
250
251 END IF
252
253 ! initialize matrix_sigma_x_minus_vxc
254 NULLIFY (matrix_sigma_x_minus_vxc)
255 CALL dbcsr_allocate_matrix_set(matrix_sigma_x_minus_vxc, nspins, nkp)
256 IF (do_kpoints_cubic_rpa) THEN
257 NULLIFY (matrix_sigma_x_minus_vxc_im)
258 CALL dbcsr_allocate_matrix_set(matrix_sigma_x_minus_vxc_im, nspins, nkp)
259 END IF
260
261 DO ispin = 1, nspins
262 DO ikp = 1, nkp
263
264 IF (do_kpoints_cubic_rpa) THEN
265
266 ALLOCATE (matrix_sigma_x_minus_vxc(ispin, ikp)%matrix)
267 CALL dbcsr_create(matrix_sigma_x_minus_vxc(ispin, ikp)%matrix, &
268 template=matrix_ks_kp_re(1, 1)%matrix, &
269 matrix_type=dbcsr_type_symmetric)
270
271 CALL dbcsr_copy(matrix_sigma_x_minus_vxc(ispin, ikp)%matrix, matrix_ks_kp_re(ispin, ikp)%matrix)
272 CALL dbcsr_set(matrix_ks_kp_re(ispin, ikp)%matrix, 0.0_dp)
273
274 ALLOCATE (matrix_sigma_x_minus_vxc_im(ispin, ikp)%matrix)
275 CALL dbcsr_create(matrix_sigma_x_minus_vxc_im(ispin, ikp)%matrix, &
276 template=matrix_ks_kp_im(1, 1)%matrix, &
277 matrix_type=dbcsr_type_antisymmetric)
278
279 CALL dbcsr_copy(matrix_sigma_x_minus_vxc_im(ispin, ikp)%matrix, matrix_ks_kp_im(ispin, ikp)%matrix)
280 CALL dbcsr_set(matrix_ks_kp_im(ispin, ikp)%matrix, 0.0_dp)
281
282 ELSE
283
284 ALLOCATE (matrix_sigma_x_minus_vxc(ispin, ikp)%matrix)
285 CALL dbcsr_create(matrix_sigma_x_minus_vxc(ispin, ikp)%matrix, &
286 template=matrix_ks(1)%matrix)
287
288 CALL dbcsr_copy(matrix_sigma_x_minus_vxc(ispin, ikp)%matrix, matrix_ks(ispin)%matrix)
289 CALL dbcsr_set(matrix_ks(ispin)%matrix, 0.0_dp)
290
291 END IF
292
293 END DO
294 END DO
295
296 ! set DFT functional to none and hfx_fraction to zero
297 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%HF")
298 CALL section_vals_get(hfx_sections, explicit=do_hfx)
299
300 IF (do_hfx) THEN
301 hfx_fraction = qs_env%x_data(1, 1)%general_parameter%fraction
302 qs_env%x_data(:, :)%general_parameter%fraction = 0.0_dp
303 END IF
304 xc_section => section_vals_get_subs_vals(input, "DFT%XC")
305 CALL section_vals_val_get(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", &
306 i_val=myfun)
307 CALL section_vals_val_set(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", &
308 i_val=xc_none)
309
310 ! in ADMM, also set the XC functional for ADMM correction to none
311 ! do not do this if we do ADMM for Sigma_x
312 IF (dft_control%do_admm) THEN
313 xc_section_admm_aux => section_vals_get_subs_vals(admm_env%xc_section_aux, &
314 "XC_FUNCTIONAL")
315 CALL section_vals_val_get(xc_section_admm_aux, "_SECTION_PARAMETERS_", &
316 i_val=myfun_aux)
317 CALL section_vals_val_set(xc_section_admm_aux, "_SECTION_PARAMETERS_", &
318 i_val=xc_none)
319
320 ! the same for the primary basis
321 xc_section_admm_prim => section_vals_get_subs_vals(admm_env%xc_section_primary, &
322 "XC_FUNCTIONAL")
323 CALL section_vals_val_get(xc_section_admm_prim, "_SECTION_PARAMETERS_", &
324 i_val=myfun_prim)
325 CALL section_vals_val_set(xc_section_admm_prim, "_SECTION_PARAMETERS_", &
326 i_val=xc_none)
327
328 ! for ADMMQ/S, set the charge_constrain to false (otherwise wrong results)
329 charge_constrain_tmp = .false.
330 IF (admm_env%charge_constrain) THEN
331 admm_env%charge_constrain = .false.
332 charge_constrain_tmp = .true.
333 END IF
334
335 END IF
336
337 ! if we do ADMM for Sigma_x, we write the ADMM correction into matrix_ks_aux_fit
338 ! and therefore we should set it to zero
339 IF (do_admm_rpa) THEN
340 DO ispin = 1, nspins
341 CALL dbcsr_set(matrix_ks_aux_fit(ispin)%matrix, 0.0_dp)
342 END DO
343 END IF
344
345 IF (.NOT. mp2_env%ri_g0w0%update_xc_energy) THEN
346 energy_total = energy%total
347 energy_exc = energy%exc
348 energy_exc1 = energy%exc1
349 energy_exc_aux_fit = energy%ex
350 energy_exc1_aux_fit = energy%exc_aux_fit
351 energy_ex = energy%exc1_aux_fit
352 END IF
353
354 ! Remove the Exchange-correlation energy contributions from the total energy
355 energy%total = energy%total - (energy%exc + energy%exc1 + energy%ex + &
356 energy%exc_aux_fit + energy%exc1_aux_fit)
357
358 ! calculate KS-matrix without XC and without HF
359 CALL qs_ks_build_kohn_sham_matrix(qs_env=qs_env, calculate_forces=.false., &
360 just_energy=.false.)
361
362 IF (.NOT. mp2_env%ri_g0w0%update_xc_energy) THEN
363 energy%exc = energy_exc
364 energy%exc1 = energy_exc1
365 energy%exc_aux_fit = energy_ex
366 energy%exc1_aux_fit = energy_exc_aux_fit
367 energy%ex = energy_exc1_aux_fit
368 energy%total = energy_total
369 END IF
370
371 ! set the DFT functional and HF fraction back
372 CALL section_vals_val_set(xc_section, "XC_FUNCTIONAL%_SECTION_PARAMETERS_", &
373 i_val=myfun)
374 IF (do_hfx) THEN
375 qs_env%x_data(:, :)%general_parameter%fraction = hfx_fraction
376 END IF
377
378 IF (dft_control%do_admm) THEN
379 xc_section_admm_aux => section_vals_get_subs_vals(admm_env%xc_section_aux, &
380 "XC_FUNCTIONAL")
381 xc_section_admm_prim => section_vals_get_subs_vals(admm_env%xc_section_primary, &
382 "XC_FUNCTIONAL")
383
384 CALL section_vals_val_set(xc_section_admm_aux, "_SECTION_PARAMETERS_", &
385 i_val=myfun_aux)
386 CALL section_vals_val_set(xc_section_admm_prim, "_SECTION_PARAMETERS_", &
387 i_val=myfun_prim)
388 IF (charge_constrain_tmp) THEN
389 admm_env%charge_constrain = .true.
390 END IF
391 END IF
392
393 IF (do_kpoints_cubic_rpa) THEN
394 CALL transform_matrix_ks_to_kp(matrix_ks_transl, matrix_ks_kp_re, matrix_ks_kp_im, kpoints)
395 END IF
396
397 ! remove the single-particle part (kin. En + Hartree pot) and change the sign
398 DO ispin = 1, nspins
399 IF (do_kpoints_cubic_rpa) THEN
400 DO ikp = 1, nkp
401 CALL dbcsr_add(matrix_sigma_x_minus_vxc(ispin, ikp)%matrix, matrix_ks_kp_re(ispin, ikp)%matrix, -1.0_dp, 1.0_dp)
402 CALL dbcsr_add(matrix_sigma_x_minus_vxc_im(ispin, ikp)%matrix, matrix_ks_kp_im(ispin, ikp)%matrix, -1.0_dp, 1.0_dp)
403 END DO
404 ELSE
405 CALL dbcsr_add(matrix_sigma_x_minus_vxc(ispin, 1)%matrix, matrix_ks(ispin)%matrix, -1.0_dp, 1.0_dp)
406 END IF
407 END DO
408
409 IF (do_kpoints_cubic_rpa) THEN
410
411 CALL transform_sigma_x_minus_vxc_to_mo_basis(kpoints, matrix_sigma_x_minus_vxc, &
412 matrix_sigma_x_minus_vxc_im, &
413 vec_sigma_x_minus_vxc_gw, &
414 vec_sigma_x_minus_vxc_gw_im, &
415 para_env, nmo, mp2_env)
416
417 ELSE
418
419 DO ispin = 1, nspins
420 CALL dbcsr_set(matrix_ks(ispin)%matrix, 0.0_dp)
421 IF (do_admm_rpa) THEN
422 CALL dbcsr_set(matrix_ks_aux_fit(ispin)%matrix, 0.0_dp)
423 END IF
424 END DO
425
426 hfx_sections => section_vals_get_subs_vals(input, "DFT%XC%WF_CORRELATION%RI_RPA%HF")
427
428 CALL section_vals_get(hfx_sections, n_repetition=n_rep_hf)
429
430 ! in most cases, we calculate the exchange self-energy here. But if we do only RI for
431 ! the exchange self-energy, we do not calculate exchange here
432 ehfx = 0.0_dp
433 IF (.NOT. do_ri_sigma_x) THEN
434
435 CALL exx_pre_hfx(hfx_sections, qs_env%mp2_env%ri_rpa%x_data, qs_env%mp2_env%ri_rpa%reuse_hfx)
436 calc_ints = .NOT. qs_env%mp2_env%ri_rpa%reuse_hfx
437
438 ! add here HFX (=Sigma_exchange) to matrix_sigma_x_minus_vxc
439 DO irep = 1, n_rep_hf
440 IF (do_admm_rpa) THEN
441 matrix_ks_2d(1:nspins, 1:1) => matrix_ks_aux_fit(1:nspins)
442 rho_ao_2d(1:nspins, 1:1) => rho_ao_aux_fit(1:nspins)
443 ELSE
444 matrix_ks_2d(1:nspins, 1:1) => matrix_ks(1:nspins)
445 rho_ao_2d(1:nspins, 1:1) => rho_ao(1:nspins)
446 END IF
447
448 IF (qs_env%mp2_env%ri_rpa%x_data(irep, 1)%do_hfx_ri) THEN
449 CALL hfx_ri_update_ks(qs_env, qs_env%mp2_env%ri_rpa%x_data(irep, 1)%ri_data, matrix_ks_2d, ehfx, &
450 rho_ao=rho_ao_2d, geometry_did_change=calc_ints, nspins=nspins, &
451 hf_fraction=qs_env%mp2_env%ri_rpa%x_data(irep, 1)%general_parameter%fraction)
452
453 IF (do_admm_rpa) THEN
454 !for ADMMS, we need the exchange matrix k(d) for both spins
455 DO ispin = 1, nspins
456 CALL dbcsr_copy(matrix_ks_aux_fit_hfx(ispin)%matrix, matrix_ks_2d(ispin, 1)%matrix, &
457 name="HF exch. part of matrix_ks_aux_fit for ADMMS")
458 END DO
459 END IF
460 ELSE
461 CALL integrate_four_center(qs_env, qs_env%mp2_env%ri_rpa%x_data, matrix_ks_2d, eh1, &
462 rho_ao_2d, hfx_sections, &
463 para_env, calc_ints, irep, .true., &
464 ispin=1)
465 ehfx = ehfx + eh1
466 END IF
467 END DO
468
469 !ADMM XC correction
470 IF (do_admm_rpa) THEN
471 CALL calc_exx_admm_xc_contributions(qs_env=qs_env, &
472 matrix_prim=matrix_ks, &
473 matrix_aux=matrix_ks_aux_fit, &
474 x_data=qs_env%mp2_env%ri_rpa%x_data, &
475 exc=energy_xc_admm(1), &
476 exc_aux_fit=energy_xc_admm(2), &
477 calc_forces=.false., &
478 use_virial=.false.)
479 END IF
480
481 IF (do_kpoints_from_gamma .AND. print_exx == gw_print_exx) THEN
482 ALLOCATE (mat_exchange_for_kp_from_gamma(1))
483
484 DO ispin = 1, 1
485 NULLIFY (mat_exchange_for_kp_from_gamma(ispin)%matrix)
486 ALLOCATE (mat_exchange_for_kp_from_gamma(ispin)%matrix)
487 CALL dbcsr_create(mat_exchange_for_kp_from_gamma(ispin)%matrix, template=matrix_ks(ispin)%matrix)
488 CALL dbcsr_desymmetrize(matrix_ks(ispin)%matrix, mat_exchange_for_kp_from_gamma(ispin)%matrix)
489 END DO
490
491 END IF
492
493 CALL exx_post_hfx(qs_env, qs_env%mp2_env%ri_rpa%x_data, qs_env%mp2_env%ri_rpa%reuse_hfx)
494 END IF
495
496 energy_ex = ehfx
497
498 ! transform Fock-Matrix (calculated in integrate_four_center, written in matrix_ks_aux_fit in case
499 ! of ADMM) from ADMM basis to primary basis
500 IF (do_admm_rpa) THEN
501 CALL admm_mo_merge_ks_matrix(qs_env)
502 END IF
503
504 DO ispin = 1, nspins
505 CALL dbcsr_add(matrix_sigma_x_minus_vxc(ispin, 1)%matrix, matrix_ks(ispin)%matrix, 1.0_dp, 1.0_dp)
506 END DO
507
508 ! safe matrix_sigma_x_minus_vxc for later: for example, we will transform matrix_sigma_x_minus_vxc
509 ! to T-cell index and then to k-points for band structure calculation
510 IF (do_kpoints_from_gamma) THEN
511 ! not yet there: open shell
512 ALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(nspins))
513 DO ispin = 1, nspins
514 NULLIFY (qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix)
515 ALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix)
516 CALL dbcsr_create(qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix, &
517 template=matrix_ks(ispin)%matrix)
518
519 CALL dbcsr_desymmetrize(matrix_sigma_x_minus_vxc(ispin, 1)%matrix, &
520 qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix)
521
522 END DO
523 END IF
524
525 CALL dbcsr_desymmetrize(matrix_ks(1)%matrix, mo_coeff_b)
526 CALL dbcsr_set(mo_coeff_b, 0.0_dp)
527
528 ! Transform matrix_sigma_x_minus_vxc to MO basis
529 DO ispin = 1, nspins
530
531 CALL get_mo_set(mo_set=mos_mp2(ispin), &
532 mo_coeff=mo_coeff, &
533 eigenvalues=mo_eigenvalues, &
534 nmo=nmo, &
535 homo=homo, &
536 nao=dimen)
537
538 IF (ispin == 1) THEN
539
540 ALLOCATE (vec_sigma_x_minus_vxc_gw(nmo, nspins, nkp))
541 vec_sigma_x_minus_vxc_gw = 0.0_dp
542
543 ALLOCATE (matrix_tmp_2_diag(dimen))
544 END IF
545
546 CALL dbcsr_set(mo_coeff_b, 0.0_dp)
547 CALL copy_fm_to_dbcsr(mo_coeff, mo_coeff_b, keep_sparsity=.false.)
548
549 ! initialize matrix_tmp and matrix_tmp2
550 IF (ispin == 1) THEN
551 CALL dbcsr_create(matrix_tmp, template=mo_coeff_b)
552 CALL dbcsr_copy(matrix_tmp, mo_coeff_b)
553 CALL dbcsr_set(matrix_tmp, 0.0_dp)
554
555 CALL dbcsr_create(matrix_tmp_2, template=mo_coeff_b)
556 CALL dbcsr_copy(matrix_tmp_2, mo_coeff_b)
557 CALL dbcsr_set(matrix_tmp_2, 0.0_dp)
558 END IF
559
560 gw_corr_lev_occ = mp2_env%ri_g0w0%corr_mos_occ
561 gw_corr_lev_virt = mp2_env%ri_g0w0%corr_mos_virt
562
563 ! If SVD is used to invert overlap matrix (for CHOLESKY OFF), some MOs are removed
564 ! Therefore, setting the number of gw_corr_lev_virt simply to dimen - homo leads to index problems
565 ! Instead, we take into account the removed MOs
566 max_corr_lev_occ = homo
567 max_corr_lev_virt = nmo - homo
568
569 ! If BSE is invoked, manipulate corrected MO number
570 IF (mp2_env%bse%do_bse) THEN
571 ! Logic: If cutoff is negative, all MOs are included in BSE, i.e. we need to correct them all
572 ! If cutoff is positive, we can reduce the number of MOs to be corrected and force gw_corr_lev_...
573 ! to a sufficiently large number by setting it to -2 and read indices afterwards
574 ! Handling for occupied levels
575 IF (mp2_env%bse%bse_cutoff_occ < 0) THEN
576 gw_corr_lev_occ = -1
577 ELSE
578 IF (gw_corr_lev_occ > 0) THEN
579 gw_corr_lev_occ = -2
580 END IF
581 END IF
582 ! Handling for virtual levels
583 IF (mp2_env%bse%bse_cutoff_empty < 0) THEN
584 gw_corr_lev_virt = -1
585 ELSE
586 IF (gw_corr_lev_virt > 0) THEN
587 gw_corr_lev_virt = -2
588 END IF
589 END IF
590
591 ! Obtain indices from DFT if gw_corr... are set to -2
592 CALL determine_mo_window(mo_eigenvalues, nmo, homo, &
593 mp2_env%bse%bse_cutoff_occ, mp2_env%bse%bse_cutoff_empty, bse_window)
594 homo_reduced_bse = homo - bse_window%first_mo + 1
595 virtual_reduced_bse = bse_window%last_mo - homo
596 IF (gw_corr_lev_occ == -2) THEN
597 cpwarn("BSE cutoff overwrites user input for CORR_MOS_OCC")
598 gw_corr_lev_occ = homo_reduced_bse
599 END IF
600 IF (gw_corr_lev_virt == -2) THEN
601 cpwarn("BSE cutoff overwrites user input for CORR_MOS_VIRT")
602 gw_corr_lev_virt = virtual_reduced_bse
603 END IF
604 END IF
605
606 ! if requested number of occ/virt levels for correction either exceed the number of
607 ! occ/virt levels or the requested number is negative, default to correct all
608 ! occ/virt level energies
609 IF (gw_corr_lev_occ > homo .OR. gw_corr_lev_occ < 0) gw_corr_lev_occ = max_corr_lev_occ
610 IF (gw_corr_lev_virt > max_corr_lev_virt .OR. gw_corr_lev_virt < 0) gw_corr_lev_virt = max_corr_lev_virt
611 IF (ispin == 1) THEN
612 mp2_env%ri_g0w0%corr_mos_occ = gw_corr_lev_occ
613 mp2_env%ri_g0w0%corr_mos_virt = gw_corr_lev_virt
614 ELSE IF (ispin == 2) THEN
615 ! ensure that the total number of corrected MOs is the same for alpha and beta, important
616 ! for parallelization
617 IF (mp2_env%ri_g0w0%corr_mos_occ + mp2_env%ri_g0w0%corr_mos_virt /= &
618 gw_corr_lev_occ + gw_corr_lev_virt) THEN
619 gw_corr_lev_virt = mp2_env%ri_g0w0%corr_mos_occ + mp2_env%ri_g0w0%corr_mos_virt - gw_corr_lev_occ
620 END IF
621 mp2_env%ri_g0w0%corr_mos_occ_beta = gw_corr_lev_occ
622 mp2_env%ri_g0w0%corr_mos_virt_beta = gw_corr_lev_virt
623
624 END IF
625
626 CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_sigma_x_minus_vxc(ispin, 1)%matrix, &
627 mo_coeff_b, 0.0_dp, matrix_tmp, first_column=homo + 1 - gw_corr_lev_occ, &
628 last_column=homo + gw_corr_lev_virt)
629
630 CALL dbcsr_multiply('T', 'N', 1.0_dp, mo_coeff_b, &
631 matrix_tmp, 0.0_dp, matrix_tmp_2, first_row=homo + 1 - gw_corr_lev_occ, &
632 last_row=homo + gw_corr_lev_virt)
633
634 CALL dbcsr_get_diag(matrix_tmp_2, matrix_tmp_2_diag)
635 vec_sigma_x_minus_vxc_gw(1:nmo, ispin, 1) = matrix_tmp_2_diag(1:nmo)
636
637 CALL dbcsr_set(matrix_tmp, 0.0_dp)
638 CALL dbcsr_set(matrix_tmp_2, 0.0_dp)
639
640 END DO
641
642 CALL para_env%sum(vec_sigma_x_minus_vxc_gw)
643
644 END IF
645
646 CALL dbcsr_release(mo_coeff_b)
647 CALL dbcsr_release(matrix_tmp)
648 CALL dbcsr_release(matrix_tmp_2)
649 IF (do_kpoints_cubic_rpa) THEN
650 CALL dbcsr_deallocate_matrix_set(matrix_ks_kp_re)
651 CALL dbcsr_deallocate_matrix_set(matrix_ks_kp_im)
652 END IF
653
654 DO ispin = 1, nspins
655 DO ikp = 1, nkp
656 CALL dbcsr_release_p(matrix_sigma_x_minus_vxc(ispin, ikp)%matrix)
657 IF (do_kpoints_cubic_rpa) THEN
658 CALL dbcsr_release_p(matrix_sigma_x_minus_vxc_im(ispin, ikp)%matrix)
659 END IF
660 END DO
661 END DO
662
663 ALLOCATE (mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(nmo, nspins, nkp))
664
665 IF (print_exx == gw_print_exx) THEN
666
667 IF (do_kpoints_from_gamma) THEN
668
669 gw_corr_lev_tot = gw_corr_lev_occ + gw_corr_lev_virt
670
671 CALL get_qs_env(qs_env=qs_env, &
672 kpoints=kpoints)
673
674 CALL trunc_coulomb_for_exchange(qs_env)
675
676 CALL compute_kpoints(qs_env, kpoints, unit_nr)
677
678 ALLOCATE (eigenval_kp(nmo, 1, nspins))
679
680 CALL get_bandstruc_and_k_dependent_mos(qs_env, eigenval_kp)
681
682 CALL compute_minus_vxc_kpoints(qs_env)
683
684 nkp_sigma = SIZE(eigenval_kp, 2)
685
686 ALLOCATE (vec_sigma_x(nmo, nkp_sigma))
687 vec_sigma_x(:, :) = 0.0_dp
688
689 CALL trafo_to_mo_and_kpoints(qs_env, &
690 mat_exchange_for_kp_from_gamma(1)%matrix, &
691 vec_sigma_x(homo - gw_corr_lev_occ + 1:homo + gw_corr_lev_virt, :), &
692 homo, gw_corr_lev_occ, gw_corr_lev_virt, 1)
693
694 CALL dbcsr_release(mat_exchange_for_kp_from_gamma(1)%matrix)
695 DEALLOCATE (mat_exchange_for_kp_from_gamma(1)%matrix)
696 DEALLOCATE (mat_exchange_for_kp_from_gamma)
697
698 DEALLOCATE (vec_sigma_x_minus_vxc_gw)
699
700 ALLOCATE (vec_sigma_x_minus_vxc_gw(nmo, nspins, nkp_sigma))
701
702 vec_sigma_x_minus_vxc_gw(:, 1, :) = vec_sigma_x(:, :) + &
703 qs_env%mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, :)
704
705 kpoints_sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
706
707 ELSE
708
709 nkp_sigma = 1
710
711 END IF
712
713 IF (unit_nr > 0) THEN
714
715 ALLOCATE (eigenval_kp_hf_at_dft(nmo, nkp_sigma))
716 eigenval_kp_hf_at_dft(:, :) = eigenval_kp(:, :, 1) + vec_sigma_x_minus_vxc_gw(:, 1, :)
717
718 min_direct_hf_at_dft_gap = 100.0_dp
719
720 WRITE (unit_nr, '(T3,A)') ''
721 WRITE (unit_nr, '(T3,A)') 'Exchange energies'
722 WRITE (unit_nr, '(T3,A)') '-----------------'
723 WRITE (unit_nr, '(T3,A)') ''
724 WRITE (unit_nr, '(T6,2A)') 'MO e_n^DFT Sigma_x-vxc e_n^HF@DFT'
725 DO ikp = 1, nkp_sigma
726 IF (nkp_sigma > 1) THEN
727 WRITE (unit_nr, '(T3,A)') ''
728 WRITE (unit_nr, '(T3,A7,I3,A3,I3,A8,3F7.3,A12,3F7.3)') 'Kpoint ', ikp, ' /', nkp_sigma, &
729 ' xkp =', kpoints_sigma%xkp(1, ikp), kpoints_sigma%xkp(2, ikp), &
730 kpoints_sigma%xkp(3, ikp), ' and xkp =', -kpoints_sigma%xkp(1, ikp), &
731 -kpoints_sigma%xkp(2, ikp), -kpoints_sigma%xkp(3, ikp)
732 WRITE (unit_nr, '(T3,A)') ''
733 END IF
734 DO n_level_gw = 1, gw_corr_lev_occ + gw_corr_lev_virt
735
736 n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
737 IF (n_level_gw <= gw_corr_lev_occ) THEN
738 occ_virt = 'occ'
739 ELSE
740 occ_virt = 'vir'
741 END IF
742
743 eigval_dft = eigenval_kp(n_level_gw_ref, ikp, 1)*evolt
744 exx_minus_vxc = real(vec_sigma_x_minus_vxc_gw(n_level_gw_ref, 1, ikp)*evolt, kind=dp)
745 eigval_hf_at_dft = eigenval_kp_hf_at_dft(n_level_gw_ref, ikp)*evolt
746
747 WRITE (unit_nr, '(T4,I4,3A,3F21.3,3F21.3,3F21.3)') &
748 n_level_gw_ref, ' ( ', occ_virt, ') ', eigval_dft, exx_minus_vxc, eigval_hf_at_dft
749
750 END DO
751 e_homo_gw = maxval(eigenval_kp_hf_at_dft(homo - gw_corr_lev_occ + 1:homo, ikp))
752 e_lumo_gw = minval(eigenval_kp_hf_at_dft(homo + 1:homo + gw_corr_lev_virt, ikp))
753 e_gap_gw = e_lumo_gw - e_homo_gw
754 IF (e_gap_gw < min_direct_hf_at_dft_gap) min_direct_hf_at_dft_gap = e_gap_gw
755 WRITE (unit_nr, '(T3,A)') ''
756 WRITE (unit_nr, '(T3,A,F53.2)') 'HF@DFT HOMO-LUMO gap (eV)', e_gap_gw*evolt
757 WRITE (unit_nr, '(T3,A)') ''
758 END DO
759
760 WRITE (unit_nr, '(T3,A)') ''
761 WRITE (unit_nr, '(T3,A)') ''
762 WRITE (unit_nr, '(T3,A,F63.3)') 'HF@DFT direct bandgap (eV)', min_direct_hf_at_dft_gap*evolt
763
764 WRITE (unit_nr, '(T3,A)') ''
765 WRITE (unit_nr, '(T3,A)') 'End of exchange energies'
766 WRITE (unit_nr, '(T3,A)') '------------------------'
767 WRITE (unit_nr, '(T3,A)') ''
768
769 cpabort('Stop after printing exchange energies.')
770
771 ELSE
772 CALL para_env%sync()
773 END IF
774
775 END IF
776
777 IF (print_exx == gw_read_exx) THEN
778
779 CALL open_file(unit_number=iunit, file_name="exx.out")
780
781 really_read_line = .false.
782
783 DO WHILE (.true.)
784
785 READ (iunit, '(A)') line
786
787 IF (line == " End of exchange energies ") EXIT
788
789 IF (really_read_line) THEN
790
791 READ (line(1:7), *) n_level_gw_ref
792 READ (line(17:40), *) tmp
793
794 DO ikp = 1, SIZE(vec_sigma_x_minus_vxc_gw, 3)
795 vec_sigma_x_minus_vxc_gw(n_level_gw_ref, 1, ikp) = tmp/evolt
796 END DO
797
798 END IF
799
800 IF (line == " MO Sigma_x-vxc ") really_read_line = .true.
801
802 END DO
803
804 CALL close_file(iunit)
805
806 END IF
807
808 ! store vec_Sigma_x_minus_vxc_gw in the mp2_environment
809 mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, :, :) = vec_sigma_x_minus_vxc_gw(:, :, :)
810
811 ! clean up
812 DEALLOCATE (matrix_sigma_x_minus_vxc, vec_sigma_x_minus_vxc_gw)
813 IF (do_kpoints_cubic_rpa) THEN
814 DEALLOCATE (matrix_sigma_x_minus_vxc_im)
815 END IF
816
817 t2 = m_walltime()
818
819 t3 = t2 - t1
820
821 CALL timestop(handle)
822
824
825! **************************************************************************************************
826!> \brief ...
827!> \param kpoints ...
828!> \param matrix_sigma_x_minus_vxc ...
829!> \param matrix_sigma_x_minus_vxc_im ...
830!> \param vec_Sigma_x_minus_vxc_gw ...
831!> \param vec_Sigma_x_minus_vxc_gw_im ...
832!> \param para_env ...
833!> \param nmo ...
834!> \param mp2_env ...
835! **************************************************************************************************
836 SUBROUTINE transform_sigma_x_minus_vxc_to_mo_basis(kpoints, matrix_sigma_x_minus_vxc, &
837 matrix_sigma_x_minus_vxc_im, vec_Sigma_x_minus_vxc_gw, &
838 vec_Sigma_x_minus_vxc_gw_im, para_env, nmo, mp2_env)
839
840 TYPE(kpoint_type), POINTER :: kpoints
841 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_sigma_x_minus_vxc, &
842 matrix_sigma_x_minus_vxc_im
843 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: vec_sigma_x_minus_vxc_gw, &
844 vec_sigma_x_minus_vxc_gw_im
845 TYPE(mp_para_env_type), INTENT(IN) :: para_env
846 INTEGER :: nmo
847 TYPE(mp2_type) :: mp2_env
848
849 CHARACTER(LEN=*), PARAMETER :: routinen = 'transform_sigma_x_minus_vxc_to_MO_basis'
850
851 INTEGER :: dimen, gw_corr_lev_occ, gw_corr_lev_virt, handle, homo, i_global, iib, ikp, &
852 ispin, j_global, jjb, max_corr_lev_occ, max_corr_lev_virt, ncol_local, nkp, nrow_local, &
853 nspins
854 INTEGER, DIMENSION(2) :: kp_range
855 INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
856 REAL(kind=dp) :: imval, reval
857 TYPE(cp_cfm_type) :: cfm_mos, cfm_sigma_x_minus_vxc, &
858 cfm_sigma_x_minus_vxc_mo_basis, cfm_tmp
859 TYPE(cp_fm_struct_type), POINTER :: matrix_struct
860 TYPE(cp_fm_type) :: fwork_im, fwork_re
861 TYPE(kpoint_env_type), POINTER :: kp
862 TYPE(mo_set_type), POINTER :: mo_set, mo_set_im, mo_set_re
863
864 CALL timeset(routinen, handle)
865
866 mo_set => kpoints%kp_env(1)%kpoint_env%mos(1, 1)
867 CALL get_mo_set(mo_set, nmo=nmo)
868
869 nspins = SIZE(matrix_sigma_x_minus_vxc, 1)
870 CALL get_kpoint_info(kpoints, nkp=nkp, kp_range=kp_range)
871
872 ! if this CPASSERT is wrong, please make sure that the kpoint group size PARALLEL_GROUP_SIZE
873 ! in the kpoint environment &DFT &KPOINTS is -1
874 cpassert(kp_range(1) == 1 .AND. kp_range(2) == nkp)
875
876 ALLOCATE (vec_sigma_x_minus_vxc_gw(nmo, nspins, nkp))
877 vec_sigma_x_minus_vxc_gw = 0.0_dp
878
879 ALLOCATE (vec_sigma_x_minus_vxc_gw_im(nmo, nspins, nkp))
880 vec_sigma_x_minus_vxc_gw_im = 0.0_dp
881
882 CALL cp_fm_get_info(mo_set%mo_coeff, matrix_struct=matrix_struct)
883 CALL cp_fm_create(fwork_re, matrix_struct)
884 CALL cp_fm_create(fwork_im, matrix_struct)
885 CALL cp_cfm_create(cfm_mos, matrix_struct)
886 CALL cp_cfm_create(cfm_sigma_x_minus_vxc, matrix_struct)
887 CALL cp_cfm_create(cfm_sigma_x_minus_vxc_mo_basis, matrix_struct)
888 CALL cp_cfm_create(cfm_tmp, matrix_struct)
889
890 CALL cp_cfm_get_info(matrix=cfm_sigma_x_minus_vxc_mo_basis, &
891 nrow_local=nrow_local, &
892 ncol_local=ncol_local, &
893 row_indices=row_indices, &
894 col_indices=col_indices)
895
896 ! Transform matrix_sigma_x_minus_vxc to MO basis
897 DO ikp = 1, nkp
898
899 kp => kpoints%kp_env(ikp)%kpoint_env
900
901 DO ispin = 1, nspins
902
903 ! v_xc_n to fm matrix
904 CALL copy_dbcsr_to_fm(matrix_sigma_x_minus_vxc(ispin, ikp)%matrix, fwork_re)
905 CALL copy_dbcsr_to_fm(matrix_sigma_x_minus_vxc_im(ispin, ikp)%matrix, fwork_im)
906
907 CALL cp_cfm_scale_and_add_fm(z_zero, cfm_sigma_x_minus_vxc, z_one, fwork_re)
908 CALL cp_cfm_scale_and_add_fm(z_one, cfm_sigma_x_minus_vxc, gaussi, fwork_im)
909
910 ! get real part (1) and imag. part (2) of the mo coeffs
911 mo_set_re => kp%mos(1, ispin)
912 mo_set_im => kp%mos(2, ispin)
913
914 CALL cp_cfm_scale_and_add_fm(z_zero, cfm_mos, z_one, mo_set_re%mo_coeff)
915 CALL cp_cfm_scale_and_add_fm(z_one, cfm_mos, gaussi, mo_set_im%mo_coeff)
916
917 ! tmp = V(k)*C(k)
918 CALL parallel_gemm('N', 'N', nmo, nmo, nmo, z_one, cfm_sigma_x_minus_vxc, &
919 cfm_mos, z_zero, cfm_tmp)
920
921 ! V_n(k) = C^H(k)*tmp
922 CALL parallel_gemm('C', 'N', nmo, nmo, nmo, z_one, cfm_mos, cfm_tmp, &
923 z_zero, cfm_sigma_x_minus_vxc_mo_basis)
924
925 DO jjb = 1, ncol_local
926
927 j_global = col_indices(jjb)
928
929 DO iib = 1, nrow_local
930
931 i_global = row_indices(iib)
932
933 IF (j_global == i_global .AND. i_global <= nmo) THEN
934
935 reval = real(cfm_sigma_x_minus_vxc_mo_basis%local_data(iib, jjb), kind=dp)
936 imval = aimag(cfm_sigma_x_minus_vxc_mo_basis%local_data(iib, jjb))
937
938 vec_sigma_x_minus_vxc_gw(i_global, ispin, ikp) = reval
939 vec_sigma_x_minus_vxc_gw_im(i_global, ispin, ikp) = imval
940
941 END IF
942
943 END DO
944
945 END DO
946
947 END DO
948
949 END DO
950
951 CALL para_env%sum(vec_sigma_x_minus_vxc_gw)
952 CALL para_env%sum(vec_sigma_x_minus_vxc_gw_im)
953 ! also adjust in the case of kpoints too big gw_corr_lev_occ and gw_corr_lev_virt
954 DO ispin = 1, nspins
955 CALL get_mo_set(mo_set=kpoints%kp_env(1)%kpoint_env%mos(ispin, 1), &
956 homo=homo, nao=dimen)
957 ! If SVD is used to invert overlap matrix (for CHOLESKY OFF), some MOs are removed
958 ! Therefore, setting the number of gw_corr_lev_virt simply to dimen - homo leads to index problems
959 ! Instead, we take into account the removed MOs
960 max_corr_lev_occ = homo
961 max_corr_lev_virt = nmo - homo
962
963 gw_corr_lev_occ = mp2_env%ri_g0w0%corr_mos_occ
964 gw_corr_lev_virt = mp2_env%ri_g0w0%corr_mos_virt
965 ! if corrected occ/virt levels exceed the number of occ/virt levels or are negative,
966 ! correct all occ/virt level energies
967 IF (gw_corr_lev_occ > homo .OR. gw_corr_lev_occ < 0) gw_corr_lev_occ = max_corr_lev_occ
968 IF (gw_corr_lev_virt > max_corr_lev_virt .OR. gw_corr_lev_virt < 0) gw_corr_lev_virt = max_corr_lev_virt
969 IF (ispin == 1) THEN
970 mp2_env%ri_g0w0%corr_mos_occ = gw_corr_lev_occ
971 mp2_env%ri_g0w0%corr_mos_virt = gw_corr_lev_virt
972 ELSE IF (ispin == 2) THEN
973 ! ensure that the total number of corrected MOs is the same for alpha and beta, important
974 ! for parallelization
975 IF (mp2_env%ri_g0w0%corr_mos_occ + mp2_env%ri_g0w0%corr_mos_virt /= &
976 gw_corr_lev_occ + gw_corr_lev_virt) THEN
977 gw_corr_lev_virt = mp2_env%ri_g0w0%corr_mos_occ + mp2_env%ri_g0w0%corr_mos_virt - gw_corr_lev_occ
978 END IF
979 mp2_env%ri_g0w0%corr_mos_occ_beta = gw_corr_lev_occ
980 mp2_env%ri_g0w0%corr_mos_virt_beta = gw_corr_lev_virt
981 END IF
982 END DO
983
984 CALL cp_fm_release(fwork_re)
985 CALL cp_fm_release(fwork_im)
986 CALL cp_cfm_release(cfm_mos)
987 CALL cp_cfm_release(cfm_sigma_x_minus_vxc)
988 CALL cp_cfm_release(cfm_sigma_x_minus_vxc_mo_basis)
989 CALL cp_cfm_release(cfm_tmp)
990
991 CALL timestop(handle)
992
993 END SUBROUTINE transform_sigma_x_minus_vxc_to_mo_basis
994
995! **************************************************************************************************
996!> \brief ...
997!> \param matrix_ks_transl ...
998!> \param matrix_ks_kp_re ...
999!> \param matrix_ks_kp_im ...
1000!> \param kpoints ...
1001! **************************************************************************************************
1002 SUBROUTINE transform_matrix_ks_to_kp(matrix_ks_transl, matrix_ks_kp_re, matrix_ks_kp_im, kpoints)
1003
1004 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_transl, matrix_ks_kp_re, &
1005 matrix_ks_kp_im
1006 TYPE(kpoint_type), POINTER :: kpoints
1007
1008 CHARACTER(len=*), PARAMETER :: routinen = 'transform_matrix_ks_to_kp'
1009
1010 INTEGER :: handle, ikp, ispin, nkp, nspin
1011 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1012 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
1013 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1014 POINTER :: sab_nl
1015
1016 CALL timeset(routinen, handle)
1017
1018 NULLIFY (sab_nl)
1019 CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, sab_nl=sab_nl, cell_to_index=cell_to_index)
1020
1021 cpassert(ASSOCIATED(sab_nl))
1022
1023 nspin = SIZE(matrix_ks_transl, 1)
1024
1025 DO ikp = 1, nkp
1026 DO ispin = 1, nspin
1027
1028 CALL dbcsr_set(matrix_ks_kp_re(ispin, ikp)%matrix, 0.0_dp)
1029 CALL dbcsr_set(matrix_ks_kp_im(ispin, ikp)%matrix, 0.0_dp)
1030 CALL rskp_transform(rmatrix=matrix_ks_kp_re(ispin, ikp)%matrix, &
1031 cmatrix=matrix_ks_kp_im(ispin, ikp)%matrix, &
1032 rsmat=matrix_ks_transl, ispin=ispin, &
1033 xkp=xkp(1:3, ikp), cell_to_index=cell_to_index, sab_nl=sab_nl)
1034
1035 END DO
1036 END DO
1037
1038 CALL timestop(handle)
1039
1040 END SUBROUTINE transform_matrix_ks_to_kp
1041
1042! **************************************************************************************************
1043!> \brief ...
1044!> \param matrix_ks_transl ...
1045!> \param matrix_ks_kp_re ...
1046!> \param matrix_ks_kp_im ...
1047!> \param kpoints ...
1048! **************************************************************************************************
1049 SUBROUTINE allocate_matrix_ks_kp(matrix_ks_transl, matrix_ks_kp_re, matrix_ks_kp_im, kpoints)
1050
1051 TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: matrix_ks_transl, matrix_ks_kp_re, &
1052 matrix_ks_kp_im
1053 TYPE(kpoint_type), POINTER :: kpoints
1054
1055 CHARACTER(len=*), PARAMETER :: routinen = 'allocate_matrix_ks_kp'
1056
1057 INTEGER :: handle, ikp, ispin, nkp, nspin
1058 INTEGER, DIMENSION(:, :, :), POINTER :: cell_to_index
1059 REAL(kind=dp), DIMENSION(:, :), POINTER :: xkp
1060 TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1061 POINTER :: sab_nl
1062
1063 CALL timeset(routinen, handle)
1064
1065 NULLIFY (sab_nl)
1066 CALL get_kpoint_info(kpoints, nkp=nkp, xkp=xkp, sab_nl=sab_nl, cell_to_index=cell_to_index)
1067
1068 cpassert(ASSOCIATED(sab_nl))
1069
1070 nspin = SIZE(matrix_ks_transl, 1)
1071
1072 NULLIFY (matrix_ks_kp_re, matrix_ks_kp_im)
1073 CALL dbcsr_allocate_matrix_set(matrix_ks_kp_re, nspin, nkp)
1074 CALL dbcsr_allocate_matrix_set(matrix_ks_kp_im, nspin, nkp)
1075
1076 DO ikp = 1, nkp
1077 DO ispin = 1, nspin
1078
1079 ALLOCATE (matrix_ks_kp_re(ispin, ikp)%matrix)
1080 ALLOCATE (matrix_ks_kp_im(ispin, ikp)%matrix)
1081
1082 CALL dbcsr_create(matrix_ks_kp_re(ispin, ikp)%matrix, &
1083 template=matrix_ks_transl(1, 1)%matrix, &
1084 matrix_type=dbcsr_type_symmetric)
1085 CALL dbcsr_create(matrix_ks_kp_im(ispin, ikp)%matrix, &
1086 template=matrix_ks_transl(1, 1)%matrix, &
1087 matrix_type=dbcsr_type_antisymmetric)
1088
1089 CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_kp_re(ispin, ikp)%matrix, sab_nl)
1090 CALL cp_dbcsr_alloc_block_from_nbl(matrix_ks_kp_im(ispin, ikp)%matrix, sab_nl)
1091
1092 CALL dbcsr_set(matrix_ks_kp_re(ispin, ikp)%matrix, 0.0_dp)
1093 CALL dbcsr_set(matrix_ks_kp_im(ispin, ikp)%matrix, 0.0_dp)
1094
1095 END DO
1096 END DO
1097
1098 CALL timestop(handle)
1099
1100 END SUBROUTINE allocate_matrix_ks_kp
1101
1102END MODULE rpa_gw_sigma_x
Contains ADMM methods which require molecular orbitals.
subroutine, public admm_mo_merge_ks_matrix(qs_env)
...
Types and set/get functions for auxiliary density matrix methods.
Definition admm_types.F:15
subroutine, public get_admm_env(admm_env, mo_derivs_aux_fit, mos_aux_fit, sab_aux_fit, sab_aux_fit_asymm, sab_aux_fit_vs_orb, matrix_s_aux_fit, matrix_s_aux_fit_kp, matrix_s_aux_fit_vs_orb, matrix_s_aux_fit_vs_orb_kp, task_list_aux_fit, matrix_ks_aux_fit, matrix_ks_aux_fit_kp, matrix_ks_aux_fit_im, matrix_ks_aux_fit_dft, matrix_ks_aux_fit_hfx, matrix_ks_aux_fit_dft_kp, matrix_ks_aux_fit_hfx_kp, rho_aux_fit, rho_aux_fit_buffer, admm_dm)
Get routine for the ADMM env.
Definition admm_types.F:599
Basic linear algebra operations for complex full matrices.
subroutine, public cp_cfm_scale_and_add_fm(alpha, matrix_a, beta, matrix_b)
Scale and add two BLACS matrices (a = alpha*a + beta*b). where b is a real matrix (adapted from cp_cf...
Represents a complex full matrix distributed on many processors.
subroutine, public cp_cfm_release(matrix)
Releases a full matrix.
subroutine, public cp_cfm_create(matrix, matrix_struct, name, nrow, ncol, set_zero)
Creates a new full matrix with the given structure.
subroutine, public cp_cfm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, matrix_struct, para_env)
Returns information about a full matrix.
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_release_p(matrix)
...
subroutine, public dbcsr_desymmetrize(matrix_a, matrix_b)
...
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
subroutine, public dbcsr_multiply(transa, transb, alpha, matrix_a, matrix_b, beta, matrix_c, first_row, last_row, first_column, last_column, first_k, last_k, retain_sparsity, filter_eps, flop)
...
subroutine, public dbcsr_set(matrix, alpha)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
subroutine, public dbcsr_get_diag(matrix, diag)
Copies the diagonal elements from the given matrix into the given array.
DBCSR operations in CP2K.
subroutine, public copy_dbcsr_to_fm(matrix, fm, plan)
Copy a DBCSR matrix to a BLACS matrix.
subroutine, public copy_fm_to_dbcsr(fm, matrix, keep_sparsity)
Copy a BLACS matrix to a dbcsr matrix.
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
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
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, nrow, ncol, set_zero)
creates a new full matrix with the given structure
Routines to calculate HFX energy and potential.
subroutine, public integrate_four_center(qs_env, x_data, ks_matrix, ehfx, rho_ao, hfx_section, para_env, geometry_did_change, irep, distribute_fock_matrix, ispin, nspins)
computes four center integrals for a full basis set and updates the Kohn-Sham-Matrix and energy....
Routines to calculate EXX in RPA and energy correction methods.
Definition hfx_exx.F:16
subroutine, public calc_exx_admm_xc_contributions(qs_env, matrix_prim, matrix_aux, x_data, exc, exc_aux_fit, calc_forces, use_virial)
Calculate the RI_RPAHF / EC_ENVHF ADMM XC contributions to the KS matrices and the respective energie...
Definition hfx_exx.F:629
subroutine, public exx_pre_hfx(ext_hfx_section, x_data, reuse_hfx)
Prepare the external x_data for integration. Simply change the HFX fraction in case the qs_envx_data ...
Definition hfx_exx.F:735
subroutine, public exx_post_hfx(qs_env, x_data, reuse_hfx)
Revert back to the proper HFX fraction in case qs_envx_data is reused.
Definition hfx_exx.F:760
RI-methods for HFX.
Definition hfx_ri.F:12
subroutine, public hfx_ri_update_ks(qs_env, ri_data, ks_matrix, ehfx, mos, rho_ao, geometry_did_change, nspins, hf_fraction)
...
Definition hfx_ri.F:1041
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public do_admm_purify_none
integer, parameter, public gw_print_exx
integer, parameter, public do_admm_basis_projection
integer, parameter, public gw_read_exx
integer, parameter, public xc_none
objects that represent the structure of input sections and the data contained in an input section
subroutine, public section_vals_val_set(section_vals, keyword_name, i_rep_section, i_rep_val, val, l_val, i_val, r_val, c_val, l_vals_ptr, i_vals_ptr, r_vals_ptr, c_vals_ptr)
sets the requested value
recursive type(section_vals_type) function, pointer, public section_vals_get_subs_vals(section_vals, subsection_name, i_rep_section, can_return_null)
returns the values of the requested subsection
subroutine, public section_vals_get(section_vals, ref_count, n_repetition, n_subs_vals_rep, section, explicit)
returns various attributes about the section_vals
subroutine, public section_vals_val_get(section_vals, keyword_name, i_rep_section, i_rep_val, n_rep_val, val, l_val, i_val, r_val, c_val, l_vals, i_vals, r_vals, c_vals, explicit)
returns the requested value
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Routines needed for kpoint calculation.
subroutine, public rskp_transform(rmatrix, cmatrix, rsmat, ispin, xkp, cell_to_index, sab_nl, is_complex, rs_sign)
Transformation of real space matrices to a kpoint.
Types and basic routines needed for a kpoint calculation.
subroutine, public get_kpoint_info(kpoint, kp_scheme, nkp_grid, kp_shift, symmetry, verbose, full_grid, use_real_wfn, eps_geo, parallel_group_size, kp_range, nkp, xkp, wkp, para_env, blacs_env_all, para_env_kp, para_env_inter_kp, blacs_env, kp_env, kp_aux_env, mpools, iogrp, nkp_groups, kp_dist, cell_to_index, index_to_cell, sab_nl, sab_nl_nosym, inversion_symmetry_only, symmetry_backend, symmetry_reduction_method, gamma_centered, lattice_fft)
Retrieve information from a kpoint environment.
Machine interface based on Fortran 2003 and POSIX.
Definition machine.F:17
real(kind=dp) function, public m_walltime()
returns time from a real-time clock, protected against rolling early/easily
Definition machine.F:141
Definition of mathematical constants and functions.
complex(kind=dp), parameter, public z_one
complex(kind=dp), parameter, public gaussi
complex(kind=dp), parameter, public z_zero
Interface to the message passing library MPI.
Common selection and union operations for contiguous molecular-orbital windows.
Definition mo_window.F:11
subroutine, public determine_mo_window(eigenvalues, n_mo, n_occ, cutoff_occ, cutoff_empty, window)
Selects one contiguous MO window from an ordered reference spectrum.
Definition mo_window.F:44
Routines to calculate and distribute 2c- and 3c- integrals for RI.
subroutine, public compute_kpoints(qs_env, kpoints, unit_nr)
...
Framework for 2c-integrals for RI.
Definition mp2_ri_2c.F:14
subroutine, public trunc_coulomb_for_exchange(qs_env, trunc_coulomb, rel_cutoff_trunc_coulomb_ri_x, cell_grid, do_bvk_cell)
...
Definition mp2_ri_2c.F:1601
Types needed for MP2 calculations.
Definition mp2_types.F:14
basic linear algebra operations for full matrixes
Definition of physical constants:
Definition physcon.F:68
real(kind=dp), parameter, public evolt
Definition physcon.F:183
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, matrix_vhxc, 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.
routines that build the Kohn-Sham matrix (i.e calculate the coulomb and xc parts
subroutine, public qs_ks_build_kohn_sham_matrix(qs_env, calculate_forces, just_energy, print_active, ext_ks_matrix, ext_xc_section)
routine where the real calculations are made: the KS matrix is calculated
Definition and initialisation of the mo data type.
Definition qs_mo_types.F:22
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.
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...
Routines treating GW and RPA calculations with kpoints.
subroutine, public get_bandstruc_and_k_dependent_mos(qs_env, eigenval_kp)
...
Routines to calculate EXX within GW.
subroutine, public compute_vec_sigma_x_minus_vxc_gw(qs_env, mp2_env, mos_mp2, energy_ex, energy_xc_admm, t3, unit_nr)
...
Routines for GW, continuous development [Jan Wilhelm].
Definition rpa_gw.F:14
subroutine, public trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao, vec_sigma, homo, gw_corr_lev_occ, gw_corr_lev_virt, ispin)
...
Definition rpa_gw.F:6259
subroutine, public compute_minus_vxc_kpoints(qs_env)
...
Definition rpa_gw.F:6134
stores some data used in wavefunction fitting
Definition admm_types.F:120
Represent a complex full matrix.
keeps the information about the structure of a full matrix
represent a full matrix
Keeps information about a specific k-point.
Contains information about kpoints.
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.