Line data Source code
1 : !--------------------------------------------------------------------------------------------------!
2 : ! CP2K: A general program to perform molecular dynamics simulations !
3 : ! Copyright 2000-2026 CP2K developers group <https://cp2k.org> !
4 : ! !
5 : ! SPDX-License-Identifier: GPL-2.0-or-later !
6 : !--------------------------------------------------------------------------------------------------!
7 :
8 : ! **************************************************************************************************
9 : !> \brief Routines for GW, continuous development [Jan Wilhelm]
10 : !> \par History
11 : !> 03.2019 created [Frederick Stein]
12 : !> 12.2022 added periodic GW routines [Jan Wilhelm]
13 : ! **************************************************************************************************
14 : MODULE rpa_gw
15 : USE atomic_kind_types, ONLY: atomic_kind_type
16 : USE basis_set_types, ONLY: gto_basis_set_p_type,&
17 : gto_basis_set_type
18 : USE cell_types, ONLY: cell_type,&
19 : get_cell
20 : USE core_ppnl, ONLY: build_core_ppnl
21 : USE cp_cfm_basic_linalg, ONLY: cp_cfm_get_diag,&
22 : cp_cfm_scale,&
23 : cp_cfm_scale_and_add,&
24 : cp_cfm_scale_and_add_fm,&
25 : cp_cfm_transpose
26 : USE cp_cfm_diag, ONLY: cp_cfm_geeig_canon
27 : USE cp_cfm_types, ONLY: &
28 : cp_cfm_copy_general, cp_cfm_create, cp_cfm_get_info, cp_cfm_release, cp_cfm_set_all, &
29 : cp_cfm_to_cfm, cp_cfm_to_fm, cp_cfm_type, cp_fm_to_cfm
30 : USE cp_control_types, ONLY: dft_control_type
31 : USE cp_dbcsr_api, ONLY: &
32 : dbcsr_copy, dbcsr_create, dbcsr_desymmetrize, dbcsr_filter, dbcsr_get_info, dbcsr_init_p, &
33 : dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, dbcsr_iterator_start, &
34 : dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_multiply, dbcsr_p_type, dbcsr_release, &
35 : dbcsr_release_p, dbcsr_scale, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, &
36 : dbcsr_type_no_symmetry
37 : USE cp_dbcsr_contrib, ONLY: dbcsr_add_on_diag
38 : USE cp_dbcsr_cp2k_link, ONLY: cp_dbcsr_alloc_block_from_nbl
39 : USE cp_dbcsr_operations, ONLY: copy_dbcsr_to_fm,&
40 : copy_fm_to_dbcsr,&
41 : dbcsr_allocate_matrix_set,&
42 : dbcsr_deallocate_matrix_set
43 : USE cp_files, ONLY: close_file,&
44 : open_file
45 : USE cp_fm_basic_linalg, ONLY: cp_fm_add_on_diag,&
46 : cp_fm_scale_and_add,&
47 : cp_fm_uplo_to_full
48 : USE cp_fm_cholesky, ONLY: cp_fm_cholesky_decompose,&
49 : cp_fm_cholesky_invert
50 : USE cp_fm_diag, ONLY: cp_fm_syevd
51 : USE cp_fm_struct, ONLY: cp_fm_struct_create,&
52 : cp_fm_struct_release,&
53 : cp_fm_struct_type
54 : USE cp_fm_types, ONLY: cp_fm_copy_general,&
55 : cp_fm_create,&
56 : cp_fm_get_info,&
57 : cp_fm_release,&
58 : cp_fm_set_all,&
59 : cp_fm_to_fm,&
60 : cp_fm_to_fm_submat,&
61 : cp_fm_type
62 : USE cp_log_handling, ONLY: cp_get_default_logger,&
63 : cp_logger_get_default_unit_nr,&
64 : cp_logger_type
65 : USE cp_output_handling, ONLY: cp_print_key_finished_output,&
66 : cp_print_key_unit_nr
67 : USE cp_realspace_grid_cube, ONLY: cp_pw_to_cube
68 : USE dbt_api, ONLY: &
69 : dbt_batched_contract_finalize, dbt_batched_contract_init, dbt_clear, dbt_contract, &
70 : dbt_copy, dbt_copy_matrix_to_tensor, dbt_copy_tensor_to_matrix, dbt_create, dbt_destroy, &
71 : dbt_get_block, dbt_get_info, dbt_iterator_blocks_left, dbt_iterator_next_block, &
72 : dbt_iterator_start, dbt_iterator_stop, dbt_iterator_type, dbt_nblks_total, &
73 : dbt_pgrid_create, dbt_pgrid_destroy, dbt_pgrid_type, dbt_type
74 : USE gw_utils_fm, ONLY: cfm_contract_ABA
75 : USE hfx_types, ONLY: block_ind_type,&
76 : dealloc_containers,&
77 : hfx_compression_type
78 : USE input_constants, ONLY: gw_pade_approx,&
79 : gw_two_pole_model,&
80 : ri_rpa_g0w0_crossing_bisection,&
81 : ri_rpa_g0w0_crossing_newton,&
82 : ri_rpa_g0w0_crossing_z_shot,&
83 : soc_none
84 : USE input_section_types, ONLY: section_vals_get_subs_vals,&
85 : section_vals_type
86 : USE kinds, ONLY: default_path_length,&
87 : dp
88 : USE kpoint_k_r_trafo_simple, ONLY: fm_gamma_to_kp
89 : USE kpoint_methods, ONLY: kpoint_density_matrices,&
90 : kpoint_density_transform,&
91 : kpoint_init_cell_index
92 : USE kpoint_types, ONLY: get_kpoint_info,&
93 : kpoint_create,&
94 : kpoint_release,&
95 : kpoint_sym_create,&
96 : kpoint_type
97 : USE machine, ONLY: m_walltime
98 : USE mathconstants, ONLY: fourpi,&
99 : gaussi,&
100 : pi,&
101 : twopi,&
102 : z_one,&
103 : z_zero
104 : USE message_passing, ONLY: mp_para_env_type
105 : USE mp2_types, ONLY: mp2_type,&
106 : one_dim_real_array,&
107 : two_dim_int_array
108 : USE parallel_gemm_api, ONLY: parallel_gemm
109 : USE particle_list_types, ONLY: particle_list_type
110 : USE particle_types, ONLY: particle_type
111 : USE physcon, ONLY: evolt
112 : USE pw_env_types, ONLY: pw_env_get,&
113 : pw_env_type
114 : USE pw_methods, ONLY: pw_axpy,&
115 : pw_copy,&
116 : pw_scale,&
117 : pw_zero
118 : USE pw_pool_types, ONLY: pw_pool_type
119 : USE pw_types, ONLY: pw_c1d_gs_type,&
120 : pw_r3d_rs_type
121 : USE qs_band_structure, ONLY: calculate_kp_orbitals
122 : USE qs_collocate_density, ONLY: calculate_rho_elec
123 : USE qs_environment_types, ONLY: get_qs_env,&
124 : qs_env_release,&
125 : qs_environment_type
126 : USE qs_force_types, ONLY: qs_force_type
127 : USE qs_gamma2kp, ONLY: create_kp_from_gamma
128 : USE qs_integral_utils, ONLY: basis_set_list_setup
129 : USE qs_kind_types, ONLY: get_qs_kind,&
130 : qs_kind_type
131 : USE qs_ks_types, ONLY: qs_ks_env_type
132 : USE qs_mo_types, ONLY: get_mo_set
133 : USE qs_moments, ONLY: build_berry_moment_matrix
134 : USE qs_neighbor_list_types, ONLY: neighbor_list_set_p_type,&
135 : release_neighbor_list_sets
136 : USE qs_neighbor_lists, ONLY: setup_neighbor_list
137 : USE qs_overlap, ONLY: build_overlap_matrix_simple
138 : USE qs_scf_types, ONLY: qs_scf_env_type
139 : USE qs_subsys_types, ONLY: qs_subsys_get,&
140 : qs_subsys_type
141 : USE qs_tensors, ONLY: decompress_tensor
142 : USE qs_tensors_types, ONLY: create_2c_tensor
143 : USE rpa_gw_ic, ONLY: apply_ic_corr
144 : USE rpa_gw_im_time_util, ONLY: get_atom_index_from_basis_function_index,&
145 : get_tensor_3c_overl_int_gw
146 : USE rpa_gw_kpoints_util, ONLY: mat_kp_from_mat_gamma
147 : USE rpa_im_time, ONLY: compute_gamma_propagator,&
148 : compute_periodic_dm,&
149 : create_propagator_matrix_set,&
150 : propagator_sector_occupied,&
151 : propagator_sector_virtual
152 : USE scf_control_types, ONLY: scf_control_type
153 : USE time_frequency_grids, ONLY: negative_time,&
154 : positive_time,&
155 : time_frequency_grid_type,&
156 : transform_time_to_frequency
157 : USE util, ONLY: sort
158 : USE virial_types, ONLY: virial_type
159 : #include "./base/base_uses.f90"
160 :
161 : IMPLICIT NONE
162 :
163 : PRIVATE
164 :
165 : CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'rpa_gw'
166 :
167 : PUBLIC :: allocate_matrices_gw_im_time, allocate_matrices_gw, compute_GW_self_energy, compute_QP_energies, &
168 : deallocate_matrices_gw_im_time, deallocate_matrices_gw, compute_minus_vxc_kpoints, trafo_to_mo_and_kpoints, &
169 : get_fermi_level_offset, compute_W_cubic_GW, continuation_pade
170 :
171 : CONTAINS
172 :
173 : ! **************************************************************************************************
174 : !> \brief ...
175 : !> \param gw_corr_lev_occ ...
176 : !> \param gw_corr_lev_virt ...
177 : !> \param homo ...
178 : !> \param nmo ...
179 : !> \param num_integ_points ...
180 : !> \param unit_nr ...
181 : !> \param RI_blk_sizes ...
182 : !> \param do_ic_model ...
183 : !> \param para_env ...
184 : !> \param fm_mat_W ...
185 : !> \param fm_mat_Q ...
186 : !> \param mo_coeff ...
187 : !> \param t_3c_overl_int_ao_mo ...
188 : !> \param t_3c_O_mo_compressed ...
189 : !> \param t_3c_O_mo_ind ...
190 : !> \param t_3c_overl_int_gw_RI ...
191 : !> \param t_3c_overl_int_gw_AO ...
192 : !> \param starts_array_mc ...
193 : !> \param ends_array_mc ...
194 : !> \param t_3c_overl_nnP_ic ...
195 : !> \param t_3c_overl_nnP_ic_reflected ...
196 : !> \param matrix_s ...
197 : !> \param mat_W ...
198 : !> \param t_3c_overl_int ...
199 : !> \param t_3c_O_compressed ...
200 : !> \param t_3c_O_ind ...
201 : !> \param qs_env ...
202 : ! **************************************************************************************************
203 92 : SUBROUTINE allocate_matrices_gw_im_time(gw_corr_lev_occ, gw_corr_lev_virt, homo, nmo, &
204 : num_integ_points, unit_nr, &
205 : RI_blk_sizes, do_ic_model, &
206 : para_env, fm_mat_W, fm_mat_Q, &
207 46 : mo_coeff, &
208 : t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
209 : t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
210 46 : starts_array_mc, ends_array_mc, &
211 : t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, &
212 46 : matrix_s, mat_W, t_3c_overl_int, &
213 46 : t_3c_O_compressed, t_3c_O_ind, &
214 : qs_env)
215 :
216 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, homo
217 : INTEGER, INTENT(IN) :: nmo, num_integ_points, unit_nr
218 : INTEGER, DIMENSION(:), POINTER :: RI_blk_sizes
219 : LOGICAL, INTENT(IN) :: do_ic_model
220 : TYPE(mp_para_env_type), POINTER :: para_env
221 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
222 : INTENT(OUT) :: fm_mat_W
223 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_Q
224 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
225 : TYPE(dbt_type) :: t_3c_overl_int_ao_mo
226 : TYPE(hfx_compression_type), ALLOCATABLE, &
227 : DIMENSION(:) :: t_3c_O_mo_compressed
228 : TYPE(two_dim_int_array), ALLOCATABLE, &
229 : DIMENSION(:), INTENT(OUT) :: t_3c_O_mo_ind
230 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:), &
231 : INTENT(INOUT) :: t_3c_overl_int_gw_RI, &
232 : t_3c_overl_int_gw_AO
233 : INTEGER, DIMENSION(:), INTENT(IN) :: starts_array_mc, ends_array_mc
234 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:), &
235 : INTENT(INOUT) :: t_3c_overl_nnP_ic, &
236 : t_3c_overl_nnP_ic_reflected
237 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
238 : TYPE(dbcsr_type), POINTER :: mat_W
239 : TYPE(dbt_type), DIMENSION(:, :) :: t_3c_overl_int
240 : TYPE(hfx_compression_type), DIMENSION(:, :, :) :: t_3c_O_compressed
241 : TYPE(block_ind_type), DIMENSION(:, :, :) :: t_3c_O_ind
242 : TYPE(qs_environment_type), POINTER :: qs_env
243 :
244 : CHARACTER(LEN=*), PARAMETER :: routineN = 'allocate_matrices_gw_im_time'
245 :
246 : INTEGER :: handle, jquad, nspins
247 : LOGICAL :: my_open_shell
248 414 : TYPE(dbt_type) :: t_3c_overl_int_ao_mo_beta
249 :
250 46 : CALL timeset(routineN, handle)
251 :
252 46 : nspins = SIZE(homo)
253 46 : my_open_shell = (nspins == 2)
254 :
255 0 : ALLOCATE (t_3c_O_mo_ind(nspins), t_3c_overl_int_gw_AO(nspins), t_3c_overl_int_gw_RI(nspins), &
256 99454 : t_3c_overl_nnP_ic(nspins), t_3c_overl_nnP_ic_reflected(nspins), t_3c_O_mo_compressed(nspins))
257 : CALL get_tensor_3c_overl_int_gw(t_3c_overl_int, &
258 : t_3c_O_compressed, t_3c_O_ind, &
259 : t_3c_overl_int_ao_mo, t_3c_O_mo_compressed(1), t_3c_O_mo_ind(1)%array, &
260 : t_3c_overl_int_gw_RI(1), t_3c_overl_int_gw_AO(1), &
261 : starts_array_mc, ends_array_mc, &
262 : mo_coeff(1), matrix_s, &
263 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), nmo, &
264 : para_env, &
265 : do_ic_model, &
266 : t_3c_overl_nnP_ic(1), t_3c_overl_nnP_ic_reflected(1), &
267 46 : qs_env, unit_nr, do_alpha=.TRUE.)
268 :
269 46 : IF (my_open_shell) THEN
270 :
271 : CALL get_tensor_3c_overl_int_gw(t_3c_overl_int, &
272 : t_3c_O_compressed, t_3c_O_ind, &
273 : t_3c_overl_int_ao_mo_beta, t_3c_O_mo_compressed(2), t_3c_O_mo_ind(2)%array, &
274 : t_3c_overl_int_gw_RI(2), t_3c_overl_int_gw_AO(2), &
275 : starts_array_mc, ends_array_mc, &
276 : mo_coeff(2), matrix_s, &
277 : gw_corr_lev_occ(2), gw_corr_lev_virt(2), homo(2), nmo, &
278 : para_env, &
279 : do_ic_model, &
280 : t_3c_overl_nnP_ic(2), t_3c_overl_nnP_ic_reflected(2), &
281 8 : qs_env, unit_nr, do_alpha=.FALSE.)
282 :
283 8 : IF (.NOT. qs_env%mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
284 6 : CALL dbt_destroy(t_3c_overl_int_ao_mo_beta)
285 : END IF
286 :
287 : END IF
288 :
289 728 : ALLOCATE (fm_mat_W(num_integ_points))
290 :
291 636 : DO jquad = 1, num_integ_points
292 :
293 636 : CALL cp_fm_create(fm_mat_W(jquad), fm_mat_Q%matrix_struct, set_zero=.TRUE.)
294 :
295 : END DO
296 :
297 46 : NULLIFY (mat_W)
298 46 : CALL dbcsr_init_p(mat_W)
299 : CALL dbcsr_create(matrix=mat_W, &
300 : template=matrix_s(1)%matrix, &
301 : matrix_type=dbcsr_type_no_symmetry, &
302 : row_blk_size=RI_blk_sizes, &
303 46 : col_blk_size=RI_blk_sizes)
304 :
305 46 : CALL timestop(handle)
306 :
307 92 : END SUBROUTINE allocate_matrices_gw_im_time
308 :
309 : ! **************************************************************************************************
310 : !> \brief ...
311 : !> \param vec_Sigma_c_gw ...
312 : !> \param color_rpa_group ...
313 : !> \param dimen_nm_gw ...
314 : !> \param gw_corr_lev_occ ...
315 : !> \param gw_corr_lev_virt ...
316 : !> \param homo ...
317 : !> \param nmo ...
318 : !> \param num_integ_group ...
319 : !> \param unit_nr ...
320 : !> \param gw_corr_lev_tot ...
321 : !> \param num_fit_points ...
322 : !> \param omega_max_fit ...
323 : !> \param do_minimax_quad ...
324 : !> \param do_periodic ...
325 : !> \param do_ri_Sigma_x ...
326 : !> \param my_do_gw ...
327 : !> \param first_cycle_periodic_correction ...
328 : !> \param grid ...
329 : !> \param Eigenval ...
330 : !> \param vec_omega_fit_gw ...
331 : !> \param vec_Sigma_x_gw ...
332 : !> \param delta_corr ...
333 : !> \param Eigenval_last ...
334 : !> \param Eigenval_scf ...
335 : !> \param vec_W_gw ...
336 : !> \param fm_mat_S_gw ...
337 : !> \param fm_mat_S_gw_work ...
338 : !> \param para_env ...
339 : !> \param mp2_env ...
340 : !> \param kpoints ...
341 : !> \param nkp ...
342 : !> \param nkp_self_energy ...
343 : !> \param do_kpoints_cubic_RPA ...
344 : !> \param do_kpoints_from_Gamma ...
345 : ! **************************************************************************************************
346 134 : SUBROUTINE allocate_matrices_gw(vec_Sigma_c_gw, color_rpa_group, dimen_nm_gw, &
347 134 : gw_corr_lev_occ, gw_corr_lev_virt, homo, &
348 : nmo, num_integ_group, unit_nr, &
349 : gw_corr_lev_tot, num_fit_points, omega_max_fit, &
350 : do_minimax_quad, do_periodic, do_ri_Sigma_x, my_do_gw, &
351 : first_cycle_periodic_correction, &
352 : grid, Eigenval, vec_omega_fit_gw, vec_Sigma_x_gw, &
353 : delta_corr, Eigenval_last, Eigenval_scf, vec_W_gw, &
354 134 : fm_mat_S_gw, fm_mat_S_gw_work, &
355 : para_env, mp2_env, kpoints, nkp, nkp_self_energy, &
356 : do_kpoints_cubic_RPA, do_kpoints_from_Gamma)
357 :
358 : COMPLEX(KIND=dp), ALLOCATABLE, &
359 : DIMENSION(:, :, :, :), INTENT(OUT) :: vec_Sigma_c_gw
360 : INTEGER, INTENT(IN) :: color_rpa_group, dimen_nm_gw
361 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, homo
362 : INTEGER, INTENT(IN) :: nmo, num_integ_group, unit_nr
363 : INTEGER, INTENT(INOUT) :: gw_corr_lev_tot, num_fit_points
364 : REAL(KIND=dp) :: omega_max_fit
365 : LOGICAL, INTENT(IN) :: do_minimax_quad, do_periodic, &
366 : do_ri_Sigma_x, my_do_gw
367 : LOGICAL, INTENT(OUT) :: first_cycle_periodic_correction
368 : TYPE(time_frequency_grid_type), INTENT(IN) :: grid
369 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
370 : INTENT(INOUT) :: Eigenval
371 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
372 : INTENT(OUT) :: vec_omega_fit_gw
373 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
374 : INTENT(OUT) :: vec_Sigma_x_gw
375 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
376 : INTENT(INOUT) :: delta_corr
377 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
378 : INTENT(OUT) :: Eigenval_last, Eigenval_scf
379 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
380 : INTENT(OUT) :: vec_W_gw
381 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_S_gw
382 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
383 : INTENT(INOUT) :: fm_mat_S_gw_work
384 : TYPE(mp_para_env_type), POINTER :: para_env
385 : TYPE(mp2_type) :: mp2_env
386 : TYPE(kpoint_type), POINTER :: kpoints
387 : INTEGER, INTENT(OUT) :: nkp, nkp_self_energy
388 : LOGICAL, INTENT(IN) :: do_kpoints_cubic_RPA, &
389 : do_kpoints_from_Gamma
390 :
391 : CHARACTER(LEN=*), PARAMETER :: routineN = 'allocate_matrices_gw'
392 :
393 : INTEGER :: handle, ispin, nspins
394 : LOGICAL :: my_open_shell
395 :
396 134 : CALL timeset(routineN, handle)
397 :
398 134 : nspins = SIZE(Eigenval, 3)
399 134 : my_open_shell = (nspins == 2)
400 :
401 134 : gw_corr_lev_tot = gw_corr_lev_occ(1) + gw_corr_lev_virt(1)
402 :
403 : ! determine number of fit points in the interval [0,w_max] for virt, or [-w_max,0] for occ
404 5744 : num_fit_points = COUNT(grid%frequency < omega_max_fit)
405 :
406 134 : IF (mp2_env%ri_g0w0%analytic_continuation == gw_pade_approx) THEN
407 98 : IF (mp2_env%ri_g0w0%nparam_pade > num_fit_points) THEN
408 32 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A)") &
409 16 : "Pade approximation: more parameters than data points. Reset # of parameters."
410 32 : mp2_env%ri_g0w0%nparam_pade = num_fit_points
411 32 : IF (unit_nr > 0) WRITE (UNIT=unit_nr, FMT="(T3,A,T74,I7)") &
412 16 : "Number of pade parameters:", mp2_env%ri_g0w0%nparam_pade
413 : END IF
414 : END IF
415 :
416 : ! create new arrays containing omega values at which we calculate vec_Sigma_c_gw
417 402 : ALLOCATE (vec_omega_fit_gw(num_fit_points))
418 5744 : vec_omega_fit_gw(:) = PACK(grid%frequency, grid%frequency < omega_max_fit)
419 :
420 134 : IF (do_kpoints_cubic_RPA) THEN
421 0 : CALL get_kpoint_info(kpoints, nkp=nkp)
422 0 : IF (mp2_env%ri_g0w0%do_gamma_only_sigma) THEN
423 0 : nkp_self_energy = 1
424 : ELSE
425 0 : nkp_self_energy = nkp
426 : END IF
427 134 : ELSE IF (do_kpoints_from_Gamma) THEN
428 16 : CALL get_kpoint_info(kpoints, nkp=nkp)
429 16 : IF (mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
430 16 : nkp_self_energy = mp2_env%ri_g0w0%nkp_self_energy
431 : ELSE
432 0 : nkp_self_energy = 1
433 : END IF
434 : ELSE
435 118 : nkp = 1
436 118 : nkp_self_energy = 1
437 : END IF
438 804 : ALLOCATE (vec_Sigma_c_gw(gw_corr_lev_tot, num_fit_points, nkp_self_energy, nspins))
439 134 : vec_Sigma_c_gw = z_zero
440 :
441 670 : ALLOCATE (Eigenval_scf(nmo, nkp_self_energy, nspins))
442 7254 : Eigenval_scf(:, :, :) = Eigenval(:, :, :)
443 :
444 536 : ALLOCATE (Eigenval_last(nmo, nkp_self_energy, nspins))
445 7254 : Eigenval_last(:, :, :) = Eigenval(:, :, :)
446 :
447 134 : IF (do_periodic) THEN
448 :
449 18 : ALLOCATE (delta_corr(1 + homo(1) - gw_corr_lev_occ(1):homo(1) + gw_corr_lev_virt(1)))
450 6 : delta_corr(:) = 0.0_dp
451 :
452 6 : first_cycle_periodic_correction = .TRUE.
453 :
454 : END IF
455 :
456 536 : ALLOCATE (vec_Sigma_x_gw(nmo, nkp_self_energy, nspins))
457 134 : vec_Sigma_x_gw = 0.0_dp
458 :
459 134 : IF (my_do_gw) THEN
460 :
461 : ! minimax grids not implemented for O(N^4) GW
462 88 : CPASSERT(.NOT. do_minimax_quad)
463 :
464 : ! create temporary matrix to store B*([1+Q(iw')]^-1-1), has the same size as B
465 368 : ALLOCATE (fm_mat_S_gw_work(nspins))
466 192 : DO ispin = 1, nspins
467 104 : CALL cp_fm_create(fm_mat_S_gw_work(ispin), fm_mat_S_gw(ispin)%matrix_struct)
468 192 : CALL cp_fm_set_all(matrix=fm_mat_S_gw_work(ispin), alpha=0.0_dp)
469 : END DO
470 :
471 352 : ALLOCATE (vec_W_gw(dimen_nm_gw, nspins))
472 88 : vec_W_gw = 0.0_dp
473 :
474 : ! in case we do RI for Sigma_x, we calculate Sigma_x right here
475 88 : IF (do_ri_Sigma_x) THEN
476 :
477 : CALL get_vec_sigma_x(vec_Sigma_x_gw(:, :, 1), nmo, fm_mat_S_gw(1), para_env, num_integ_group, color_rpa_group, &
478 68 : homo(1), gw_corr_lev_occ(1), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, 1))
479 :
480 68 : IF (my_open_shell) THEN
481 : CALL get_vec_sigma_x(vec_Sigma_x_gw(:, :, 2), nmo, fm_mat_S_gw(2), para_env, num_integ_group, &
482 : color_rpa_group, homo(2), gw_corr_lev_occ(2), &
483 12 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, 1))
484 : END IF
485 :
486 : END IF
487 :
488 : END IF
489 :
490 134 : CALL timestop(handle)
491 :
492 134 : END SUBROUTINE allocate_matrices_gw
493 :
494 : ! **************************************************************************************************
495 : !> \brief ...
496 : !> \param vec_Sigma_x_gw ...
497 : !> \param nmo ...
498 : !> \param fm_mat_S_gw ...
499 : !> \param para_env ...
500 : !> \param num_integ_group ...
501 : !> \param color_rpa_group ...
502 : !> \param homo ...
503 : !> \param gw_corr_lev_occ ...
504 : !> \param vec_Sigma_x_minus_vxc_gw11 ...
505 : ! **************************************************************************************************
506 80 : SUBROUTINE get_vec_sigma_x(vec_Sigma_x_gw, nmo, fm_mat_S_gw, para_env, num_integ_group, color_rpa_group, homo, &
507 80 : gw_corr_lev_occ, vec_Sigma_x_minus_vxc_gw11)
508 :
509 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: vec_Sigma_x_gw
510 : INTEGER, INTENT(IN) :: nmo
511 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_S_gw
512 : TYPE(mp_para_env_type), POINTER :: para_env
513 : INTEGER, INTENT(IN) :: num_integ_group, color_rpa_group, homo, &
514 : gw_corr_lev_occ
515 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: vec_Sigma_x_minus_vxc_gw11
516 :
517 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_vec_sigma_x'
518 :
519 : INTEGER :: handle, iiB, m_global, n_global, &
520 : ncol_local, nm_global, nrow_local
521 80 : INTEGER, DIMENSION(:), POINTER :: col_indices
522 :
523 80 : CALL timeset(routineN, handle)
524 :
525 : CALL cp_fm_get_info(matrix=fm_mat_S_gw, &
526 : nrow_local=nrow_local, &
527 : ncol_local=ncol_local, &
528 80 : col_indices=col_indices)
529 :
530 80 : CALL para_env%sync()
531 :
532 : ! loop over (nm) index
533 83522 : DO iiB = 1, ncol_local
534 :
535 : ! this is needed for correct values within parallelization
536 83442 : IF (MODULO(1, num_integ_group) /= color_rpa_group) CYCLE
537 :
538 81303 : nm_global = col_indices(iiB)
539 :
540 : ! transform the index nm to n and m, formulae copied from Mauro's code
541 81303 : n_global = MAX(1, nm_global - 1)/nmo + 1
542 81303 : m_global = nm_global - (n_global - 1)*nmo
543 81303 : n_global = n_global + homo - gw_corr_lev_occ
544 :
545 81383 : IF (m_global <= homo) THEN
546 :
547 : ! Sigma_x_n = -sum_m^occ sum_P (B_(nm)^P)^2
548 : vec_Sigma_x_gw(n_global, 1) = &
549 : vec_Sigma_x_gw(n_global, 1) - &
550 761232 : DOT_PRODUCT(fm_mat_S_gw%local_data(:, iiB), fm_mat_S_gw%local_data(:, iiB))
551 :
552 : END IF
553 :
554 : END DO
555 :
556 80 : CALL para_env%sync()
557 :
558 5020 : CALL para_env%sum(vec_Sigma_x_gw)
559 :
560 : vec_Sigma_x_minus_vxc_gw11(:) = &
561 : vec_Sigma_x_minus_vxc_gw11(:) + &
562 2470 : vec_Sigma_x_gw(:, 1)
563 :
564 80 : CALL timestop(handle)
565 :
566 80 : END SUBROUTINE get_vec_sigma_x
567 :
568 : ! **************************************************************************************************
569 : !> \brief ...
570 : !> \param fm_mat_S_gw_work ...
571 : !> \param vec_W_gw ...
572 : !> \param vec_Sigma_c_gw ...
573 : !> \param vec_omega_fit_gw ...
574 : !> \param vec_Sigma_x_minus_vxc_gw ...
575 : !> \param Eigenval_last ...
576 : !> \param Eigenval_scf ...
577 : !> \param do_periodic ...
578 : !> \param matrix_berry_re_mo_mo ...
579 : !> \param matrix_berry_im_mo_mo ...
580 : !> \param kpoints ...
581 : !> \param vec_Sigma_x_gw ...
582 : !> \param my_do_gw ...
583 : ! **************************************************************************************************
584 134 : SUBROUTINE deallocate_matrices_gw(fm_mat_S_gw_work, vec_W_gw, vec_Sigma_c_gw, vec_omega_fit_gw, &
585 : vec_Sigma_x_minus_vxc_gw, Eigenval_last, &
586 : Eigenval_scf, do_periodic, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, kpoints, &
587 : vec_Sigma_x_gw, my_do_gw)
588 :
589 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
590 : INTENT(INOUT) :: fm_mat_S_gw_work
591 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
592 : INTENT(INOUT) :: vec_W_gw
593 : COMPLEX(KIND=dp), ALLOCATABLE, &
594 : DIMENSION(:, :, :, :), INTENT(INOUT) :: vec_Sigma_c_gw
595 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
596 : INTENT(INOUT) :: vec_omega_fit_gw
597 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
598 : INTENT(INOUT) :: vec_Sigma_x_minus_vxc_gw, Eigenval_last, &
599 : Eigenval_scf
600 : LOGICAL, INTENT(IN) :: do_periodic
601 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_re_mo_mo, &
602 : matrix_berry_im_mo_mo
603 : TYPE(kpoint_type), POINTER :: kpoints
604 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
605 : INTENT(INOUT) :: vec_Sigma_x_gw
606 : LOGICAL, INTENT(IN) :: my_do_gw
607 :
608 : CHARACTER(LEN=*), PARAMETER :: routineN = 'deallocate_matrices_gw'
609 :
610 : INTEGER :: handle, nspins
611 : LOGICAL :: my_open_shell
612 :
613 134 : CALL timeset(routineN, handle)
614 :
615 134 : nspins = SIZE(Eigenval_last, 3)
616 134 : my_open_shell = (nspins == 2)
617 :
618 134 : IF (my_do_gw) THEN
619 88 : CALL cp_fm_release(fm_mat_S_gw_work)
620 88 : DEALLOCATE (vec_Sigma_x_minus_vxc_gw)
621 88 : DEALLOCATE (vec_W_gw)
622 : END IF
623 :
624 134 : DEALLOCATE (vec_Sigma_c_gw)
625 134 : DEALLOCATE (vec_Sigma_x_gw)
626 134 : DEALLOCATE (vec_omega_fit_gw)
627 134 : DEALLOCATE (Eigenval_last)
628 134 : DEALLOCATE (Eigenval_scf)
629 :
630 134 : IF (do_periodic) THEN
631 6 : CALL dbcsr_deallocate_matrix_set(matrix_berry_re_mo_mo)
632 6 : CALL dbcsr_deallocate_matrix_set(matrix_berry_im_mo_mo)
633 6 : CALL kpoint_release(kpoints)
634 : END IF
635 :
636 134 : CALL timestop(handle)
637 :
638 134 : END SUBROUTINE deallocate_matrices_gw
639 :
640 : ! **************************************************************************************************
641 : !> \brief ...
642 : !> \param do_ic_model ...
643 : !> \param do_kpoints_cubic_RPA ...
644 : !> \param fm_mat_W ...
645 : !> \param t_3c_overl_int_ao_mo ...
646 : !> \param t_3c_O_mo_compressed ...
647 : !> \param t_3c_O_mo_ind ...
648 : !> \param t_3c_overl_int_gw_RI ...
649 : !> \param t_3c_overl_int_gw_AO ...
650 : !> \param t_3c_overl_nnP_ic ...
651 : !> \param t_3c_overl_nnP_ic_reflected ...
652 : !> \param mat_W ...
653 : !> \param qs_env ...
654 : ! **************************************************************************************************
655 46 : SUBROUTINE deallocate_matrices_gw_im_time(do_ic_model, do_kpoints_cubic_RPA, fm_mat_W, &
656 : t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
657 : t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
658 : t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, mat_W, &
659 : qs_env)
660 :
661 : LOGICAL, INTENT(IN) :: do_ic_model, do_kpoints_cubic_RPA
662 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
663 : INTENT(INOUT) :: fm_mat_W
664 : TYPE(dbt_type), INTENT(INOUT) :: t_3c_overl_int_ao_mo
665 : TYPE(hfx_compression_type), ALLOCATABLE, &
666 : DIMENSION(:) :: t_3c_O_mo_compressed
667 : TYPE(two_dim_int_array), ALLOCATABLE, DIMENSION(:) :: t_3c_O_mo_ind
668 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:), &
669 : INTENT(INOUT) :: t_3c_overl_int_gw_RI, &
670 : t_3c_overl_int_gw_AO, &
671 : t_3c_overl_nnP_ic, &
672 : t_3c_overl_nnP_ic_reflected
673 : TYPE(dbcsr_type), POINTER :: mat_W
674 : TYPE(qs_environment_type), POINTER :: qs_env
675 :
676 : CHARACTER(LEN=*), PARAMETER :: routineN = 'deallocate_matrices_gw_im_time'
677 :
678 : INTEGER :: handle, ispin, nspins, unused
679 : LOGICAL :: my_open_shell
680 :
681 46 : CALL timeset(routineN, handle)
682 :
683 46 : nspins = SIZE(t_3c_overl_int_gw_RI)
684 46 : my_open_shell = (nspins == 2)
685 :
686 46 : IF (.NOT. do_kpoints_cubic_RPA) THEN
687 46 : CALL cp_fm_release(fm_mat_W)
688 46 : CALL dbcsr_release_P(mat_W)
689 : END IF
690 :
691 100 : DO ispin = 1, nspins
692 54 : CALL dbt_destroy(t_3c_overl_int_gw_RI(ispin))
693 100 : CALL dbt_destroy(t_3c_overl_int_gw_AO(ispin))
694 : END DO
695 154 : DEALLOCATE (t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI)
696 46 : IF (do_ic_model) THEN
697 4 : DO ispin = 1, nspins
698 2 : CALL dbt_destroy(t_3c_overl_nnP_ic(ispin))
699 4 : CALL dbt_destroy(t_3c_overl_nnP_ic_reflected(ispin))
700 : END DO
701 6 : DEALLOCATE (t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected)
702 : END IF
703 :
704 46 : IF (.NOT. qs_env%mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
705 66 : DO ispin = 1, nspins
706 36 : DEALLOCATE (t_3c_O_mo_ind(ispin)%array)
707 66 : CALL dealloc_containers(t_3c_O_mo_compressed(ispin), unused)
708 : END DO
709 66 : DEALLOCATE (t_3c_O_mo_ind, t_3c_O_mo_compressed)
710 :
711 30 : CALL dbt_destroy(t_3c_overl_int_ao_mo)
712 : END IF
713 :
714 46 : IF (qs_env%mp2_env%ri_g0w0%do_kpoints_Sigma) THEN
715 34 : DO ispin = 1, nspins
716 18 : CALL dbcsr_release(qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix)
717 18 : DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc(ispin)%matrix)
718 :
719 18 : CALL dbcsr_release(qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix)
720 34 : DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_ks(ispin)%matrix)
721 : END DO
722 16 : DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_sigma_x_minus_vxc)
723 16 : DEALLOCATE (qs_env%mp2_env%ri_g0w0%matrix_ks)
724 : END IF
725 :
726 46 : CALL timestop(handle)
727 :
728 46 : END SUBROUTINE deallocate_matrices_gw_im_time
729 :
730 : ! **************************************************************************************************
731 : !> \brief ...
732 : !> \param vec_Sigma_c_gw ...
733 : !> \param dimen_nm_gw ...
734 : !> \param dimen_RI ...
735 : !> \param gw_corr_lev_occ ...
736 : !> \param gw_corr_lev_virt ...
737 : !> \param homo ...
738 : !> \param jquad ...
739 : !> \param nmo ...
740 : !> \param num_fit_points ...
741 : !> \param do_im_time ...
742 : !> \param do_periodic ...
743 : !> \param first_cycle_periodic_correction ...
744 : !> \param fermi_level_offset ...
745 : !> \param omega ...
746 : !> \param Eigenval ...
747 : !> \param delta_corr ...
748 : !> \param vec_omega_fit_gw ...
749 : !> \param vec_W_gw ...
750 : !> \param grid ...
751 : !> \param fm_mat_Q ...
752 : !> \param fm_mat_R_gw ...
753 : !> \param fm_mat_S_gw ...
754 : !> \param fm_mat_S_gw_work ...
755 : !> \param mo_coeff ...
756 : !> \param para_env ...
757 : !> \param para_env_RPA ...
758 : !> \param matrix_berry_im_mo_mo ...
759 : !> \param matrix_berry_re_mo_mo ...
760 : !> \param kpoints ...
761 : !> \param qs_env ...
762 : !> \param mp2_env ...
763 : ! **************************************************************************************************
764 45480 : SUBROUTINE compute_GW_self_energy(vec_Sigma_c_gw, dimen_nm_gw, dimen_RI, gw_corr_lev_occ, &
765 11370 : gw_corr_lev_virt, homo, jquad, nmo, num_fit_points, &
766 : do_im_time, do_periodic, &
767 : first_cycle_periodic_correction, fermi_level_offset, &
768 11370 : omega, Eigenval, delta_corr, vec_omega_fit_gw, vec_W_gw, grid, &
769 11370 : fm_mat_Q, fm_mat_R_gw, fm_mat_S_gw, &
770 11370 : fm_mat_S_gw_work, mo_coeff, para_env, &
771 : para_env_RPA, matrix_berry_im_mo_mo, matrix_berry_re_mo_mo, &
772 : kpoints, qs_env, mp2_env)
773 :
774 : COMPLEX(KIND=dp), ALLOCATABLE, &
775 : DIMENSION(:, :, :, :), INTENT(INOUT) :: vec_Sigma_c_gw
776 : INTEGER, INTENT(IN) :: dimen_nm_gw, dimen_RI
777 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, homo
778 : INTEGER, INTENT(IN) :: jquad, nmo, num_fit_points
779 : LOGICAL, INTENT(IN) :: do_im_time, do_periodic
780 : LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
781 : REAL(KIND=dp), INTENT(INOUT) :: fermi_level_offset, omega
782 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: Eigenval
783 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
784 : INTENT(INOUT) :: delta_corr
785 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
786 : INTENT(IN) :: vec_omega_fit_gw
787 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :), &
788 : INTENT(INOUT) :: vec_W_gw
789 : TYPE(time_frequency_grid_type), INTENT(IN) :: grid
790 : TYPE(cp_fm_type), INTENT(INOUT) :: fm_mat_Q
791 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_R_gw
792 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_S_gw, fm_mat_S_gw_work
793 : TYPE(cp_fm_type), INTENT(IN) :: mo_coeff
794 : TYPE(mp_para_env_type), POINTER :: para_env, para_env_RPA
795 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_im_mo_mo, &
796 : matrix_berry_re_mo_mo
797 : TYPE(kpoint_type), POINTER :: kpoints
798 : TYPE(qs_environment_type), POINTER :: qs_env
799 : TYPE(mp2_type) :: mp2_env
800 :
801 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_GW_self_energy'
802 :
803 : INTEGER :: handle, ispin, nspins
804 :
805 11370 : CALL timeset(routineN, handle)
806 :
807 11370 : nspins = SIZE(fm_mat_S_gw)
808 :
809 11370 : IF (.NOT. do_im_time) THEN
810 : ! Invert [1+Q(iw')], using fm_mat_R_gw as temporary workspace.
811 11370 : CALL cp_fm_cholesky_invert(fm_mat_Q, n=dimen_RI, work=fm_mat_R_gw)
812 :
813 : ! periodic correction for GW (paper Phys. Rev. B 95, 235123 (2017))
814 11370 : IF (do_periodic) THEN
815 : CALL calc_periodic_correction(delta_corr, qs_env, para_env, para_env_RPA, &
816 : mp2_env%ri_g0w0%kp_grid, homo(1), nmo, gw_corr_lev_occ(1), &
817 : gw_corr_lev_virt(1), omega, mo_coeff, Eigenval(:, 1), &
818 : matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
819 : first_cycle_periodic_correction, kpoints, &
820 : mp2_env%ri_g0w0%do_mo_coeff_gamma, &
821 : mp2_env%ri_g0w0%num_kp_grids, mp2_env%ri_g0w0%eps_kpoint, &
822 : mp2_env%ri_g0w0%do_extra_kpoints, &
823 240 : mp2_env%ri_g0w0%do_aux_bas_gw, mp2_env%ri_g0w0%frac_aux_mos)
824 : END IF
825 :
826 11370 : CALL para_env_RPA%sync()
827 :
828 : ! subtract 1 from the diagonal to get rid of exchange self-energy
829 11370 : CALL cp_fm_add_on_diag(fm_mat_Q, -1.0_dp, n_active=dimen_RI)
830 :
831 11370 : CALL para_env_RPA%sync()
832 :
833 23280 : DO ispin = 1, nspins
834 : CALL compute_GW_self_energy_deep(vec_Sigma_c_gw(:, :, :, ispin), dimen_nm_gw, dimen_RI, &
835 : gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), &
836 : homo(ispin), jquad, nmo, &
837 : num_fit_points, do_periodic, fermi_level_offset, omega, &
838 : Eigenval(:, ispin), delta_corr, &
839 : vec_omega_fit_gw, vec_W_gw(:, ispin), grid, fm_mat_Q, &
840 23280 : fm_mat_S_gw(ispin), fm_mat_S_gw_work(ispin))
841 : END DO
842 :
843 : END IF ! GW
844 :
845 11370 : CALL timestop(handle)
846 :
847 11370 : END SUBROUTINE compute_GW_self_energy
848 :
849 : ! **************************************************************************************************
850 : !> \brief ...
851 : !> \param fermi_level_offset ...
852 : !> \param fermi_level_offset_input ...
853 : !> \param Eigenval ...
854 : !> \param homo ...
855 : ! **************************************************************************************************
856 12188 : SUBROUTINE get_fermi_level_offset(fermi_level_offset, fermi_level_offset_input, Eigenval, homo)
857 :
858 : REAL(KIND=dp), INTENT(INOUT) :: fermi_level_offset
859 : REAL(KIND=dp), INTENT(IN) :: fermi_level_offset_input
860 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: Eigenval
861 : INTEGER, DIMENSION(:), INTENT(IN) :: homo
862 :
863 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_fermi_level_offset'
864 :
865 : INTEGER :: handle, ispin, nspins
866 :
867 12188 : CALL timeset(routineN, handle)
868 :
869 12188 : nspins = SIZE(Eigenval, 2)
870 :
871 : ! Fermi level offset should have a maximum such that the Fermi level of occupied orbitals
872 : ! is always closer to occupied orbitals than to virtual orbitals and vice versa
873 : ! that means, the Fermi level offset is at most as big as half the bandgap
874 12188 : fermi_level_offset = fermi_level_offset_input
875 25084 : DO ispin = 1, nspins
876 25084 : fermi_level_offset = MIN(fermi_level_offset, (Eigenval(homo(ispin) + 1, ispin) - Eigenval(homo(ispin), ispin))*0.5_dp)
877 : END DO
878 :
879 12188 : CALL timestop(handle)
880 :
881 12188 : END SUBROUTINE get_fermi_level_offset
882 :
883 : ! **************************************************************************************************
884 : !> \brief ...
885 : !> \param fm_mat_W ...
886 : !> \param fm_mat_Q upper Cholesky factor of epsilon from RPA, overwritten by the screened interaction
887 : !> \param fm_mat_work ...
888 : !> \param dimen_RI ...
889 : !> \param fm_mat_L ...
890 : !> \param grid ...
891 : !> \param jquad ...
892 : !> \param omega ...
893 : ! **************************************************************************************************
894 722 : SUBROUTINE compute_W_cubic_GW(fm_mat_W, fm_mat_Q, fm_mat_work, dimen_RI, fm_mat_L, &
895 : grid, jquad, omega)
896 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_W
897 : TYPE(cp_fm_type), INTENT(INOUT) :: fm_mat_Q
898 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_work
899 : INTEGER, INTENT(IN) :: dimen_RI
900 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_L
901 : TYPE(time_frequency_grid_type), INTENT(IN) :: grid
902 : INTEGER, INTENT(IN) :: jquad
903 : REAL(KIND=dp), INTENT(INOUT) :: omega
904 :
905 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_W_cubic_GW'
906 :
907 : INTEGER :: handle, iquad, num_integ_points
908 : REAL(KIND=dp) :: weight
909 :
910 722 : CALL timeset(routineN, handle)
911 :
912 722 : num_integ_points = SIZE(grid%imaginary_time)
913 :
914 : ! calculate [1+Q(iw')]^-1
915 722 : CALL cp_fm_cholesky_invert(fm_mat_Q, n=dimen_RI, work=fm_mat_work)
916 :
917 : ! subtract 1 from the diagonal to get rid of exchange self-energy
918 722 : CALL cp_fm_add_on_diag(fm_mat_Q, -1.0_dp, n_active=dimen_RI)
919 :
920 : ! multiply with L from the left and the right to get the screened Coulomb interaction
921 : CALL parallel_gemm('T', 'N', dimen_RI, dimen_RI, dimen_RI, 1.0_dp, fm_mat_L, fm_mat_Q, &
922 722 : 0.0_dp, fm_mat_work)
923 :
924 : CALL parallel_gemm('N', 'N', dimen_RI, dimen_RI, dimen_RI, 1.0_dp, fm_mat_work, fm_mat_L, &
925 722 : 0.0_dp, fm_mat_Q)
926 :
927 : ! Fourier transform from w to t
928 722 : omega = grid%frequency(jquad)
929 17528 : DO iquad = 1, num_integ_points
930 :
931 16806 : weight = grid%cosine_frequency_to_time(iquad, jquad)
932 :
933 16806 : IF (jquad == 1) THEN
934 :
935 722 : CALL cp_fm_set_all(matrix=fm_mat_W(iquad), alpha=0.0_dp)
936 :
937 : END IF
938 :
939 17528 : CALL cp_fm_scale_and_add(alpha=1.0_dp, matrix_a=fm_mat_W(iquad), beta=weight, matrix_b=fm_mat_Q)
940 :
941 : END DO
942 :
943 722 : CALL timestop(handle)
944 722 : END SUBROUTINE compute_W_cubic_GW
945 :
946 : ! **************************************************************************************************
947 : !> \brief ...
948 : !> \param vec_Sigma_c_gw ...
949 : !> \param dimen_nm_gw ...
950 : !> \param dimen_RI ...
951 : !> \param gw_corr_lev_occ ...
952 : !> \param gw_corr_lev_virt ...
953 : !> \param homo ...
954 : !> \param jquad ...
955 : !> \param nmo ...
956 : !> \param num_fit_points ...
957 : !> \param do_periodic ...
958 : !> \param fermi_level_offset ...
959 : !> \param omega ...
960 : !> \param Eigenval ...
961 : !> \param delta_corr ...
962 : !> \param vec_omega_fit_gw ...
963 : !> \param vec_W_gw ...
964 : !> \param grid ...
965 : !> \param fm_mat_Q ...
966 : !> \param fm_mat_S_gw ...
967 : !> \param fm_mat_S_gw_work ...
968 : ! **************************************************************************************************
969 47640 : SUBROUTINE compute_GW_self_energy_deep(vec_Sigma_c_gw, dimen_nm_gw, dimen_RI, &
970 : gw_corr_lev_occ, gw_corr_lev_virt, &
971 : homo, jquad, nmo, num_fit_points, &
972 23820 : do_periodic, fermi_level_offset, omega, Eigenval, &
973 23150 : delta_corr, vec_omega_fit_gw, vec_W_gw, &
974 : grid, fm_mat_Q, fm_mat_S_gw, fm_mat_S_gw_work)
975 :
976 : COMPLEX(KIND=dp), DIMENSION(:, :, :), &
977 : INTENT(INOUT) :: vec_Sigma_c_gw
978 : INTEGER, INTENT(IN) :: dimen_nm_gw, dimen_RI, gw_corr_lev_occ, &
979 : gw_corr_lev_virt, homo, jquad, nmo, &
980 : num_fit_points
981 : LOGICAL, INTENT(IN) :: do_periodic
982 : REAL(KIND=dp), INTENT(IN) :: fermi_level_offset
983 : REAL(KIND=dp), INTENT(INOUT) :: omega
984 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: Eigenval
985 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: delta_corr, vec_omega_fit_gw
986 : REAL(KIND=dp), DIMENSION(:), INTENT(OUT) :: vec_W_gw
987 : TYPE(time_frequency_grid_type), INTENT(IN) :: grid
988 : TYPE(cp_fm_type), INTENT(IN) :: fm_mat_Q, fm_mat_S_gw, fm_mat_S_gw_work
989 :
990 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_GW_self_energy_deep'
991 :
992 : INTEGER :: handle, iiB, iquad, m_global, n_global, &
993 : ncol_local, nm_global
994 11910 : INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
995 : REAL(KIND=dp) :: delta_corr_nn, e_fermi, omega_i, &
996 : sign_occ_virt
997 :
998 11910 : CALL timeset(routineN, handle)
999 :
1000 : ! S_work_(nm)Q = B_(nm)P * ([1+Q]^-1-1)_PQ
1001 : CALL parallel_gemm(transa="N", transb="N", m=dimen_RI, n=dimen_nm_gw, k=dimen_RI, alpha=1.0_dp, &
1002 : matrix_a=fm_mat_Q, matrix_b=fm_mat_S_gw, beta=0.0_dp, &
1003 11910 : matrix_c=fm_mat_S_gw_work)
1004 :
1005 : CALL cp_fm_get_info(matrix=fm_mat_S_gw, &
1006 : ncol_local=ncol_local, &
1007 : row_indices=row_indices, &
1008 11910 : col_indices=col_indices)
1009 :
1010 : ! vector W_(nm) = S_work_(nm)Q * [B_(nm)Q]^T
1011 :
1012 6594530 : vec_W_gw = 0.0_dp
1013 :
1014 6594530 : DO iiB = 1, ncol_local
1015 6582620 : nm_global = col_indices(iiB)
1016 : vec_W_gw(nm_global) = vec_W_gw(nm_global) + &
1017 367355880 : DOT_PRODUCT(fm_mat_S_gw_work%local_data(:, iiB), fm_mat_S_gw%local_data(:, iiB))
1018 :
1019 : ! transform the index nm of vec_W_gw back to n and m, formulae copied from Mauro's code
1020 6582620 : n_global = MAX(1, nm_global - 1)/nmo + 1
1021 6582620 : m_global = nm_global - (n_global - 1)*nmo
1022 6582620 : n_global = n_global + homo - gw_corr_lev_occ
1023 :
1024 : ! compute self-energy for imaginary frequencies
1025 418052110 : DO iquad = 1, num_fit_points
1026 :
1027 : ! for occ orbitals, we compute the self-energy for negative frequencies
1028 411457580 : IF (n_global <= homo) THEN
1029 : sign_occ_virt = -1.0_dp
1030 : ELSE
1031 320975740 : sign_occ_virt = 1.0_dp
1032 : END IF
1033 :
1034 411457580 : omega_i = vec_omega_fit_gw(iquad)*sign_occ_virt
1035 :
1036 : ! set the Fermi energy for occ orbitals slightly above the HOMO and
1037 : ! for virt orbitals slightly below the LUMO
1038 411457580 : IF (n_global <= homo) THEN
1039 487157960 : e_fermi = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo)) + fermi_level_offset
1040 : ELSE
1041 7323644220 : e_fermi = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_virt)) - fermi_level_offset
1042 : END IF
1043 :
1044 : ! add here the periodic correction
1045 411457580 : IF (do_periodic .AND. row_indices(1) == 1 .AND. n_global == m_global) THEN
1046 57120 : delta_corr_nn = delta_corr(n_global)
1047 : ELSE
1048 : delta_corr_nn = 0.0_dp
1049 : END IF
1050 :
1051 : ! update the self-energy (use that vec_W_gw(iw) is symmetric), divide the integration
1052 : ! weight by 2, because the integration is from -infty to +infty and not just 0 to +infty
1053 : ! as for RPA, also we need for virtual orbitals a complex conjugate
1054 : vec_Sigma_c_gw(n_global - homo + gw_corr_lev_occ, iquad, 1) = &
1055 : vec_Sigma_c_gw(n_global - homo + gw_corr_lev_occ, iquad, 1) - &
1056 : 0.5_dp/pi*grid%frequency_weights(jquad)/2.0_dp*(vec_W_gw(nm_global) + delta_corr_nn)* &
1057 : (1.0_dp/(gaussi*(omega + omega_i) + e_fermi - Eigenval(m_global)) + &
1058 418040200 : 1.0_dp/(gaussi*(-omega + omega_i) + e_fermi - Eigenval(m_global)))
1059 : END DO
1060 :
1061 : END DO
1062 :
1063 11910 : CALL timestop(handle)
1064 :
1065 11910 : END SUBROUTINE compute_GW_self_energy_deep
1066 :
1067 : ! **************************************************************************************************
1068 : !> \brief ...
1069 : !> \param vec_Sigma_c_gw ...
1070 : !> \param count_ev_sc_GW ...
1071 : !> \param gw_corr_lev_occ ...
1072 : !> \param gw_corr_lev_tot ...
1073 : !> \param gw_corr_lev_virt ...
1074 : !> \param homo ...
1075 : !> \param nmo ...
1076 : !> \param num_fit_points ...
1077 : !> \param unit_nr ...
1078 : !> \param do_apply_ic_corr_to_gw ...
1079 : !> \param do_im_time ...
1080 : !> \param do_periodic ...
1081 : !> \param do_ri_Sigma_x ...
1082 : !> \param first_cycle_periodic_correction ...
1083 : !> \param e_fermi ...
1084 : !> \param eps_filter ...
1085 : !> \param fermi_level_offset ...
1086 : !> \param delta_corr ...
1087 : !> \param Eigenval ...
1088 : !> \param Eigenval_last ...
1089 : !> \param Eigenval_scf ...
1090 : !> \param iter_sc_GW0 ...
1091 : !> \param exit_ev_gw ...
1092 : !> \param grid ...
1093 : !> \param vec_omega_fit_gw ...
1094 : !> \param vec_Sigma_x_gw ...
1095 : !> \param ic_corr_list ...
1096 : !> \param mo_coeff ...
1097 : !> \param fm_mat_W ...
1098 : !> \param para_env ...
1099 : !> \param para_env_RPA ...
1100 : !> \param mat_dm ...
1101 : !> \param mat_MinvVMinv ...
1102 : !> \param t_3c_O ...
1103 : !> \param t_3c_M ...
1104 : !> \param t_3c_overl_int_ao_mo ...
1105 : !> \param t_3c_O_compressed ...
1106 : !> \param t_3c_O_mo_compressed ...
1107 : !> \param t_3c_O_ind ...
1108 : !> \param t_3c_O_mo_ind ...
1109 : !> \param t_3c_overl_int_gw_RI ...
1110 : !> \param t_3c_overl_int_gw_AO ...
1111 : !> \param matrix_berry_im_mo_mo ...
1112 : !> \param matrix_berry_re_mo_mo ...
1113 : !> \param mat_W ...
1114 : !> \param matrix_s ...
1115 : !> \param kpoints ...
1116 : !> \param mp2_env ...
1117 : !> \param qs_env ...
1118 : !> \param nkp_self_energy ...
1119 : !> \param do_kpoints_cubic_RPA ...
1120 : !> \param starts_array_mc ...
1121 : !> \param ends_array_mc ...
1122 : ! **************************************************************************************************
1123 1270 : SUBROUTINE compute_QP_energies(vec_Sigma_c_gw, count_ev_sc_GW, gw_corr_lev_occ, &
1124 508 : gw_corr_lev_tot, gw_corr_lev_virt, homo, &
1125 : nmo, num_fit_points, &
1126 : unit_nr, do_apply_ic_corr_to_gw, do_im_time, &
1127 : do_periodic, do_ri_Sigma_x, &
1128 254 : first_cycle_periodic_correction, e_fermi, eps_filter, &
1129 254 : fermi_level_offset, delta_corr, Eigenval, &
1130 : Eigenval_last, Eigenval_scf, iter_sc_GW0, exit_ev_gw, grid, &
1131 : vec_omega_fit_gw, vec_Sigma_x_gw, ic_corr_list, &
1132 254 : mo_coeff, fm_mat_W, &
1133 : para_env, para_env_RPA, mat_dm, mat_MinvVMinv, &
1134 : t_3c_O, t_3c_M, t_3c_overl_int_ao_mo, &
1135 254 : t_3c_O_compressed, t_3c_O_mo_compressed, &
1136 254 : t_3c_O_ind, t_3c_O_mo_ind, &
1137 374 : t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, matrix_berry_im_mo_mo, &
1138 : matrix_berry_re_mo_mo, mat_W, matrix_s, &
1139 : kpoints, mp2_env, qs_env, nkp_self_energy, do_kpoints_cubic_RPA, &
1140 258 : starts_array_mc, ends_array_mc)
1141 :
1142 : COMPLEX(KIND=dp), DIMENSION(:, :, :, :), &
1143 : INTENT(OUT) :: vec_Sigma_c_gw
1144 : INTEGER, INTENT(IN) :: count_ev_sc_GW
1145 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ
1146 : INTEGER, INTENT(IN) :: gw_corr_lev_tot
1147 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_virt, homo
1148 : INTEGER, INTENT(IN) :: nmo, num_fit_points, unit_nr
1149 : LOGICAL, INTENT(IN) :: do_apply_ic_corr_to_gw, do_im_time, &
1150 : do_periodic, do_ri_Sigma_x
1151 : LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
1152 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: e_fermi
1153 : REAL(KIND=dp), INTENT(IN) :: eps_filter, fermi_level_offset
1154 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
1155 : INTENT(INOUT) :: delta_corr
1156 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT) :: Eigenval
1157 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
1158 : INTENT(INOUT) :: Eigenval_last, Eigenval_scf
1159 : INTEGER, INTENT(IN) :: iter_sc_GW0
1160 : LOGICAL, INTENT(INOUT) :: exit_ev_gw
1161 : TYPE(time_frequency_grid_type), INTENT(IN) :: grid
1162 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
1163 : INTENT(INOUT) :: vec_omega_fit_gw
1164 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
1165 : INTENT(INOUT) :: vec_Sigma_x_gw
1166 : TYPE(one_dim_real_array), DIMENSION(2), INTENT(IN) :: ic_corr_list
1167 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
1168 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:), &
1169 : INTENT(IN) :: fm_mat_W
1170 : TYPE(mp_para_env_type), POINTER :: para_env, para_env_RPA
1171 : TYPE(dbcsr_p_type), INTENT(IN) :: mat_dm, mat_MinvVMinv
1172 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_O
1173 : TYPE(dbt_type) :: t_3c_M, t_3c_overl_int_ao_mo
1174 : TYPE(hfx_compression_type), ALLOCATABLE, &
1175 : DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_O_compressed
1176 : TYPE(hfx_compression_type), DIMENSION(:) :: t_3c_O_mo_compressed
1177 : TYPE(block_ind_type), ALLOCATABLE, &
1178 : DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_O_ind
1179 : TYPE(two_dim_int_array), DIMENSION(:) :: t_3c_O_mo_ind
1180 : TYPE(dbt_type), DIMENSION(:) :: t_3c_overl_int_gw_RI, &
1181 : t_3c_overl_int_gw_AO
1182 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_im_mo_mo, &
1183 : matrix_berry_re_mo_mo
1184 : TYPE(dbcsr_type), POINTER :: mat_W
1185 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s
1186 : TYPE(kpoint_type), POINTER :: kpoints
1187 : TYPE(mp2_type) :: mp2_env
1188 : TYPE(qs_environment_type), POINTER :: qs_env
1189 : INTEGER, INTENT(IN) :: nkp_self_energy
1190 : LOGICAL, INTENT(IN) :: do_kpoints_cubic_RPA
1191 : INTEGER, DIMENSION(:), INTENT(IN) :: starts_array_mc, ends_array_mc
1192 :
1193 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_QP_energies'
1194 :
1195 : INTEGER :: count_ev_sc_GW_print, count_sc_GW0, count_sc_GW0_print, crossing_search, handle, &
1196 : idos, ikp, ispin, iunit, n_level_gw, ndos, nspins, num_points_corr, num_poles
1197 : LOGICAL :: do_kpoints_Sigma, my_open_shell
1198 : REAL(KIND=dp) :: dos_lower_bound, dos_precision, dos_upper_bound, E_CBM_GW, E_CBM_GW_beta, &
1199 : E_CBM_SCF, E_CBM_SCF_beta, E_VBM_GW, E_VBM_GW_beta, E_VBM_SCF, E_VBM_SCF_beta, stop_crit
1200 254 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: vec_gw_dos
1201 254 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: m_value, vec_gw_energ, z_value
1202 : TYPE(cp_logger_type), POINTER :: logger
1203 : TYPE(kpoint_type), POINTER :: kpoints_Sigma
1204 :
1205 254 : CALL timeset(routineN, handle)
1206 :
1207 254 : nspins = SIZE(homo)
1208 254 : my_open_shell = (nspins == 2)
1209 :
1210 254 : do_kpoints_Sigma = mp2_env%ri_g0w0%do_kpoints_Sigma
1211 :
1212 322 : DO count_sc_GW0 = 1, iter_sc_GW0
1213 :
1214 : ! postprocessing for cubic scaling GW calculation
1215 268 : IF (do_im_time .AND. .NOT. do_kpoints_cubic_RPA .AND. .NOT. do_kpoints_Sigma) THEN
1216 56 : num_points_corr = mp2_env%ri_g0w0%num_omega_points
1217 :
1218 118 : DO ispin = 1, nspins
1219 : CALL compute_self_energy_cubic_gw(nmo, grid, &
1220 : matrix_s, Eigenval(:, 1, ispin), eps_filter, &
1221 : e_fermi(ispin), fm_mat_W, &
1222 : gw_corr_lev_tot, gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), homo(ispin), &
1223 : count_ev_sc_GW, count_sc_GW0, &
1224 : t_3c_overl_int_ao_mo, t_3c_O_mo_compressed(ispin), &
1225 : t_3c_O_mo_ind(ispin)%array, &
1226 : t_3c_overl_int_gw_RI(ispin), t_3c_overl_int_gw_AO(ispin), &
1227 : mat_W, mat_MinvVMinv, mat_dm, &
1228 : vec_Sigma_c_gw(:, :, :, ispin), &
1229 : do_periodic, num_points_corr, delta_corr, qs_env, para_env, para_env_RPA, &
1230 : mp2_env, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
1231 : first_cycle_periodic_correction, kpoints, num_fit_points, mo_coeff(ispin), &
1232 118 : do_ri_Sigma_x, vec_Sigma_x_gw(:, :, ispin), unit_nr, ispin)
1233 : END DO
1234 :
1235 : END IF
1236 :
1237 252 : IF (do_kpoints_Sigma) THEN
1238 : CALL compute_self_energy_cubic_gw_kpoints(grid, &
1239 : matrix_s, Eigenval(:, :, :), e_fermi, fm_mat_W, &
1240 : gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, &
1241 : count_ev_sc_GW, count_sc_GW0, &
1242 : t_3c_O, t_3c_M, t_3c_O_compressed, t_3c_O_ind, &
1243 : mat_W, mat_MinvVMinv, &
1244 : vec_Sigma_c_gw(:, :, :, :), &
1245 : qs_env, para_env, &
1246 : mp2_env, mo_coeff(1), &
1247 : do_ri_Sigma_x, vec_Sigma_x_gw(:, :, :), unit_nr, nspins, &
1248 16 : starts_array_mc, ends_array_mc, eps_filter)
1249 :
1250 : END IF
1251 :
1252 268 : IF (do_periodic .AND. mp2_env%ri_g0w0%do_average_deg_levels) THEN
1253 :
1254 20 : DO ispin = 1, nspins
1255 : CALL average_degenerate_levels(vec_Sigma_c_gw(:, :, :, ispin), &
1256 : Eigenval(1 + homo(ispin) - gw_corr_lev_occ(ispin): &
1257 : homo(ispin) + gw_corr_lev_virt(ispin), 1, ispin), &
1258 20 : mp2_env%ri_g0w0%eps_eigenval)
1259 : END DO
1260 : END IF
1261 :
1262 268 : IF (.NOT. do_im_time) THEN
1263 402048 : CALL para_env%sum(vec_Sigma_c_gw)
1264 : END IF
1265 :
1266 268 : CALL para_env%sync()
1267 :
1268 268 : stop_crit = 1.0e-7_dp
1269 268 : num_poles = mp2_env%ri_g0w0%num_poles
1270 268 : crossing_search = mp2_env%ri_g0w0%crossing_search
1271 :
1272 : ! arrays storing the correlation self-energy, stat. error and z-shot value
1273 1340 : ALLOCATE (vec_gw_energ(gw_corr_lev_tot, nkp_self_energy, nspins))
1274 268 : vec_gw_energ = 0.0_dp
1275 1072 : ALLOCATE (z_value(gw_corr_lev_tot, nkp_self_energy, nspins))
1276 268 : z_value = 0.0_dp
1277 1072 : ALLOCATE (m_value(gw_corr_lev_tot, nkp_self_energy, nspins))
1278 268 : m_value = 0.0_dp
1279 268 : E_VBM_GW = -1.0E3_dp
1280 268 : E_CBM_GW = 1.0E3_dp
1281 268 : E_VBM_SCF = -1.0E3_dp
1282 268 : E_CBM_SCF = 1.0E3_dp
1283 268 : E_VBM_GW_beta = -1.0E3_dp
1284 268 : E_CBM_GW_beta = 1.0E3_dp
1285 268 : E_VBM_SCF_beta = -1.0E3_dp
1286 268 : E_CBM_SCF_beta = 1.0E3_dp
1287 :
1288 268 : ndos = 0
1289 268 : dos_precision = mp2_env%ri_g0w0%dos_prec
1290 268 : dos_upper_bound = mp2_env%ri_g0w0%dos_upper
1291 268 : dos_lower_bound = mp2_env%ri_g0w0%dos_lower
1292 :
1293 268 : IF (dos_lower_bound >= dos_upper_bound) THEN
1294 0 : CALL cp_abort(__LOCATION__, "Invalid settings for GW_DOS calculation!")
1295 : END IF
1296 :
1297 268 : IF (dos_precision /= 0) THEN
1298 0 : ndos = INT((dos_upper_bound - dos_lower_bound)/dos_precision)
1299 0 : ALLOCATE (vec_gw_dos(ndos))
1300 0 : vec_gw_dos = 0.0_dp
1301 : END IF
1302 :
1303 : ! for the normal code for molecules or Gamma only: nkp = 1
1304 640 : DO ikp = 1, nkp_self_energy
1305 :
1306 372 : kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
1307 :
1308 : ! fit the self-energy on imaginary frequency axis and evaluate the fit on the MO energy of the SCF
1309 4372 : DO n_level_gw = 1, gw_corr_lev_tot
1310 : ! processes perform different fits
1311 4000 : IF (MODULO(n_level_gw, para_env%num_pe) /= para_env%mepos) CYCLE
1312 :
1313 2442 : SELECT CASE (mp2_env%ri_g0w0%analytic_continuation)
1314 : CASE (gw_two_pole_model)
1315 : CALL fit_and_continuation_2pole(vec_gw_energ(:, ikp, 1), vec_omega_fit_gw, &
1316 : z_value(:, ikp, 1), m_value(:, ikp, 1), vec_Sigma_c_gw(:, :, ikp, 1), &
1317 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
1318 : Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), n_level_gw, &
1319 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), num_poles, &
1320 : num_fit_points, crossing_search, homo(1), stop_crit, &
1321 442 : fermi_level_offset, do_im_time)
1322 :
1323 : CASE (gw_pade_approx)
1324 : CALL continuation_pade(vec_gw_energ(:, ikp, 1), vec_omega_fit_gw, &
1325 : z_value(:, ikp, 1), m_value(:, ikp, 1), vec_Sigma_c_gw(:, :, ikp, 1), &
1326 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
1327 : Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), &
1328 : mp2_env%ri_g0w0%do_hedin_shift, n_level_gw, &
1329 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), mp2_env%ri_g0w0%nparam_pade, &
1330 : num_fit_points, crossing_search, homo(1), fermi_level_offset, &
1331 : do_im_time, mp2_env%ri_g0w0%print_self_energy, count_ev_sc_GW, &
1332 : vec_gw_dos, dos_lower_bound, dos_precision, ndos, &
1333 : mp2_env%ri_g0w0%min_level_self_energy, &
1334 : mp2_env%ri_g0w0%max_level_self_energy, mp2_env%ri_g0w0%dos_eta, &
1335 1558 : mp2_env%ri_g0w0%dos_min, mp2_env%ri_g0w0%dos_max)
1336 : CASE DEFAULT
1337 2000 : CPABORT("Only two-model and Pade approximation are implemented.")
1338 : END SELECT
1339 :
1340 2372 : IF (my_open_shell) THEN
1341 535 : SELECT CASE (mp2_env%ri_g0w0%analytic_continuation)
1342 : CASE (gw_two_pole_model)
1343 : CALL fit_and_continuation_2pole( &
1344 : vec_gw_energ(:, ikp, 2), vec_omega_fit_gw, &
1345 : z_value(:, ikp, 2), m_value(:, ikp, 2), vec_Sigma_c_gw(:, :, ikp, 2), &
1346 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, ikp), &
1347 : Eigenval(:, ikp, 2), Eigenval_scf(:, ikp, 2), n_level_gw, &
1348 : gw_corr_lev_occ(2), gw_corr_lev_virt(2), num_poles, &
1349 : num_fit_points, crossing_search, homo(2), stop_crit, &
1350 126 : fermi_level_offset, do_im_time)
1351 : CASE (gw_pade_approx)
1352 : CALL continuation_pade(vec_gw_energ(:, ikp, 2), vec_omega_fit_gw, &
1353 : z_value(:, ikp, 2), m_value(:, ikp, 2), vec_Sigma_c_gw(:, :, ikp, 2), &
1354 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, ikp), &
1355 : Eigenval(:, ikp, 2), Eigenval_scf(:, ikp, 2), &
1356 : mp2_env%ri_g0w0%do_hedin_shift, n_level_gw, &
1357 : gw_corr_lev_occ(2), gw_corr_lev_virt(2), mp2_env%ri_g0w0%nparam_pade, &
1358 : num_fit_points, crossing_search, homo(2), &
1359 : fermi_level_offset, do_im_time, &
1360 : mp2_env%ri_g0w0%print_self_energy, count_ev_sc_GW, &
1361 : vec_gw_dos, dos_lower_bound, dos_precision, ndos, &
1362 : mp2_env%ri_g0w0%min_level_self_energy, &
1363 : mp2_env%ri_g0w0%max_level_self_energy, mp2_env%ri_g0w0%dos_eta, &
1364 283 : mp2_env%ri_g0w0%dos_min, mp2_env%ri_g0w0%dos_max)
1365 : CASE DEFAULT
1366 409 : CPABORT("Only two-pole model and Pade approximation are implemented.")
1367 : END SELECT
1368 :
1369 : END IF
1370 :
1371 : END DO ! n_level_gw
1372 :
1373 372 : CALL para_env%sum(vec_gw_energ)
1374 372 : CALL para_env%sum(z_value)
1375 372 : CALL para_env%sum(m_value)
1376 :
1377 372 : IF (dos_precision /= 0.0_dp) THEN
1378 0 : CALL para_env%sum(vec_gw_dos)
1379 : END IF
1380 :
1381 372 : CALL check_NaN(vec_gw_energ, 0.0_dp)
1382 372 : CALL check_NaN(z_value, 1.0_dp)
1383 372 : CALL check_NaN(m_value, 0.0_dp)
1384 :
1385 372 : IF (do_im_time .OR. mp2_env%ri_g0w0%iter_sc_GW0 == 1) THEN
1386 298 : count_ev_sc_GW_print = count_ev_sc_GW
1387 298 : count_sc_GW0_print = count_sc_GW0
1388 : ELSE
1389 74 : count_ev_sc_GW_print = count_sc_GW0
1390 74 : count_sc_GW0_print = count_ev_sc_GW
1391 : END IF
1392 :
1393 : ! print the quasiparticle energies and update Eigenval in case you do eigenvalue self-consistent GW
1394 640 : IF (my_open_shell) THEN
1395 :
1396 : CALL print_and_update_for_ev_sc( &
1397 : vec_gw_energ(:, ikp, 1), &
1398 : z_value(:, ikp, 1), m_value(:, ikp, 1), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
1399 : Eigenval(:, ikp, 1), Eigenval_last(:, ikp, 1), Eigenval_scf(:, ikp, 1), &
1400 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
1401 : crossing_search, homo(1), unit_nr, count_ev_sc_GW_print, count_sc_GW0_print, &
1402 46 : ikp, nkp_self_energy, kpoints_Sigma, 1, E_VBM_GW, E_CBM_GW, E_VBM_SCF, E_CBM_SCF)
1403 :
1404 : CALL print_and_update_for_ev_sc( &
1405 : vec_gw_energ(:, ikp, 2), &
1406 : z_value(:, ikp, 2), m_value(:, ikp, 2), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 2, ikp), &
1407 : Eigenval(:, ikp, 2), Eigenval_last(:, ikp, 2), Eigenval_scf(:, ikp, 2), &
1408 : gw_corr_lev_occ(2), gw_corr_lev_virt(2), gw_corr_lev_tot, &
1409 : crossing_search, homo(2), unit_nr, count_ev_sc_GW_print, count_sc_GW0_print, &
1410 46 : ikp, nkp_self_energy, kpoints_Sigma, 2, E_VBM_GW_beta, E_CBM_GW_beta, E_VBM_SCF_beta, E_CBM_SCF_beta)
1411 :
1412 46 : IF (do_apply_ic_corr_to_gw .AND. count_ev_sc_GW == 1) THEN
1413 :
1414 : CALL apply_ic_corr(Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), ic_corr_list(1)%array, &
1415 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
1416 0 : homo(1), nmo, unit_nr, do_alpha=.TRUE.)
1417 :
1418 : CALL apply_ic_corr(Eigenval(:, ikp, 2), Eigenval_scf(:, ikp, 2), ic_corr_list(2)%array, &
1419 : gw_corr_lev_occ(2), gw_corr_lev_virt(2), gw_corr_lev_tot, &
1420 0 : homo(2), nmo, unit_nr, do_beta=.TRUE.)
1421 :
1422 : END IF
1423 :
1424 : ELSE
1425 :
1426 : CALL print_and_update_for_ev_sc( &
1427 : vec_gw_energ(:, ikp, 1), &
1428 : z_value(:, ikp, 1), m_value(:, ikp, 1), mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, 1, ikp), &
1429 : Eigenval(:, ikp, 1), Eigenval_last(:, ikp, 1), Eigenval_scf(:, ikp, 1), &
1430 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
1431 : crossing_search, homo(1), unit_nr, count_ev_sc_GW_print, count_sc_GW0_print, &
1432 326 : ikp, nkp_self_energy, kpoints_Sigma, 0, E_VBM_GW, E_CBM_GW, E_VBM_SCF, E_CBM_SCF)
1433 :
1434 326 : IF (do_apply_ic_corr_to_gw .AND. count_ev_sc_GW == 1) THEN
1435 :
1436 : CALL apply_ic_corr(Eigenval(:, ikp, 1), Eigenval_scf(:, ikp, 1), ic_corr_list(1)%array, &
1437 : gw_corr_lev_occ(1), gw_corr_lev_virt(1), gw_corr_lev_tot, &
1438 0 : homo(1), nmo, unit_nr)
1439 :
1440 : END IF
1441 :
1442 : END IF
1443 :
1444 : END DO ! ikp
1445 :
1446 268 : IF (nkp_self_energy > 1 .AND. unit_nr > 0) THEN
1447 :
1448 : CALL print_gaps(E_VBM_SCF, E_CBM_SCF, E_VBM_SCF_beta, E_CBM_SCF_beta, &
1449 8 : E_VBM_GW, E_CBM_GW, E_VBM_GW_beta, E_CBM_GW_beta, my_open_shell, unit_nr)
1450 :
1451 : END IF
1452 :
1453 : ! Decide whether to add spin-orbit splitting of bands, spin-orbit coupling strength comes from
1454 : ! Hartwigsen parametrization (1999) of GTH pseudopotentials
1455 268 : IF (mp2_env%ri_g0w0%soc_type /= soc_none) THEN
1456 : CALL calculate_and_print_soc(qs_env, Eigenval_scf, Eigenval_scf, gw_corr_lev_occ, gw_corr_lev_virt, &
1457 2 : homo, unit_nr, do_soc_gw=.FALSE., do_soc_scf=.TRUE.)
1458 : CALL calculate_and_print_soc(qs_env, Eigenval, Eigenval_scf, gw_corr_lev_occ, gw_corr_lev_virt, &
1459 2 : homo, unit_nr, do_soc_gw=.TRUE., do_soc_scf=.FALSE.)
1460 : END IF
1461 :
1462 268 : logger => cp_get_default_logger()
1463 268 : IF (logger%para_env%is_source()) THEN
1464 265 : iunit = cp_logger_get_default_unit_nr()
1465 : ELSE
1466 3 : iunit = -1
1467 : END IF
1468 :
1469 268 : IF (dos_precision /= 0.0_dp) THEN
1470 0 : IF (iunit > 0) THEN
1471 0 : CALL open_file('spectral.dat', unit_number=iunit, file_status="UNKNOWN", file_action="WRITE")
1472 0 : DO idos = 1, ndos
1473 : ! 1/pi
1474 : ! [1/Hartree] -> [1/evolt]
1475 0 : WRITE (iunit, '(E17.10, E17.10)') (dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision)*evolt, &
1476 0 : vec_gw_dos(idos)/evolt/pi
1477 : END DO
1478 0 : CALL close_file(iunit)
1479 : END IF
1480 0 : DEALLOCATE (vec_gw_dos)
1481 : END IF
1482 :
1483 268 : DEALLOCATE (z_value)
1484 268 : DEALLOCATE (m_value)
1485 268 : DEALLOCATE (vec_gw_energ)
1486 :
1487 268 : exit_ev_gw = .FALSE.
1488 :
1489 : ! if HOMO-LUMO gap differs by less than mp2_env%ri_g0w0%eps_sc_iter, exit ev sc GW loop
1490 268 : IF (ABS(Eigenval(homo(1), 1, 1) - Eigenval_last(homo(1), 1, 1) - &
1491 : Eigenval(homo(1) + 1, 1, 1) + Eigenval_last(homo(1) + 1, 1, 1)) &
1492 : < mp2_env%ri_g0w0%eps_iter) THEN
1493 22 : IF (count_sc_GW0 == 1) exit_ev_gw = .TRUE.
1494 : EXIT
1495 : END IF
1496 :
1497 524 : DO ispin = 1, nspins
1498 : CALL shift_unshifted_levels(Eigenval(:, 1, ispin), Eigenval_last(:, 1, ispin), gw_corr_lev_occ(ispin), &
1499 524 : gw_corr_lev_virt(ispin), homo(ispin), nmo)
1500 : END DO
1501 :
1502 246 : IF (do_im_time .AND. do_kpoints_Sigma .AND. mp2_env%ri_g0w0%print_local_bandgap) THEN
1503 2 : CALL print_local_bandgap(qs_env, Eigenval, gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), "GW")
1504 2 : CALL print_local_bandgap(qs_env, Eigenval_scf, gw_corr_lev_occ(1), gw_corr_lev_virt(1), homo(1), "DFT")
1505 : END IF
1506 :
1507 : ! in case of N^4 scaling GW, the scGW0 cycle is the eigenvalue sc cycle
1508 300 : IF (.NOT. do_im_time) EXIT
1509 :
1510 : END DO ! scGW0
1511 :
1512 254 : CALL timestop(handle)
1513 :
1514 254 : END SUBROUTINE compute_QP_energies
1515 :
1516 : ! **************************************************************************************************
1517 : !> \brief ...
1518 : !> \param qs_env ...
1519 : !> \param Eigenval ...
1520 : !> \param Eigenval_scf ...
1521 : !> \param gw_corr_lev_occ ...
1522 : !> \param gw_corr_lev_virt ...
1523 : !> \param homo ...
1524 : !> \param unit_nr ...
1525 : !> \param do_soc_gw ...
1526 : !> \param do_soc_scf ...
1527 : ! **************************************************************************************************
1528 4 : SUBROUTINE calculate_and_print_soc(qs_env, Eigenval, Eigenval_scf, gw_corr_lev_occ, gw_corr_lev_virt, &
1529 4 : homo, unit_nr, do_soc_gw, do_soc_scf)
1530 : TYPE(qs_environment_type), POINTER :: qs_env
1531 : REAL(KIND=dp), DIMENSION(:, :, :) :: Eigenval, Eigenval_scf
1532 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, homo
1533 : INTEGER :: unit_nr
1534 : LOGICAL :: do_soc_gw, do_soc_scf
1535 :
1536 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_and_print_soc'
1537 :
1538 : INTEGER :: handle, i_dim, i_glob, i_row, ikp, j_col, j_glob, n_level_gw, nao, ncol_local, &
1539 : nder, nkind, nkp_self_energy, nrow_local, periodic(3), size_real_space
1540 4 : INTEGER, ALLOCATABLE, DIMENSION(:) :: index0
1541 4 : INTEGER, DIMENSION(:), POINTER :: col_indices, row_indices
1542 : LOGICAL :: calculate_forces, use_virial
1543 : REAL(KIND=dp) :: avg_occ_QP_shift, avg_virt_QP_shift, E_CBM_GW_SOC, E_GAP_GW_SOC, E_HOMO, &
1544 : E_HOMO_GW_SOC, E_i, E_j, E_LUMO, E_LUMO_GW_SOC, E_VBM_GW_SOC, E_window, eps_ppnl
1545 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eigenvalues_without_soc_sorted
1546 4 : REAL(KIND=dp), DIMENSION(:), POINTER :: eigenvalues
1547 4 : TYPE(atomic_kind_type), DIMENSION(:), POINTER :: atomic_kind_set
1548 : TYPE(cell_type), POINTER :: cell
1549 : TYPE(cp_cfm_type) :: cfm_mat_h_double, cfm_mat_h_ks, &
1550 : cfm_mat_s_double, cfm_mat_work_double, &
1551 : cfm_mo_coeff, cfm_mo_coeff_double
1552 : TYPE(cp_cfm_type), POINTER :: cmos
1553 4 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, matrix_s_desymm
1554 4 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_VSOC_l_nosymm, mat_VSOC_lx_kp, &
1555 4 : mat_VSOC_ly_kp, mat_VSOC_lz_kp, &
1556 4 : matrix_dummy, matrix_l, &
1557 4 : matrix_pot_dummy
1558 : TYPE(dft_control_type), POINTER :: dft_control
1559 : TYPE(kpoint_type), POINTER :: kpoints_Sigma
1560 : TYPE(mp_para_env_type), POINTER :: para_env
1561 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
1562 4 : POINTER :: sab_orb, sap_ppnl
1563 4 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
1564 4 : TYPE(qs_force_type), DIMENSION(:), POINTER :: force
1565 4 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
1566 : TYPE(scf_control_type), POINTER :: scf_control
1567 : TYPE(virial_type), POINTER :: virial
1568 :
1569 4 : CALL timeset(routineN, handle)
1570 :
1571 4 : CPASSERT(do_soc_gw .NEQV. do_soc_scf)
1572 :
1573 : CALL get_qs_env(qs_env=qs_env, &
1574 : matrix_s=matrix_s, &
1575 : para_env=para_env, &
1576 : qs_kind_set=qs_kind_set, &
1577 : sab_orb=sab_orb, &
1578 : atomic_kind_set=atomic_kind_set, &
1579 : particle_set=particle_set, &
1580 : sap_ppnl=sap_ppnl, &
1581 : dft_control=dft_control, &
1582 : cell=cell, &
1583 : nkind=nkind, &
1584 4 : scf_control=scf_control)
1585 :
1586 4 : calculate_forces = .FALSE.
1587 4 : use_virial = .FALSE.
1588 4 : nder = 0
1589 4 : eps_ppnl = dft_control%qs_control%eps_ppnl
1590 :
1591 4 : CALL get_cell(cell=cell, periodic=periodic)
1592 :
1593 4 : size_real_space = 3**(periodic(1) + periodic(2) + periodic(3))
1594 :
1595 4 : NULLIFY (matrix_l)
1596 4 : CALL dbcsr_allocate_matrix_set(matrix_l, 3, 1)
1597 16 : DO i_dim = 1, 3
1598 12 : ALLOCATE (matrix_l(i_dim, 1)%matrix)
1599 : CALL dbcsr_create(matrix_l(i_dim, 1)%matrix, template=matrix_s(1)%matrix, &
1600 12 : matrix_type=dbcsr_type_antisymmetric)
1601 12 : CALL cp_dbcsr_alloc_block_from_nbl(matrix_l(i_dim, 1)%matrix, sab_orb)
1602 16 : CALL dbcsr_set(matrix_l(i_dim, 1)%matrix, 0.0_dp)
1603 : END DO
1604 :
1605 4 : NULLIFY (matrix_pot_dummy)
1606 4 : CALL dbcsr_allocate_matrix_set(matrix_pot_dummy, 1, 1)
1607 4 : ALLOCATE (matrix_pot_dummy(1, 1)%matrix)
1608 4 : CALL dbcsr_create(matrix_pot_dummy(1, 1)%matrix, template=matrix_s(1)%matrix)
1609 4 : CALL cp_dbcsr_alloc_block_from_nbl(matrix_pot_dummy(1, 1)%matrix, sab_orb)
1610 4 : CALL dbcsr_set(matrix_pot_dummy(1, 1)%matrix, 0.0_dp)
1611 :
1612 : CALL build_core_ppnl(matrix_pot_dummy, matrix_dummy, force, virial, calculate_forces, use_virial, nder, &
1613 : qs_kind_set, atomic_kind_set, particle_set, sab_orb, sap_ppnl, eps_ppnl, &
1614 4 : nimages=1, basis_type="ORB", matrix_l=matrix_l)
1615 :
1616 4 : CALL alloc_mat_set_2d(mat_VSOC_l_nosymm, 3, size_real_space, matrix_s(1)%matrix, explicitly_no_symmetry=.TRUE.)
1617 16 : DO i_dim = 1, 3
1618 16 : CALL dbcsr_desymmetrize(matrix_l(i_dim, 1)%matrix, mat_VSOC_l_nosymm(i_dim, 1)%matrix)
1619 : END DO
1620 :
1621 4 : kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
1622 :
1623 4 : CALL mat_kp_from_mat_gamma(qs_env, mat_VSOC_lx_kp, mat_VSOC_l_nosymm(1, 1)%matrix, kpoints_Sigma, 1, .FALSE.)
1624 4 : CALL mat_kp_from_mat_gamma(qs_env, mat_VSOC_ly_kp, mat_VSOC_l_nosymm(2, 1)%matrix, kpoints_Sigma, 1, .FALSE.)
1625 4 : CALL mat_kp_from_mat_gamma(qs_env, mat_VSOC_lz_kp, mat_VSOC_l_nosymm(3, 1)%matrix, kpoints_Sigma, 1, .FALSE.)
1626 :
1627 4 : nkp_self_energy = kpoints_Sigma%nkp
1628 :
1629 4 : CALL get_mo_set(kpoints_Sigma%kp_env(1)%kpoint_env%mos(1), cmo_coeff=cmos)
1630 :
1631 4 : CALL create_cfm_double_row_col_size(cmos, cfm_mat_h_double)
1632 4 : CALL create_cfm_double_row_col_size(cmos, cfm_mat_s_double)
1633 4 : CALL create_cfm_double_row_col_size(cmos, cfm_mo_coeff_double)
1634 4 : CALL create_cfm_double_row_col_size(cmos, cfm_mat_work_double)
1635 :
1636 4 : CALL cp_cfm_set_all(cfm_mo_coeff_double, z_zero)
1637 :
1638 4 : CALL cp_cfm_create(cfm_mo_coeff, cmos%matrix_struct)
1639 4 : CALL cp_cfm_create(cfm_mat_h_ks, cmos%matrix_struct)
1640 :
1641 4 : CALL cp_cfm_get_info(matrix=cmos, nrow_global=nao)
1642 :
1643 4 : NULLIFY (matrix_s_desymm)
1644 4 : CALL dbcsr_allocate_matrix_set(matrix_s_desymm, 1)
1645 4 : ALLOCATE (matrix_s_desymm(1)%matrix)
1646 : CALL dbcsr_create(matrix=matrix_s_desymm(1)%matrix, template=matrix_s(1)%matrix, &
1647 4 : matrix_type=dbcsr_type_no_symmetry)
1648 4 : CALL dbcsr_desymmetrize(matrix_s(1)%matrix, matrix_s_desymm(1)%matrix)
1649 :
1650 12 : ALLOCATE (eigenvalues(2*nao))
1651 76 : eigenvalues = 0.0_dp
1652 8 : ALLOCATE (eigenvalues_without_soc_sorted(2*nao))
1653 :
1654 4 : E_window = qs_env%mp2_env%ri_g0w0%soc_energy_window
1655 4 : IF (unit_nr > 0) THEN
1656 2 : WRITE (unit_nr, '(T3,A)') ' '
1657 2 : WRITE (unit_nr, '(T3,A)') '------------------------------------------------------------------------------'
1658 2 : WRITE (unit_nr, '(T3,A)') ' '
1659 2 : WRITE (unit_nr, '(T3,A,F42.1)') 'GW_SOC_INFO | SOC energy window (eV)', E_window*evolt
1660 : END IF
1661 :
1662 4 : E_VBM_GW_SOC = -1000.0_dp
1663 4 : E_CBM_GW_SOC = 1000.0_dp
1664 :
1665 20 : DO ikp = 1, nkp_self_energy
1666 :
1667 16 : CALL get_mo_set(kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(1), cmo_coeff=cmos)
1668 16 : CALL cp_cfm_to_cfm(cmos, cfm_mo_coeff)
1669 :
1670 : ! ispin = 1
1671 : avg_occ_QP_shift = SUM(Eigenval(homo(1) - gw_corr_lev_occ(1) + 1:homo(1), ikp, 1) - &
1672 32 : Eigenval_scf(homo(1) - gw_corr_lev_occ(1) + 1:homo(1), ikp, 1))/gw_corr_lev_occ(1)
1673 : avg_virt_QP_shift = SUM(Eigenval(homo(1):homo(1) + gw_corr_lev_virt(1), ikp, 1) - &
1674 48 : Eigenval_scf(homo(1):homo(1) + gw_corr_lev_virt(1), ikp, 1))/gw_corr_lev_virt(1)
1675 :
1676 16 : IF (gw_corr_lev_occ(1) < homo(1)) THEN
1677 : Eigenval(1:homo(1) - gw_corr_lev_occ(1), ikp, 1) = Eigenval_scf(1:homo(1) - gw_corr_lev_occ(1), ikp, 1) &
1678 64 : + avg_occ_QP_shift
1679 : END IF
1680 16 : IF (gw_corr_lev_virt(1) < nao - homo(1) + 1) THEN
1681 : Eigenval(homo(1) + gw_corr_lev_virt(1) + 1:nao, ikp, 1) = Eigenval_scf(homo(1) + gw_corr_lev_virt(1) + 1:nao, ikp, 1) &
1682 80 : + avg_virt_QP_shift
1683 : END IF
1684 :
1685 16 : CALL cp_cfm_set_all(cfm_mat_h_double, z_zero)
1686 16 : CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_lx_kp(ikp, 1:2), cfm_mat_h_ks, nao + 1, 1, z_one, .TRUE.)
1687 16 : CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_ly_kp(ikp, 1:2), cfm_mat_h_ks, nao + 1, 1, gaussi, .TRUE.)
1688 16 : CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_lz_kp(ikp, 1:2), cfm_mat_h_ks, 1, 1, z_one, .FALSE.)
1689 16 : CALL add_dbcsr_submatrix(cfm_mat_h_double, mat_VSOC_lz_kp(ikp, 1:2), cfm_mat_h_ks, nao + 1, nao + 1, -z_one, .FALSE.)
1690 :
1691 : ! trafo to MO basis
1692 2896 : cfm_mo_coeff_double%local_data = z_zero
1693 16 : CALL add_cfm_submatrix(cfm_mo_coeff_double, cfm_mo_coeff, 1, 1)
1694 16 : CALL add_cfm_submatrix(cfm_mo_coeff_double, cfm_mo_coeff, nao + 1, nao + 1)
1695 :
1696 : CALL cp_cfm_get_info(matrix=cfm_mat_h_double, &
1697 : nrow_local=nrow_local, &
1698 : ncol_local=ncol_local, &
1699 : row_indices=row_indices, &
1700 16 : col_indices=col_indices)
1701 :
1702 : CALL parallel_gemm(transa="N", transb="N", m=2*nao, n=2*nao, k=2*nao, alpha=z_one, &
1703 : matrix_a=cfm_mat_h_double, matrix_b=cfm_mo_coeff_double, beta=z_zero, &
1704 16 : matrix_c=cfm_mat_work_double)
1705 :
1706 : CALL parallel_gemm(transa="C", transb="N", m=2*nao, n=2*nao, k=2*nao, alpha=z_one, &
1707 : matrix_a=cfm_mo_coeff_double, matrix_b=cfm_mat_work_double, beta=z_zero, &
1708 16 : matrix_c=cfm_mat_h_double)
1709 :
1710 : CALL cp_cfm_get_info(matrix=cfm_mat_h_double, &
1711 : nrow_local=nrow_local, &
1712 : ncol_local=ncol_local, &
1713 : row_indices=row_indices, &
1714 16 : col_indices=col_indices)
1715 :
1716 16 : CALL cp_cfm_set_all(cfm_mat_s_double, z_zero)
1717 :
1718 16 : E_HOMO = Eigenval(homo(1), ikp, 1)
1719 16 : E_LUMO = Eigenval(homo(1) + 1, ikp, 1)
1720 :
1721 16 : CALL para_env%sync()
1722 :
1723 160 : DO i_row = 1, nrow_local
1724 2752 : DO j_col = 1, ncol_local
1725 2592 : i_glob = row_indices(i_row)
1726 2592 : j_glob = col_indices(j_col)
1727 2592 : IF (i_glob <= nao) THEN
1728 1296 : E_i = Eigenval(i_glob, ikp, 1)
1729 : ELSE
1730 1296 : E_i = Eigenval(i_glob - nao, ikp, 1)
1731 : END IF
1732 2592 : IF (j_glob <= nao) THEN
1733 1296 : E_j = Eigenval(j_glob, ikp, 1)
1734 : ELSE
1735 1296 : E_j = Eigenval(j_glob - nao, ikp, 1)
1736 : END IF
1737 :
1738 : ! add eigenvalues to diagonal entries
1739 2736 : IF (i_glob == j_glob) THEN
1740 144 : cfm_mat_h_double%local_data(i_row, j_col) = cfm_mat_h_double%local_data(i_row, j_col) + E_i*z_one
1741 144 : cfm_mat_s_double%local_data(i_row, j_col) = z_one
1742 : ELSE
1743 : IF (E_i < E_HOMO - 0.5_dp*E_window .OR. E_i > E_LUMO + 0.5_dp*E_window .OR. &
1744 2448 : E_j < E_HOMO - 0.5_dp*E_window .OR. E_j > E_LUMO + 0.5_dp*E_window) THEN
1745 2000 : cfm_mat_h_double%local_data(i_row, j_col) = z_zero
1746 : END IF
1747 : END IF
1748 :
1749 : END DO
1750 : END DO
1751 :
1752 16 : CALL para_env%sync()
1753 :
1754 304 : eigenvalues = 0.0_dp
1755 : CALL cp_cfm_geeig_canon(cfm_mat_h_double, cfm_mat_s_double, cfm_mo_coeff_double, eigenvalues, &
1756 16 : cfm_mat_work_double, scf_control%eps_eigval)
1757 :
1758 160 : eigenvalues_without_soc_sorted(1:nao) = Eigenval(:, ikp, 1)
1759 160 : eigenvalues_without_soc_sorted(nao + 1:2*nao) = Eigenval(:, ikp, 1)
1760 48 : ALLOCATE (index0(2*nao))
1761 16 : CALL sort(eigenvalues_without_soc_sorted, 2*nao, index0)
1762 16 : DEALLOCATE (index0)
1763 :
1764 48 : E_HOMO_GW_SOC = MAXVAL(eigenvalues(2*homo(1) - 2*gw_corr_lev_occ(1) + 1:2*homo(1)))
1765 48 : E_LUMO_GW_SOC = MINVAL(eigenvalues(2*homo(1) + 1:2*homo(1) + 2*gw_corr_lev_virt(1)))
1766 16 : E_GAP_GW_SOC = E_LUMO_GW_SOC - E_HOMO_GW_SOC
1767 : IF (E_HOMO_GW_SOC > E_VBM_GW_SOC) E_VBM_GW_SOC = E_HOMO_GW_SOC
1768 : IF (E_LUMO_GW_SOC < E_CBM_GW_SOC) E_CBM_GW_SOC = E_LUMO_GW_SOC
1769 :
1770 52 : IF (unit_nr > 0) THEN
1771 8 : WRITE (unit_nr, '(T3,A)') ' '
1772 8 : WRITE (unit_nr, '(T3,A7,I3,A3,I3,A8,3F7.3,A12,3F7.3)') 'Kpoint ', ikp, ' /', nkp_self_energy, &
1773 8 : ' xkp =', kpoints_Sigma%xkp(1, ikp), kpoints_Sigma%xkp(2, ikp), kpoints_Sigma%xkp(3, ikp), &
1774 16 : ' and xkp =', -kpoints_Sigma%xkp(1, ikp), -kpoints_Sigma%xkp(2, ikp), -kpoints_Sigma%xkp(3, ikp)
1775 8 : WRITE (unit_nr, '(T3,A)') ' '
1776 8 : IF (do_soc_gw) THEN
1777 4 : WRITE (unit_nr, '(T3,A)') ' '
1778 4 : WRITE (unit_nr, '(T3,A,F13.4)') 'GW_SOC_INFO | Average GW shift of occupied levels compared to SCF', &
1779 8 : avg_occ_QP_shift*evolt
1780 4 : WRITE (unit_nr, '(T3,A,F11.4)') 'GW_SOC_INFO | Average GW shift of unoccupied levels compared to SCF', &
1781 8 : avg_virt_QP_shift*evolt
1782 4 : WRITE (unit_nr, '(T3,A)') ' '
1783 4 : WRITE (unit_nr, '(T3,2A)') 'Molecular orbital E_GW with SOC (eV) E_GW without SOC (eV) SOC shift (eV)'
1784 : ELSE
1785 4 : WRITE (unit_nr, '(T3,2A)') 'Molecular orbital E_SCF with SOC (eV) E_SCF without SOC (eV) SOC shift (eV)'
1786 : END IF
1787 :
1788 24 : DO n_level_gw = 2*(homo(1) - gw_corr_lev_occ(1)) + 1, 2*homo(1)
1789 16 : WRITE (unit_nr, '(T3,I4,A,3F21.4)') n_level_gw, ' ( occ ) ', eigenvalues(n_level_gw)*evolt, &
1790 16 : eigenvalues_without_soc_sorted(n_level_gw)*evolt, &
1791 40 : (eigenvalues(n_level_gw) - eigenvalues_without_soc_sorted(n_level_gw))*evolt
1792 : END DO
1793 24 : DO n_level_gw = 2*homo(1) + 1, 2*(homo(1) + gw_corr_lev_virt(1))
1794 16 : WRITE (unit_nr, '(T3,I4,A,3F21.4)') n_level_gw, ' ( vir ) ', eigenvalues(n_level_gw)*evolt, &
1795 16 : eigenvalues_without_soc_sorted(n_level_gw)*evolt, &
1796 40 : (eigenvalues(n_level_gw) - eigenvalues_without_soc_sorted(n_level_gw))*evolt
1797 : END DO
1798 8 : WRITE (unit_nr, '(T3,A)') ' '
1799 8 : IF (do_soc_gw) THEN
1800 4 : WRITE (unit_nr, '(T3,A,F38.4)') 'GW+SOC direct gap at current kpoint (eV)', E_GAP_GW_SOC*evolt
1801 : ELSE
1802 4 : WRITE (unit_nr, '(T3,A,F37.4)') 'SCF+SOC direct gap at current kpoint (eV)', E_GAP_GW_SOC*evolt
1803 : END IF
1804 8 : WRITE (unit_nr, '(T3,A)') ' '
1805 8 : WRITE (unit_nr, '(T3,A)') '------------------------------------------------------------------------------'
1806 : END IF
1807 :
1808 : END DO
1809 :
1810 4 : IF (unit_nr > 0) THEN
1811 2 : WRITE (unit_nr, '(T3,A)') ' '
1812 2 : IF (do_soc_gw) THEN
1813 1 : WRITE (unit_nr, '(T3,A,F46.4)') 'GW+SOC valence band maximum (eV)', E_VBM_GW_SOC*evolt
1814 1 : WRITE (unit_nr, '(T3,A,F43.4)') 'GW+SOC conduction band minimum (eV)', E_CBM_GW_SOC*evolt
1815 1 : WRITE (unit_nr, '(T3,A,F59.4)') 'GW+SOC bandgap (eV)', (E_CBM_GW_SOC - E_VBM_GW_SOC)*evolt
1816 : ELSE
1817 1 : WRITE (unit_nr, '(T3,A,F45.4)') 'SCF+SOC valence band maximum (eV)', E_VBM_GW_SOC*evolt
1818 1 : WRITE (unit_nr, '(T3,A,F42.4)') 'SCF+SOC conduction band minimum (eV)', E_CBM_GW_SOC*evolt
1819 1 : WRITE (unit_nr, '(T3,A,F58.4)') 'SCF+SOC bandgap (eV)', (E_CBM_GW_SOC - E_VBM_GW_SOC)*evolt
1820 : END IF
1821 : END IF
1822 :
1823 4 : CALL dbcsr_deallocate_matrix_set(matrix_l)
1824 4 : CALL dbcsr_deallocate_matrix_set(mat_VSOC_l_nosymm)
1825 4 : CALL dbcsr_deallocate_matrix_set(matrix_pot_dummy)
1826 4 : CALL dbcsr_deallocate_matrix_set(mat_VSOC_lx_kp)
1827 4 : CALL dbcsr_deallocate_matrix_set(mat_VSOC_ly_kp)
1828 4 : CALL dbcsr_deallocate_matrix_set(mat_VSOC_lz_kp)
1829 4 : CALL dbcsr_deallocate_matrix_set(matrix_s_desymm)
1830 :
1831 4 : CALL cp_cfm_release(cfm_mat_h_double)
1832 4 : CALL cp_cfm_release(cfm_mat_s_double)
1833 4 : CALL cp_cfm_release(cfm_mo_coeff_double)
1834 4 : CALL cp_cfm_release(cfm_mo_coeff)
1835 4 : CALL cp_cfm_release(cfm_mat_h_ks)
1836 4 : CALL cp_cfm_release(cfm_mat_work_double)
1837 4 : DEALLOCATE (eigenvalues)
1838 :
1839 4 : CALL timestop(handle)
1840 :
1841 12 : END SUBROUTINE calculate_and_print_soc
1842 :
1843 : ! **************************************************************************************************
1844 : !> \brief ...
1845 : !> \param cfm_mat_target ...
1846 : !> \param mat_source ...
1847 : !> \param cfm_source_template ...
1848 : !> \param nstart_row ...
1849 : !> \param nstart_col ...
1850 : !> \param factor ...
1851 : !> \param add_also_herm_conj ...
1852 : ! **************************************************************************************************
1853 64 : SUBROUTINE add_dbcsr_submatrix(cfm_mat_target, mat_source, cfm_source_template, &
1854 : nstart_row, nstart_col, factor, add_also_herm_conj)
1855 : TYPE(cp_cfm_type) :: cfm_mat_target
1856 : TYPE(dbcsr_p_type), DIMENSION(:) :: mat_source
1857 : TYPE(cp_cfm_type) :: cfm_source_template
1858 : INTEGER :: nstart_row, nstart_col
1859 : COMPLEX(KIND=dp) :: factor
1860 : LOGICAL :: add_also_herm_conj
1861 :
1862 : CHARACTER(LEN=*), PARAMETER :: routineN = 'add_dbcsr_submatrix'
1863 :
1864 : INTEGER :: handle, nao
1865 : TYPE(cp_cfm_type) :: cfm_mat_work_double, &
1866 : cfm_mat_work_double_2
1867 : TYPE(cp_fm_type) :: fm_mat_work_double_im, &
1868 : fm_mat_work_double_re, fm_mat_work_im, &
1869 : fm_mat_work_re
1870 :
1871 64 : CALL timeset(routineN, handle)
1872 :
1873 64 : CALL cp_fm_create(fm_mat_work_double_re, cfm_mat_target%matrix_struct)
1874 64 : CALL cp_fm_create(fm_mat_work_double_im, cfm_mat_target%matrix_struct)
1875 64 : CALL cp_fm_set_all(fm_mat_work_double_re, 0.0_dp)
1876 64 : CALL cp_fm_set_all(fm_mat_work_double_im, 0.0_dp)
1877 :
1878 64 : CALL cp_cfm_create(cfm_mat_work_double, cfm_mat_target%matrix_struct)
1879 64 : CALL cp_cfm_create(cfm_mat_work_double_2, cfm_mat_target%matrix_struct)
1880 64 : CALL cp_cfm_set_all(cfm_mat_work_double, z_zero)
1881 64 : CALL cp_cfm_set_all(cfm_mat_work_double_2, z_zero)
1882 :
1883 64 : CALL cp_fm_create(fm_mat_work_re, cfm_source_template%matrix_struct)
1884 64 : CALL cp_fm_create(fm_mat_work_im, cfm_source_template%matrix_struct)
1885 :
1886 64 : CALL copy_dbcsr_to_fm(mat_source(1)%matrix, fm_mat_work_re)
1887 64 : CALL copy_dbcsr_to_fm(mat_source(2)%matrix, fm_mat_work_im)
1888 :
1889 64 : CALL cp_cfm_get_info(cfm_source_template, nrow_global=nao)
1890 :
1891 : CALL cp_fm_to_fm_submat(msource=fm_mat_work_re, mtarget=fm_mat_work_double_re, &
1892 : nrow=nao, ncol=nao, &
1893 : s_firstrow=1, s_firstcol=1, &
1894 64 : t_firstrow=nstart_row, t_firstcol=nstart_col)
1895 :
1896 : CALL cp_fm_to_fm_submat(msource=fm_mat_work_im, mtarget=fm_mat_work_double_im, &
1897 : nrow=nao, ncol=nao, &
1898 : s_firstrow=1, s_firstcol=1, &
1899 64 : t_firstrow=nstart_row, t_firstcol=nstart_col)
1900 :
1901 64 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_work_double, z_one, fm_mat_work_double_re)
1902 64 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_work_double, gaussi, fm_mat_work_double_im)
1903 :
1904 64 : CALL cp_cfm_scale(factor, cfm_mat_work_double)
1905 :
1906 64 : CALL cp_cfm_scale_and_add(z_one, cfm_mat_target, z_one, cfm_mat_work_double)
1907 :
1908 64 : IF (add_also_herm_conj) THEN
1909 32 : CALL cp_cfm_transpose(cfm_mat_work_double, 'C', cfm_mat_work_double_2)
1910 32 : CALL cp_cfm_scale_and_add(z_one, cfm_mat_target, z_one, cfm_mat_work_double_2)
1911 : END IF
1912 :
1913 64 : CALL cp_fm_release(fm_mat_work_double_re)
1914 64 : CALL cp_fm_release(fm_mat_work_double_im)
1915 64 : CALL cp_cfm_release(cfm_mat_work_double)
1916 64 : CALL cp_cfm_release(cfm_mat_work_double_2)
1917 64 : CALL cp_fm_release(fm_mat_work_re)
1918 64 : CALL cp_fm_release(fm_mat_work_im)
1919 :
1920 64 : CALL timestop(handle)
1921 :
1922 64 : END SUBROUTINE add_dbcsr_submatrix
1923 :
1924 : ! **************************************************************************************************
1925 : !> \brief ...
1926 : !> \param cfm_mat_target ...
1927 : !> \param cfm_mat_source ...
1928 : !> \param nstart_row ...
1929 : !> \param nstart_col ...
1930 : ! **************************************************************************************************
1931 192 : SUBROUTINE add_cfm_submatrix(cfm_mat_target, cfm_mat_source, nstart_row, nstart_col)
1932 :
1933 : TYPE(cp_cfm_type) :: cfm_mat_target, cfm_mat_source
1934 : INTEGER :: nstart_row, nstart_col
1935 :
1936 : CHARACTER(LEN=*), PARAMETER :: routineN = 'add_cfm_submatrix'
1937 :
1938 : INTEGER :: handle, nao
1939 : TYPE(cp_fm_type) :: fm_mat_work_double_im, &
1940 : fm_mat_work_double_re, fm_mat_work_im, &
1941 : fm_mat_work_re
1942 :
1943 32 : CALL timeset(routineN, handle)
1944 :
1945 32 : CALL cp_fm_create(fm_mat_work_double_re, cfm_mat_target%matrix_struct)
1946 32 : CALL cp_fm_create(fm_mat_work_double_im, cfm_mat_target%matrix_struct)
1947 32 : CALL cp_fm_set_all(fm_mat_work_double_re, 0.0_dp)
1948 32 : CALL cp_fm_set_all(fm_mat_work_double_im, 0.0_dp)
1949 :
1950 32 : CALL cp_fm_create(fm_mat_work_re, cfm_mat_source%matrix_struct)
1951 32 : CALL cp_fm_create(fm_mat_work_im, cfm_mat_source%matrix_struct)
1952 32 : CALL cp_cfm_to_fm(cfm_mat_source, fm_mat_work_re, fm_mat_work_im)
1953 :
1954 32 : CALL cp_cfm_get_info(cfm_mat_source, nrow_global=nao)
1955 :
1956 : CALL cp_fm_to_fm_submat(msource=fm_mat_work_re, mtarget=fm_mat_work_double_re, &
1957 : nrow=nao, ncol=nao, &
1958 : s_firstrow=1, s_firstcol=1, &
1959 32 : t_firstrow=nstart_row, t_firstcol=nstart_col)
1960 :
1961 : CALL cp_fm_to_fm_submat(msource=fm_mat_work_im, mtarget=fm_mat_work_double_im, &
1962 : nrow=nao, ncol=nao, &
1963 : s_firstrow=1, s_firstcol=1, &
1964 32 : t_firstrow=nstart_row, t_firstcol=nstart_col)
1965 :
1966 32 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_target, z_one, fm_mat_work_double_re)
1967 32 : CALL cp_cfm_scale_and_add_fm(z_one, cfm_mat_target, gaussi, fm_mat_work_double_im)
1968 :
1969 32 : CALL cp_fm_release(fm_mat_work_double_re)
1970 32 : CALL cp_fm_release(fm_mat_work_double_im)
1971 32 : CALL cp_fm_release(fm_mat_work_re)
1972 32 : CALL cp_fm_release(fm_mat_work_im)
1973 :
1974 32 : CALL timestop(handle)
1975 :
1976 32 : END SUBROUTINE add_cfm_submatrix
1977 :
1978 : ! **************************************************************************************************
1979 : !> \brief ...
1980 : !> \param cfm_orig ...
1981 : !> \param cfm_double ...
1982 : ! **************************************************************************************************
1983 48 : SUBROUTINE create_cfm_double_row_col_size(cfm_orig, cfm_double)
1984 : TYPE(cp_cfm_type) :: cfm_orig, cfm_double
1985 :
1986 : CHARACTER(LEN=*), PARAMETER :: routineN = 'create_cfm_double_row_col_size'
1987 :
1988 : INTEGER :: handle, ncol_global_orig, &
1989 : nrow_global_orig
1990 : TYPE(cp_fm_struct_type), POINTER :: fm_struct_double
1991 :
1992 16 : CALL timeset(routineN, handle)
1993 :
1994 16 : CALL cp_cfm_get_info(matrix=cfm_orig, nrow_global=nrow_global_orig, ncol_global=ncol_global_orig)
1995 :
1996 : CALL cp_fm_struct_create(fm_struct_double, &
1997 : nrow_global=2*nrow_global_orig, &
1998 : ncol_global=2*ncol_global_orig, &
1999 16 : template_fmstruct=cfm_orig%matrix_struct)
2000 :
2001 16 : CALL cp_cfm_create(cfm_double, fm_struct_double)
2002 :
2003 16 : CALL cp_fm_struct_release(fm_struct_double)
2004 :
2005 16 : CALL timestop(handle)
2006 :
2007 16 : END SUBROUTINE create_cfm_double_row_col_size
2008 :
2009 : ! **************************************************************************************************
2010 : !> \brief ...
2011 : !> \param E_VBM_SCF ...
2012 : !> \param E_CBM_SCF ...
2013 : !> \param E_VBM_SCF_beta ...
2014 : !> \param E_CBM_SCF_beta ...
2015 : !> \param E_VBM_GW ...
2016 : !> \param E_CBM_GW ...
2017 : !> \param E_VBM_GW_beta ...
2018 : !> \param E_CBM_GW_beta ...
2019 : !> \param my_open_shell ...
2020 : !> \param unit_nr ...
2021 : ! **************************************************************************************************
2022 8 : SUBROUTINE print_gaps(E_VBM_SCF, E_CBM_SCF, E_VBM_SCF_beta, E_CBM_SCF_beta, &
2023 : E_VBM_GW, E_CBM_GW, E_VBM_GW_beta, E_CBM_GW_beta, my_open_shell, unit_nr)
2024 :
2025 : REAL(KIND=dp) :: E_VBM_SCF, E_CBM_SCF, E_VBM_SCF_beta, &
2026 : E_CBM_SCF_beta, E_VBM_GW, E_CBM_GW, &
2027 : E_VBM_GW_beta, E_CBM_GW_beta
2028 : LOGICAL :: my_open_shell
2029 : INTEGER :: unit_nr
2030 :
2031 8 : IF (my_open_shell) THEN
2032 1 : WRITE (unit_nr, '(T3,A)') ' '
2033 1 : WRITE (unit_nr, '(T3,A,F43.4)') 'Alpha SCF valence band maximum (eV)', E_VBM_SCF*evolt
2034 1 : WRITE (unit_nr, '(T3,A,F40.4)') 'Alpha SCF conduction band minimum (eV)', E_CBM_SCF*evolt
2035 1 : WRITE (unit_nr, '(T3,A,F56.4)') 'Alpha SCF bandgap (eV)', (E_CBM_SCF - E_VBM_SCF)*evolt
2036 1 : WRITE (unit_nr, '(T3,A)') ' '
2037 1 : WRITE (unit_nr, '(T3,A,F44.4)') 'Beta SCF valence band maximum (eV)', E_VBM_SCF_beta*evolt
2038 1 : WRITE (unit_nr, '(T3,A,F41.4)') 'Beta SCF conduction band minimum (eV)', E_CBM_SCF_beta*evolt
2039 1 : WRITE (unit_nr, '(T3,A,F57.4)') 'Beta SCF bandgap (eV)', (E_CBM_SCF_beta - E_VBM_SCF_beta)*evolt
2040 1 : WRITE (unit_nr, '(T3,A)') ' '
2041 1 : WRITE (unit_nr, '(T3,A,F44.4)') 'Alpha GW valence band maximum (eV)', E_VBM_GW*evolt
2042 1 : WRITE (unit_nr, '(T3,A,F41.4)') 'Alpha GW conduction band minimum (eV)', E_CBM_GW*evolt
2043 1 : WRITE (unit_nr, '(T3,A,F57.4)') 'Alpha GW bandgap (eV)', (E_CBM_GW - E_VBM_GW)*evolt
2044 1 : WRITE (unit_nr, '(T3,A)') ' '
2045 1 : WRITE (unit_nr, '(T3,A,F45.4)') 'Beta GW valence band maximum (eV)', E_VBM_GW_beta*evolt
2046 1 : WRITE (unit_nr, '(T3,A,F42.4)') 'Beta GW conduction band minimum (eV)', E_CBM_GW_beta*evolt
2047 1 : WRITE (unit_nr, '(T3,A,F58.4)') 'Beta GW bandgap (eV)', (E_CBM_GW_beta - E_VBM_GW_beta)*evolt
2048 : ELSE
2049 7 : WRITE (unit_nr, '(T3,A)') ' '
2050 7 : WRITE (unit_nr, '(T3,A,F49.4)') 'SCF valence band maximum (eV)', E_VBM_SCF*evolt
2051 7 : WRITE (unit_nr, '(T3,A,F46.4)') 'SCF conduction band minimum (eV)', E_CBM_SCF*evolt
2052 7 : WRITE (unit_nr, '(T3,A,F62.4)') 'SCF bandgap (eV)', (E_CBM_SCF - E_VBM_SCF)*evolt
2053 7 : WRITE (unit_nr, '(T3,A)') ' '
2054 7 : WRITE (unit_nr, '(T3,A,F50.4)') 'GW valence band maximum (eV)', E_VBM_GW*evolt
2055 7 : WRITE (unit_nr, '(T3,A,F47.4)') 'GW conduction band minimum (eV)', E_CBM_GW*evolt
2056 7 : WRITE (unit_nr, '(T3,A,F63.4)') 'GW bandgap (eV)', (E_CBM_GW - E_VBM_GW)*evolt
2057 : END IF
2058 :
2059 8 : END SUBROUTINE print_gaps
2060 :
2061 : ! **************************************************************************************************
2062 : !> \brief ...
2063 : !> \param array ...
2064 : !> \param real_value ...
2065 : ! **************************************************************************************************
2066 1116 : SUBROUTINE check_NaN(array, real_value)
2067 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :), &
2068 : INTENT(INOUT) :: array
2069 : REAL(KIND=dp), INTENT(IN) :: real_value
2070 :
2071 : CHARACTER(LEN=*), PARAMETER :: routineN = 'check_NaN'
2072 :
2073 : INTEGER :: handle, i, j, k
2074 :
2075 1116 : CALL timeset(routineN, handle)
2076 :
2077 13116 : DO i = 1, SIZE(array, 1)
2078 29964 : DO j = 1, SIZE(array, 2)
2079 48822 : DO k = 1, SIZE(array, 3)
2080 :
2081 : ! check for NaN
2082 36822 : IF (array(i, j, k) /= array(i, j, k)) array(i, j, k) = real_value
2083 :
2084 : END DO
2085 : END DO
2086 : END DO
2087 :
2088 1116 : CALL timestop(handle)
2089 :
2090 1116 : END SUBROUTINE check_NaN
2091 :
2092 : ! **************************************************************************************************
2093 : !> \brief ...
2094 : !> \param qs_env ...
2095 : !> \param Eigenval ...
2096 : !> \param gw_corr_lev_occ ...
2097 : !> \param gw_corr_lev_virt ...
2098 : !> \param homo ...
2099 : !> \param dft_gw_char ...
2100 : ! **************************************************************************************************
2101 4 : SUBROUTINE print_local_bandgap(qs_env, Eigenval, gw_corr_lev_occ, gw_corr_lev_virt, homo, dft_gw_char)
2102 : TYPE(qs_environment_type), POINTER :: qs_env
2103 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: Eigenval
2104 : INTEGER :: gw_corr_lev_occ, gw_corr_lev_virt, homo
2105 : CHARACTER(len=*) :: dft_gw_char
2106 :
2107 : CHARACTER(LEN=*), PARAMETER :: routineN = 'print_local_bandgap'
2108 :
2109 : INTEGER :: handle, i_E
2110 : TYPE(pw_c1d_gs_type) :: rho_g_dummy
2111 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2112 : TYPE(pw_r3d_rs_type) :: E_CBM_rspace, E_gap_rspace, E_VBM_rspace
2113 4 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: LDOS
2114 :
2115 4 : CALL timeset(routineN, handle)
2116 :
2117 4 : CALL create_real_space_grids(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, LDOS, auxbas_pw_pool, qs_env)
2118 :
2119 : CALL calculate_E_gap_rspace(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, &
2120 4 : LDOS, qs_env, Eigenval, gw_corr_lev_occ, gw_corr_lev_virt, homo, dft_gw_char)
2121 :
2122 4 : CALL auxbas_pw_pool%give_back_pw(E_gap_rspace)
2123 4 : CALL auxbas_pw_pool%give_back_pw(E_VBM_rspace)
2124 4 : CALL auxbas_pw_pool%give_back_pw(E_CBM_rspace)
2125 4 : CALL auxbas_pw_pool%give_back_pw(rho_g_dummy)
2126 20 : DO i_E = 1, SIZE(LDOS)
2127 20 : CALL auxbas_pw_pool%give_back_pw(LDOS(i_E))
2128 : END DO
2129 4 : DEALLOCATE (LDOS)
2130 :
2131 4 : CALL timestop(handle)
2132 :
2133 4 : END SUBROUTINE print_local_bandgap
2134 :
2135 : ! **************************************************************************************************
2136 : !> \brief ...
2137 : !> \param E_gap_rspace ...
2138 : !> \param E_VBM_rspace ...
2139 : !> \param E_CBM_rspace ...
2140 : !> \param rho_g_dummy ...
2141 : !> \param LDOS ...
2142 : !> \param qs_env ...
2143 : !> \param Eigenval ...
2144 : !> \param gw_corr_lev_occ ...
2145 : !> \param gw_corr_lev_virt ...
2146 : !> \param homo ...
2147 : !> \param dft_gw_char ...
2148 : ! **************************************************************************************************
2149 4 : SUBROUTINE calculate_E_gap_rspace(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, &
2150 4 : LDOS, qs_env, Eigenval, gw_corr_lev_occ, gw_corr_lev_virt, homo, dft_gw_char)
2151 : TYPE(pw_r3d_rs_type) :: E_gap_rspace, E_VBM_rspace, E_CBM_rspace
2152 : TYPE(pw_c1d_gs_type) :: rho_g_dummy
2153 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: LDOS
2154 : TYPE(qs_environment_type), POINTER :: qs_env
2155 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: Eigenval
2156 : INTEGER :: gw_corr_lev_occ, gw_corr_lev_virt, homo
2157 : CHARACTER(len=*) :: dft_gw_char
2158 :
2159 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calculate_E_gap_rspace'
2160 :
2161 : INTEGER :: handle, i_E, i_img, i_spin, i_x, i_y, i_z, ikp, imo, n_E, n_E_occ, n_x_end, &
2162 : n_x_start, n_y_end, n_y_start, n_z_end, n_z_start, nimg, nkp, nkp_self_energy
2163 : REAL(KIND=dp) :: avg_LDOS_occ, avg_LDOS_virt, d_E, E_CBM, &
2164 : E_CBM_at_k, E_diff, E_VBM, E_VBM_at_k
2165 4 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: E_array
2166 4 : REAL(KIND=dp), DIMENSION(:), POINTER :: occupation
2167 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
2168 4 : TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_work
2169 4 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, rho_ao
2170 4 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: rho_ao_weighted
2171 : TYPE(dft_control_type), POINTER :: dft_control
2172 : TYPE(kpoint_type), POINTER :: kpoints_Sigma
2173 : TYPE(mp2_type), POINTER :: mp2_env
2174 : TYPE(mp_para_env_type), POINTER :: para_env
2175 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2176 4 : POINTER :: sab_orb
2177 : TYPE(particle_list_type), POINTER :: particles
2178 : TYPE(qs_ks_env_type), POINTER :: ks_env
2179 : TYPE(qs_scf_env_type), POINTER :: scf_env
2180 : TYPE(qs_subsys_type), POINTER :: subsys
2181 : TYPE(section_vals_type), POINTER :: gw_section
2182 :
2183 4 : CALL timeset(routineN, handle)
2184 :
2185 : CALL get_qs_env(qs_env=qs_env, para_env=para_env, mp2_env=mp2_env, ks_env=ks_env, matrix_s=matrix_s, &
2186 4 : scf_env=scf_env, sab_orb=sab_orb, dft_control=dft_control, subsys=subsys)
2187 :
2188 : ! compute valence band maximum (VBM) and conduction band minimum (CBM)
2189 4 : nkp = SIZE(Eigenval, 2)
2190 4 : E_VBM = -1.0E3_dp
2191 4 : E_CBM = 1.0E3_dp
2192 :
2193 36 : DO ikp = 1, nkp
2194 :
2195 64 : E_VBM_at_k = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo, ikp, 1))
2196 : IF (E_VBM_at_k > E_VBM) E_VBM = E_VBM_at_k
2197 :
2198 64 : E_CBM_at_k = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_virt, ikp, 1))
2199 4 : IF (E_CBM_at_k < E_CBM) E_CBM = E_CBM_at_k
2200 :
2201 : END DO
2202 :
2203 4 : d_E = mp2_env%ri_g0w0%energy_spacing_print_loc_bandgap
2204 :
2205 4 : n_E = INT(mp2_env%ri_g0w0%energy_window_print_loc_bandgap/d_E)
2206 :
2207 4 : n_E_occ = n_E/2
2208 12 : ALLOCATE (E_array(n_E))
2209 12 : DO i_E = 1, n_E_occ
2210 12 : E_array(i_E) = E_VBM - REAL(n_E_occ - i_E, KIND=dp)*d_E
2211 : END DO
2212 12 : DO i_E = n_E_occ + 1, n_E
2213 12 : E_array(i_E) = E_CBM + REAL(i_E - n_E_occ - 1, KIND=dp)*d_E
2214 : END DO
2215 :
2216 4 : kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
2217 :
2218 4 : nkp_self_energy = kpoints_Sigma%nkp
2219 4 : CPASSERT(nkp == nkp_self_energy)
2220 :
2221 4 : kpoints_Sigma%sab_nl => sab_orb
2222 :
2223 4 : DEALLOCATE (kpoints_Sigma%cell_to_index)
2224 : NULLIFY (kpoints_Sigma%cell_to_index)
2225 4 : CALL kpoint_init_cell_index(kpoints_Sigma, sab_orb, para_env, dft_control%nimages)
2226 :
2227 424 : nimg = MAXVAL(kpoints_Sigma%cell_to_index)
2228 :
2229 4 : NULLIFY (rho_ao_weighted)
2230 4 : CALL dbcsr_allocate_matrix_set(rho_ao_weighted, 2, nimg)
2231 :
2232 12 : DO i_spin = 1, 2
2233 236 : DO i_img = 1, nimg
2234 224 : ALLOCATE (rho_ao_weighted(i_spin, i_img)%matrix)
2235 224 : CALL dbcsr_create(matrix=rho_ao_weighted(i_spin, i_img)%matrix, template=matrix_s(1)%matrix)
2236 224 : CALL cp_dbcsr_alloc_block_from_nbl(rho_ao_weighted(i_spin, i_img)%matrix, sab_orb)
2237 232 : CALL dbcsr_set(rho_ao_weighted(i_spin, i_img)%matrix, 0.0_dp)
2238 : END DO
2239 : END DO
2240 :
2241 124 : ALLOCATE (fm_work(nimg))
2242 4 : matrix_struct => kpoints_Sigma%kp_env(1)%kpoint_env%mos(1)%cmo_coeff%matrix_struct
2243 116 : DO i_img = 1, nimg
2244 116 : CALL cp_fm_create(fm_work(i_img), matrix_struct)
2245 : END DO
2246 :
2247 20 : DO i_E = 1, n_E
2248 :
2249 : ! occupation = weight factor for computing LDOS
2250 144 : DO ikp = 1, nkp
2251 : CALL get_mo_set(kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(1), &
2252 128 : occupation_numbers=occupation)
2253 :
2254 3072 : occupation(:) = 0.0_dp
2255 400 : DO imo = homo - gw_corr_lev_occ + 1, homo + gw_corr_lev_virt
2256 256 : E_diff = E_array(i_E) - Eigenval(imo, ikp, 1)
2257 384 : occupation(imo) = EXP(-(E_diff/d_E)**2)
2258 : END DO
2259 :
2260 : END DO
2261 :
2262 : CALL get_mo_set(kpoints_Sigma%kp_env(1)%kpoint_env%mos(1), &
2263 16 : occupation_numbers=occupation)
2264 :
2265 : ! density matrices
2266 16 : CALL kpoint_density_matrices(kpoints_Sigma)
2267 :
2268 : ! density matrices in real space
2269 : CALL kpoint_density_transform(kpoints_Sigma, rho_ao_weighted, .FALSE., &
2270 16 : matrix_s(1)%matrix, sab_orb, fm_work)
2271 :
2272 16 : rho_ao => rho_ao_weighted(1, :)
2273 :
2274 : CALL calculate_rho_elec(matrix_p_kp=rho_ao, &
2275 : rho=LDOS(i_E), &
2276 : rho_gspace=rho_g_dummy, &
2277 16 : ks_env=ks_env)
2278 :
2279 52 : DO i_spin = 1, 2
2280 944 : DO i_img = 1, nimg
2281 928 : CALL dbcsr_set(rho_ao_weighted(i_spin, i_img)%matrix, 0.0_dp)
2282 : END DO
2283 : END DO
2284 :
2285 : END DO
2286 :
2287 4 : n_x_start = LBOUND(LDOS(1)%array, 1)
2288 4 : n_x_end = UBOUND(LDOS(1)%array, 1)
2289 4 : n_y_start = LBOUND(LDOS(1)%array, 2)
2290 4 : n_y_end = UBOUND(LDOS(1)%array, 2)
2291 4 : n_z_start = LBOUND(LDOS(1)%array, 3)
2292 4 : n_z_end = UBOUND(LDOS(1)%array, 3)
2293 :
2294 4 : CALL pw_zero(E_VBM_rspace)
2295 4 : CALL pw_zero(E_CBM_rspace)
2296 :
2297 68 : DO i_x = n_x_start, n_x_end
2298 2116 : DO i_y = n_y_start, n_y_end
2299 94272 : DO i_z = n_z_start, n_z_end
2300 : ! compute average occ and virt LDOS
2301 : avg_LDOS_occ = 0.0_dp
2302 276480 : DO i_E = 1, n_E_occ
2303 276480 : avg_LDOS_occ = avg_LDOS_occ + LDOS(i_E)%array(i_x, i_y, i_z)
2304 : END DO
2305 92160 : avg_LDOS_occ = avg_LDOS_occ/REAL(n_E_occ, KIND=dp)
2306 :
2307 92160 : avg_LDOS_virt = 0.0_dp
2308 276480 : DO i_E = n_E_occ + 1, n_E
2309 276480 : avg_LDOS_virt = avg_LDOS_virt + LDOS(i_E)%array(i_x, i_y, i_z)
2310 : END DO
2311 92160 : avg_LDOS_virt = avg_LDOS_virt/REAL(n_E - n_E_occ, KIND=dp)
2312 :
2313 : ! compute local valence band maximum (VBM)
2314 117790 : DO i_E = n_E_occ, 1, -1
2315 117790 : IF (LDOS(i_E)%array(i_x, i_y, i_z) > mp2_env%ri_g0w0%ldos_thresh_print_loc_bandgap*avg_LDOS_occ) THEN
2316 79632 : E_VBM_rspace%array(i_x, i_y, i_z) = E_array(i_E)
2317 79632 : EXIT
2318 : END IF
2319 : END DO
2320 :
2321 : ! compute local valence band maximum (VBM)
2322 94304 : DO i_E = n_E_occ + 1, n_E
2323 92256 : IF (LDOS(i_E)%array(i_x, i_y, i_z) > mp2_env%ri_g0w0%ldos_thresh_print_loc_bandgap*avg_LDOS_virt) THEN
2324 92112 : E_CBM_rspace%array(i_x, i_y, i_z) = E_array(i_E)
2325 92112 : EXIT
2326 : END IF
2327 : END DO
2328 :
2329 : END DO
2330 : END DO
2331 : END DO
2332 :
2333 4 : CALL pw_scale(E_VBM_rspace, evolt)
2334 4 : CALL pw_scale(E_CBM_rspace, evolt)
2335 :
2336 4 : CALL pw_copy(E_CBM_rspace, E_gap_rspace)
2337 4 : CALL pw_axpy(E_VBM_rspace, E_gap_rspace, -1.0_dp)
2338 :
2339 4 : gw_section => section_vals_get_subs_vals(qs_env%input, "DFT%XC%WF_CORRELATION%RI_RPA%GW")
2340 4 : CALL qs_subsys_get(subsys, particles=particles)
2341 :
2342 4 : CALL print_file(E_gap_rspace, dft_gw_char//"_Gap_in_eV", gw_section, particles, mp2_env)
2343 4 : CALL print_file(E_VBM_rspace, dft_gw_char//"_VBM_in_eV", gw_section, particles, mp2_env)
2344 4 : CALL print_file(E_CBM_rspace, dft_gw_char//"_CBM_in_eV", gw_section, particles, mp2_env)
2345 4 : CALL print_file(LDOS(n_E_occ), dft_gw_char//"_LDOS_VBM_in_eV", gw_section, particles, mp2_env)
2346 4 : CALL print_file(LDOS(n_E_occ + 1), dft_gw_char//"_LDOS_CBM_in_eV", gw_section, particles, mp2_env)
2347 :
2348 4 : CALL dbcsr_deallocate_matrix_set(rho_ao_weighted)
2349 :
2350 4 : CALL cp_fm_release(fm_work)
2351 :
2352 4 : DEALLOCATE (E_array)
2353 :
2354 4 : NULLIFY (kpoints_Sigma%sab_nl)
2355 :
2356 4 : CALL timestop(handle)
2357 :
2358 8 : END SUBROUTINE calculate_E_gap_rspace
2359 :
2360 : ! **************************************************************************************************
2361 : !> \brief ...
2362 : !> \param pw_print ...
2363 : !> \param middle_name ...
2364 : !> \param gw_section ...
2365 : !> \param particles ...
2366 : !> \param mp2_env ...
2367 : ! **************************************************************************************************
2368 20 : SUBROUTINE print_file(pw_print, middle_name, gw_section, particles, mp2_env)
2369 : TYPE(pw_r3d_rs_type) :: pw_print
2370 : CHARACTER(len=*) :: middle_name
2371 : TYPE(section_vals_type), POINTER :: gw_section
2372 : TYPE(particle_list_type), POINTER :: particles
2373 : TYPE(mp2_type), POINTER :: mp2_env
2374 :
2375 : CHARACTER(LEN=*), PARAMETER :: routineN = 'print_file'
2376 :
2377 : INTEGER :: handle, unit_nr_cube
2378 : LOGICAL :: mpi_io
2379 : TYPE(cp_logger_type), POINTER :: logger
2380 :
2381 20 : CALL timeset(routineN, handle)
2382 :
2383 20 : NULLIFY (logger)
2384 20 : logger => cp_get_default_logger()
2385 20 : mpi_io = .TRUE.
2386 : unit_nr_cube = cp_print_key_unit_nr(logger, gw_section, "PRINT%LOCAL_BANDGAP", extension=".cube", &
2387 20 : middle_name=middle_name, file_form="FORMATTED", mpi_io=mpi_io)
2388 : CALL cp_pw_to_cube(pw_print, unit_nr_cube, middle_name, particles=particles, &
2389 20 : stride=mp2_env%ri_g0w0%stride_loc_bandgap, mpi_io=mpi_io)
2390 : CALL cp_print_key_finished_output(unit_nr_cube, logger, gw_section, &
2391 20 : "PRINT%LOCAL_BANDGAP", mpi_io=mpi_io)
2392 :
2393 20 : CALL timestop(handle)
2394 :
2395 20 : END SUBROUTINE print_file
2396 :
2397 : ! **************************************************************************************************
2398 : !> \brief ...
2399 : !> \param E_gap_rspace ...
2400 : !> \param E_VBM_rspace ...
2401 : !> \param E_CBM_rspace ...
2402 : !> \param rho_g_dummy ...
2403 : !> \param LDOS ...
2404 : !> \param auxbas_pw_pool ...
2405 : !> \param qs_env ...
2406 : ! **************************************************************************************************
2407 4 : SUBROUTINE create_real_space_grids(E_gap_rspace, E_VBM_rspace, E_CBM_rspace, rho_g_dummy, LDOS, auxbas_pw_pool, qs_env)
2408 : TYPE(pw_r3d_rs_type) :: E_gap_rspace, E_VBM_rspace, E_CBM_rspace
2409 : TYPE(pw_c1d_gs_type) :: rho_g_dummy
2410 : TYPE(pw_r3d_rs_type), ALLOCATABLE, DIMENSION(:) :: LDOS
2411 : TYPE(pw_pool_type), POINTER :: auxbas_pw_pool
2412 : TYPE(qs_environment_type), POINTER :: qs_env
2413 :
2414 : CHARACTER(LEN=*), PARAMETER :: routineN = 'create_real_space_grids'
2415 :
2416 : INTEGER :: handle, i_E, n_E
2417 : TYPE(mp2_type), POINTER :: mp2_env
2418 : TYPE(pw_env_type), POINTER :: pw_env
2419 :
2420 4 : CALL timeset(routineN, handle)
2421 :
2422 4 : CALL get_qs_env(qs_env=qs_env, mp2_env=mp2_env, pw_env=pw_env)
2423 :
2424 4 : CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool)
2425 :
2426 4 : CALL auxbas_pw_pool%create_pw(E_gap_rspace)
2427 4 : CALL auxbas_pw_pool%create_pw(E_VBM_rspace)
2428 4 : CALL auxbas_pw_pool%create_pw(E_CBM_rspace)
2429 4 : CALL auxbas_pw_pool%create_pw(rho_g_dummy)
2430 :
2431 : n_E = INT(mp2_env%ri_g0w0%energy_window_print_loc_bandgap/ &
2432 4 : mp2_env%ri_g0w0%energy_spacing_print_loc_bandgap)
2433 :
2434 28 : ALLOCATE (LDOS(n_E))
2435 :
2436 20 : DO i_E = 1, n_E
2437 20 : CALL auxbas_pw_pool%create_pw(LDOS(i_E))
2438 : END DO
2439 :
2440 4 : CALL timestop(handle)
2441 :
2442 4 : END SUBROUTINE create_real_space_grids
2443 :
2444 : ! **************************************************************************************************
2445 : !> \brief ...
2446 : !> \param delta_corr ...
2447 : !> \param qs_env ...
2448 : !> \param para_env ...
2449 : !> \param para_env_RPA ...
2450 : !> \param kp_grid ...
2451 : !> \param homo ...
2452 : !> \param nmo ...
2453 : !> \param gw_corr_lev_occ ...
2454 : !> \param gw_corr_lev_virt ...
2455 : !> \param omega ...
2456 : !> \param fm_mo_coeff ...
2457 : !> \param Eigenval ...
2458 : !> \param matrix_berry_re_mo_mo ...
2459 : !> \param matrix_berry_im_mo_mo ...
2460 : !> \param first_cycle_periodic_correction ...
2461 : !> \param kpoints ...
2462 : !> \param do_mo_coeff_Gamma_only ...
2463 : !> \param num_kp_grids ...
2464 : !> \param eps_kpoint ...
2465 : !> \param do_extra_kpoints ...
2466 : !> \param do_aux_bas ...
2467 : !> \param frac_aux_mos ...
2468 : ! **************************************************************************************************
2469 260 : SUBROUTINE calc_periodic_correction(delta_corr, qs_env, para_env, para_env_RPA, kp_grid, homo, nmo, &
2470 260 : gw_corr_lev_occ, gw_corr_lev_virt, omega, fm_mo_coeff, Eigenval, &
2471 : matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
2472 : first_cycle_periodic_correction, kpoints, do_mo_coeff_Gamma_only, &
2473 : num_kp_grids, eps_kpoint, do_extra_kpoints, do_aux_bas, frac_aux_mos)
2474 :
2475 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
2476 : INTENT(INOUT) :: delta_corr
2477 : TYPE(qs_environment_type), POINTER :: qs_env
2478 : TYPE(mp_para_env_type), POINTER :: para_env, para_env_RPA
2479 : INTEGER, DIMENSION(:), POINTER :: kp_grid
2480 : INTEGER, INTENT(IN) :: homo, nmo, gw_corr_lev_occ, &
2481 : gw_corr_lev_virt
2482 : REAL(KIND=dp), INTENT(IN) :: omega
2483 : TYPE(cp_fm_type), INTENT(IN) :: fm_mo_coeff
2484 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: Eigenval
2485 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_re_mo_mo, &
2486 : matrix_berry_im_mo_mo
2487 : LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
2488 : TYPE(kpoint_type), POINTER :: kpoints
2489 : LOGICAL, INTENT(IN) :: do_mo_coeff_Gamma_only
2490 : INTEGER, INTENT(IN) :: num_kp_grids
2491 : REAL(KIND=dp), INTENT(IN) :: eps_kpoint
2492 : LOGICAL, INTENT(IN) :: do_extra_kpoints, do_aux_bas
2493 : REAL(KIND=dp), INTENT(IN) :: frac_aux_mos
2494 :
2495 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calc_periodic_correction'
2496 :
2497 : INTEGER :: handle
2498 260 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: eps_head, eps_inv_head
2499 : REAL(KIND=dp), DIMENSION(3, 3) :: h_inv
2500 :
2501 260 : CALL timeset(routineN, handle)
2502 :
2503 260 : IF (first_cycle_periodic_correction) THEN
2504 :
2505 : CALL get_kpoints(qs_env, kpoints, kp_grid, num_kp_grids, para_env, h_inv, nmo, do_mo_coeff_Gamma_only, &
2506 6 : do_extra_kpoints)
2507 :
2508 : CALL get_berry_phase(qs_env, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, fm_mo_coeff, &
2509 : para_env, do_mo_coeff_Gamma_only, homo, nmo, gw_corr_lev_virt, eps_kpoint, do_aux_bas, &
2510 6 : frac_aux_mos)
2511 :
2512 : END IF
2513 :
2514 : CALL compute_eps_head_Berry(eps_head, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, para_env_RPA, &
2515 260 : qs_env, homo, Eigenval, omega)
2516 :
2517 260 : CALL compute_eps_inv_head(eps_inv_head, eps_head, kpoints)
2518 :
2519 : CALL kpoint_sum_for_eps_inv_head_Berry(delta_corr, eps_inv_head, kpoints, qs_env, &
2520 : matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
2521 : homo, gw_corr_lev_occ, gw_corr_lev_virt, para_env_RPA, &
2522 260 : do_extra_kpoints)
2523 :
2524 260 : DEALLOCATE (eps_head, eps_inv_head)
2525 :
2526 260 : first_cycle_periodic_correction = .FALSE.
2527 :
2528 260 : CALL timestop(handle)
2529 :
2530 260 : END SUBROUTINE calc_periodic_correction
2531 :
2532 : ! **************************************************************************************************
2533 : !> \brief ...
2534 : !> \param eps_head ...
2535 : !> \param kpoints ...
2536 : !> \param matrix_berry_re_mo_mo ...
2537 : !> \param matrix_berry_im_mo_mo ...
2538 : !> \param para_env_RPA ...
2539 : !> \param qs_env ...
2540 : !> \param homo ...
2541 : !> \param Eigenval ...
2542 : !> \param omega ...
2543 : ! **************************************************************************************************
2544 260 : SUBROUTINE compute_eps_head_Berry(eps_head, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, para_env_RPA, &
2545 260 : qs_env, homo, Eigenval, omega)
2546 :
2547 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
2548 : INTENT(OUT) :: eps_head
2549 : TYPE(kpoint_type), POINTER :: kpoints
2550 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: matrix_berry_re_mo_mo, &
2551 : matrix_berry_im_mo_mo
2552 : TYPE(mp_para_env_type), INTENT(IN) :: para_env_RPA
2553 : TYPE(qs_environment_type), POINTER :: qs_env
2554 : INTEGER, INTENT(IN) :: homo
2555 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: Eigenval
2556 : REAL(KIND=dp), INTENT(IN) :: omega
2557 :
2558 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_eps_head_Berry'
2559 :
2560 : INTEGER :: col, col_end_in_block, col_offset, col_size, handle, i_col, i_row, ikp, nkp, nmo, &
2561 : row, row_offset, row_size, row_start_in_block
2562 : REAL(KIND=dp) :: abs_k_square, cell_volume, &
2563 : correct_kpoint(3), cos_square, &
2564 : eigen_diff, relative_kpoint(3), &
2565 : sin_square
2566 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: P_head
2567 260 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: data_block
2568 : TYPE(cell_type), POINTER :: cell
2569 : TYPE(dbcsr_iterator_type) :: iter
2570 :
2571 260 : CALL timeset(routineN, handle)
2572 :
2573 260 : CALL get_qs_env(qs_env=qs_env, cell=cell)
2574 260 : CALL get_cell(cell=cell, deth=cell_volume)
2575 :
2576 260 : NULLIFY (data_block)
2577 :
2578 260 : nkp = kpoints%nkp
2579 :
2580 260 : nmo = SIZE(Eigenval)
2581 :
2582 780 : ALLOCATE (P_head(nkp))
2583 260 : P_head(:) = 0.0_dp
2584 :
2585 520 : ALLOCATE (eps_head(nkp))
2586 260 : eps_head(:) = 0.0_dp
2587 :
2588 279620 : DO ikp = 1, nkp
2589 :
2590 3631680 : relative_kpoint(1:3) = MATMUL(cell%hmat, kpoints%xkp(1:3, ikp))
2591 :
2592 1117440 : correct_kpoint(1:3) = twopi*kpoints%xkp(1:3, ikp)
2593 :
2594 279360 : abs_k_square = (correct_kpoint(1))**2 + (correct_kpoint(2))**2 + (correct_kpoint(3))**2
2595 :
2596 : ! real part of the Berry phase
2597 279360 : CALL dbcsr_iterator_start(iter, matrix_berry_re_mo_mo(ikp)%matrix)
2598 465120 : DO WHILE (dbcsr_iterator_blocks_left(iter))
2599 :
2600 : CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
2601 : row_size=row_size, col_size=col_size, &
2602 185760 : row_offset=row_offset, col_offset=col_offset)
2603 :
2604 185760 : IF (row_offset + row_size <= homo .OR. col_offset > homo) CYCLE
2605 :
2606 185760 : IF (row_offset <= homo) THEN
2607 139680 : row_start_in_block = homo - row_offset + 2
2608 : ELSE
2609 : row_start_in_block = 1
2610 : END IF
2611 :
2612 185760 : IF (col_offset + col_size - 1 > homo) THEN
2613 185760 : col_end_in_block = homo - col_offset + 1
2614 : ELSE
2615 : col_end_in_block = col_size
2616 : END IF
2617 :
2618 1929600 : DO i_row = row_start_in_block, MIN(row_size, nmo - row_offset + 1)
2619 :
2620 7508160 : DO i_col = 1, MIN(col_end_in_block, nmo - col_offset + 1)
2621 :
2622 5857920 : eigen_diff = Eigenval(i_col + col_offset - 1) - Eigenval(i_row + row_offset - 1)
2623 :
2624 5857920 : cos_square = (data_block(i_row, i_col))**2
2625 :
2626 7322400 : P_head(ikp) = P_head(ikp) + 2.0_dp*eigen_diff/(omega**2 + eigen_diff**2)*cos_square/abs_k_square
2627 :
2628 : END DO
2629 :
2630 : END DO
2631 :
2632 : END DO
2633 :
2634 279360 : CALL dbcsr_iterator_stop(iter)
2635 :
2636 : ! imaginary part of the Berry phase
2637 279360 : CALL dbcsr_iterator_start(iter, matrix_berry_im_mo_mo(ikp)%matrix)
2638 465120 : DO WHILE (dbcsr_iterator_blocks_left(iter))
2639 :
2640 : CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
2641 : row_size=row_size, col_size=col_size, &
2642 185760 : row_offset=row_offset, col_offset=col_offset)
2643 :
2644 185760 : IF (row_offset + row_size <= homo .OR. col_offset > homo) CYCLE
2645 :
2646 185760 : IF (row_offset <= homo) THEN
2647 139680 : row_start_in_block = homo - row_offset + 2
2648 : ELSE
2649 : row_start_in_block = 1
2650 : END IF
2651 :
2652 185760 : IF (col_offset + col_size - 1 > homo) THEN
2653 185760 : col_end_in_block = homo - col_offset + 1
2654 : ELSE
2655 : col_end_in_block = col_size
2656 : END IF
2657 :
2658 1929600 : DO i_row = row_start_in_block, MIN(row_size, nmo - row_offset + 1)
2659 :
2660 7508160 : DO i_col = 1, MIN(col_end_in_block, nmo - col_offset + 1)
2661 :
2662 5857920 : eigen_diff = Eigenval(i_col + col_offset - 1) - Eigenval(i_row + row_offset - 1)
2663 :
2664 5857920 : sin_square = (data_block(i_row, i_col))**2
2665 :
2666 7322400 : P_head(ikp) = P_head(ikp) + 2.0_dp*eigen_diff/(omega**2 + eigen_diff**2)*sin_square/abs_k_square
2667 :
2668 : END DO
2669 :
2670 : END DO
2671 :
2672 : END DO
2673 :
2674 838340 : CALL dbcsr_iterator_stop(iter)
2675 :
2676 : END DO
2677 :
2678 260 : CALL para_env_RPA%sum(P_head)
2679 :
2680 : ! normalize eps_head
2681 : ! 2.0_dp due to closed shell
2682 279620 : eps_head(:) = 1.0_dp - 2.0_dp*P_head(:)/cell_volume*fourpi
2683 :
2684 260 : DEALLOCATE (P_head)
2685 :
2686 260 : CALL timestop(handle)
2687 :
2688 520 : END SUBROUTINE compute_eps_head_Berry
2689 :
2690 : ! **************************************************************************************************
2691 : !> \brief ...
2692 : !> \param qs_env ...
2693 : !> \param kpoints ...
2694 : !> \param matrix_berry_re_mo_mo ...
2695 : !> \param matrix_berry_im_mo_mo ...
2696 : !> \param fm_mo_coeff ...
2697 : !> \param para_env ...
2698 : !> \param do_mo_coeff_Gamma_only ...
2699 : !> \param homo ...
2700 : !> \param nmo ...
2701 : !> \param gw_corr_lev_virt ...
2702 : !> \param eps_kpoint ...
2703 : !> \param do_aux_bas ...
2704 : !> \param frac_aux_mos ...
2705 : ! **************************************************************************************************
2706 6 : SUBROUTINE get_berry_phase(qs_env, kpoints, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, fm_mo_coeff, para_env, &
2707 : do_mo_coeff_Gamma_only, homo, nmo, gw_corr_lev_virt, eps_kpoint, do_aux_bas, &
2708 : frac_aux_mos)
2709 : TYPE(qs_environment_type), POINTER :: qs_env
2710 : TYPE(kpoint_type), POINTER :: kpoints
2711 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_re_mo_mo, &
2712 : matrix_berry_im_mo_mo
2713 : TYPE(cp_fm_type), INTENT(IN) :: fm_mo_coeff
2714 : TYPE(mp_para_env_type), POINTER :: para_env
2715 : LOGICAL, INTENT(IN) :: do_mo_coeff_Gamma_only
2716 : INTEGER, INTENT(IN) :: homo, nmo, gw_corr_lev_virt
2717 : REAL(KIND=dp), INTENT(IN) :: eps_kpoint
2718 : LOGICAL, INTENT(IN) :: do_aux_bas
2719 : REAL(KIND=dp), INTENT(IN) :: frac_aux_mos
2720 :
2721 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_berry_phase'
2722 :
2723 : INTEGER :: col_index, handle, i_col_local, ikind, &
2724 : ikp, nao_aux, ncol_local, nkind, nkp, &
2725 : nmo_for_aux_bas
2726 6 : INTEGER, DIMENSION(:), POINTER :: col_indices
2727 : REAL(dp) :: abs_kpoint, correct_kpoint(3), &
2728 : scale_kpoint
2729 6 : REAL(KIND=dp), DIMENSION(:), POINTER :: evals_P, evals_P_sqrt_inv
2730 : TYPE(cell_type), POINTER :: cell
2731 : TYPE(cp_fm_struct_type), POINTER :: fm_struct_aux_aux
2732 : TYPE(cp_fm_type) :: fm_mat_eigv_P, fm_mat_P, fm_mat_P_sqrt_inv, fm_mat_s_aux_aux_inv, &
2733 : fm_mat_scaled_eigv_P, fm_mat_work_aux_aux, fm_mo_coeff_im, fm_mo_coeff_re
2734 6 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_s, matrix_s_aux_aux, &
2735 6 : matrix_s_aux_orb
2736 : TYPE(dbcsr_type), POINTER :: cosmat, cosmat_desymm, mat_mo_coeff_aux, mat_mo_coeff_aux_2, &
2737 : mat_mo_coeff_Gamma_all, mat_mo_coeff_Gamma_occ_and_GW, mat_mo_coeff_im, mat_mo_coeff_re, &
2738 : mat_work_aux_orb, mat_work_aux_orb_2, matrix_P, matrix_P_sqrt, matrix_P_sqrt_inv, &
2739 : matrix_s_inv_aux_aux, sinmat, sinmat_desymm, tmp
2740 6 : TYPE(gto_basis_set_p_type), DIMENSION(:), POINTER :: gw_aux_basis_set_list, orb_basis_set_list
2741 : TYPE(gto_basis_set_type), POINTER :: basis_set_gw_aux
2742 : TYPE(neighbor_list_set_p_type), DIMENSION(:), &
2743 6 : POINTER :: sab_orb, sab_orb_mic, sgwgw_list, &
2744 6 : sgworb_list
2745 6 : TYPE(qs_kind_type), DIMENSION(:), POINTER :: qs_kind_set
2746 : TYPE(qs_kind_type), POINTER :: qs_kind
2747 : TYPE(qs_ks_env_type), POINTER :: ks_env
2748 :
2749 6 : CALL timeset(routineN, handle)
2750 :
2751 6 : nkp = kpoints%nkp
2752 :
2753 6 : NULLIFY (matrix_berry_re_mo_mo, matrix_s, cell, matrix_berry_im_mo_mo, sinmat, cosmat, tmp, &
2754 6 : cosmat_desymm, sinmat_desymm, qs_kind_set, orb_basis_set_list, sab_orb_mic)
2755 :
2756 : CALL get_qs_env(qs_env=qs_env, &
2757 : cell=cell, &
2758 : matrix_s=matrix_s, &
2759 : qs_kind_set=qs_kind_set, &
2760 : nkind=nkind, &
2761 : ks_env=ks_env, &
2762 6 : sab_orb=sab_orb)
2763 :
2764 30 : ALLOCATE (orb_basis_set_list(nkind))
2765 6 : CALL basis_set_list_setup(orb_basis_set_list, "ORB", qs_kind_set)
2766 :
2767 6 : CALL setup_neighbor_list(sab_orb_mic, orb_basis_set_list, qs_env=qs_env, mic=.FALSE.)
2768 :
2769 : ! create dbcsr matrix of mo_coeff for multiplcation
2770 6 : NULLIFY (mat_mo_coeff_re)
2771 6 : CALL dbcsr_init_p(mat_mo_coeff_re)
2772 : CALL dbcsr_create(matrix=mat_mo_coeff_re, &
2773 : template=matrix_s(1)%matrix, &
2774 6 : matrix_type=dbcsr_type_no_symmetry)
2775 :
2776 6 : NULLIFY (mat_mo_coeff_im)
2777 6 : CALL dbcsr_init_p(mat_mo_coeff_im)
2778 : CALL dbcsr_create(matrix=mat_mo_coeff_im, &
2779 : template=matrix_s(1)%matrix, &
2780 6 : matrix_type=dbcsr_type_no_symmetry)
2781 :
2782 6 : NULLIFY (mat_mo_coeff_Gamma_all)
2783 6 : CALL dbcsr_init_p(mat_mo_coeff_Gamma_all)
2784 : CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_all, &
2785 : template=matrix_s(1)%matrix, &
2786 6 : matrix_type=dbcsr_type_no_symmetry)
2787 :
2788 6 : CALL copy_fm_to_dbcsr(fm_mo_coeff, mat_mo_coeff_Gamma_all, keep_sparsity=.FALSE.)
2789 :
2790 6 : NULLIFY (mat_mo_coeff_Gamma_occ_and_GW)
2791 6 : CALL dbcsr_init_p(mat_mo_coeff_Gamma_occ_and_GW)
2792 : CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_occ_and_GW, &
2793 : template=matrix_s(1)%matrix, &
2794 6 : matrix_type=dbcsr_type_no_symmetry)
2795 :
2796 6 : CALL copy_fm_to_dbcsr(fm_mo_coeff, mat_mo_coeff_Gamma_occ_and_GW, keep_sparsity=.FALSE.)
2797 :
2798 6 : IF (.NOT. do_aux_bas) THEN
2799 :
2800 : ! allocate intermediate matrices
2801 4 : CALL dbcsr_init_p(cosmat)
2802 4 : CALL dbcsr_init_p(sinmat)
2803 4 : CALL dbcsr_init_p(tmp)
2804 4 : CALL dbcsr_init_p(cosmat_desymm)
2805 4 : CALL dbcsr_init_p(sinmat_desymm)
2806 4 : CALL dbcsr_create(matrix=cosmat, template=matrix_s(1)%matrix)
2807 4 : CALL dbcsr_create(matrix=sinmat, template=matrix_s(1)%matrix)
2808 : CALL dbcsr_create(matrix=tmp, &
2809 : template=matrix_s(1)%matrix, &
2810 4 : matrix_type=dbcsr_type_no_symmetry)
2811 : CALL dbcsr_create(matrix=cosmat_desymm, &
2812 : template=matrix_s(1)%matrix, &
2813 4 : matrix_type=dbcsr_type_no_symmetry)
2814 : CALL dbcsr_create(matrix=sinmat_desymm, &
2815 : template=matrix_s(1)%matrix, &
2816 4 : matrix_type=dbcsr_type_no_symmetry)
2817 4 : CALL dbcsr_copy(cosmat, matrix_s(1)%matrix)
2818 4 : CALL dbcsr_copy(sinmat, matrix_s(1)%matrix)
2819 :
2820 4 : CALL dbcsr_allocate_matrix_set(matrix_berry_re_mo_mo, nkp)
2821 4 : CALL dbcsr_allocate_matrix_set(matrix_berry_im_mo_mo, nkp)
2822 :
2823 : ELSE
2824 :
2825 2 : NULLIFY (gw_aux_basis_set_list)
2826 10 : ALLOCATE (gw_aux_basis_set_list(nkind))
2827 :
2828 6 : DO ikind = 1, nkind
2829 :
2830 4 : NULLIFY (gw_aux_basis_set_list(ikind)%gto_basis_set)
2831 :
2832 4 : NULLIFY (basis_set_gw_aux)
2833 :
2834 4 : qs_kind => qs_kind_set(ikind)
2835 4 : CALL get_qs_kind(qs_kind=qs_kind, basis_set=basis_set_gw_aux, basis_type="AUX_GW")
2836 4 : CPASSERT(ASSOCIATED(basis_set_gw_aux))
2837 :
2838 4 : basis_set_gw_aux%kind_radius = orb_basis_set_list(ikind)%gto_basis_set%kind_radius
2839 :
2840 6 : gw_aux_basis_set_list(ikind)%gto_basis_set => basis_set_gw_aux
2841 :
2842 : END DO
2843 :
2844 : ! neighbor lists
2845 2 : NULLIFY (sgwgw_list, sgworb_list)
2846 2 : CALL setup_neighbor_list(sgwgw_list, gw_aux_basis_set_list, qs_env=qs_env)
2847 2 : CALL setup_neighbor_list(sgworb_list, gw_aux_basis_set_list, orb_basis_set_list, qs_env=qs_env)
2848 :
2849 2 : NULLIFY (matrix_s_aux_aux, matrix_s_aux_orb)
2850 :
2851 : ! build overlap matrix in gw aux basis and the mixed gw aux basis-orb basis
2852 : CALL build_overlap_matrix_simple(ks_env, matrix_s_aux_aux, &
2853 2 : gw_aux_basis_set_list, gw_aux_basis_set_list, sgwgw_list)
2854 :
2855 : CALL build_overlap_matrix_simple(ks_env, matrix_s_aux_orb, &
2856 2 : gw_aux_basis_set_list, orb_basis_set_list, sgworb_list)
2857 :
2858 2 : CALL dbcsr_get_info(matrix_s_aux_aux(1)%matrix, nfullrows_total=nao_aux)
2859 :
2860 2 : nmo_for_aux_bas = FLOOR(frac_aux_mos*REAL(nao_aux, KIND=dp))
2861 :
2862 : CALL cp_fm_struct_create(fm_struct_aux_aux, &
2863 : context=fm_mo_coeff%matrix_struct%context, &
2864 : nrow_global=nao_aux, &
2865 : ncol_global=nao_aux, &
2866 2 : para_env=para_env)
2867 :
2868 2 : NULLIFY (mat_work_aux_orb)
2869 2 : CALL dbcsr_init_p(mat_work_aux_orb)
2870 : CALL dbcsr_create(matrix=mat_work_aux_orb, &
2871 : template=matrix_s_aux_orb(1)%matrix, &
2872 2 : matrix_type=dbcsr_type_no_symmetry)
2873 :
2874 2 : NULLIFY (mat_work_aux_orb_2)
2875 2 : CALL dbcsr_init_p(mat_work_aux_orb_2)
2876 : CALL dbcsr_create(matrix=mat_work_aux_orb_2, &
2877 : template=matrix_s_aux_orb(1)%matrix, &
2878 2 : matrix_type=dbcsr_type_no_symmetry)
2879 :
2880 2 : NULLIFY (mat_mo_coeff_aux)
2881 2 : CALL dbcsr_init_p(mat_mo_coeff_aux)
2882 : CALL dbcsr_create(matrix=mat_mo_coeff_aux, &
2883 : template=matrix_s_aux_orb(1)%matrix, &
2884 2 : matrix_type=dbcsr_type_no_symmetry)
2885 :
2886 2 : NULLIFY (mat_mo_coeff_aux_2)
2887 2 : CALL dbcsr_init_p(mat_mo_coeff_aux_2)
2888 : CALL dbcsr_create(matrix=mat_mo_coeff_aux_2, &
2889 : template=matrix_s_aux_orb(1)%matrix, &
2890 2 : matrix_type=dbcsr_type_no_symmetry)
2891 :
2892 2 : NULLIFY (matrix_s_inv_aux_aux)
2893 2 : CALL dbcsr_init_p(matrix_s_inv_aux_aux)
2894 : CALL dbcsr_create(matrix=matrix_s_inv_aux_aux, &
2895 : template=matrix_s_aux_aux(1)%matrix, &
2896 2 : matrix_type=dbcsr_type_no_symmetry)
2897 :
2898 2 : NULLIFY (matrix_P)
2899 2 : CALL dbcsr_init_p(matrix_P)
2900 : CALL dbcsr_create(matrix=matrix_P, &
2901 : template=matrix_s(1)%matrix, &
2902 2 : matrix_type=dbcsr_type_no_symmetry)
2903 :
2904 2 : NULLIFY (matrix_P_sqrt)
2905 2 : CALL dbcsr_init_p(matrix_P_sqrt)
2906 : CALL dbcsr_create(matrix=matrix_P_sqrt, &
2907 : template=matrix_s(1)%matrix, &
2908 2 : matrix_type=dbcsr_type_no_symmetry)
2909 :
2910 2 : NULLIFY (matrix_P_sqrt_inv)
2911 2 : CALL dbcsr_init_p(matrix_P_sqrt_inv)
2912 : CALL dbcsr_create(matrix=matrix_P_sqrt_inv, &
2913 : template=matrix_s(1)%matrix, &
2914 2 : matrix_type=dbcsr_type_no_symmetry)
2915 :
2916 2 : CALL cp_fm_create(fm_mat_s_aux_aux_inv, fm_struct_aux_aux, name="inverse overlap mat")
2917 2 : CALL cp_fm_create(fm_mat_work_aux_aux, fm_struct_aux_aux, name="work mat")
2918 2 : CALL cp_fm_create(fm_mat_P, fm_mo_coeff%matrix_struct)
2919 2 : CALL cp_fm_create(fm_mat_eigv_P, fm_mo_coeff%matrix_struct)
2920 2 : CALL cp_fm_create(fm_mat_scaled_eigv_P, fm_mo_coeff%matrix_struct)
2921 2 : CALL cp_fm_create(fm_mat_P_sqrt_inv, fm_mo_coeff%matrix_struct)
2922 :
2923 : NULLIFY (evals_P)
2924 6 : ALLOCATE (evals_P(nmo))
2925 :
2926 2 : NULLIFY (evals_P_sqrt_inv)
2927 4 : ALLOCATE (evals_P_sqrt_inv(nmo))
2928 :
2929 2 : CALL copy_dbcsr_to_fm(matrix_s_aux_aux(1)%matrix, fm_mat_s_aux_aux_inv)
2930 : ! Calculate S_inverse
2931 2 : CALL cp_fm_cholesky_decompose(fm_mat_s_aux_aux_inv)
2932 2 : CALL cp_fm_cholesky_invert(fm_mat_s_aux_aux_inv)
2933 : ! Symmetrize the guy
2934 2 : CALL cp_fm_uplo_to_full(fm_mat_s_aux_aux_inv, fm_mat_work_aux_aux)
2935 :
2936 2 : CALL copy_fm_to_dbcsr(fm_mat_s_aux_aux_inv, matrix_s_inv_aux_aux, keep_sparsity=.FALSE.)
2937 :
2938 : CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s_inv_aux_aux, matrix_s_aux_orb(1)%matrix, 0.0_dp, mat_work_aux_orb, &
2939 2 : filter_eps=1.0E-15_dp)
2940 :
2941 : CALL dbcsr_multiply('N', 'N', 1.0_dp, mat_work_aux_orb, mat_mo_coeff_Gamma_all, 0.0_dp, mat_mo_coeff_aux_2, &
2942 2 : last_column=nmo_for_aux_bas, filter_eps=1.0E-15_dp)
2943 :
2944 : CALL dbcsr_multiply('N', 'N', 1.0_dp, matrix_s_aux_aux(1)%matrix, mat_mo_coeff_aux_2, 0.0_dp, mat_work_aux_orb, &
2945 2 : filter_eps=1.0E-15_dp)
2946 :
2947 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_aux_2, mat_work_aux_orb, 0.0_dp, matrix_P, &
2948 2 : filter_eps=1.0E-15_dp)
2949 :
2950 2 : CALL copy_dbcsr_to_fm(matrix_P, fm_mat_P)
2951 :
2952 2 : CALL cp_fm_syevd(fm_mat_P, fm_mat_eigv_P, evals_P)
2953 :
2954 : ! only invert the eigenvalues which correspond to the MOs used in the aux. basis
2955 62 : evals_P_sqrt_inv(1:nmo - nmo_for_aux_bas) = 0.0_dp
2956 46 : evals_P_sqrt_inv(nmo - nmo_for_aux_bas + 1:nmo) = 1.0_dp/SQRT(evals_P(nmo - nmo_for_aux_bas + 1:nmo))
2957 :
2958 2 : CALL cp_fm_to_fm(fm_mat_eigv_P, fm_mat_scaled_eigv_P)
2959 :
2960 : CALL cp_fm_get_info(matrix=fm_mat_scaled_eigv_P, &
2961 : ncol_local=ncol_local, &
2962 2 : col_indices=col_indices)
2963 :
2964 2 : CALL para_env%sync()
2965 :
2966 : ! multiply eigenvectors with inverse sqrt of eigenvalues
2967 84 : DO i_col_local = 1, ncol_local
2968 :
2969 82 : col_index = col_indices(i_col_local)
2970 :
2971 : fm_mat_scaled_eigv_P%local_data(:, i_col_local) = &
2972 1765 : fm_mat_scaled_eigv_P%local_data(:, i_col_local)*evals_P_sqrt_inv(col_index)
2973 :
2974 : END DO
2975 :
2976 2 : CALL para_env%sync()
2977 :
2978 : CALL parallel_gemm(transa="N", transb="T", m=nmo, n=nmo, k=nmo, alpha=1.0_dp, &
2979 : matrix_a=fm_mat_eigv_P, matrix_b=fm_mat_scaled_eigv_P, beta=0.0_dp, &
2980 2 : matrix_c=fm_mat_P_sqrt_inv)
2981 :
2982 2 : CALL copy_fm_to_dbcsr(fm_mat_P_sqrt_inv, matrix_P_sqrt_inv, keep_sparsity=.FALSE.)
2983 :
2984 : CALL dbcsr_multiply('N', 'N', 1.0_dp, mat_mo_coeff_aux_2, matrix_P_sqrt_inv, 0.0_dp, mat_mo_coeff_aux, &
2985 2 : filter_eps=1.0E-15_dp)
2986 :
2987 : ! allocate intermediate matrices
2988 2 : CALL dbcsr_init_p(cosmat)
2989 2 : CALL dbcsr_init_p(sinmat)
2990 2 : CALL dbcsr_init_p(tmp)
2991 2 : CALL dbcsr_init_p(cosmat_desymm)
2992 2 : CALL dbcsr_init_p(sinmat_desymm)
2993 2 : CALL dbcsr_create(matrix=cosmat, template=matrix_s_aux_aux(1)%matrix)
2994 2 : CALL dbcsr_create(matrix=sinmat, template=matrix_s_aux_aux(1)%matrix)
2995 : CALL dbcsr_create(matrix=tmp, &
2996 : template=matrix_s_aux_orb(1)%matrix, &
2997 2 : matrix_type=dbcsr_type_no_symmetry)
2998 : CALL dbcsr_create(matrix=cosmat_desymm, &
2999 : template=matrix_s_aux_aux(1)%matrix, &
3000 2 : matrix_type=dbcsr_type_no_symmetry)
3001 : CALL dbcsr_create(matrix=sinmat_desymm, &
3002 : template=matrix_s_aux_aux(1)%matrix, &
3003 2 : matrix_type=dbcsr_type_no_symmetry)
3004 2 : CALL dbcsr_copy(cosmat, matrix_s_aux_aux(1)%matrix)
3005 2 : CALL dbcsr_copy(sinmat, matrix_s_aux_aux(1)%matrix)
3006 :
3007 2 : CALL dbcsr_allocate_matrix_set(matrix_berry_re_mo_mo, nkp)
3008 2 : CALL dbcsr_allocate_matrix_set(matrix_berry_im_mo_mo, nkp)
3009 :
3010 : ! allocate the new MO coefficients in the aux basis
3011 2 : CALL dbcsr_release_p(mat_mo_coeff_Gamma_all)
3012 2 : CALL dbcsr_release_p(mat_mo_coeff_Gamma_occ_and_GW)
3013 :
3014 2 : NULLIFY (mat_mo_coeff_Gamma_all)
3015 2 : CALL dbcsr_init_p(mat_mo_coeff_Gamma_all)
3016 : CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_all, &
3017 : template=matrix_s_aux_orb(1)%matrix, &
3018 2 : matrix_type=dbcsr_type_no_symmetry)
3019 :
3020 2 : CALL dbcsr_copy(mat_mo_coeff_Gamma_all, mat_mo_coeff_aux)
3021 :
3022 2 : NULLIFY (mat_mo_coeff_Gamma_occ_and_GW)
3023 2 : CALL dbcsr_init_p(mat_mo_coeff_Gamma_occ_and_GW)
3024 : CALL dbcsr_create(matrix=mat_mo_coeff_Gamma_occ_and_GW, &
3025 : template=matrix_s_aux_orb(1)%matrix, &
3026 2 : matrix_type=dbcsr_type_no_symmetry)
3027 :
3028 2 : CALL dbcsr_copy(mat_mo_coeff_Gamma_occ_and_GW, mat_mo_coeff_aux)
3029 :
3030 8 : DEALLOCATE (evals_P, evals_P_sqrt_inv)
3031 :
3032 : END IF
3033 :
3034 6 : CALL remove_unnecessary_blocks(mat_mo_coeff_Gamma_occ_and_GW, homo, gw_corr_lev_virt)
3035 :
3036 11166 : DO ikp = 1, nkp
3037 :
3038 11160 : ALLOCATE (matrix_berry_re_mo_mo(ikp)%matrix)
3039 11160 : CALL dbcsr_init_p(matrix_berry_re_mo_mo(ikp)%matrix)
3040 : CALL dbcsr_create(matrix_berry_re_mo_mo(ikp)%matrix, &
3041 : template=matrix_s(1)%matrix, &
3042 11160 : matrix_type=dbcsr_type_no_symmetry)
3043 11160 : CALL dbcsr_desymmetrize(matrix_s(1)%matrix, matrix_berry_re_mo_mo(ikp)%matrix)
3044 11160 : CALL dbcsr_set(matrix_berry_re_mo_mo(ikp)%matrix, 0.0_dp)
3045 :
3046 11160 : ALLOCATE (matrix_berry_im_mo_mo(ikp)%matrix)
3047 11160 : CALL dbcsr_init_p(matrix_berry_im_mo_mo(ikp)%matrix)
3048 : CALL dbcsr_create(matrix_berry_im_mo_mo(ikp)%matrix, &
3049 : template=matrix_s(1)%matrix, &
3050 11160 : matrix_type=dbcsr_type_no_symmetry)
3051 11160 : CALL dbcsr_desymmetrize(matrix_s(1)%matrix, matrix_berry_im_mo_mo(ikp)%matrix)
3052 11160 : CALL dbcsr_set(matrix_berry_im_mo_mo(ikp)%matrix, 0.0_dp)
3053 :
3054 44640 : correct_kpoint(1:3) = -twopi*kpoints%xkp(1:3, ikp)
3055 :
3056 11160 : abs_kpoint = SQRT(correct_kpoint(1)**2 + correct_kpoint(2)**2 + correct_kpoint(3)**2)
3057 :
3058 11160 : IF (abs_kpoint < eps_kpoint) THEN
3059 :
3060 0 : scale_kpoint = eps_kpoint/abs_kpoint
3061 0 : correct_kpoint(:) = correct_kpoint(:)*scale_kpoint
3062 :
3063 : END IF
3064 :
3065 : ! get the Berry phase
3066 11160 : IF (do_aux_bas) THEN
3067 : CALL build_berry_moment_matrix(qs_env, cosmat, sinmat, correct_kpoint, sab_orb_external=sab_orb_mic, &
3068 1944 : basis_type="AUX_GW")
3069 : ELSE
3070 : CALL build_berry_moment_matrix(qs_env, cosmat, sinmat, correct_kpoint, sab_orb_external=sab_orb_mic, &
3071 9216 : basis_type="ORB")
3072 : END IF
3073 :
3074 11160 : IF (do_mo_coeff_Gamma_only) THEN
3075 :
3076 11160 : CALL dbcsr_desymmetrize(cosmat, cosmat_desymm)
3077 :
3078 : CALL dbcsr_multiply('N', 'N', 1.0_dp, cosmat_desymm, mat_mo_coeff_Gamma_occ_and_GW, 0.0_dp, tmp, &
3079 11160 : filter_eps=1.0E-15_dp)
3080 :
3081 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
3082 11160 : matrix_berry_re_mo_mo(ikp)%matrix, filter_eps=1.0E-15_dp)
3083 :
3084 11160 : CALL dbcsr_desymmetrize(sinmat, sinmat_desymm)
3085 :
3086 : CALL dbcsr_multiply('N', 'N', 1.0_dp, sinmat_desymm, mat_mo_coeff_Gamma_occ_and_GW, 0.0_dp, tmp, &
3087 11160 : filter_eps=1.0E-15_dp)
3088 :
3089 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
3090 11160 : matrix_berry_im_mo_mo(ikp)%matrix, filter_eps=1.0E-15_dp)
3091 :
3092 : ELSE
3093 :
3094 : ! get mo coeff at the ikp
3095 0 : CALL cp_fm_create(fm_mo_coeff_re, kpoints%kp_env(ikp)%kpoint_env%mos(1)%cmo_coeff%matrix_struct)
3096 0 : CALL cp_fm_create(fm_mo_coeff_im, kpoints%kp_env(ikp)%kpoint_env%mos(1)%cmo_coeff%matrix_struct)
3097 : CALL cp_cfm_to_fm(kpoints%kp_env(ikp)%kpoint_env%mos(1)%cmo_coeff, &
3098 0 : fm_mo_coeff_re, fm_mo_coeff_im)
3099 0 : CALL copy_fm_to_dbcsr(fm_mo_coeff_re, mat_mo_coeff_re, keep_sparsity=.FALSE.)
3100 0 : CALL copy_fm_to_dbcsr(fm_mo_coeff_im, mat_mo_coeff_im, keep_sparsity=.FALSE.)
3101 0 : CALL cp_fm_release(fm_mo_coeff_re)
3102 0 : CALL cp_fm_release(fm_mo_coeff_im)
3103 :
3104 0 : CALL dbcsr_desymmetrize(cosmat, cosmat_desymm)
3105 :
3106 0 : CALL dbcsr_desymmetrize(sinmat, sinmat_desymm)
3107 :
3108 : ! I.
3109 0 : CALL dbcsr_multiply('N', 'N', 1.0_dp, cosmat_desymm, mat_mo_coeff_re, 0.0_dp, tmp)
3110 :
3111 : ! I.1
3112 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
3113 0 : matrix_berry_re_mo_mo(ikp)%matrix)
3114 :
3115 : ! II.
3116 0 : CALL dbcsr_multiply('N', 'N', 1.0_dp, sinmat_desymm, mat_mo_coeff_re, 0.0_dp, tmp)
3117 :
3118 : ! II.5
3119 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 0.0_dp, &
3120 0 : matrix_berry_im_mo_mo(ikp)%matrix)
3121 :
3122 : ! III.
3123 0 : CALL dbcsr_multiply('N', 'N', 1.0_dp, cosmat_desymm, mat_mo_coeff_im, 0.0_dp, tmp)
3124 :
3125 : ! III.7
3126 : CALL dbcsr_multiply('T', 'N', 1.0_dp, mat_mo_coeff_Gamma_all, tmp, 1.0_dp, &
3127 0 : matrix_berry_im_mo_mo(ikp)%matrix)
3128 :
3129 : ! IV.
3130 0 : CALL dbcsr_multiply('N', 'N', 1.0_dp, sinmat_desymm, mat_mo_coeff_im, 0.0_dp, tmp)
3131 :
3132 : ! IV.3
3133 : CALL dbcsr_multiply('T', 'N', -1.0_dp, mat_mo_coeff_Gamma_all, tmp, 1.0_dp, &
3134 0 : matrix_berry_re_mo_mo(ikp)%matrix)
3135 :
3136 : END IF
3137 :
3138 11166 : IF (abs_kpoint < eps_kpoint) THEN
3139 :
3140 0 : CALL dbcsr_scale(matrix_berry_im_mo_mo(ikp)%matrix, 1.0_dp/scale_kpoint)
3141 0 : CALL dbcsr_set(matrix_berry_re_mo_mo(ikp)%matrix, 0.0_dp)
3142 0 : CALL dbcsr_add_on_diag(matrix_berry_re_mo_mo(ikp)%matrix, 1.0_dp)
3143 :
3144 : END IF
3145 :
3146 : END DO
3147 :
3148 6 : CALL dbcsr_release_p(cosmat)
3149 6 : CALL dbcsr_release_p(sinmat)
3150 6 : CALL dbcsr_release_p(mat_mo_coeff_re)
3151 6 : CALL dbcsr_release_p(mat_mo_coeff_im)
3152 6 : CALL dbcsr_release_p(mat_mo_coeff_Gamma_all)
3153 6 : CALL dbcsr_release_p(mat_mo_coeff_Gamma_occ_and_GW)
3154 6 : CALL dbcsr_release_p(tmp)
3155 6 : CALL dbcsr_release_p(cosmat_desymm)
3156 6 : CALL dbcsr_release_p(sinmat_desymm)
3157 6 : DEALLOCATE (orb_basis_set_list)
3158 :
3159 6 : CALL release_neighbor_list_sets(sab_orb_mic)
3160 :
3161 6 : IF (do_aux_bas) THEN
3162 :
3163 2 : DEALLOCATE (gw_aux_basis_set_list)
3164 2 : CALL dbcsr_deallocate_matrix_set(matrix_s_aux_aux)
3165 2 : CALL dbcsr_deallocate_matrix_set(matrix_s_aux_orb)
3166 2 : CALL dbcsr_release_p(mat_work_aux_orb)
3167 2 : CALL dbcsr_release_p(mat_work_aux_orb_2)
3168 2 : CALL dbcsr_release_p(mat_mo_coeff_aux)
3169 2 : CALL dbcsr_release_p(mat_mo_coeff_aux_2)
3170 2 : CALL dbcsr_release_p(matrix_s_inv_aux_aux)
3171 2 : CALL dbcsr_release_p(matrix_P)
3172 2 : CALL dbcsr_release_p(matrix_P_sqrt)
3173 2 : CALL dbcsr_release_p(matrix_P_sqrt_inv)
3174 :
3175 2 : CALL cp_fm_struct_release(fm_struct_aux_aux)
3176 :
3177 2 : CALL cp_fm_release(fm_mat_s_aux_aux_inv)
3178 2 : CALL cp_fm_release(fm_mat_work_aux_aux)
3179 2 : CALL cp_fm_release(fm_mat_P)
3180 2 : CALL cp_fm_release(fm_mat_eigv_P)
3181 2 : CALL cp_fm_release(fm_mat_scaled_eigv_P)
3182 2 : CALL cp_fm_release(fm_mat_P_sqrt_inv)
3183 :
3184 : ! Deallocate the neighbor list structure
3185 2 : CALL release_neighbor_list_sets(sgwgw_list)
3186 2 : CALL release_neighbor_list_sets(sgworb_list)
3187 :
3188 : END IF
3189 :
3190 6 : CALL timestop(handle)
3191 :
3192 6 : END SUBROUTINE get_berry_phase
3193 :
3194 : ! **************************************************************************************************
3195 : !> \brief ...
3196 : !> \param mat_mo_coeff_Gamma_occ_and_GW ...
3197 : !> \param homo ...
3198 : !> \param gw_corr_lev_virt ...
3199 : ! **************************************************************************************************
3200 6 : SUBROUTINE remove_unnecessary_blocks(mat_mo_coeff_Gamma_occ_and_GW, homo, gw_corr_lev_virt)
3201 :
3202 : TYPE(dbcsr_type), POINTER :: mat_mo_coeff_Gamma_occ_and_GW
3203 : INTEGER, INTENT(IN) :: homo, gw_corr_lev_virt
3204 :
3205 : INTEGER :: col, col_offset, row
3206 6 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: data_block
3207 : TYPE(dbcsr_iterator_type) :: iter
3208 :
3209 6 : CALL dbcsr_iterator_start(iter, mat_mo_coeff_Gamma_occ_and_GW)
3210 :
3211 27 : DO WHILE (dbcsr_iterator_blocks_left(iter))
3212 :
3213 : CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
3214 21 : col_offset=col_offset)
3215 :
3216 27 : IF (col_offset > homo + gw_corr_lev_virt) THEN
3217 :
3218 532 : data_block = 0.0_dp
3219 :
3220 : END IF
3221 :
3222 : END DO
3223 :
3224 6 : CALL dbcsr_iterator_stop(iter)
3225 :
3226 6 : CALL dbcsr_filter(mat_mo_coeff_Gamma_occ_and_GW, 1.0E-15_dp)
3227 :
3228 6 : END SUBROUTINE remove_unnecessary_blocks
3229 :
3230 : ! **************************************************************************************************
3231 : !> \brief ...
3232 : !> \param delta_corr ...
3233 : !> \param eps_inv_head ...
3234 : !> \param kpoints ...
3235 : !> \param qs_env ...
3236 : !> \param matrix_berry_re_mo_mo ...
3237 : !> \param matrix_berry_im_mo_mo ...
3238 : !> \param homo ...
3239 : !> \param gw_corr_lev_occ ...
3240 : !> \param gw_corr_lev_virt ...
3241 : !> \param para_env_RPA ...
3242 : !> \param do_extra_kpoints ...
3243 : ! **************************************************************************************************
3244 260 : SUBROUTINE kpoint_sum_for_eps_inv_head_Berry(delta_corr, eps_inv_head, kpoints, qs_env, matrix_berry_re_mo_mo, &
3245 260 : matrix_berry_im_mo_mo, homo, gw_corr_lev_occ, gw_corr_lev_virt, &
3246 : para_env_RPA, do_extra_kpoints)
3247 :
3248 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
3249 : INTENT(INOUT) :: delta_corr
3250 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: eps_inv_head
3251 : TYPE(kpoint_type), POINTER :: kpoints
3252 : TYPE(qs_environment_type), POINTER :: qs_env
3253 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: matrix_berry_re_mo_mo, &
3254 : matrix_berry_im_mo_mo
3255 : INTEGER, INTENT(IN) :: homo, gw_corr_lev_occ, gw_corr_lev_virt
3256 : TYPE(mp_para_env_type), INTENT(IN), OPTIONAL :: para_env_RPA
3257 : LOGICAL, INTENT(IN) :: do_extra_kpoints
3258 :
3259 : INTEGER :: col, col_offset, col_size, i_col, i_row, &
3260 : ikp, m_level, n_level_gw, nkp, row, &
3261 : row_offset, row_size
3262 : REAL(KIND=dp) :: abs_k_square, cell_volume, &
3263 : check_int_one_over_ksq, contribution, &
3264 : weight
3265 : REAL(KIND=dp), DIMENSION(3) :: correct_kpoint
3266 260 : REAL(KIND=dp), DIMENSION(:), POINTER :: delta_corr_extra
3267 260 : REAL(KIND=dp), DIMENSION(:, :), POINTER :: data_block
3268 : TYPE(cell_type), POINTER :: cell
3269 : TYPE(dbcsr_iterator_type) :: iter, iter_new
3270 :
3271 260 : CALL get_qs_env(qs_env=qs_env, cell=cell)
3272 :
3273 260 : CALL get_cell(cell=cell, deth=cell_volume)
3274 :
3275 260 : nkp = kpoints%nkp
3276 :
3277 260 : delta_corr = 0.0_dp
3278 :
3279 260 : IF (do_extra_kpoints) THEN
3280 260 : NULLIFY (delta_corr_extra)
3281 780 : ALLOCATE (delta_corr_extra(1 + homo - gw_corr_lev_occ:homo + gw_corr_lev_virt))
3282 3800 : delta_corr_extra = 0.0_dp
3283 : END IF
3284 :
3285 260 : check_int_one_over_ksq = 0.0_dp
3286 :
3287 279620 : DO ikp = 1, nkp
3288 :
3289 279360 : weight = kpoints%wkp(ikp)
3290 :
3291 1117440 : correct_kpoint(1:3) = twopi*kpoints%xkp(1:3, ikp)
3292 :
3293 279360 : abs_k_square = (correct_kpoint(1))**2 + (correct_kpoint(2))**2 + (correct_kpoint(3))**2
3294 :
3295 : ! cos part of the Berry phase
3296 279360 : CALL dbcsr_iterator_start(iter, matrix_berry_re_mo_mo(ikp)%matrix)
3297 465120 : DO WHILE (dbcsr_iterator_blocks_left(iter))
3298 :
3299 : CALL dbcsr_iterator_next_block(iter, row, col, data_block, &
3300 : row_size=row_size, col_size=col_size, &
3301 185760 : row_offset=row_offset, col_offset=col_offset)
3302 :
3303 2880000 : DO i_col = 1, col_size
3304 :
3305 31916160 : DO n_level_gw = 1 + homo - gw_corr_lev_occ, homo + gw_corr_lev_virt
3306 :
3307 31730400 : IF (n_level_gw == i_col + col_offset - 1) THEN
3308 :
3309 26619840 : DO i_row = 1, row_size
3310 :
3311 24481440 : contribution = weight*(eps_inv_head(ikp) - 1.0_dp)/abs_k_square*(data_block(i_row, i_col))**2
3312 :
3313 24481440 : m_level = i_row + row_offset - 1
3314 :
3315 : ! we only compute the correction for n=m
3316 24481440 : IF (m_level /= n_level_gw) CYCLE
3317 :
3318 3862080 : IF (.NOT. do_extra_kpoints) THEN
3319 :
3320 0 : delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
3321 :
3322 : ELSE
3323 :
3324 1723680 : IF (ikp <= nkp*8/9) THEN
3325 :
3326 1532160 : delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
3327 :
3328 : ELSE
3329 :
3330 191520 : delta_corr_extra(n_level_gw) = delta_corr_extra(n_level_gw) + contribution
3331 :
3332 : END IF
3333 :
3334 : END IF
3335 :
3336 : END DO
3337 :
3338 : END IF
3339 :
3340 : END DO
3341 :
3342 : END DO
3343 :
3344 : END DO
3345 :
3346 279360 : CALL dbcsr_iterator_stop(iter)
3347 :
3348 : ! the same for the im. part of the Berry phase
3349 279360 : CALL dbcsr_iterator_start(iter_new, matrix_berry_im_mo_mo(ikp)%matrix)
3350 465120 : DO WHILE (dbcsr_iterator_blocks_left(iter_new))
3351 :
3352 : CALL dbcsr_iterator_next_block(iter_new, row, col, data_block, &
3353 : row_size=row_size, col_size=col_size, &
3354 185760 : row_offset=row_offset, col_offset=col_offset)
3355 :
3356 2880000 : DO i_col = 1, col_size
3357 :
3358 31916160 : DO n_level_gw = 1 + homo - gw_corr_lev_occ, homo + gw_corr_lev_virt
3359 :
3360 31730400 : IF (n_level_gw == i_col + col_offset - 1) THEN
3361 :
3362 26619840 : DO i_row = 1, row_size
3363 :
3364 24481440 : m_level = i_row + row_offset - 1
3365 :
3366 24481440 : contribution = weight*(eps_inv_head(ikp) - 1.0_dp)/abs_k_square*(data_block(i_row, i_col))**2
3367 :
3368 : ! we only compute the correction for n=m
3369 24481440 : IF (m_level /= n_level_gw) CYCLE
3370 :
3371 3862080 : IF (.NOT. do_extra_kpoints) THEN
3372 :
3373 0 : delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
3374 :
3375 : ELSE
3376 :
3377 1723680 : IF (ikp <= nkp*8/9) THEN
3378 :
3379 1532160 : delta_corr(n_level_gw) = delta_corr(n_level_gw) + contribution
3380 :
3381 : ELSE
3382 :
3383 191520 : delta_corr_extra(n_level_gw) = delta_corr_extra(n_level_gw) + contribution
3384 :
3385 : END IF
3386 :
3387 : END IF
3388 :
3389 : END DO
3390 :
3391 : END IF
3392 :
3393 : END DO
3394 :
3395 : END DO
3396 :
3397 : END DO
3398 :
3399 279360 : CALL dbcsr_iterator_stop(iter_new)
3400 :
3401 838340 : check_int_one_over_ksq = check_int_one_over_ksq + weight/abs_k_square
3402 :
3403 : END DO
3404 :
3405 : ! normalize by the cell volume
3406 3800 : delta_corr = delta_corr/cell_volume*fourpi
3407 :
3408 260 : check_int_one_over_ksq = check_int_one_over_ksq/cell_volume
3409 :
3410 260 : CALL para_env_RPA%sum(delta_corr)
3411 :
3412 260 : IF (do_extra_kpoints) THEN
3413 :
3414 3800 : delta_corr_extra = delta_corr_extra/cell_volume*fourpi
3415 :
3416 7340 : CALL para_env_RPA%sum(delta_corr_extra)
3417 :
3418 3800 : delta_corr(:) = delta_corr(:) + (delta_corr(:) - delta_corr_extra(:))
3419 :
3420 260 : DEALLOCATE (delta_corr_extra)
3421 :
3422 : END IF
3423 :
3424 260 : END SUBROUTINE kpoint_sum_for_eps_inv_head_Berry
3425 :
3426 : ! **************************************************************************************************
3427 : !> \brief ...
3428 : !> \param eps_inv_head ...
3429 : !> \param eps_head ...
3430 : !> \param kpoints ...
3431 : ! **************************************************************************************************
3432 260 : SUBROUTINE compute_eps_inv_head(eps_inv_head, eps_head, kpoints)
3433 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
3434 : INTENT(OUT) :: eps_inv_head
3435 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: eps_head
3436 : TYPE(kpoint_type), POINTER :: kpoints
3437 :
3438 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_eps_inv_head'
3439 :
3440 : INTEGER :: handle, ikp, nkp
3441 :
3442 260 : CALL timeset(routineN, handle)
3443 :
3444 260 : nkp = kpoints%nkp
3445 :
3446 780 : ALLOCATE (eps_inv_head(nkp))
3447 :
3448 279620 : DO ikp = 1, nkp
3449 :
3450 279620 : eps_inv_head(ikp) = 1.0_dp/eps_head(ikp)
3451 :
3452 : END DO
3453 :
3454 260 : CALL timestop(handle)
3455 :
3456 260 : END SUBROUTINE compute_eps_inv_head
3457 :
3458 : ! **************************************************************************************************
3459 : !> \brief ...
3460 : !> \param qs_env ...
3461 : !> \param kpoints ...
3462 : !> \param kp_grid ...
3463 : !> \param num_kp_grids ...
3464 : !> \param para_env ...
3465 : !> \param h_inv ...
3466 : !> \param nmo ...
3467 : !> \param do_mo_coeff_Gamma_only ...
3468 : !> \param do_extra_kpoints ...
3469 : ! **************************************************************************************************
3470 6 : SUBROUTINE get_kpoints(qs_env, kpoints, kp_grid, num_kp_grids, para_env, h_inv, nmo, &
3471 : do_mo_coeff_Gamma_only, do_extra_kpoints)
3472 : TYPE(qs_environment_type), POINTER :: qs_env
3473 : TYPE(kpoint_type), POINTER :: kpoints
3474 : INTEGER, DIMENSION(:), POINTER :: kp_grid
3475 : INTEGER, INTENT(IN) :: num_kp_grids
3476 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
3477 : REAL(KIND=dp), DIMENSION(3, 3), INTENT(INOUT) :: h_inv
3478 : INTEGER, INTENT(IN) :: nmo
3479 : LOGICAL, INTENT(IN) :: do_mo_coeff_Gamma_only, do_extra_kpoints
3480 :
3481 : INTEGER :: end_kp, i, i_grid_level, ix, iy, iz, &
3482 : nkp_inner_grid, nkp_outer_grid, &
3483 : npoints, start_kp
3484 : INTEGER, DIMENSION(3) :: outer_kp_grid
3485 : REAL(KIND=dp) :: kpoint_weight_left, single_weight
3486 : REAL(KIND=dp), DIMENSION(3) :: kpt_latt, reducing_factor
3487 : TYPE(cell_type), POINTER :: cell
3488 6 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
3489 :
3490 6 : NULLIFY (kpoints, cell, particle_set)
3491 :
3492 : ! check whether kp_grid includes the Gamma point. If so, abort.
3493 6 : CPASSERT(MOD(kp_grid(1)*kp_grid(2)*kp_grid(3), 2) == 0)
3494 6 : IF (do_extra_kpoints) THEN
3495 6 : CPASSERT(do_mo_coeff_Gamma_only)
3496 : END IF
3497 :
3498 6 : IF (do_mo_coeff_Gamma_only) THEN
3499 :
3500 6 : outer_kp_grid(1) = kp_grid(1) - 1
3501 6 : outer_kp_grid(2) = kp_grid(2) - 1
3502 6 : outer_kp_grid(3) = kp_grid(3) - 1
3503 :
3504 6 : CALL get_qs_env(qs_env=qs_env, cell=cell, particle_set=particle_set)
3505 :
3506 6 : CALL get_cell(cell, h_inv=h_inv)
3507 :
3508 6 : CALL kpoint_create(kpoints)
3509 :
3510 6 : kpoints%kp_scheme = "GENERAL"
3511 6 : kpoints%symmetry = .FALSE.
3512 6 : kpoints%verbose = .FALSE.
3513 6 : kpoints%full_grid = .FALSE.
3514 6 : kpoints%use_real_wfn = .FALSE.
3515 6 : kpoints%eps_geo = 1.e-6_dp
3516 : npoints = kp_grid(1)*kp_grid(2)*kp_grid(3)/2 + &
3517 6 : (num_kp_grids - 1)*((outer_kp_grid(1) + 1)/2*outer_kp_grid(2)*outer_kp_grid(3) - 1)
3518 :
3519 6 : IF (do_extra_kpoints) THEN
3520 :
3521 6 : CPASSERT(num_kp_grids == 1)
3522 6 : CPASSERT(MOD(kp_grid(1), 4) == 0)
3523 6 : CPASSERT(MOD(kp_grid(2), 4) == 0)
3524 6 : CPASSERT(MOD(kp_grid(3), 4) == 0)
3525 :
3526 : END IF
3527 :
3528 6 : IF (do_extra_kpoints) THEN
3529 :
3530 6 : npoints = kp_grid(1)*kp_grid(2)*kp_grid(3)/2 + kp_grid(1)*kp_grid(2)*kp_grid(3)/2/8
3531 :
3532 : END IF
3533 :
3534 6 : kpoints%full_grid = .TRUE.
3535 6 : kpoints%nkp = npoints
3536 30 : ALLOCATE (kpoints%xkp(3, npoints), kpoints%wkp(npoints))
3537 44646 : kpoints%xkp = 0.0_dp
3538 11166 : kpoints%wkp = 0.0_dp
3539 :
3540 6 : nkp_outer_grid = outer_kp_grid(1)*outer_kp_grid(2)*outer_kp_grid(3)
3541 6 : nkp_inner_grid = kp_grid(1)*kp_grid(2)*kp_grid(3)
3542 :
3543 6 : i = 0
3544 24 : reducing_factor(:) = 1.0_dp
3545 : kpoint_weight_left = 1.0_dp
3546 :
3547 : ! the outer grids
3548 6 : DO i_grid_level = 1, num_kp_grids - 1
3549 :
3550 0 : single_weight = kpoint_weight_left/REAL(nkp_outer_grid, KIND=dp)
3551 :
3552 0 : start_kp = i + 1
3553 :
3554 0 : DO ix = 1, outer_kp_grid(1)
3555 0 : DO iy = 1, outer_kp_grid(2)
3556 0 : DO iz = 1, outer_kp_grid(3)
3557 :
3558 : ! exclude Gamma
3559 0 : IF (2*ix - outer_kp_grid(1) - 1 == 0 .AND. 2*iy - outer_kp_grid(2) - 1 == 0 .AND. &
3560 : 2*iz - outer_kp_grid(3) - 1 == 0) CYCLE
3561 :
3562 : ! use time reversal symmetry k<->-k
3563 0 : IF (2*ix - outer_kp_grid(1) - 1 < 0) CYCLE
3564 :
3565 0 : i = i + 1
3566 : kpt_latt(1) = REAL(2*ix - outer_kp_grid(1) - 1, KIND=dp)/(2._dp*REAL(outer_kp_grid(1), KIND=dp)) &
3567 0 : *reducing_factor(1)
3568 : kpt_latt(2) = REAL(2*iy - outer_kp_grid(2) - 1, KIND=dp)/(2._dp*REAL(outer_kp_grid(2), KIND=dp)) &
3569 0 : *reducing_factor(2)
3570 : kpt_latt(3) = REAL(2*iz - outer_kp_grid(3) - 1, KIND=dp)/(2._dp*REAL(outer_kp_grid(3), KIND=dp)) &
3571 0 : *reducing_factor(3)
3572 0 : kpoints%xkp(1:3, i) = MATMUL(TRANSPOSE(h_inv), kpt_latt(:))
3573 :
3574 0 : IF (2*ix - outer_kp_grid(1) - 1 == 0) THEN
3575 0 : kpoints%wkp(i) = single_weight
3576 : ELSE
3577 0 : kpoints%wkp(i) = 2._dp*single_weight
3578 : END IF
3579 :
3580 : END DO
3581 : END DO
3582 : END DO
3583 :
3584 0 : end_kp = i
3585 :
3586 0 : kpoint_weight_left = kpoint_weight_left - SUM(kpoints%wkp(start_kp:end_kp))
3587 :
3588 0 : reducing_factor(1) = reducing_factor(1)/REAL(outer_kp_grid(1), KIND=dp)
3589 0 : reducing_factor(2) = reducing_factor(2)/REAL(outer_kp_grid(2), KIND=dp)
3590 6 : reducing_factor(3) = reducing_factor(3)/REAL(outer_kp_grid(3), KIND=dp)
3591 :
3592 : END DO
3593 :
3594 6 : single_weight = kpoint_weight_left/REAL(nkp_inner_grid, KIND=dp)
3595 :
3596 : ! the inner grid
3597 94 : DO ix = 1, kp_grid(1)
3598 1406 : DO iy = 1, kp_grid(2)
3599 21240 : DO iz = 1, kp_grid(3)
3600 :
3601 : ! use time reversal symmetry k<->-k
3602 19840 : IF (2*ix - kp_grid(1) - 1 < 0) CYCLE
3603 :
3604 9920 : i = i + 1
3605 9920 : kpt_latt(1) = REAL(2*ix - kp_grid(1) - 1, KIND=dp)/(2._dp*REAL(kp_grid(1), KIND=dp))*reducing_factor(1)
3606 9920 : kpt_latt(2) = REAL(2*iy - kp_grid(2) - 1, KIND=dp)/(2._dp*REAL(kp_grid(2), KIND=dp))*reducing_factor(2)
3607 9920 : kpt_latt(3) = REAL(2*iz - kp_grid(3) - 1, KIND=dp)/(2._dp*REAL(kp_grid(3), KIND=dp))*reducing_factor(3)
3608 :
3609 39680 : kpoints%xkp(1:3, i) = MATMUL(TRANSPOSE(h_inv), kpt_latt(:))
3610 :
3611 21152 : kpoints%wkp(i) = 2._dp*single_weight
3612 :
3613 : END DO
3614 : END DO
3615 : END DO
3616 :
3617 6 : IF (do_extra_kpoints) THEN
3618 :
3619 6 : single_weight = kpoint_weight_left/REAL(kp_grid(1)*kp_grid(2)*kp_grid(3)/8, KIND=dp)
3620 :
3621 50 : DO ix = 1, kp_grid(1)/2
3622 378 : DO iy = 1, kp_grid(2)/2
3623 2852 : DO iz = 1, kp_grid(3)/2
3624 :
3625 : ! use time reversal symmetry k<->-k
3626 2480 : IF (2*ix - kp_grid(1)/2 - 1 < 0) CYCLE
3627 :
3628 1240 : i = i + 1
3629 1240 : kpt_latt(1) = REAL(2*ix - kp_grid(1)/2 - 1, KIND=dp)/(REAL(kp_grid(1), KIND=dp))
3630 1240 : kpt_latt(2) = REAL(2*iy - kp_grid(2)/2 - 1, KIND=dp)/(REAL(kp_grid(2), KIND=dp))
3631 1240 : kpt_latt(3) = REAL(2*iz - kp_grid(3)/2 - 1, KIND=dp)/(REAL(kp_grid(3), KIND=dp))
3632 :
3633 4960 : kpoints%xkp(1:3, i) = MATMUL(TRANSPOSE(h_inv), kpt_latt(:))
3634 :
3635 2808 : kpoints%wkp(i) = 2._dp*single_weight
3636 :
3637 : END DO
3638 : END DO
3639 : END DO
3640 :
3641 : END IF
3642 :
3643 : ! default: no symmetry settings
3644 11178 : ALLOCATE (kpoints%kp_sym(kpoints%nkp))
3645 11166 : DO i = 1, kpoints%nkp
3646 11160 : NULLIFY (kpoints%kp_sym(i)%kpoint_sym)
3647 11166 : CALL kpoint_sym_create(kpoints%kp_sym(i)%kpoint_sym)
3648 : END DO
3649 :
3650 : ELSE
3651 :
3652 : BLOCK
3653 : TYPE(qs_environment_type), POINTER :: qs_env_kp_Gamma_only
3654 0 : CALL create_kp_from_gamma(qs_env, qs_env_kp_Gamma_only)
3655 :
3656 0 : CALL get_qs_env(qs_env=qs_env, cell=cell, particle_set=particle_set)
3657 :
3658 : CALL calculate_kp_orbitals(qs_env_kp_Gamma_only, kpoints, "MONKHORST-PACK", nadd=nmo, mp_grid=kp_grid(1:3), &
3659 0 : group_size_ext=para_env%num_pe)
3660 :
3661 0 : CALL qs_env_release(qs_env_kp_Gamma_only)
3662 0 : DEALLOCATE (qs_env_kp_Gamma_only)
3663 : END BLOCK
3664 :
3665 : END IF
3666 :
3667 6 : END SUBROUTINE get_kpoints
3668 :
3669 : ! **************************************************************************************************
3670 : !> \brief ...
3671 : !> \param vec_Sigma_c_gw ...
3672 : !> \param Eigenval_DFT ...
3673 : !> \param eps_eigenval ...
3674 : ! **************************************************************************************************
3675 10 : PURE SUBROUTINE average_degenerate_levels(vec_Sigma_c_gw, Eigenval_DFT, eps_eigenval)
3676 : COMPLEX(KIND=dp), DIMENSION(:, :, :), &
3677 : INTENT(INOUT) :: vec_Sigma_c_gw
3678 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: Eigenval_DFT
3679 : REAL(KIND=dp), INTENT(IN) :: eps_eigenval
3680 :
3681 10 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: avg_self_energy
3682 : INTEGER :: degeneracy, first_degenerate_level, i_deg_level, i_level_gw, j_deg_level, jquad, &
3683 : num_deg_levels, num_integ_points, num_levels_gw
3684 10 : INTEGER, ALLOCATABLE, DIMENSION(:) :: list_degenerate_levels
3685 :
3686 10 : num_levels_gw = SIZE(vec_Sigma_c_gw, 1)
3687 :
3688 30 : ALLOCATE (list_degenerate_levels(num_levels_gw))
3689 130 : list_degenerate_levels = 1
3690 :
3691 10 : num_integ_points = SIZE(vec_Sigma_c_gw, 2)
3692 :
3693 30 : ALLOCATE (avg_self_energy(num_integ_points))
3694 :
3695 120 : DO i_level_gw = 2, num_levels_gw
3696 :
3697 120 : IF (ABS(Eigenval_DFT(i_level_gw) - Eigenval_DFT(i_level_gw - 1)) < eps_eigenval) THEN
3698 :
3699 0 : list_degenerate_levels(i_level_gw) = list_degenerate_levels(i_level_gw - 1)
3700 :
3701 : ELSE
3702 :
3703 110 : list_degenerate_levels(i_level_gw) = list_degenerate_levels(i_level_gw - 1) + 1
3704 :
3705 : END IF
3706 :
3707 : END DO
3708 :
3709 10 : num_deg_levels = list_degenerate_levels(num_levels_gw)
3710 :
3711 130 : DO i_deg_level = 1, num_deg_levels
3712 :
3713 : degeneracy = 0
3714 :
3715 1624 : DO i_level_gw = 1, num_levels_gw
3716 :
3717 1504 : IF (degeneracy == 0 .AND. i_deg_level == list_degenerate_levels(i_level_gw)) THEN
3718 :
3719 120 : first_degenerate_level = i_level_gw
3720 :
3721 : END IF
3722 :
3723 1624 : IF (i_deg_level == list_degenerate_levels(i_level_gw)) THEN
3724 :
3725 120 : degeneracy = degeneracy + 1
3726 :
3727 : END IF
3728 :
3729 : END DO
3730 :
3731 3136 : DO jquad = 1, num_integ_points
3732 :
3733 : avg_self_energy(jquad) = SUM(vec_Sigma_c_gw(first_degenerate_level:first_degenerate_level + degeneracy - 1, jquad, 1)) &
3734 6152 : /REAL(degeneracy, KIND=dp)
3735 :
3736 : END DO
3737 :
3738 250 : DO j_deg_level = 0, degeneracy - 1
3739 :
3740 3256 : vec_Sigma_c_gw(first_degenerate_level + j_deg_level, :, 1) = avg_self_energy(:)
3741 :
3742 : END DO
3743 :
3744 : END DO
3745 :
3746 10 : END SUBROUTINE average_degenerate_levels
3747 :
3748 : ! **************************************************************************************************
3749 : !> \brief ...
3750 : !> \param vec_gw_energ ...
3751 : !> \param vec_omega_fit_gw ...
3752 : !> \param z_value ...
3753 : !> \param m_value ...
3754 : !> \param vec_Sigma_c_gw ...
3755 : !> \param vec_Sigma_x_minus_vxc_gw ...
3756 : !> \param Eigenval ...
3757 : !> \param Eigenval_scf ...
3758 : !> \param n_level_gw ...
3759 : !> \param gw_corr_lev_occ ...
3760 : !> \param gw_corr_lev_vir ...
3761 : !> \param num_poles ...
3762 : !> \param num_fit_points ...
3763 : !> \param crossing_search ...
3764 : !> \param homo ...
3765 : !> \param stop_crit ...
3766 : !> \param fermi_level_offset ...
3767 : !> \param do_gw_im_time ...
3768 : ! **************************************************************************************************
3769 568 : SUBROUTINE fit_and_continuation_2pole(vec_gw_energ, vec_omega_fit_gw, &
3770 1136 : z_value, m_value, vec_Sigma_c_gw, vec_Sigma_x_minus_vxc_gw, &
3771 1136 : Eigenval, Eigenval_scf, n_level_gw, &
3772 : gw_corr_lev_occ, gw_corr_lev_vir, num_poles, &
3773 : num_fit_points, crossing_search, homo, stop_crit, &
3774 : fermi_level_offset, do_gw_im_time)
3775 :
3776 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: vec_gw_energ, vec_omega_fit_gw, z_value, &
3777 : m_value
3778 : COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN) :: vec_Sigma_c_gw
3779 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: vec_Sigma_x_minus_vxc_gw, Eigenval, &
3780 : Eigenval_scf
3781 : INTEGER, INTENT(IN) :: n_level_gw, gw_corr_lev_occ, &
3782 : gw_corr_lev_vir, num_poles, &
3783 : num_fit_points, crossing_search, homo
3784 : REAL(KIND=dp), INTENT(IN) :: stop_crit, fermi_level_offset
3785 : LOGICAL, INTENT(IN) :: do_gw_im_time
3786 :
3787 : CHARACTER(LEN=*), PARAMETER :: routineN = 'fit_and_continuation_2pole'
3788 : REAL(KIND=dp), PARAMETER :: eps_delta = 1.0E-08_dp
3789 :
3790 : COMPLEX(KIND=dp) :: func_val, rho1
3791 568 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: dLambda, dLambda_2, Lambda, &
3792 568 : Lambda_without_offset, vec_b_gw, &
3793 568 : vec_b_gw_copy
3794 568 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: mat_A_gw, mat_B_gw
3795 : INTEGER :: handle4, ierr, iii, iiter, info, &
3796 : integ_range, jjj, jquad, kkk, &
3797 : max_iter_fit, n_level_gw_ref, num_var, &
3798 : xpos
3799 568 : INTEGER, ALLOCATABLE, DIMENSION(:) :: ipiv
3800 : LOGICAL :: could_exit
3801 : REAL(KIND=dp) :: chi2, chi2_old, delta, deriv_val_real, e_fermi, gw_energ, Ldown, &
3802 : level_energ_GW, Lup, range_step, ScalParam, sign_occ_virt, stat_error
3803 568 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: Lambda_Im, Lambda_Re, stat_errors, &
3804 568 : vec_N_gw, vec_omega_fit_gw_sign
3805 568 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: mat_N_gw
3806 :
3807 568 : max_iter_fit = 10000
3808 :
3809 568 : num_var = 2*num_poles + 1
3810 1704 : ALLOCATE (Lambda(num_var))
3811 568 : Lambda = z_zero
3812 1136 : ALLOCATE (Lambda_without_offset(num_var))
3813 568 : Lambda_without_offset = z_zero
3814 1704 : ALLOCATE (Lambda_Re(num_var))
3815 568 : Lambda_Re = 0.0_dp
3816 1136 : ALLOCATE (Lambda_Im(num_var))
3817 568 : Lambda_Im = 0.0_dp
3818 :
3819 1704 : ALLOCATE (vec_omega_fit_gw_sign(num_fit_points))
3820 :
3821 568 : IF (n_level_gw <= gw_corr_lev_occ) THEN
3822 : sign_occ_virt = -1.0_dp
3823 : ELSE
3824 405 : sign_occ_virt = 1.0_dp
3825 : END IF
3826 :
3827 568 : n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
3828 :
3829 7324 : DO jquad = 1, num_fit_points
3830 7324 : vec_omega_fit_gw_sign(jquad) = ABS(vec_omega_fit_gw(jquad))*sign_occ_virt
3831 : END DO
3832 :
3833 : ! initial guess
3834 568 : range_step = (vec_omega_fit_gw_sign(num_fit_points) - vec_omega_fit_gw_sign(1))/(num_poles - 1)
3835 1704 : DO iii = 1, num_poles
3836 1704 : Lambda_Im(2*iii + 1) = vec_omega_fit_gw_sign(1) + (iii - 1)*range_step
3837 : END DO
3838 568 : range_step = (vec_omega_fit_gw_sign(num_fit_points) - vec_omega_fit_gw_sign(1))/num_poles
3839 1704 : DO iii = 1, num_poles
3840 1704 : Lambda_Re(2*iii + 1) = ABS(vec_omega_fit_gw_sign(1) + (iii - 0.5_dp)*range_step)
3841 : END DO
3842 :
3843 3408 : DO iii = 1, num_var
3844 3408 : Lambda(iii) = Lambda_Re(iii) + gaussi*Lambda_Im(iii)
3845 : END DO
3846 :
3847 : CALL calc_chi2(chi2_old, Lambda, vec_Sigma_c_gw, vec_omega_fit_gw_sign, num_poles, &
3848 568 : num_fit_points, n_level_gw)
3849 :
3850 2272 : ALLOCATE (mat_A_gw(num_poles + 1, num_poles + 1))
3851 1704 : ALLOCATE (vec_b_gw(num_poles + 1))
3852 1704 : ALLOCATE (ipiv(num_poles + 1))
3853 568 : mat_A_gw = z_zero
3854 568 : vec_b_gw = 0.0_dp
3855 :
3856 2272 : mat_A_gw(1:num_poles + 1, 1) = z_one
3857 568 : integ_range = num_fit_points/num_poles
3858 2272 : DO kkk = 1, num_poles + 1
3859 1704 : xpos = (kkk - 1)*integ_range + 1
3860 1704 : xpos = MIN(xpos, num_fit_points)
3861 : ! calculate coefficient at this point
3862 5112 : DO iii = 1, num_poles
3863 3408 : jjj = iii*2
3864 : func_val = z_one/(gaussi*vec_omega_fit_gw_sign(xpos) - &
3865 3408 : CMPLX(Lambda_Re(jjj + 1), Lambda_Im(jjj + 1), KIND=dp))
3866 5112 : mat_A_gw(kkk, iii + 1) = func_val
3867 : END DO
3868 2272 : vec_b_gw(kkk) = vec_Sigma_c_gw(n_level_gw, xpos)
3869 : END DO
3870 :
3871 : ! Solve system of linear equations
3872 568 : CALL ZGETRF(num_poles + 1, num_poles + 1, mat_A_gw, num_poles + 1, ipiv, info)
3873 :
3874 568 : CALL ZGETRS('N', num_poles + 1, 1, mat_A_gw, num_poles + 1, ipiv, vec_b_gw, num_poles + 1, info)
3875 :
3876 568 : Lambda_Re(1) = REAL(vec_b_gw(1))
3877 568 : Lambda_Im(1) = AIMAG(vec_b_gw(1))
3878 1704 : DO iii = 1, num_poles
3879 1136 : jjj = iii*2
3880 1136 : Lambda_Re(jjj) = REAL(vec_b_gw(iii + 1))
3881 1704 : Lambda_Im(jjj) = AIMAG(vec_b_gw(iii + 1))
3882 : END DO
3883 :
3884 568 : DEALLOCATE (mat_A_gw)
3885 568 : DEALLOCATE (vec_b_gw)
3886 568 : DEALLOCATE (ipiv)
3887 :
3888 2272 : ALLOCATE (mat_A_gw(num_var*2, num_var*2))
3889 2272 : ALLOCATE (mat_B_gw(num_fit_points, num_var*2))
3890 1704 : ALLOCATE (dLambda(num_fit_points))
3891 1136 : ALLOCATE (dLambda_2(num_fit_points))
3892 1704 : ALLOCATE (vec_b_gw(num_var*2))
3893 1136 : ALLOCATE (vec_b_gw_copy(num_var*2))
3894 1704 : ALLOCATE (ipiv(num_var*2))
3895 :
3896 : ScalParam = 0.01_dp
3897 : Ldown = 1.5_dp
3898 : Lup = 10.0_dp
3899 : could_exit = .FALSE.
3900 :
3901 : ! iteration loop for fitting
3902 1163809 : DO iiter = 1, max_iter_fit
3903 :
3904 1163774 : CALL timeset(routineN//"_fit_loop_1", handle4)
3905 :
3906 : ! calc delta lambda
3907 6982644 : DO iii = 1, num_var
3908 6982644 : Lambda(iii) = Lambda_Re(iii) + gaussi*Lambda_Im(iii)
3909 : END DO
3910 1163774 : dLambda = z_zero
3911 :
3912 14963930 : DO kkk = 1, num_fit_points
3913 13800156 : func_val = Lambda(1)
3914 41400468 : DO iii = 1, num_poles
3915 27600312 : jjj = iii*2
3916 41400468 : func_val = func_val + Lambda(jjj)/(vec_omega_fit_gw_sign(kkk)*gaussi - Lambda(jjj + 1))
3917 : END DO
3918 14963930 : dLambda(kkk) = vec_Sigma_c_gw(n_level_gw, kkk) - func_val
3919 : END DO
3920 14963930 : rho1 = SUM(dLambda*dLambda)
3921 :
3922 : ! fill matrix
3923 1163774 : mat_B_gw = z_zero
3924 14963930 : DO iii = 1, num_fit_points
3925 13800156 : mat_B_gw(iii, 1) = 1.0_dp
3926 14963930 : mat_B_gw(iii, num_var + 1) = gaussi
3927 : END DO
3928 3491322 : DO iii = 1, num_poles
3929 2327548 : jjj = iii*2
3930 31091634 : DO kkk = 1, num_fit_points
3931 27600312 : mat_B_gw(kkk, jjj) = 1.0_dp/(gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))
3932 27600312 : mat_B_gw(kkk, jjj + num_var) = gaussi/(gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))
3933 27600312 : mat_B_gw(kkk, jjj + 1) = Lambda(jjj)/(gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))**2
3934 : mat_B_gw(kkk, jjj + 1 + num_var) = (-Lambda_Im(jjj) + gaussi*Lambda_Re(jjj))/ &
3935 29927860 : (gaussi*vec_omega_fit_gw_sign(kkk) - Lambda(jjj + 1))**2
3936 : END DO
3937 : END DO
3938 :
3939 1163774 : CALL timestop(handle4)
3940 :
3941 1163774 : CALL timeset(routineN//"_fit_matmul_1", handle4)
3942 :
3943 : CALL zgemm('C', 'N', num_var*2, num_var*2, num_fit_points, z_one, mat_B_gw, num_fit_points, mat_B_gw, num_fit_points, &
3944 1163774 : z_zero, mat_A_gw, num_var*2)
3945 1163774 : CALL timestop(handle4)
3946 :
3947 1163774 : CALL timeset(routineN//"_fit_zgemv_1", handle4)
3948 : CALL zgemv('C', num_fit_points, num_var*2, z_one, mat_B_gw, num_fit_points, dLambda, 1, &
3949 1163774 : z_zero, vec_b_gw, 1)
3950 :
3951 1163774 : CALL timestop(handle4)
3952 :
3953 : ! scale diagonal elements of a_mat
3954 12801514 : DO iii = 1, num_var*2
3955 12801514 : mat_A_gw(iii, iii) = mat_A_gw(iii, iii) + ScalParam*mat_A_gw(iii, iii)
3956 : END DO
3957 :
3958 : ! solve linear system
3959 1163774 : ierr = 0
3960 1163774 : ipiv = 0
3961 :
3962 1163774 : CALL timeset(routineN//"_fit_lin_eq_2", handle4)
3963 :
3964 1163774 : CALL ZGETRF(2*num_var, 2*num_var, mat_A_gw, 2*num_var, ipiv, info)
3965 :
3966 1163774 : CALL ZGETRS('N', 2*num_var, 1, mat_A_gw, 2*num_var, ipiv, vec_b_gw, 2*num_var, info)
3967 :
3968 1163774 : CALL timestop(handle4)
3969 :
3970 6982644 : DO iii = 1, num_var
3971 6982644 : Lambda(iii) = Lambda_Re(iii) + gaussi*Lambda_Im(iii) + vec_b_gw(iii) + vec_b_gw(iii + num_var)
3972 : END DO
3973 :
3974 : ! calculate chi2
3975 : CALL calc_chi2(chi2, Lambda, vec_Sigma_c_gw, vec_omega_fit_gw_sign, num_poles, &
3976 1163774 : num_fit_points, n_level_gw)
3977 :
3978 : ! if the fit is already super accurate, exit. otherwise maybe issues when dividing by 0
3979 1163774 : IF (chi2 < 1.0E-30_dp) EXIT
3980 :
3981 1163728 : IF (chi2 < chi2_old) THEN
3982 988056 : ScalParam = MAX(ScalParam/Ldown, 1E-12_dp)
3983 5928336 : DO iii = 1, num_var
3984 4940280 : Lambda_Re(iii) = Lambda_Re(iii) + REAL(vec_b_gw(iii) + vec_b_gw(iii + num_var))
3985 5928336 : Lambda_Im(iii) = Lambda_Im(iii) + AIMAG(vec_b_gw(iii) + vec_b_gw(iii + num_var))
3986 : END DO
3987 988056 : IF (chi2_old/chi2 - 1.0_dp < stop_crit) could_exit = .TRUE.
3988 988056 : chi2_old = chi2
3989 : ELSE
3990 175672 : ScalParam = ScalParam*Lup
3991 : END IF
3992 1163728 : IF (ScalParam > 100.0_dp .AND. could_exit) EXIT
3993 :
3994 4655664 : IF (ScalParam > 1E+10_dp) ScalParam = 1E-4_dp
3995 :
3996 : END DO
3997 :
3998 568 : IF (.NOT. do_gw_im_time) THEN
3999 :
4000 : ! change a_0 [Lambda(1)], so that Sigma(i0) = Fit(i0)
4001 : ! do not do this for imaginary time since we do not have many fit points and the fit should be perfect
4002 420 : func_val = Lambda(1)
4003 1260 : DO iii = 1, num_poles
4004 840 : jjj = iii*2
4005 : ! calculate value of the fit function
4006 1260 : func_val = func_val + Lambda(jjj)/(-Lambda(jjj + 1))
4007 : END DO
4008 :
4009 420 : Lambda_Re(1) = Lambda_Re(1) - REAL(func_val) + REAL(vec_Sigma_c_gw(n_level_gw, num_fit_points))
4010 420 : Lambda_Im(1) = Lambda_Im(1) - AIMAG(func_val) + AIMAG(vec_Sigma_c_gw(n_level_gw, num_fit_points))
4011 :
4012 : END IF
4013 :
4014 3408 : Lambda_without_offset(:) = Lambda(:)
4015 :
4016 3408 : DO iii = 1, num_var
4017 3408 : Lambda(iii) = CMPLX(Lambda_Re(iii), Lambda_Im(iii), KIND=dp)
4018 : END DO
4019 :
4020 568 : IF (do_gw_im_time) THEN
4021 : ! for cubic-scaling GW, we have one Green's function for occ and virt states with the Fermi level
4022 : ! in the middle of homo and lumo
4023 148 : e_fermi = 0.5_dp*(Eigenval(homo) + Eigenval(homo + 1))
4024 : ELSE
4025 : ! in case of O(N^4) GW, we have the Fermi level differently for occ and virt states, see
4026 : ! Fig. 1 in JCTC 12, 3623-3635 (2016)
4027 420 : IF (n_level_gw <= gw_corr_lev_occ) THEN
4028 552 : e_fermi = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo)) + fermi_level_offset
4029 : ELSE
4030 3432 : e_fermi = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_vir)) - fermi_level_offset
4031 : END IF
4032 : END IF
4033 :
4034 : ! either Z-shot or Newton/bisection crossing search for evaluating Sigma_c
4035 568 : IF (crossing_search == ri_rpa_g0w0_crossing_z_shot .OR. &
4036 : crossing_search == ri_rpa_g0w0_crossing_newton) THEN
4037 :
4038 : ! calculate Sigma_c_fit(e_n) and Z
4039 568 : func_val = Lambda(1)
4040 568 : z_value(n_level_gw) = 1.0_dp
4041 1704 : DO iii = 1, num_poles
4042 1136 : jjj = iii*2
4043 : z_value(n_level_gw) = z_value(n_level_gw) + REAL(Lambda(jjj)/ &
4044 1136 : (Eigenval(n_level_gw_ref) - e_fermi - Lambda(jjj + 1))**2)
4045 1704 : func_val = func_val + Lambda(jjj)/(Eigenval(n_level_gw_ref) - e_fermi - Lambda(jjj + 1))
4046 : END DO
4047 : ! m is the slope of the correl self-energy
4048 568 : m_value(n_level_gw) = 1.0_dp - z_value(n_level_gw)
4049 568 : z_value(n_level_gw) = 1.0_dp/z_value(n_level_gw)
4050 568 : gw_energ = REAL(func_val)
4051 568 : vec_gw_energ(n_level_gw) = gw_energ
4052 :
4053 : ! in case one wants to do Newton-Raphson on top of the Z-shot
4054 568 : IF (crossing_search == ri_rpa_g0w0_crossing_newton) THEN
4055 :
4056 : level_energ_GW = (Eigenval_scf(n_level_gw_ref) - &
4057 : m_value(n_level_gw)*Eigenval(n_level_gw_ref) + &
4058 : vec_gw_energ(n_level_gw) + &
4059 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))* &
4060 32 : z_value(n_level_gw)
4061 :
4062 : ! Newton-Raphson iteration
4063 112 : DO kkk = 1, 1000
4064 :
4065 : ! calculate the value of the fit function for level_energ_GW
4066 112 : func_val = Lambda(1)
4067 112 : z_value(n_level_gw) = 1.0_dp
4068 336 : DO iii = 1, num_poles
4069 224 : jjj = iii*2
4070 336 : func_val = func_val + Lambda(jjj)/(level_energ_GW - e_fermi - Lambda(jjj + 1))
4071 : END DO
4072 :
4073 : ! Derivative of the QP residual: Re[sum_j -r_j/(E-e_fermi-p_j)^2] - 1.
4074 112 : deriv_val_real = -1.0_dp
4075 336 : DO iii = 1, num_poles
4076 224 : jjj = iii*2
4077 : deriv_val_real = deriv_val_real - REAL(Lambda(jjj)/ &
4078 336 : (level_energ_GW - e_fermi - Lambda(jjj + 1))**2, KIND=dp)
4079 :
4080 : END DO
4081 :
4082 : delta = (Eigenval_scf(n_level_gw_ref) + vec_Sigma_x_minus_vxc_gw(n_level_gw_ref) + REAL(func_val) - level_energ_GW)/ &
4083 112 : deriv_val_real
4084 :
4085 112 : level_energ_GW = level_energ_GW - delta
4086 :
4087 112 : IF (ABS(delta) < eps_delta) EXIT
4088 :
4089 : END DO
4090 :
4091 : ! update the GW-energy by Newton-Raphson and set the Z-value to 1
4092 :
4093 32 : vec_gw_energ(n_level_gw) = REAL(func_val)
4094 32 : z_value(n_level_gw) = 1.0_dp
4095 32 : m_value(n_level_gw) = 0.0_dp
4096 :
4097 : END IF ! Newton-Raphson on top of Z-shot
4098 :
4099 : ELSE
4100 0 : CPABORT("Only NONE, ZSHOT and NEWTON implemented for 2-pole model")
4101 : END IF ! decision crossing search none, Z-shot
4102 :
4103 : ! --------------------------------------------
4104 : ! | calculate statistical error due to fitting |
4105 : ! --------------------------------------------
4106 :
4107 : ! estimate the statistical error of the calculated Sigma_c(i*omega)
4108 : ! by sqrt(chi2/n), where n is the number of fit points
4109 :
4110 : CALL calc_chi2(chi2, Lambda_without_offset, vec_Sigma_c_gw, vec_omega_fit_gw_sign, num_poles, &
4111 568 : num_fit_points, n_level_gw)
4112 :
4113 : ! Estimate the statistical error of every fit point
4114 568 : stat_error = SQRT(chi2/num_fit_points)
4115 :
4116 : ! allocate N array containing the second derivatives of chi^2
4117 1704 : ALLOCATE (vec_N_gw(num_var*2))
4118 568 : vec_N_gw = 0.0_dp
4119 :
4120 2272 : ALLOCATE (mat_N_gw(num_var*2, num_var*2))
4121 568 : mat_N_gw = 0.0_dp
4122 :
4123 6248 : DO iii = 1, num_var*2
4124 : CALL calc_mat_N(vec_N_gw(iii), Lambda_without_offset, vec_Sigma_c_gw, vec_omega_fit_gw_sign, &
4125 6248 : iii, iii, num_poles, num_fit_points, n_level_gw, 0.001_dp)
4126 : END DO
4127 :
4128 6248 : DO iii = 1, num_var*2
4129 63048 : DO jjj = 1, num_var*2
4130 : CALL calc_mat_N(mat_N_gw(iii, jjj), Lambda_without_offset, vec_Sigma_c_gw, vec_omega_fit_gw_sign, &
4131 62480 : iii, jjj, num_poles, num_fit_points, n_level_gw, 0.001_dp)
4132 : END DO
4133 : END DO
4134 :
4135 568 : CALL DGETRF(2*num_var, 2*num_var, mat_N_gw, 2*num_var, ipiv, info)
4136 :
4137 : ! vec_b_gw is only working array
4138 568 : CALL DGETRI(2*num_var, mat_N_gw, 2*num_var, ipiv, vec_b_gw, 2*num_var, info)
4139 :
4140 1136 : ALLOCATE (stat_errors(2*num_var))
4141 : stat_errors = 0.0_dp
4142 :
4143 6248 : DO iii = 1, 2*num_var
4144 6248 : stat_errors(iii) = SQRT(ABS(mat_N_gw(iii, iii)))*stat_error
4145 : END DO
4146 :
4147 568 : DEALLOCATE (mat_N_gw)
4148 568 : DEALLOCATE (vec_N_gw)
4149 568 : DEALLOCATE (mat_A_gw)
4150 568 : DEALLOCATE (mat_B_gw)
4151 568 : DEALLOCATE (stat_errors)
4152 568 : DEALLOCATE (dLambda)
4153 568 : DEALLOCATE (dLambda_2)
4154 568 : DEALLOCATE (vec_b_gw)
4155 568 : DEALLOCATE (vec_b_gw_copy)
4156 568 : DEALLOCATE (ipiv)
4157 568 : DEALLOCATE (vec_omega_fit_gw_sign)
4158 568 : DEALLOCATE (Lambda)
4159 568 : DEALLOCATE (Lambda_without_offset)
4160 568 : DEALLOCATE (Lambda_Re)
4161 568 : DEALLOCATE (Lambda_Im)
4162 :
4163 568 : END SUBROUTINE fit_and_continuation_2pole
4164 :
4165 : ! **************************************************************************************************
4166 : !> \brief perform analytic continuation with pade approximation
4167 : !> \param vec_gw_energ real Sigma_c
4168 : !> \param vec_omega_fit_gw frequency points for Sigma_c(iomega)
4169 : !> \param z_value 1/(1-dev)
4170 : !> \param m_value derivative of real Sigma_c
4171 : !> \param vec_Sigma_c_gw complex Sigma_c(iomega)
4172 : !> \param vec_Sigma_x_minus_vxc_gw ...
4173 : !> \param Eigenval quasiparticle energy during ev self-consistent GW
4174 : !> \param Eigenval_scf KS/HF eigenvalue
4175 : !> \param do_hedin_shift ...
4176 : !> \param n_level_gw ...
4177 : !> \param gw_corr_lev_occ ...
4178 : !> \param gw_corr_lev_vir ...
4179 : !> \param nparam_pade number of pade parameters
4180 : !> \param num_fit_points number of fit points for Sigma_c(iomega)
4181 : !> \param crossing_search type ofr cross search to find quasiparticle energies
4182 : !> \param homo ...
4183 : !> \param fermi_level_offset ...
4184 : !> \param do_gw_im_time ...
4185 : !> \param print_self_energy ...
4186 : !> \param count_ev_sc_GW ...
4187 : !> \param vec_gw_dos ...
4188 : !> \param dos_lower_bound ...
4189 : !> \param dos_precision ...
4190 : !> \param ndos ...
4191 : !> \param min_level_self_energy ...
4192 : !> \param max_level_self_energy ...
4193 : !> \param dos_eta ...
4194 : !> \param dos_min ...
4195 : !> \param dos_max ...
4196 : !> \param e_fermi_ext ...
4197 : ! **************************************************************************************************
4198 4712 : SUBROUTINE continuation_pade(vec_gw_energ, vec_omega_fit_gw, &
4199 9424 : z_value, m_value, vec_Sigma_c_gw, vec_Sigma_x_minus_vxc_gw, &
4200 9424 : Eigenval, Eigenval_scf, do_hedin_shift, n_level_gw, &
4201 : gw_corr_lev_occ, gw_corr_lev_vir, &
4202 : nparam_pade, num_fit_points, crossing_search, homo, &
4203 : fermi_level_offset, do_gw_im_time, print_self_energy, count_ev_sc_GW, &
4204 : vec_gw_dos, dos_lower_bound, dos_precision, ndos, &
4205 : min_level_self_energy, max_level_self_energy, &
4206 : dos_eta, dos_min, dos_max, e_fermi_ext)
4207 :
4208 : ! Optional arguments for spectral function
4209 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: vec_gw_energ
4210 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: vec_omega_fit_gw
4211 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: z_value, m_value
4212 : COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN) :: vec_Sigma_c_gw
4213 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: vec_Sigma_x_minus_vxc_gw, Eigenval, &
4214 : Eigenval_scf
4215 : LOGICAL, INTENT(IN) :: do_hedin_shift
4216 : INTEGER, INTENT(IN) :: n_level_gw, gw_corr_lev_occ, &
4217 : gw_corr_lev_vir, nparam_pade, &
4218 : num_fit_points, crossing_search, homo
4219 : REAL(KIND=dp), INTENT(IN) :: fermi_level_offset
4220 : LOGICAL, INTENT(IN) :: do_gw_im_time, print_self_energy
4221 : INTEGER, INTENT(IN) :: count_ev_sc_GW
4222 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), OPTIONAL :: vec_gw_dos
4223 : REAL(KIND=dp), OPTIONAL :: dos_lower_bound, dos_precision
4224 : INTEGER, INTENT(IN), OPTIONAL :: ndos, min_level_self_energy, &
4225 : max_level_self_energy
4226 : REAL(KIND=dp), OPTIONAL :: dos_eta
4227 : INTEGER, INTENT(IN), OPTIONAL :: dos_min, dos_max
4228 : REAL(KIND=dp), OPTIONAL :: e_fermi_ext
4229 :
4230 : CHARACTER(LEN=*), PARAMETER :: routineN = 'continuation_pade'
4231 :
4232 : CHARACTER(LEN=5) :: string_level
4233 : CHARACTER(len=default_path_length) :: filename
4234 : COMPLEX(KIND=dp) :: sigma_c_pade, sigma_c_pade_im_freq
4235 4712 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: coeff_pade, omega_points_pade, &
4236 4712 : Sigma_c_gw_reorder
4237 : INTEGER :: handle, i_omega, idos, iunit, jquad, &
4238 : n_level_gw_ref, num_omega
4239 : REAL(KIND=dp) :: e_fermi, energy_val, hedin_shift, &
4240 : level_energ_GW_start, omega, &
4241 : omega_dos, omega_dos_pade_eval, &
4242 : sign_occ_virt
4243 4712 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:) :: vec_omega_fit_gw_sign, &
4244 4712 : vec_omega_fit_gw_sign_reorder, &
4245 4712 : vec_sigma_imag, vec_sigma_real
4246 : TYPE(cp_logger_type), POINTER :: logger
4247 :
4248 4712 : CALL timeset(routineN, handle)
4249 :
4250 14136 : ALLOCATE (vec_omega_fit_gw_sign(num_fit_points))
4251 :
4252 4712 : IF (n_level_gw <= gw_corr_lev_occ) THEN
4253 : sign_occ_virt = -1.0_dp
4254 : ELSE
4255 3396 : sign_occ_virt = 1.0_dp
4256 : END IF
4257 :
4258 107565 : DO jquad = 1, num_fit_points
4259 107565 : vec_omega_fit_gw_sign(jquad) = ABS(vec_omega_fit_gw(jquad))*sign_occ_virt
4260 : END DO
4261 :
4262 4712 : IF (do_gw_im_time) THEN
4263 : ! for cubic-scaling GW, we have one Green's function for occ and virt states
4264 : ! with the Fermi level in the middle of homo and lumo
4265 3115 : e_fermi = 0.5_dp*(Eigenval(homo) + Eigenval(homo + 1))
4266 : ELSE
4267 : ! in case of O(N^4) GW, we have the Fermi level differently for occ and virt states, see
4268 : ! Fig. 1 in JCTC 12, 3623-3635 (2016)
4269 1597 : IF (n_level_gw <= gw_corr_lev_occ) THEN
4270 1850 : e_fermi = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo)) + fermi_level_offset
4271 : ELSE
4272 34444 : e_fermi = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_vir)) - fermi_level_offset
4273 : END IF
4274 : END IF
4275 :
4276 4712 : IF (PRESENT(e_fermi_ext)) e_fermi = e_fermi_ext
4277 :
4278 4712 : n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
4279 :
4280 : !*** reorder, such that omega=i*0 is first entry
4281 14136 : ALLOCATE (Sigma_c_gw_reorder(num_fit_points))
4282 9424 : ALLOCATE (vec_omega_fit_gw_sign_reorder(num_fit_points))
4283 : ! for cubic scaling GW fit points are ordered differently than in N^4 GW
4284 4712 : IF (do_gw_im_time) THEN
4285 15770 : DO jquad = 1, num_fit_points
4286 12655 : Sigma_c_gw_reorder(jquad) = vec_Sigma_c_gw(n_level_gw, jquad)
4287 15770 : vec_omega_fit_gw_sign_reorder(jquad) = vec_omega_fit_gw_sign(jquad)
4288 : END DO
4289 : ELSE
4290 91795 : DO jquad = 1, num_fit_points
4291 90198 : Sigma_c_gw_reorder(jquad) = vec_Sigma_c_gw(n_level_gw, num_fit_points - jquad + 1)
4292 91795 : vec_omega_fit_gw_sign_reorder(jquad) = vec_omega_fit_gw_sign(num_fit_points - jquad + 1)
4293 : END DO
4294 : END IF
4295 :
4296 : !*** evaluate parameters for pade approximation
4297 14136 : ALLOCATE (coeff_pade(nparam_pade))
4298 9424 : ALLOCATE (omega_points_pade(nparam_pade))
4299 4712 : coeff_pade = 0.0_dp
4300 : CALL get_pade_parameters(Sigma_c_gw_reorder, vec_omega_fit_gw_sign_reorder, &
4301 4712 : num_fit_points, nparam_pade, omega_points_pade, coeff_pade)
4302 :
4303 : !*** calculate start_value for iterative cross-searching methods
4304 4712 : IF ((crossing_search == ri_rpa_g0w0_crossing_bisection) .OR. &
4305 : (crossing_search == ri_rpa_g0w0_crossing_newton)) THEN
4306 4712 : energy_val = Eigenval(n_level_gw_ref) - e_fermi
4307 : CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
4308 4712 : coeff_pade, sigma_c_pade)
4309 : CALL get_z_and_m_value_pade(energy_val, nparam_pade, omega_points_pade, &
4310 4712 : coeff_pade, z_value(n_level_gw), m_value(n_level_gw))
4311 : level_energ_GW_start = (Eigenval_scf(n_level_gw_ref) - &
4312 : m_value(n_level_gw)*Eigenval(n_level_gw_ref) + &
4313 : REAL(sigma_c_pade) + &
4314 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))* &
4315 4712 : z_value(n_level_gw)
4316 :
4317 : ! calculate Hedin shift; the last line is for evGW0 and evGW
4318 4712 : hedin_shift = 0.0_dp
4319 4712 : IF (do_hedin_shift) hedin_shift = REAL(sigma_c_pade) + &
4320 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref) &
4321 60 : - Eigenval(n_level_gw_ref) + Eigenval_scf(n_level_gw_ref)
4322 : END IF
4323 :
4324 4712 : IF (PRESENT(min_level_self_energy) .AND. PRESENT(max_level_self_energy)) THEN
4325 1841 : IF (n_level_gw_ref >= min_level_self_energy .AND. &
4326 : n_level_gw_ref <= max_level_self_energy) THEN
4327 0 : ALLOCATE (vec_sigma_real(ndos))
4328 0 : ALLOCATE (vec_sigma_imag(ndos))
4329 0 : WRITE (string_level, "(I4)") n_level_gw_ref
4330 0 : string_level = ADJUSTL(string_level)
4331 : END IF
4332 : END IF
4333 :
4334 : !*** Calculate spectral function
4335 : !*** 1 \‾‾ |Im 𝚺ₘ(ω)|+η
4336 : !*** A(ω) = --- | ---------------------------------------------------
4337 : !*** π /__ [ω - eₘ^DFT - (Re 𝚺ₘ(ω) - vₘ^xc)]² + (|Im 𝚺ₘ(ω)|+η)²
4338 :
4339 4712 : IF (PRESENT(ndos)) THEN
4340 1841 : IF (ndos /= 0) THEN
4341 : ! Hedin shift not implemented
4342 0 : CPASSERT(.NOT. do_hedin_shift)
4343 0 : logger => cp_get_default_logger()
4344 0 : IF (logger%para_env%is_source()) THEN
4345 0 : iunit = cp_logger_get_default_unit_nr()
4346 : ELSE
4347 0 : iunit = -1
4348 : END IF
4349 0 : DO idos = 1, ndos
4350 0 : omega_dos = dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision
4351 0 : omega_dos_pade_eval = omega_dos - e_fermi
4352 : CALL evaluate_pade_function(omega_dos_pade_eval, nparam_pade, omega_points_pade, &
4353 0 : coeff_pade, sigma_c_pade)
4354 :
4355 : IF (n_level_gw_ref >= min_level_self_energy .AND. &
4356 0 : n_level_gw_ref <= max_level_self_energy .AND. iunit > 0) THEN
4357 :
4358 0 : vec_sigma_real(idos) = (REAL(sigma_c_pade))
4359 0 : vec_sigma_imag(idos) = (AIMAG(sigma_c_pade))
4360 :
4361 : END IF
4362 :
4363 0 : IF (n_level_gw_ref >= dos_min .AND. &
4364 0 : (n_level_gw_ref <= dos_max .OR. dos_max == 0)) THEN
4365 : vec_gw_dos(idos) = vec_gw_dos(idos) + &
4366 : (ABS(AIMAG(sigma_c_pade)) + dos_eta) &
4367 : /( &
4368 : (omega_dos - Eigenval_scf(n_level_gw_ref) - &
4369 : (REAL(sigma_c_pade) + vec_Sigma_x_minus_vxc_gw(n_level_gw_ref)) &
4370 : )**2 &
4371 : + (ABS(AIMAG(sigma_c_pade)) + dos_eta)**2 &
4372 0 : )
4373 : END IF
4374 :
4375 : END DO
4376 : END IF
4377 : END IF
4378 :
4379 4712 : IF (PRESENT(min_level_self_energy) .AND. PRESENT(max_level_self_energy)) THEN
4380 1841 : logger => cp_get_default_logger()
4381 1841 : IF (logger%para_env%is_source()) THEN
4382 1817 : iunit = cp_logger_get_default_unit_nr()
4383 : ELSE
4384 24 : iunit = -1
4385 : END IF
4386 : IF (n_level_gw_ref >= min_level_self_energy .AND. &
4387 1841 : n_level_gw_ref <= max_level_self_energy .AND. iunit > 0) THEN
4388 :
4389 : CALL open_file('self_energy_re_'//TRIM(string_level)//'.dat', unit_number=iunit, &
4390 0 : file_status="UNKNOWN", file_action="WRITE")
4391 0 : DO idos = 1, ndos
4392 0 : omega_dos = dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision
4393 0 : WRITE (iunit, '(F17.10, F17.10)') omega_dos*evolt, vec_sigma_real(idos)*evolt
4394 : END DO
4395 :
4396 0 : CALL close_file(iunit)
4397 :
4398 : CALL open_file('self_energy_im_'//TRIM(string_level)//'.dat', unit_number=iunit, &
4399 0 : file_status="UNKNOWN", file_action="WRITE")
4400 0 : DO idos = 1, ndos
4401 0 : omega_dos = dos_lower_bound + REAL(idos - 1, KIND=dp)*dos_precision
4402 0 : WRITE (iunit, '(F17.10, F17.10)') omega_dos*evolt, vec_sigma_imag(idos)*evolt
4403 : END DO
4404 :
4405 0 : CALL close_file(iunit)
4406 :
4407 0 : DEALLOCATE (vec_sigma_real)
4408 0 : DEALLOCATE (vec_sigma_imag)
4409 : END IF
4410 : END IF
4411 :
4412 : !*** perform crossing search
4413 0 : SELECT CASE (crossing_search)
4414 : CASE (ri_rpa_g0w0_crossing_z_shot)
4415 : ! Hedin shift not implemented
4416 0 : CPASSERT(.NOT. do_hedin_shift)
4417 0 : energy_val = Eigenval(n_level_gw_ref) - e_fermi
4418 : CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
4419 0 : coeff_pade, sigma_c_pade)
4420 0 : vec_gw_energ(n_level_gw) = REAL(sigma_c_pade)
4421 :
4422 : CALL get_z_and_m_value_pade(energy_val, nparam_pade, omega_points_pade, &
4423 0 : coeff_pade, z_value(n_level_gw), m_value(n_level_gw))
4424 :
4425 : CASE (ri_rpa_g0w0_crossing_bisection)
4426 : CALL get_sigma_c_bisection_pade(vec_gw_energ(n_level_gw), Eigenval_scf(n_level_gw_ref), &
4427 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref), e_fermi, &
4428 : nparam_pade, omega_points_pade, coeff_pade, &
4429 8 : level_energ_GW_start, hedin_shift)
4430 8 : z_value(n_level_gw) = 1.0_dp
4431 8 : m_value(n_level_gw) = 0.0_dp
4432 :
4433 : CASE (ri_rpa_g0w0_crossing_newton)
4434 : CALL get_sigma_c_newton_pade(vec_gw_energ(n_level_gw), Eigenval_scf(n_level_gw_ref), &
4435 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref), e_fermi, &
4436 : nparam_pade, omega_points_pade, coeff_pade, &
4437 4704 : level_energ_GW_start, hedin_shift)
4438 4704 : z_value(n_level_gw) = 1.0_dp
4439 4704 : m_value(n_level_gw) = 0.0_dp
4440 :
4441 : CASE DEFAULT
4442 4712 : CPABORT("Only Z_SHOT, NEWTON, and BISECTION crossing search implemented.")
4443 : END SELECT
4444 :
4445 4712 : IF (print_self_energy) THEN
4446 :
4447 0 : IF (count_ev_sc_GW == 1) THEN
4448 :
4449 0 : IF (n_level_gw_ref < 10) THEN
4450 0 : WRITE (filename, "(A26,I1)") "G0W0_self_energy_level_000", n_level_gw_ref
4451 0 : ELSE IF (n_level_gw_ref < 100) THEN
4452 0 : WRITE (filename, "(A25,I2)") "G0W0_self_energy_level_00", n_level_gw_ref
4453 0 : ELSE IF (n_level_gw_ref < 1000) THEN
4454 0 : WRITE (filename, "(A24,I3)") "G0W0_self_energy_level_0", n_level_gw_ref
4455 : ELSE
4456 0 : WRITE (filename, "(A23,I4)") "G0W0_self_energy_level_", n_level_gw_ref
4457 : END IF
4458 :
4459 : ELSE
4460 :
4461 0 : IF (n_level_gw_ref < 10) THEN
4462 0 : WRITE (filename, "(A11,I1,A22,I1)") "evGW_cycle_", count_ev_sc_GW, &
4463 0 : "_self_energy_level_000", n_level_gw_ref
4464 0 : ELSE IF (n_level_gw_ref < 100) THEN
4465 0 : WRITE (filename, "(A11,I1,A21,I2)") "evGW_cycle_", count_ev_sc_GW, &
4466 0 : "_self_energy_level_00", n_level_gw_ref
4467 0 : ELSE IF (n_level_gw_ref < 1000) THEN
4468 0 : WRITE (filename, "(A11,I1,A20,I3)") "evGW_cycle_", count_ev_sc_GW, &
4469 0 : "_self_energy_level_0", n_level_gw_ref
4470 : ELSE
4471 0 : WRITE (filename, "(A11,I1,A19,I4)") "evGW_cycle_", count_ev_sc_GW, &
4472 0 : "_self_energy_level_", n_level_gw_ref
4473 : END IF
4474 :
4475 : END IF
4476 :
4477 0 : logger => cp_get_default_logger()
4478 0 : IF (logger%para_env%is_source()) THEN
4479 0 : iunit = cp_logger_get_default_unit_nr()
4480 : ELSE
4481 : iunit = -1
4482 : END IF
4483 0 : CALL open_file(TRIM(filename), unit_number=iunit, file_status="UNKNOWN", file_action="WRITE")
4484 :
4485 0 : num_omega = 10000
4486 :
4487 0 : WRITE (iunit, "(2A42)") " omega (eV) Sigma(omega) (eV) ", &
4488 0 : " omega - e_n^DFT - Sigma_n^x - v_n^xc (eV)"
4489 :
4490 0 : DO i_omega = 0, num_omega
4491 :
4492 0 : omega = -50.0_dp/evolt + REAL(i_omega, KIND=dp)/REAL(num_omega, KIND=dp)*100.0_dp/evolt
4493 :
4494 : CALL evaluate_pade_function(omega - e_fermi, nparam_pade, omega_points_pade, &
4495 0 : coeff_pade, sigma_c_pade)
4496 :
4497 0 : WRITE (iunit, "(F12.2,2F17.5)") omega*evolt, REAL(sigma_c_pade)*evolt, &
4498 0 : (omega - Eigenval_scf(n_level_gw_ref) - vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))*evolt
4499 :
4500 : END DO
4501 :
4502 0 : WRITE (iunit, "(A51,A39)") " w (eV) Re(Sigma(i*w)) (eV) Im(Sigma(i*w)) (eV) ", &
4503 0 : " Re(Fit(i*w)) (eV) Im(Fit(iw)) (eV)"
4504 :
4505 0 : DO jquad = 1, num_fit_points
4506 :
4507 : CALL evaluate_pade_function(vec_omega_fit_gw_sign_reorder(jquad), &
4508 : nparam_pade, omega_points_pade, &
4509 0 : coeff_pade, sigma_c_pade_im_freq, do_imag_freq=.TRUE.)
4510 :
4511 0 : WRITE (iunit, "(F12.2,4F17.5)") vec_omega_fit_gw_sign_reorder(jquad)*evolt, &
4512 0 : REAL(Sigma_c_gw_reorder(jquad)*evolt), &
4513 0 : AIMAG(Sigma_c_gw_reorder(jquad)*evolt), &
4514 0 : REAL(sigma_c_pade_im_freq*evolt), &
4515 0 : AIMAG(sigma_c_pade_im_freq*evolt)
4516 :
4517 : END DO
4518 :
4519 0 : CALL close_file(iunit)
4520 :
4521 : END IF
4522 :
4523 4712 : DEALLOCATE (vec_omega_fit_gw_sign)
4524 4712 : DEALLOCATE (Sigma_c_gw_reorder)
4525 4712 : DEALLOCATE (vec_omega_fit_gw_sign_reorder)
4526 4712 : DEALLOCATE (coeff_pade, omega_points_pade)
4527 :
4528 4712 : CALL timestop(handle)
4529 :
4530 9424 : END SUBROUTINE continuation_pade
4531 :
4532 : ! **************************************************************************************************
4533 : !> \brief calculate pade parameter recursively as in Eq. (A2) in J. Low Temp. Phys., Vol. 29,
4534 : !> 1977, pp. 179
4535 : !> \param y f(x), here: Sigma_c(iomega)
4536 : !> \param x the frequency points omega
4537 : !> \param num_fit_points ...
4538 : !> \param nparam number of pade parameters
4539 : !> \param xpoints set of points used in pade approximation, selection of x
4540 : !> \param coeff pade coefficients
4541 : ! **************************************************************************************************
4542 4712 : PURE SUBROUTINE get_pade_parameters(y, x, num_fit_points, nparam, xpoints, coeff)
4543 :
4544 : COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN) :: y
4545 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: x
4546 : INTEGER, INTENT(IN) :: num_fit_points, nparam
4547 : COMPLEX(KIND=dp), DIMENSION(:), INTENT(INOUT) :: xpoints, coeff
4548 :
4549 4712 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: ypoints
4550 4712 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: g_mat
4551 : INTEGER :: idat, iparam, nstep
4552 :
4553 4712 : nstep = INT(num_fit_points/(nparam - 1))
4554 :
4555 14136 : ALLOCATE (ypoints(nparam))
4556 : !omega=i0 is in element x(1)
4557 4712 : idat = 1
4558 36513 : DO iparam = 1, nparam - 1
4559 31801 : xpoints(iparam) = gaussi*x(idat)
4560 31801 : ypoints(iparam) = y(idat)
4561 36513 : idat = idat + nstep
4562 : END DO
4563 4712 : xpoints(nparam) = gaussi*x(num_fit_points)
4564 4712 : ypoints(nparam) = y(num_fit_points)
4565 :
4566 : !*** generate parameters recursively
4567 :
4568 18848 : ALLOCATE (g_mat(nparam, nparam))
4569 41225 : g_mat(:, 1) = ypoints(:)
4570 36513 : DO iparam = 2, nparam
4571 238758 : DO idat = iparam, nparam
4572 : g_mat(idat, iparam) = (g_mat(iparam - 1, iparam - 1) - g_mat(idat, iparam - 1))/ &
4573 234046 : ((xpoints(idat) - xpoints(iparam - 1))*g_mat(idat, iparam - 1))
4574 : END DO
4575 : END DO
4576 :
4577 41225 : DO iparam = 1, nparam
4578 41225 : coeff(iparam) = g_mat(iparam, iparam)
4579 : END DO
4580 :
4581 4712 : DEALLOCATE (ypoints)
4582 4712 : DEALLOCATE (g_mat)
4583 :
4584 4712 : END SUBROUTINE get_pade_parameters
4585 :
4586 : ! **************************************************************************************************
4587 : !> \brief evaluate pade function for a real value x_val
4588 : !> \param x_val real value
4589 : !> \param nparam number of pade parameters
4590 : !> \param xpoints selection of points of the original complex function, i.e. here of Sigma_c(iomega)
4591 : !> \param coeff pade coefficients
4592 : !> \param func_val function value
4593 : !> \param do_imag_freq ...
4594 : ! **************************************************************************************************
4595 24852 : PURE SUBROUTINE evaluate_pade_function(x_val, nparam, xpoints, coeff, func_val, do_imag_freq)
4596 :
4597 : REAL(KIND=dp), INTENT(IN) :: x_val
4598 : INTEGER, INTENT(IN) :: nparam
4599 : COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN) :: xpoints, coeff
4600 : COMPLEX(KIND=dp), INTENT(OUT) :: func_val
4601 : LOGICAL, INTENT(IN), OPTIONAL :: do_imag_freq
4602 :
4603 : INTEGER :: iparam
4604 : LOGICAL :: my_do_imag_freq
4605 :
4606 24852 : my_do_imag_freq = .FALSE.
4607 24852 : IF (PRESENT(do_imag_freq)) my_do_imag_freq = do_imag_freq
4608 :
4609 24852 : func_val = z_one
4610 203144 : DO iparam = nparam, 2, -1
4611 203144 : IF (my_do_imag_freq) THEN
4612 0 : func_val = z_one + coeff(iparam)*(gaussi*x_val - xpoints(iparam - 1))/func_val
4613 : ELSE
4614 178292 : func_val = z_one + coeff(iparam)*(x_val*z_one - xpoints(iparam - 1))/func_val
4615 : END IF
4616 : END DO
4617 :
4618 24852 : func_val = coeff(1)/func_val
4619 :
4620 24852 : END SUBROUTINE evaluate_pade_function
4621 :
4622 : ! **************************************************************************************************
4623 : !> \brief get the z-value and the m-value (derivative) of the pade function
4624 : !> \param x_val real value
4625 : !> \param nparam number of pade parameters
4626 : !> \param xpoints selection of points of the original complex function, i.e. here of Sigma_c(iomega)
4627 : !> \param coeff pade coefficients
4628 : !> \param z_value 1/(1-dev)
4629 : !> \param m_value derivative
4630 : ! **************************************************************************************************
4631 24744 : PURE SUBROUTINE get_z_and_m_value_pade(x_val, nparam, xpoints, coeff, z_value, m_value)
4632 :
4633 : REAL(KIND=dp), INTENT(IN) :: x_val
4634 : INTEGER, INTENT(IN) :: nparam
4635 : COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN) :: xpoints, coeff
4636 : REAL(KIND=dp), INTENT(OUT), OPTIONAL :: z_value, m_value
4637 :
4638 : COMPLEX(KIND=dp) :: denominator, dev_denominator, &
4639 : dev_numerator, dev_val, func_val, &
4640 : numerator
4641 : INTEGER :: iparam
4642 :
4643 24744 : func_val = z_one
4644 24744 : dev_val = z_zero
4645 202928 : DO iparam = nparam, 2, -1
4646 178184 : numerator = coeff(iparam)*(x_val*z_one - xpoints(iparam - 1))
4647 178184 : dev_numerator = coeff(iparam)*z_one
4648 178184 : denominator = func_val
4649 178184 : dev_denominator = dev_val
4650 178184 : dev_val = dev_numerator/denominator - (numerator*dev_denominator)/(denominator**2)
4651 202928 : func_val = z_one + coeff(iparam)*(x_val*z_one - xpoints(iparam - 1))/func_val
4652 : END DO
4653 :
4654 24744 : dev_val = -1.0_dp*coeff(1)/(func_val**2)*dev_val
4655 24744 : func_val = coeff(1)/func_val
4656 :
4657 24744 : IF (PRESENT(z_value)) THEN
4658 4712 : z_value = 1.0_dp - REAL(dev_val)
4659 4712 : z_value = 1.0_dp/z_value
4660 : END IF
4661 24744 : IF (PRESENT(m_value)) m_value = REAL(dev_val)
4662 :
4663 24744 : END SUBROUTINE get_z_and_m_value_pade
4664 :
4665 : ! **************************************************************************************************
4666 : !> \brief crossing search using the bisection method to find the quasiparticle energy
4667 : !> \param gw_energ real Sigma_c
4668 : !> \param Eigenval_scf Eigenvalue from the SCF
4669 : !> \param Sigma_x_minus_vxc_gw ...
4670 : !> \param e_fermi fermi level
4671 : !> \param nparam_pade number of pade parameters
4672 : !> \param omega_points_pade selection of frequency points of Sigma_c(iomega)
4673 : !> \param coeff_pade pade coefficients
4674 : !> \param start_val start value for the quasiparticle iteration
4675 : !> \param hedin_shift ...
4676 : ! **************************************************************************************************
4677 16 : SUBROUTINE get_sigma_c_bisection_pade(gw_energ, Eigenval_scf, Sigma_x_minus_vxc_gw, e_fermi, &
4678 8 : nparam_pade, omega_points_pade, coeff_pade, start_val, &
4679 : hedin_shift)
4680 :
4681 : REAL(KIND=dp), INTENT(OUT) :: gw_energ
4682 : REAL(KIND=dp), INTENT(IN) :: Eigenval_scf, Sigma_x_minus_vxc_gw, &
4683 : e_fermi
4684 : INTEGER, INTENT(IN) :: nparam_pade
4685 : COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN) :: omega_points_pade, coeff_pade
4686 : REAL(KIND=dp), INTENT(IN) :: start_val, hedin_shift
4687 :
4688 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_sigma_c_bisection_pade'
4689 :
4690 : COMPLEX(KIND=dp) :: sigma_c
4691 : INTEGER :: handle, icount
4692 : REAL(KIND=dp) :: delta, energy_val, qp_energy, &
4693 : qp_energy_old, threshold
4694 :
4695 8 : CALL timeset(routineN, handle)
4696 :
4697 8 : threshold = 1.0E-7_dp
4698 :
4699 8 : qp_energy = start_val
4700 8 : qp_energy_old = start_val
4701 8 : delta = 1.0E-3_dp
4702 :
4703 8 : icount = 0
4704 116 : DO WHILE (ABS(delta) > threshold)
4705 108 : icount = icount + 1
4706 108 : qp_energy = qp_energy_old + 0.5_dp*delta
4707 108 : qp_energy_old = qp_energy
4708 108 : energy_val = qp_energy - e_fermi - hedin_shift
4709 : CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
4710 108 : coeff_pade, sigma_c)
4711 108 : qp_energy = Eigenval_scf + REAL(sigma_c) + Sigma_x_minus_vxc_gw
4712 108 : delta = qp_energy - qp_energy_old
4713 : ! Self-consistent quasi-particle solution has not been found
4714 116 : IF (icount > 500) EXIT
4715 : END DO
4716 :
4717 8 : gw_energ = REAL(sigma_c)
4718 :
4719 8 : CALL timestop(handle)
4720 :
4721 8 : END SUBROUTINE get_sigma_c_bisection_pade
4722 :
4723 : ! **************************************************************************************************
4724 : !> \brief crossing search using the Newton method to find the quasiparticle energy
4725 : !> \param gw_energ real Sigma_c
4726 : !> \param Eigenval_scf Eigenvalue from the SCF
4727 : !> \param Sigma_x_minus_vxc_gw ...
4728 : !> \param e_fermi fermi level
4729 : !> \param nparam_pade number of pade parameters
4730 : !> \param omega_points_pade selection of frequency points of Sigma_c(iomega)
4731 : !> \param coeff_pade pade coefficients
4732 : !> \param start_val start value for the quasiparticle iteration
4733 : !> \param hedin_shift ...
4734 : ! **************************************************************************************************
4735 9408 : SUBROUTINE get_sigma_c_newton_pade(gw_energ, Eigenval_scf, Sigma_x_minus_vxc_gw, e_fermi, &
4736 4704 : nparam_pade, omega_points_pade, coeff_pade, start_val, &
4737 : hedin_shift)
4738 :
4739 : REAL(KIND=dp), INTENT(OUT) :: gw_energ
4740 : REAL(KIND=dp), INTENT(IN) :: Eigenval_scf, Sigma_x_minus_vxc_gw, &
4741 : e_fermi
4742 : INTEGER, INTENT(IN) :: nparam_pade
4743 : COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN) :: omega_points_pade, coeff_pade
4744 : REAL(KIND=dp), INTENT(IN) :: start_val, hedin_shift
4745 :
4746 : CHARACTER(LEN=*), PARAMETER :: routineN = 'get_sigma_c_newton_pade'
4747 :
4748 : COMPLEX(KIND=dp) :: sigma_c
4749 : INTEGER :: handle, icount
4750 : REAL(KIND=dp) :: delta, energy_val, m_value, qp_energy, &
4751 : qp_energy_old, threshold
4752 :
4753 4704 : CALL timeset(routineN, handle)
4754 :
4755 4704 : threshold = 1.0E-7_dp
4756 :
4757 4704 : qp_energy = start_val
4758 4704 : qp_energy_old = start_val
4759 4704 : delta = 1.0E-3_dp
4760 :
4761 4704 : icount = 0
4762 24728 : DO WHILE (ABS(delta) > threshold)
4763 20032 : icount = icount + 1
4764 20032 : energy_val = qp_energy - e_fermi - hedin_shift
4765 : CALL evaluate_pade_function(energy_val, nparam_pade, omega_points_pade, &
4766 20032 : coeff_pade, sigma_c)
4767 : !get m_value --> derivative of function
4768 : CALL get_z_and_m_value_pade(energy_val, nparam_pade, omega_points_pade, &
4769 20032 : coeff_pade, m_value=m_value)
4770 20032 : qp_energy_old = qp_energy
4771 : qp_energy = qp_energy - (Eigenval_scf + Sigma_x_minus_vxc_gw + REAL(sigma_c) - qp_energy)/ &
4772 20032 : (m_value - 1.0_dp)
4773 20032 : delta = qp_energy - qp_energy_old
4774 : ! Self-consistent quasi-particle solution has not been found
4775 24728 : IF (icount > 500) EXIT
4776 : END DO
4777 :
4778 4704 : gw_energ = REAL(sigma_c)
4779 :
4780 4704 : CALL timestop(handle)
4781 :
4782 4704 : END SUBROUTINE get_sigma_c_newton_pade
4783 :
4784 : ! **************************************************************************************************
4785 : !> \brief Prints the GW stuff to the output and optinally to an external file.
4786 : !> Also updates the eigenvalues for eigenvalue-self-consistent GW
4787 : !> \param vec_gw_energ ...
4788 : !> \param z_value ...
4789 : !> \param m_value ...
4790 : !> \param vec_Sigma_x_minus_vxc_gw ...
4791 : !> \param Eigenval ...
4792 : !> \param Eigenval_last ...
4793 : !> \param Eigenval_scf ...
4794 : !> \param gw_corr_lev_occ ...
4795 : !> \param gw_corr_lev_virt ...
4796 : !> \param gw_corr_lev_tot ...
4797 : !> \param crossing_search ...
4798 : !> \param homo ...
4799 : !> \param unit_nr ...
4800 : !> \param count_ev_sc_GW ...
4801 : !> \param count_sc_GW0 ...
4802 : !> \param ikp ...
4803 : !> \param nkp_self_energy ...
4804 : !> \param kpoints ...
4805 : !> \param ispin requested spin-state (1 for alpha, 2 for beta, else closed-shell)
4806 : !> \param E_VBM_GW ...
4807 : !> \param E_CBM_GW ...
4808 : !> \param E_VBM_SCF ...
4809 : !> \param E_CBM_SCF ...
4810 : ! **************************************************************************************************
4811 1672 : SUBROUTINE print_and_update_for_ev_sc(vec_gw_energ, &
4812 418 : z_value, m_value, vec_Sigma_x_minus_vxc_gw, Eigenval, &
4813 418 : Eigenval_last, Eigenval_scf, &
4814 : gw_corr_lev_occ, gw_corr_lev_virt, gw_corr_lev_tot, &
4815 : crossing_search, homo, unit_nr, count_ev_sc_GW, count_sc_GW0, &
4816 : ikp, nkp_self_energy, kpoints, ispin, E_VBM_GW, E_CBM_GW, &
4817 : E_VBM_SCF, E_CBM_SCF)
4818 :
4819 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: vec_gw_energ, z_value, m_value
4820 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: vec_Sigma_x_minus_vxc_gw, Eigenval, &
4821 : Eigenval_last, Eigenval_scf
4822 : INTEGER, INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, gw_corr_lev_tot, crossing_search, &
4823 : homo, unit_nr, count_ev_sc_GW, count_sc_GW0, ikp, nkp_self_energy
4824 : TYPE(kpoint_type), INTENT(IN), POINTER :: kpoints
4825 : INTEGER, INTENT(IN) :: ispin
4826 : REAL(KIND=dp), INTENT(INOUT), OPTIONAL :: E_VBM_GW, E_CBM_GW, E_VBM_SCF, E_CBM_SCF
4827 :
4828 : CHARACTER(LEN=*), PARAMETER :: routineN = 'print_and_update_for_ev_sc'
4829 :
4830 : CHARACTER(4) :: occ_virt
4831 : INTEGER :: handle, n_level_gw, n_level_gw_ref
4832 : LOGICAL :: do_alpha, do_beta, do_closed_shell, &
4833 : do_kpoints, is_energy_okay
4834 : REAL(KIND=dp) :: E_GAP_GW, E_HOMO_GW, E_HOMO_SCF, &
4835 : E_LUMO_GW, E_LUMO_SCF, new_energy
4836 :
4837 418 : CALL timeset(routineN, handle)
4838 :
4839 418 : do_alpha = (ispin == 1)
4840 418 : do_beta = (ispin == 2)
4841 418 : do_closed_shell = .NOT. (do_alpha .OR. do_beta)
4842 418 : do_kpoints = (nkp_self_energy > 1)
4843 :
4844 10264 : Eigenval_last(:) = Eigenval(:)
4845 :
4846 418 : IF (unit_nr > 0) THEN
4847 :
4848 209 : IF (count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1 .AND. ikp == 1) THEN
4849 :
4850 74 : WRITE (unit_nr, *) ' '
4851 :
4852 74 : IF (do_alpha .OR. do_closed_shell) THEN
4853 62 : WRITE (unit_nr, *) ' '
4854 62 : WRITE (unit_nr, '(T3,A)') '******************************************************************************'
4855 62 : WRITE (unit_nr, '(T3,A)') '** **'
4856 62 : WRITE (unit_nr, '(T3,A)') '** GW QUASIPARTICLE ENERGIES **'
4857 62 : WRITE (unit_nr, '(T3,A)') '** **'
4858 62 : WRITE (unit_nr, '(T3,A)') '******************************************************************************'
4859 62 : WRITE (unit_nr, '(T3,A)') ' '
4860 62 : WRITE (unit_nr, '(T3,A)') ' '
4861 62 : WRITE (unit_nr, '(T3,A)') 'The GW quasiparticle energies are calculated according to: '
4862 :
4863 62 : IF (crossing_search == ri_rpa_g0w0_crossing_z_shot) THEN
4864 16 : WRITE (unit_nr, '(T3,A)') 'E_GW = E_SCF + Z * ( Sigc(E_SCF) + Sigx - vxc )'
4865 : ELSE
4866 46 : WRITE (unit_nr, '(T3,A)') ' '
4867 46 : WRITE (unit_nr, '(T3,A)') ' E_GW = E_SCF + Sigc(E_GW) + Sigx - vxc '
4868 46 : WRITE (unit_nr, '(T3,A)') ' '
4869 46 : WRITE (unit_nr, '(T3,A)') 'Upper equation is solved self-consistently for E_GW, see Eq. (12) in J. Phys.'
4870 46 : WRITE (unit_nr, '(T3,A)') 'Chem. Lett. 9, 306 (2018), doi: 10.1021/acs.jpclett.7b02740'
4871 : END IF
4872 62 : WRITE (unit_nr, *) ' '
4873 62 : WRITE (unit_nr, *) ' '
4874 62 : WRITE (unit_nr, '(T3,A)') '------------'
4875 62 : WRITE (unit_nr, '(T3,A)') 'G0W0 results'
4876 62 : WRITE (unit_nr, '(T3,A)') '------------'
4877 :
4878 : END IF
4879 :
4880 74 : IF (.NOT. do_kpoints) THEN
4881 65 : IF (do_alpha) THEN
4882 11 : WRITE (unit_nr, *) ' '
4883 11 : WRITE (unit_nr, '(T3,A)') '---------------------------------------'
4884 11 : WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of alpha spins'
4885 11 : WRITE (unit_nr, '(T3,A)') '----------------------------------------'
4886 54 : ELSE IF (do_beta) THEN
4887 11 : WRITE (unit_nr, *) ' '
4888 11 : WRITE (unit_nr, '(T3,A)') '---------------------------------------'
4889 11 : WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of beta spins'
4890 11 : WRITE (unit_nr, '(T3,A)') '---------------------------------------'
4891 : END IF
4892 : END IF
4893 :
4894 : END IF
4895 :
4896 209 : IF (count_ev_sc_GW > 1) THEN
4897 41 : WRITE (unit_nr, *) ' '
4898 41 : WRITE (unit_nr, '(T3,A)') '---------------------------------------'
4899 41 : WRITE (unit_nr, '(T3,A,I4)') 'Eigenvalue-selfconsistency cycle: ', count_ev_sc_GW
4900 41 : WRITE (unit_nr, '(T3,A)') '---------------------------------------'
4901 : END IF
4902 :
4903 209 : IF (count_sc_GW0 > 1) THEN
4904 36 : WRITE (unit_nr, '(T3,A)') '----------------------------------'
4905 36 : WRITE (unit_nr, '(T3,A,I4)') 'scGW0 selfconsistency cycle: ', count_sc_GW0
4906 36 : WRITE (unit_nr, '(T3,A)') '----------------------------------'
4907 : END IF
4908 :
4909 209 : IF (do_kpoints) THEN
4910 68 : WRITE (unit_nr, *) ' '
4911 68 : WRITE (unit_nr, '(T3,A7,I3,A3,I3,A8,3F7.3,A12,3F7.3)') 'Kpoint ', ikp, ' /', nkp_self_energy, &
4912 68 : ' xkp =', kpoints%xkp(1, ikp), kpoints%xkp(2, ikp), kpoints%xkp(3, ikp), &
4913 136 : ' and xkp =', -kpoints%xkp(1, ikp), -kpoints%xkp(2, ikp), -kpoints%xkp(3, ikp)
4914 68 : WRITE (unit_nr, '(T3,A72)') '(Relative Brillouin zone size: [-0.5, 0.5] x [-0.5, 0.5] x [-0.5, 0.5])'
4915 68 : WRITE (unit_nr, *) ' '
4916 68 : IF (do_alpha) THEN
4917 8 : WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of alpha spins:'
4918 60 : ELSE IF (do_beta) THEN
4919 8 : WRITE (unit_nr, '(T3,A)') 'GW quasiparticle energies of beta spins:'
4920 : END IF
4921 : END IF
4922 :
4923 : END IF
4924 :
4925 5236 : DO n_level_gw = 1, gw_corr_lev_tot
4926 :
4927 4818 : n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
4928 :
4929 : new_energy = (Eigenval_scf(n_level_gw_ref) - &
4930 : m_value(n_level_gw)*Eigenval(n_level_gw_ref) + &
4931 : vec_gw_energ(n_level_gw) + &
4932 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref))* &
4933 4818 : z_value(n_level_gw)
4934 :
4935 4818 : is_energy_okay = .TRUE.
4936 :
4937 4818 : IF (n_level_gw_ref > homo .AND. new_energy < Eigenval(homo)) THEN
4938 : is_energy_okay = .FALSE.
4939 : END IF
4940 :
4941 418 : IF (is_energy_okay) THEN
4942 4818 : Eigenval(n_level_gw_ref) = new_energy
4943 : END IF
4944 :
4945 : END DO
4946 :
4947 418 : IF (unit_nr > 0) THEN
4948 209 : WRITE (unit_nr, '(T3,A)') ' '
4949 209 : IF (crossing_search == ri_rpa_g0w0_crossing_z_shot) THEN
4950 39 : WRITE (unit_nr, '(T13,2A)') 'MO E_SCF (eV) Sigc (eV) Sigx-vxc (eV) Z E_GW (eV)'
4951 : ELSE
4952 170 : WRITE (unit_nr, '(T3,2A)') 'Molecular orbital E_SCF (eV) Sigc (eV) Sigx-vxc (eV) E_GW (eV)'
4953 : END IF
4954 : END IF
4955 :
4956 5236 : DO n_level_gw = 1, gw_corr_lev_tot
4957 4818 : n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
4958 4818 : IF (n_level_gw <= gw_corr_lev_occ) THEN
4959 1184 : occ_virt = 'occ'
4960 : ELSE
4961 3634 : occ_virt = 'vir'
4962 : END IF
4963 :
4964 5236 : IF (unit_nr > 0) THEN
4965 2409 : IF (crossing_search == ri_rpa_g0w0_crossing_z_shot) THEN
4966 : WRITE (unit_nr, '(T3,I4,3A,5F13.4)') &
4967 536 : n_level_gw_ref, ' ( ', occ_virt, ') ', &
4968 536 : Eigenval_last(n_level_gw_ref)*evolt, &
4969 536 : vec_gw_energ(n_level_gw)*evolt, &
4970 536 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref)*evolt, &
4971 536 : z_value(n_level_gw), &
4972 1072 : Eigenval(n_level_gw_ref)*evolt
4973 : ELSE
4974 : WRITE (unit_nr, '(T3,I4,3A,4F16.4)') &
4975 1873 : n_level_gw_ref, ' ( ', occ_virt, ') ', &
4976 1873 : Eigenval_last(n_level_gw_ref)*evolt, &
4977 1873 : vec_gw_energ(n_level_gw)*evolt, &
4978 1873 : vec_Sigma_x_minus_vxc_gw(n_level_gw_ref)*evolt, &
4979 3746 : Eigenval(n_level_gw_ref)*evolt
4980 : END IF
4981 : END IF
4982 : END DO
4983 :
4984 1602 : E_HOMO_SCF = MAXVAL(Eigenval_last(homo - gw_corr_lev_occ + 1:homo))
4985 4052 : E_LUMO_SCF = MINVAL(Eigenval_last(homo + 1:homo + gw_corr_lev_virt))
4986 :
4987 1602 : E_HOMO_GW = MAXVAL(Eigenval(homo - gw_corr_lev_occ + 1:homo))
4988 4052 : E_LUMO_GW = MINVAL(Eigenval(homo + 1:homo + gw_corr_lev_virt))
4989 418 : E_GAP_GW = E_LUMO_GW - E_HOMO_GW
4990 :
4991 : IF (PRESENT(E_VBM_SCF) .AND. PRESENT(E_CBM_SCF) .AND. &
4992 418 : PRESENT(E_VBM_GW) .AND. PRESENT(E_CBM_GW)) THEN
4993 418 : IF (E_HOMO_SCF > E_VBM_SCF) E_VBM_SCF = E_HOMO_SCF
4994 418 : IF (E_LUMO_SCF < E_CBM_SCF) E_CBM_SCF = E_LUMO_SCF
4995 418 : IF (E_HOMO_GW > E_VBM_GW) E_VBM_GW = E_HOMO_GW
4996 418 : IF (E_LUMO_GW < E_CBM_GW) E_CBM_GW = E_LUMO_GW
4997 : END IF
4998 :
4999 418 : IF (unit_nr > 0) THEN
5000 :
5001 209 : IF (do_kpoints) THEN
5002 68 : IF (do_closed_shell) THEN
5003 52 : WRITE (unit_nr, '(T3,A)') ' '
5004 52 : WRITE (unit_nr, '(T3,A,F42.4)') 'GW direct gap at current kpoint (eV)', E_GAP_GW*evolt
5005 16 : ELSE IF (do_alpha) THEN
5006 8 : WRITE (unit_nr, '(T3,A)') ' '
5007 8 : WRITE (unit_nr, '(T3,A,F36.4)') 'Alpha GW direct gap at current kpoint (eV)', &
5008 16 : E_GAP_GW*evolt
5009 8 : ELSE IF (do_beta) THEN
5010 8 : WRITE (unit_nr, '(T3,A)') ' '
5011 8 : WRITE (unit_nr, '(T3,A,F37.4)') 'Beta GW direct gap at current kpoint (eV)', &
5012 16 : E_GAP_GW*evolt
5013 : END IF
5014 : ELSE
5015 141 : IF (do_closed_shell) THEN
5016 111 : WRITE (unit_nr, '(T3,A)') ' '
5017 111 : IF (count_ev_sc_GW > 1) THEN
5018 33 : WRITE (unit_nr, '(T3,A,I3,A,F39.4)') 'HOMO-LUMO gap in evGW iteration', &
5019 66 : count_ev_sc_GW, ' (eV)', E_GAP_GW*evolt
5020 78 : ELSE IF (count_sc_GW0 > 1) THEN
5021 35 : WRITE (unit_nr, '(T3,A,I3,A,F38.4)') 'HOMO-LUMO gap in evGW0 iteration', &
5022 70 : count_sc_GW0, ' (eV)', E_GAP_GW*evolt
5023 : ELSE
5024 43 : WRITE (unit_nr, '(T3,A,F55.4)') 'G0W0 HOMO-LUMO gap (eV)', E_GAP_GW*evolt
5025 : END IF
5026 30 : ELSE IF (do_alpha) THEN
5027 15 : WRITE (unit_nr, '(T3,A)') ' '
5028 15 : WRITE (unit_nr, '(T3,A,F51.4)') 'Alpha GW HOMO-LUMO gap (eV)', E_GAP_GW*evolt
5029 15 : ELSE IF (do_beta) THEN
5030 15 : WRITE (unit_nr, '(T3,A)') ' '
5031 15 : WRITE (unit_nr, '(T3,A,F52.4)') 'Beta GW HOMO-LUMO gap (eV)', E_GAP_GW*evolt
5032 : END IF
5033 : END IF
5034 : END IF
5035 :
5036 418 : IF (unit_nr > 0) THEN
5037 209 : WRITE (unit_nr, *) ' '
5038 209 : WRITE (unit_nr, '(T3,A)') '------------------------------------------------------------------------------'
5039 : END IF
5040 :
5041 418 : CALL timestop(handle)
5042 :
5043 418 : END SUBROUTINE print_and_update_for_ev_sc
5044 :
5045 : ! **************************************************************************************************
5046 : !> \brief ...
5047 : !> \param Eigenval ...
5048 : !> \param Eigenval_last ...
5049 : !> \param gw_corr_lev_occ ...
5050 : !> \param gw_corr_lev_virt ...
5051 : !> \param homo ...
5052 : !> \param nmo ...
5053 : ! **************************************************************************************************
5054 278 : PURE SUBROUTINE shift_unshifted_levels(Eigenval, Eigenval_last, gw_corr_lev_occ, gw_corr_lev_virt, &
5055 : homo, nmo)
5056 :
5057 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: Eigenval, Eigenval_last
5058 : INTEGER, INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, homo, &
5059 : nmo
5060 :
5061 : INTEGER :: n_level_gw, n_level_gw_ref
5062 : REAL(KIND=dp) :: eigen_diff
5063 :
5064 : ! for eigenvalue self-consistent GW, all eigenvalues have to be corrected
5065 : ! 1) the occupied; check if there are occupied MOs not being corrected by GW
5066 278 : IF (gw_corr_lev_occ < homo .AND. gw_corr_lev_occ > 0) THEN
5067 :
5068 : ! calculate average GW correction for occupied orbitals
5069 : eigen_diff = 0.0_dp
5070 :
5071 108 : DO n_level_gw = 1, gw_corr_lev_occ
5072 62 : n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
5073 108 : eigen_diff = eigen_diff + Eigenval(n_level_gw_ref) - Eigenval_last(n_level_gw_ref)
5074 : END DO
5075 46 : eigen_diff = eigen_diff/gw_corr_lev_occ
5076 :
5077 : ! correct the eigenvalues of the occupied orbitals which have not been corrected by GW
5078 180 : DO n_level_gw = 1, homo - gw_corr_lev_occ
5079 180 : Eigenval(n_level_gw) = Eigenval(n_level_gw) + eigen_diff
5080 : END DO
5081 :
5082 : END IF
5083 :
5084 : ! 2) the virtual: check if there are virtual orbitals not being corrected by GW
5085 278 : IF (gw_corr_lev_virt < nmo - homo .AND. gw_corr_lev_virt > 0) THEN
5086 :
5087 : ! calculate average GW correction for virtual orbitals
5088 : eigen_diff = 0.0_dp
5089 2600 : DO n_level_gw = 1, gw_corr_lev_virt
5090 2342 : n_level_gw_ref = n_level_gw + homo
5091 2600 : eigen_diff = eigen_diff + Eigenval(n_level_gw_ref) - Eigenval_last(n_level_gw_ref)
5092 : END DO
5093 258 : eigen_diff = eigen_diff/gw_corr_lev_virt
5094 :
5095 : ! correct the eigenvalues of the virtual orbitals which have not been corrected by GW
5096 2792 : DO n_level_gw = homo + gw_corr_lev_virt + 1, nmo
5097 2792 : Eigenval(n_level_gw) = Eigenval(n_level_gw) + eigen_diff
5098 : END DO
5099 :
5100 : END IF
5101 :
5102 278 : END SUBROUTINE shift_unshifted_levels
5103 :
5104 : ! **************************************************************************************************
5105 : !> \brief Calculate the matrix mat_N_gw containing the second derivatives
5106 : !> with respect to the fitting parameters. The second derivatives are
5107 : !> calculated numerically by finite differences.
5108 : !> \param N_ij matrix element
5109 : !> \param Lambda fitting parameters
5110 : !> \param Sigma_c ...
5111 : !> \param vec_omega_fit_gw ...
5112 : !> \param i ...
5113 : !> \param j ...
5114 : !> \param num_poles ...
5115 : !> \param num_fit_points ...
5116 : !> \param n_level_gw ...
5117 : !> \param h ...
5118 : ! **************************************************************************************************
5119 62480 : SUBROUTINE calc_mat_N(N_ij, Lambda, Sigma_c, vec_omega_fit_gw, i, j, &
5120 : num_poles, num_fit_points, n_level_gw, h)
5121 : REAL(KIND=dp), INTENT(OUT) :: N_ij
5122 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:), &
5123 : INTENT(IN) :: Lambda
5124 : COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN) :: Sigma_c
5125 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
5126 : INTENT(IN) :: vec_omega_fit_gw
5127 : INTEGER, INTENT(IN) :: i, j, num_poles, num_fit_points, &
5128 : n_level_gw
5129 : REAL(KIND=dp), INTENT(IN) :: h
5130 :
5131 : CHARACTER(LEN=*), PARAMETER :: routineN = 'calc_mat_N'
5132 :
5133 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: Lambda_tmp
5134 : INTEGER :: handle, num_var
5135 : REAL(KIND=dp) :: chi2, chi2_sum
5136 :
5137 62480 : CALL timeset(routineN, handle)
5138 :
5139 62480 : num_var = 2*num_poles + 1
5140 187440 : ALLOCATE (Lambda_tmp(num_var))
5141 62480 : Lambda_tmp = z_zero
5142 62480 : chi2_sum = 0.0_dp
5143 :
5144 : !test
5145 374880 : Lambda_tmp(:) = Lambda(:)
5146 : CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
5147 62480 : num_fit_points, n_level_gw)
5148 :
5149 : ! Fitting parameters with offset h
5150 374880 : Lambda_tmp(:) = Lambda(:)
5151 62480 : IF (MODULO(i, 2) == 0) THEN
5152 31240 : Lambda_tmp(i/2) = Lambda_tmp(i/2) + h*z_one
5153 : ELSE
5154 31240 : Lambda_tmp((i + 1)/2) = Lambda_tmp((i + 1)/2) + h*gaussi
5155 : END IF
5156 62480 : IF (MODULO(j, 2) == 0) THEN
5157 31240 : Lambda_tmp(j/2) = Lambda_tmp(j/2) + h*z_one
5158 : ELSE
5159 31240 : Lambda_tmp((j + 1)/2) = Lambda_tmp((j + 1)/2) + h*gaussi
5160 : END IF
5161 : CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
5162 62480 : num_fit_points, n_level_gw)
5163 62480 : chi2_sum = chi2_sum + chi2
5164 :
5165 62480 : IF (MODULO(i, 2) == 0) THEN
5166 31240 : Lambda_tmp(i/2) = Lambda_tmp(i/2) - 2.0_dp*h*z_one
5167 : ELSE
5168 31240 : Lambda_tmp((i + 1)/2) = Lambda_tmp((i + 1)/2) - 2.0_dp*h*gaussi
5169 : END IF
5170 : CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
5171 62480 : num_fit_points, n_level_gw)
5172 62480 : chi2_sum = chi2_sum - chi2
5173 :
5174 62480 : IF (MODULO(j, 2) == 0) THEN
5175 31240 : Lambda_tmp(j/2) = Lambda_tmp(j/2) - 2.0_dp*h*z_one
5176 : ELSE
5177 31240 : Lambda_tmp((j + 1)/2) = Lambda_tmp((j + 1)/2) - 2.0_dp*h*gaussi
5178 : END IF
5179 : CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
5180 62480 : num_fit_points, n_level_gw)
5181 62480 : chi2_sum = chi2_sum + chi2
5182 :
5183 62480 : IF (MODULO(i, 2) == 0) THEN
5184 31240 : Lambda_tmp(i/2) = Lambda_tmp(i/2) + 2.0_dp*h*z_one
5185 : ELSE
5186 31240 : Lambda_tmp((i + 1)/2) = Lambda_tmp((i + 1)/2) + 2.0_dp*h*gaussi
5187 : END IF
5188 : CALL calc_chi2(chi2, Lambda_tmp, Sigma_c, vec_omega_fit_gw, num_poles, &
5189 62480 : num_fit_points, n_level_gw)
5190 62480 : chi2_sum = chi2_sum - chi2
5191 :
5192 : ! Second derivative with symmetric difference quotient
5193 62480 : N_ij = 1.0_dp/2.0_dp*chi2_sum/(4.0_dp*h*h)
5194 :
5195 62480 : DEALLOCATE (Lambda_tmp)
5196 :
5197 62480 : CALL timestop(handle)
5198 :
5199 62480 : END SUBROUTINE calc_mat_N
5200 :
5201 : ! **************************************************************************************************
5202 : !> \brief Calculate chi2
5203 : !> \param chi2 ...
5204 : !> \param Lambda fitting parameters
5205 : !> \param Sigma_c ...
5206 : !> \param vec_omega_fit_gw ...
5207 : !> \param num_poles ...
5208 : !> \param num_fit_points ...
5209 : !> \param n_level_gw ...
5210 : ! **************************************************************************************************
5211 1414830 : PURE SUBROUTINE calc_chi2(chi2, Lambda, Sigma_c, vec_omega_fit_gw, num_poles, &
5212 : num_fit_points, n_level_gw)
5213 : REAL(KIND=dp), INTENT(OUT) :: chi2
5214 : COMPLEX(KIND=dp), DIMENSION(:), INTENT(IN) :: Lambda
5215 : COMPLEX(KIND=dp), DIMENSION(:, :), INTENT(IN) :: Sigma_c
5216 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: vec_omega_fit_gw
5217 : INTEGER, INTENT(IN) :: num_poles, num_fit_points, n_level_gw
5218 :
5219 : COMPLEX(KIND=dp) :: func_val
5220 : INTEGER :: iii, jjj, kkk
5221 :
5222 1414830 : chi2 = 0.0_dp
5223 18201138 : DO kkk = 1, num_fit_points
5224 16786308 : func_val = Lambda(1)
5225 50358924 : DO iii = 1, num_poles
5226 33572616 : jjj = iii*2
5227 : ! calculate value of the fit function
5228 50358924 : func_val = func_val + Lambda(jjj)/(gaussi*vec_omega_fit_gw(kkk) - Lambda(jjj + 1))
5229 : END DO
5230 18201138 : chi2 = chi2 + (ABS(Sigma_c(n_level_gw, kkk) - func_val))**2
5231 : END DO
5232 :
5233 1414830 : END SUBROUTINE calc_chi2
5234 :
5235 : ! **************************************************************************************************
5236 : !> \brief ...
5237 : !> \param nmo ...
5238 : !> \param grid ...
5239 : !> \param matrix_s ...
5240 : !> \param Eigenval ...
5241 : !> \param eps_filter ...
5242 : !> \param e_fermi ...
5243 : !> \param fm_mat_W ...
5244 : !> \param gw_corr_lev_tot ...
5245 : !> \param gw_corr_lev_occ ...
5246 : !> \param gw_corr_lev_virt ...
5247 : !> \param homo ...
5248 : !> \param count_ev_sc_GW ...
5249 : !> \param count_sc_GW0 ...
5250 : !> \param t_3c_overl_int_ao_mo ...
5251 : !> \param t_3c_O_mo_compressed ...
5252 : !> \param t_3c_O_mo_ind ...
5253 : !> \param t_3c_overl_int_gw_RI ...
5254 : !> \param t_3c_overl_int_gw_AO ...
5255 : !> \param mat_W ...
5256 : !> \param mat_MinvVMinv ...
5257 : !> \param mat_dm ...
5258 : !> \param vec_Sigma_c_gw ...
5259 : !> \param do_periodic ...
5260 : !> \param num_points_corr ...
5261 : !> \param delta_corr ...
5262 : !> \param qs_env ...
5263 : !> \param para_env ...
5264 : !> \param para_env_RPA ...
5265 : !> \param mp2_env ...
5266 : !> \param matrix_berry_re_mo_mo ...
5267 : !> \param matrix_berry_im_mo_mo ...
5268 : !> \param first_cycle_periodic_correction ...
5269 : !> \param kpoints ...
5270 : !> \param num_fit_points ...
5271 : !> \param fm_mo_coeff ...
5272 : !> \param do_ri_Sigma_x ...
5273 : !> \param vec_Sigma_x_gw ...
5274 : !> \param unit_nr ...
5275 : !> \param ispin ...
5276 : ! **************************************************************************************************
5277 62 : SUBROUTINE compute_self_energy_cubic_gw(nmo, grid, &
5278 124 : matrix_s, Eigenval, eps_filter, &
5279 62 : e_fermi, fm_mat_W, &
5280 : gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, &
5281 : count_ev_sc_GW, count_sc_GW0, &
5282 62 : t_3c_overl_int_ao_mo, t_3c_O_mo_compressed, t_3c_O_mo_ind, &
5283 : t_3c_overl_int_gw_RI, t_3c_overl_int_gw_AO, &
5284 : mat_W, mat_MinvVMinv, mat_dm, &
5285 62 : vec_Sigma_c_gw, &
5286 : do_periodic, num_points_corr, delta_corr, qs_env, para_env, para_env_RPA, &
5287 : mp2_env, matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
5288 : first_cycle_periodic_correction, kpoints, num_fit_points, fm_mo_coeff, &
5289 62 : do_ri_Sigma_x, vec_Sigma_x_gw, unit_nr, ispin)
5290 : INTEGER, INTENT(IN) :: nmo
5291 : TYPE(time_frequency_grid_type), INTENT(IN) :: grid
5292 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: matrix_s
5293 : REAL(KIND=dp), DIMENSION(:), INTENT(IN) :: Eigenval
5294 : REAL(KIND=dp), INTENT(IN) :: eps_filter
5295 : REAL(KIND=dp), INTENT(INOUT) :: e_fermi
5296 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_W
5297 : INTEGER, INTENT(IN) :: gw_corr_lev_tot, gw_corr_lev_occ, &
5298 : gw_corr_lev_virt, homo, &
5299 : count_ev_sc_GW, count_sc_GW0
5300 : TYPE(dbt_type) :: t_3c_overl_int_ao_mo
5301 : TYPE(hfx_compression_type) :: t_3c_O_mo_compressed
5302 : INTEGER, DIMENSION(:, :) :: t_3c_O_mo_ind
5303 : TYPE(dbt_type) :: t_3c_overl_int_gw_RI, &
5304 : t_3c_overl_int_gw_AO
5305 : TYPE(dbcsr_type), INTENT(INOUT), TARGET :: mat_W
5306 : TYPE(dbcsr_p_type) :: mat_MinvVMinv, mat_dm
5307 : COMPLEX(KIND=dp), DIMENSION(:, :, :), INTENT(OUT) :: vec_Sigma_c_gw
5308 : LOGICAL, INTENT(IN) :: do_periodic
5309 : INTEGER, INTENT(IN) :: num_points_corr
5310 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:), &
5311 : INTENT(INOUT) :: delta_corr
5312 : TYPE(qs_environment_type), POINTER :: qs_env
5313 : TYPE(mp_para_env_type), POINTER :: para_env, para_env_RPA
5314 : TYPE(mp2_type), INTENT(INOUT) :: mp2_env
5315 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: matrix_berry_re_mo_mo, &
5316 : matrix_berry_im_mo_mo
5317 : LOGICAL, INTENT(INOUT) :: first_cycle_periodic_correction
5318 : TYPE(kpoint_type), POINTER :: kpoints
5319 : INTEGER, INTENT(IN) :: num_fit_points
5320 : TYPE(cp_fm_type), INTENT(IN) :: fm_mo_coeff
5321 : LOGICAL, INTENT(IN) :: do_ri_Sigma_x
5322 : REAL(KIND=dp), DIMENSION(:, :), INTENT(INOUT) :: vec_Sigma_x_gw
5323 : INTEGER, INTENT(IN) :: unit_nr, ispin
5324 :
5325 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_self_energy_cubic_gw'
5326 :
5327 62 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:, :) :: delta_corr_omega
5328 : INTEGER :: gw_lev_end, gw_lev_start, handle, handle3, i, iblk_mo, iquad, jquad, mo_end, &
5329 : mo_start, n_level_gw, n_level_gw_ref, nao, nblk_mo, num_integ_points, unit_nr_prv
5330 62 : INTEGER, ALLOCATABLE, DIMENSION(:) :: batch_range_mo, dist1, dist2, mo_bsizes, &
5331 124 : mo_offsets, sizes_AO, sizes_RI
5332 : INTEGER, DIMENSION(2) :: mo_bounds, pdims_2d
5333 : INTEGER, DIMENSION(3, 1) :: index_to_cell_zero
5334 : LOGICAL :: memory_info
5335 : REAL(KIND=dp) :: ext_scaling, omega_i, omega_sign, &
5336 : sign_occ_virt, t_i_Clenshaw, weight_i
5337 62 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: samples_tau
5338 : TYPE(cp_fm_type) :: fm_scaled_dm_occ_tau
5339 62 : TYPE(dbcsr_p_type), DIMENSION(:, :, :), POINTER :: greens_fct
5340 : TYPE(dbcsr_type), POINTER :: mat_greens_fct_occ, mat_greens_fct_virt
5341 186 : TYPE(dbt_pgrid_type) :: pgrid_2d
5342 1178 : TYPE(dbt_type) :: t_3c_ctr_AO, t_3c_ctr_RI, t_AO_tmp, &
5343 806 : t_dm, t_greens_fct_occ, &
5344 806 : t_greens_fct_virt, t_RI_tmp, &
5345 806 : t_SinvVSinv, t_W
5346 :
5347 62 : CALL timeset(routineN, handle)
5348 :
5349 62 : num_integ_points = SIZE(grid%imaginary_time)
5350 :
5351 62 : CALL cp_fm_get_info(fm_mo_coeff, nrow_global=nao)
5352 :
5353 : CALL decompress_tensor(t_3c_overl_int_ao_mo, t_3c_O_mo_ind, t_3c_O_mo_compressed, &
5354 62 : mp2_env%ri_rpa_im_time%eps_compress)
5355 :
5356 62 : CALL dbt_copy(t_3c_overl_int_ao_mo, t_3c_overl_int_gw_RI)
5357 62 : CALL dbt_copy(t_3c_overl_int_ao_mo, t_3c_overl_int_gw_AO, order=[2, 1, 3], move_data=.TRUE.)
5358 :
5359 62 : memory_info = mp2_env%ri_rpa_im_time%memory_info
5360 62 : IF (memory_info) THEN
5361 0 : unit_nr_prv = unit_nr
5362 : ELSE
5363 62 : unit_nr_prv = 0
5364 : END IF
5365 :
5366 62 : mo_start = homo - gw_corr_lev_occ + 1
5367 62 : mo_end = homo + gw_corr_lev_virt
5368 62 : CPASSERT(mo_end - mo_start + 1 == gw_corr_lev_tot)
5369 :
5370 310 : ALLOCATE (samples_tau(gw_corr_lev_tot, num_integ_points, 2), SOURCE=0.0_dp)
5371 :
5372 248 : ALLOCATE (delta_corr_omega(1 + homo - gw_corr_lev_occ:homo + gw_corr_lev_virt, num_integ_points))
5373 62 : delta_corr_omega(:, :) = z_zero
5374 :
5375 62 : e_fermi = 0.5_dp*(Eigenval(homo) + Eigenval(homo + 1))
5376 :
5377 62 : index_to_cell_zero = 0
5378 62 : NULLIFY (greens_fct)
5379 62 : CALL create_propagator_matrix_set(greens_fct, 1, matrix_s(1)%matrix, index_to_cell_zero)
5380 62 : mat_greens_fct_occ => greens_fct(propagator_sector_occupied, 1, 1)%matrix
5381 62 : mat_greens_fct_virt => greens_fct(propagator_sector_virtual, 1, 1)%matrix
5382 :
5383 62 : nblk_mo = dbt_nblks_total(t_3c_overl_int_gw_AO, 3)
5384 186 : ALLOCATE (mo_offsets(nblk_mo))
5385 124 : ALLOCATE (mo_bsizes(nblk_mo))
5386 186 : ALLOCATE (batch_range_mo(nblk_mo - 1))
5387 62 : CALL dbt_get_info(t_3c_overl_int_gw_AO, blk_offset_3=mo_offsets, blk_size_3=mo_bsizes)
5388 :
5389 62 : pdims_2d = 0
5390 62 : CALL dbt_pgrid_create(para_env, pdims_2d, pgrid_2d)
5391 186 : ALLOCATE (sizes_RI(dbt_nblks_total(t_3c_overl_int_gw_RI, 1)))
5392 62 : CALL dbt_get_info(t_3c_overl_int_gw_RI, blk_size_1=sizes_RI)
5393 :
5394 62 : CALL create_2c_tensor(t_W, dist1, dist2, pgrid_2d, sizes_RI, sizes_RI, name="(RI|RI)")
5395 :
5396 62 : DEALLOCATE (dist1, dist2)
5397 :
5398 62 : CALL dbt_create(mat_W, t_RI_tmp, name="(RI|RI)")
5399 :
5400 62 : CALL dbt_create(t_3c_overl_int_gw_RI, t_3c_ctr_RI)
5401 62 : CALL dbt_create(t_3c_overl_int_gw_AO, t_3c_ctr_AO)
5402 :
5403 186 : ALLOCATE (sizes_AO(dbt_nblks_total(t_3c_overl_int_gw_AO, 1)))
5404 62 : CALL dbt_get_info(t_3c_overl_int_gw_AO, blk_size_1=sizes_AO)
5405 62 : CALL create_2c_tensor(t_greens_fct_occ, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
5406 62 : DEALLOCATE (dist1, dist2)
5407 62 : CALL create_2c_tensor(t_greens_fct_virt, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
5408 62 : DEALLOCATE (dist1, dist2)
5409 :
5410 1010 : DO jquad = 1, num_integ_points
5411 :
5412 : CALL compute_gamma_propagator(greens_fct, 1, fm_mo_coeff, homo, Eigenval, nmo, &
5413 948 : eps_filter, e_fermi, grid%imaginary_time(jquad), para_env)
5414 :
5415 948 : CALL dbcsr_set(mat_W, 0.0_dp)
5416 948 : CALL copy_fm_to_dbcsr(fm_mat_W(jquad), mat_W, keep_sparsity=.FALSE.)
5417 :
5418 948 : IF (jquad == 1) CALL dbt_create(mat_greens_fct_occ, t_AO_tmp, name="(AO|AO)")
5419 :
5420 948 : CALL dbt_copy_matrix_to_tensor(mat_W, t_RI_tmp)
5421 948 : CALL dbt_copy(t_RI_tmp, t_W)
5422 948 : CALL dbt_copy_matrix_to_tensor(mat_greens_fct_occ, t_AO_tmp)
5423 948 : CALL dbt_copy(t_AO_tmp, t_greens_fct_occ)
5424 948 : CALL dbt_copy_matrix_to_tensor(mat_greens_fct_virt, t_AO_tmp)
5425 948 : CALL dbt_copy(t_AO_tmp, t_greens_fct_virt)
5426 :
5427 4740 : batch_range_mo(:) = [(i, i=2, nblk_mo)]
5428 948 : CALL dbt_batched_contract_init(t_3c_overl_int_gw_AO, batch_range_3=batch_range_mo)
5429 948 : CALL dbt_batched_contract_init(t_3c_overl_int_gw_RI, batch_range_3=batch_range_mo)
5430 948 : CALL dbt_batched_contract_init(t_3c_ctr_AO, batch_range_3=batch_range_mo)
5431 948 : CALL dbt_batched_contract_init(t_3c_ctr_RI, batch_range_3=batch_range_mo)
5432 948 : CALL dbt_batched_contract_init(t_W)
5433 948 : CALL dbt_batched_contract_init(t_greens_fct_occ)
5434 948 : CALL dbt_batched_contract_init(t_greens_fct_virt)
5435 :
5436 : ! in iteration over MO blocks skip first and last block because they correspond to the MO s
5437 : ! outside of the GW range of required MOs
5438 1896 : DO iblk_mo = 2, nblk_mo - 1
5439 2844 : mo_bounds = [mo_offsets(iblk_mo), mo_offsets(iblk_mo) + mo_bsizes(iblk_mo) - 1]
5440 : CALL contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
5441 : t_greens_fct_occ, t_W, [1.0_dp, -1.0_dp], &
5442 : mo_bounds, unit_nr_prv, &
5443 948 : t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_ri=.TRUE.)
5444 : CALL trace_sigma_gw(t_3c_ctr_AO, t_3c_ctr_RI, samples_tau(:, jquad, negative_time), &
5445 948 : mo_start, mo_bounds, para_env)
5446 :
5447 : CALL contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
5448 : t_greens_fct_virt, t_W, [1.0_dp, 1.0_dp], &
5449 : mo_bounds, unit_nr_prv, &
5450 948 : t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_ri=.FALSE.)
5451 :
5452 : CALL trace_sigma_gw(t_3c_ctr_AO, t_3c_ctr_RI, samples_tau(:, jquad, positive_time), &
5453 1896 : mo_start, mo_bounds, para_env)
5454 : END DO
5455 948 : CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_AO)
5456 948 : CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_RI)
5457 948 : CALL dbt_batched_contract_finalize(t_3c_ctr_AO)
5458 948 : CALL dbt_batched_contract_finalize(t_3c_ctr_RI)
5459 948 : CALL dbt_batched_contract_finalize(t_W)
5460 948 : CALL dbt_batched_contract_finalize(t_greens_fct_occ)
5461 948 : CALL dbt_batched_contract_finalize(t_greens_fct_virt)
5462 :
5463 948 : CALL dbt_clear(t_3c_ctr_AO)
5464 1010 : CALL dbt_clear(t_3c_ctr_RI)
5465 :
5466 : END DO ! jquad (tau)
5467 62 : CALL dbt_destroy(t_W)
5468 :
5469 62 : CALL dbt_destroy(t_greens_fct_occ)
5470 62 : CALL dbt_destroy(t_greens_fct_virt)
5471 :
5472 62 : CALL transform_time_to_frequency(grid, samples_tau, vec_Sigma_c_gw(:, :, 1))
5473 : ! Occupied levels use negative frequencies; the time-domain samples are real.
5474 2646 : vec_Sigma_c_gw(1:gw_corr_lev_occ, :, 1) = CONJG(vec_Sigma_c_gw(1:gw_corr_lev_occ, :, 1))
5475 :
5476 62 : CALL dbcsr_deallocate_matrix_set(greens_fct)
5477 :
5478 62 : IF (do_ri_Sigma_x .AND. count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1) THEN
5479 :
5480 2 : CALL timeset(routineN//"_RI_HFX_operation_1", handle3)
5481 :
5482 2 : CALL cp_fm_create(fm_scaled_dm_occ_tau, fm_mo_coeff%matrix_struct, nrow=nao, ncol=nao)
5483 :
5484 : ! get density matrix
5485 : CALL parallel_gemm(transa="N", transb="T", m=nao, n=nao, k=homo, alpha=1.0_dp, &
5486 : matrix_a=fm_mo_coeff, matrix_b=fm_mo_coeff, beta=0.0_dp, &
5487 2 : matrix_c=fm_scaled_dm_occ_tau)
5488 :
5489 2 : CALL timestop(handle3)
5490 :
5491 2 : CALL timeset(routineN//"_RI_HFX_operation_2", handle3)
5492 :
5493 : CALL copy_fm_to_dbcsr(fm_scaled_dm_occ_tau, &
5494 : mat_dm%matrix, &
5495 2 : keep_sparsity=.FALSE.)
5496 :
5497 2 : CALL cp_fm_release(fm_scaled_dm_occ_tau)
5498 :
5499 2 : CALL timestop(handle3)
5500 :
5501 2 : CALL create_2c_tensor(t_dm, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
5502 2 : DEALLOCATE (dist1, dist2)
5503 :
5504 2 : CALL dbt_copy_matrix_to_tensor(mat_dm%matrix, t_AO_tmp)
5505 2 : CALL dbt_copy(t_AO_tmp, t_dm)
5506 :
5507 2 : CALL create_2c_tensor(t_SinvVSinv, dist1, dist2, pgrid_2d, sizes_RI, sizes_RI, name="(RI|RI)")
5508 2 : DEALLOCATE (dist1, dist2)
5509 :
5510 2 : CALL dbt_copy_matrix_to_tensor(mat_MinvVMinv%matrix, t_RI_tmp)
5511 2 : CALL dbt_copy(t_RI_tmp, t_SinvVSinv)
5512 :
5513 2 : CALL dbt_batched_contract_init(t_3c_overl_int_gw_AO, batch_range_3=batch_range_mo)
5514 2 : CALL dbt_batched_contract_init(t_3c_overl_int_gw_RI, batch_range_3=batch_range_mo)
5515 2 : CALL dbt_batched_contract_init(t_3c_ctr_RI, batch_range_3=batch_range_mo)
5516 2 : CALL dbt_batched_contract_init(t_3c_ctr_AO, batch_range_3=batch_range_mo)
5517 2 : CALL dbt_batched_contract_init(t_dm)
5518 2 : CALL dbt_batched_contract_init(t_SinvVSinv)
5519 :
5520 4 : DO iblk_mo = 2, nblk_mo - 1
5521 6 : mo_bounds = [mo_offsets(iblk_mo), mo_offsets(iblk_mo) + mo_bsizes(iblk_mo) - 1]
5522 :
5523 : CALL contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
5524 : t_dm, t_SinvVSinv, [1.0_dp, -1.0_dp], &
5525 : mo_bounds, unit_nr_prv, &
5526 2 : t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_ri=.TRUE.)
5527 :
5528 4 : CALL trace_sigma_gw(t_3c_ctr_AO, t_3c_ctr_RI, vec_Sigma_x_gw(mo_start:mo_end, 1), mo_start, mo_bounds, para_env)
5529 : END DO
5530 2 : CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_AO)
5531 2 : CALL dbt_batched_contract_finalize(t_3c_overl_int_gw_RI)
5532 2 : CALL dbt_batched_contract_finalize(t_dm)
5533 2 : CALL dbt_batched_contract_finalize(t_SinvVSinv)
5534 2 : CALL dbt_batched_contract_finalize(t_3c_ctr_RI)
5535 2 : CALL dbt_batched_contract_finalize(t_3c_ctr_AO)
5536 :
5537 2 : CALL dbt_destroy(t_dm)
5538 2 : CALL dbt_destroy(t_SinvVSinv)
5539 :
5540 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, 1) = &
5541 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, 1) + &
5542 48 : vec_Sigma_x_gw(:, 1)
5543 :
5544 : END IF
5545 :
5546 62 : CALL dbt_pgrid_destroy(pgrid_2d)
5547 :
5548 62 : CALL dbt_destroy(t_3c_ctr_RI)
5549 62 : CALL dbt_destroy(t_3c_ctr_AO)
5550 62 : CALL dbt_destroy(t_AO_tmp)
5551 62 : CALL dbt_destroy(t_RI_tmp)
5552 :
5553 : ! compute and add the periodic correction
5554 62 : IF (do_periodic) THEN
5555 :
5556 4 : ext_scaling = 0.2_dp
5557 :
5558 : ! loop over omega' (integration)
5559 24 : DO iquad = 1, num_points_corr
5560 :
5561 : ! use the Clenshaw-grid
5562 20 : t_i_Clenshaw = iquad*pi/(2.0_dp*num_points_corr)
5563 20 : omega_i = ext_scaling/TAN(t_i_Clenshaw)
5564 :
5565 20 : IF (iquad < num_points_corr) THEN
5566 16 : weight_i = ext_scaling*pi/(num_points_corr*SIN(t_i_Clenshaw)**2)
5567 : ELSE
5568 4 : weight_i = ext_scaling*pi/(2.0_dp*num_points_corr*SIN(t_i_Clenshaw)**2)
5569 : END IF
5570 :
5571 : CALL calc_periodic_correction(delta_corr, qs_env, para_env, para_env_RPA, &
5572 : mp2_env%ri_g0w0%kp_grid, homo, nmo, gw_corr_lev_occ, &
5573 : gw_corr_lev_virt, omega_i, fm_mo_coeff, Eigenval, &
5574 : matrix_berry_re_mo_mo, matrix_berry_im_mo_mo, &
5575 : first_cycle_periodic_correction, kpoints, &
5576 : mp2_env%ri_g0w0%do_mo_coeff_gamma, &
5577 : mp2_env%ri_g0w0%num_kp_grids, mp2_env%ri_g0w0%eps_kpoint, &
5578 : mp2_env%ri_g0w0%do_extra_kpoints, &
5579 20 : mp2_env%ri_g0w0%do_aux_bas_gw, mp2_env%ri_g0w0%frac_aux_mos)
5580 :
5581 204 : DO n_level_gw = 1, gw_corr_lev_tot
5582 :
5583 180 : n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
5584 :
5585 180 : IF (n_level_gw <= gw_corr_lev_occ) THEN
5586 : sign_occ_virt = -1.0_dp
5587 : ELSE
5588 100 : sign_occ_virt = 1.0_dp
5589 : END IF
5590 :
5591 2160 : DO jquad = 1, num_integ_points
5592 :
5593 1960 : omega_sign = grid%frequency(jquad)*sign_occ_virt
5594 :
5595 : delta_corr_omega(n_level_gw_ref, jquad) = &
5596 : delta_corr_omega(n_level_gw_ref, jquad) - &
5597 : 0.5_dp/pi*weight_i/2.0_dp*delta_corr(n_level_gw_ref)* &
5598 : (1.0_dp/(gaussi*(omega_i + omega_sign) + e_fermi - Eigenval(n_level_gw_ref)) + &
5599 2140 : 1.0_dp/(gaussi*(-omega_i + omega_sign) + e_fermi - Eigenval(n_level_gw_ref)))
5600 :
5601 : END DO
5602 :
5603 : END DO
5604 :
5605 : END DO
5606 :
5607 4 : gw_lev_start = 1 + homo - gw_corr_lev_occ
5608 4 : gw_lev_end = homo + gw_corr_lev_virt
5609 :
5610 : ! add the periodic correction
5611 : vec_Sigma_c_gw(1:gw_corr_lev_tot, :, 1) = vec_Sigma_c_gw(1:gw_corr_lev_tot, :, 1) + &
5612 182 : delta_corr_omega(gw_lev_start:gw_lev_end, 1:num_fit_points)
5613 :
5614 : END IF
5615 :
5616 62 : CALL timestop(handle)
5617 :
5618 186 : END SUBROUTINE compute_self_energy_cubic_gw
5619 :
5620 : ! **************************************************************************************************
5621 : !> \brief ...
5622 : !> \param grid ...
5623 : !> \param matrix_s ...
5624 : !> \param Eigenval ...
5625 : !> \param e_fermi ...
5626 : !> \param fm_mat_W ...
5627 : !> \param gw_corr_lev_tot ...
5628 : !> \param gw_corr_lev_occ ...
5629 : !> \param gw_corr_lev_virt ...
5630 : !> \param homo ...
5631 : !> \param count_ev_sc_GW ...
5632 : !> \param count_sc_GW0 ...
5633 : !> \param t_3c_O ...
5634 : !> \param t_3c_M ...
5635 : !> \param t_3c_O_compressed ...
5636 : !> \param t_3c_O_ind ...
5637 : !> \param mat_W ...
5638 : !> \param mat_MinvVMinv ...
5639 : !> \param vec_Sigma_c_gw ...
5640 : !> \param qs_env ...
5641 : !> \param para_env ...
5642 : !> \param mp2_env ...
5643 : !> \param fm_mo_coeff ...
5644 : !> \param do_ri_Sigma_x ...
5645 : !> \param vec_Sigma_x_gw ...
5646 : !> \param unit_nr ...
5647 : !> \param nspins ...
5648 : !> \param starts_array_mc ...
5649 : !> \param ends_array_mc ...
5650 : !> \param eps_filter ...
5651 : ! **************************************************************************************************
5652 16 : SUBROUTINE compute_self_energy_cubic_gw_kpoints(grid, &
5653 16 : matrix_s, Eigenval, e_fermi, fm_mat_W, &
5654 16 : gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, &
5655 : count_ev_sc_GW, count_sc_GW0, &
5656 : t_3c_O, t_3c_M, t_3c_O_compressed, t_3c_O_ind, &
5657 : mat_W, mat_MinvVMinv, &
5658 32 : vec_Sigma_c_gw, &
5659 : qs_env, para_env, &
5660 : mp2_env, fm_mo_coeff, &
5661 16 : do_ri_Sigma_x, vec_Sigma_x_gw, unit_nr, nspins, &
5662 16 : starts_array_mc, ends_array_mc, eps_filter)
5663 :
5664 : TYPE(time_frequency_grid_type), INTENT(IN) :: grid
5665 : TYPE(dbcsr_p_type), DIMENSION(:), INTENT(IN) :: matrix_s
5666 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(IN) :: Eigenval
5667 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: e_fermi
5668 : TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: fm_mat_W
5669 : INTEGER, INTENT(IN) :: gw_corr_lev_tot
5670 : INTEGER, DIMENSION(:), INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, homo
5671 : INTEGER, INTENT(IN) :: count_ev_sc_GW, count_sc_GW0
5672 : TYPE(dbt_type), ALLOCATABLE, DIMENSION(:, :) :: t_3c_O
5673 : TYPE(dbt_type) :: t_3c_M
5674 : TYPE(hfx_compression_type), ALLOCATABLE, &
5675 : DIMENSION(:, :, :) :: t_3c_O_compressed
5676 : TYPE(block_ind_type), ALLOCATABLE, &
5677 : DIMENSION(:, :, :), INTENT(INOUT) :: t_3c_O_ind
5678 : TYPE(dbcsr_type), INTENT(INOUT), TARGET :: mat_W
5679 : TYPE(dbcsr_p_type) :: mat_MinvVMinv
5680 : COMPLEX(KIND=dp), DIMENSION(:, :, :, :), &
5681 : INTENT(OUT) :: vec_Sigma_c_gw
5682 : TYPE(qs_environment_type), POINTER :: qs_env
5683 : TYPE(mp_para_env_type), POINTER :: para_env
5684 : TYPE(mp2_type), INTENT(INOUT) :: mp2_env
5685 : TYPE(cp_fm_type), INTENT(IN) :: fm_mo_coeff
5686 : LOGICAL, INTENT(IN) :: do_ri_Sigma_x
5687 : REAL(KIND=dp), DIMENSION(:, :, :), INTENT(INOUT) :: vec_Sigma_x_gw
5688 : INTEGER, INTENT(IN) :: unit_nr, nspins
5689 : INTEGER, DIMENSION(:), INTENT(IN) :: starts_array_mc, ends_array_mc
5690 : REAL(KIND=dp), INTENT(IN) :: eps_filter
5691 :
5692 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_self_energy_cubic_gw_kpoints'
5693 :
5694 : INTEGER :: cut_memory, handle, handle2, i_mem, ikp, ispin, j_mem, jquad, nkp_self_energy, &
5695 : num_integ_points, num_points, unit_nr_prv
5696 32 : INTEGER, ALLOCATABLE, DIMENSION(:) :: dist1, dist2, sizes_AO, sizes_RI
5697 : INTEGER, DIMENSION(2) :: mo_end, mo_start, pdims_2d
5698 : INTEGER, DIMENSION(2, 1) :: bounds_RI_i
5699 : INTEGER, DIMENSION(2, 2) :: bounds_ao_ao_j
5700 : INTEGER, DIMENSION(3) :: dims_3c
5701 : LOGICAL :: memory_info
5702 : REAL(KIND=dp) :: t1, t2, tau
5703 : REAL(KIND=dp), ALLOCATABLE, &
5704 16 : DIMENSION(:, :, :, :, :) :: samples_tau
5705 16 : TYPE(dbcsr_p_type), DIMENSION(:, :, :), POINTER :: propagator
5706 : TYPE(dbcsr_type), TARGET :: mat_greens_fct_occ, mat_greens_fct_virt, mat_mo_coeff, &
5707 : mat_self_energy_ao_ao_neg_tau, mat_self_energy_ao_ao_pos_tau
5708 48 : TYPE(dbt_pgrid_type) :: pgrid_2d
5709 304 : TYPE(dbt_type) :: t_3c_M_W_tmp, t_3c_O_all, t_3c_O_W, &
5710 208 : t_AO_tmp, t_greens_fct_occ, &
5711 304 : t_greens_fct_virt, t_RI_tmp, t_W
5712 :
5713 16 : CALL timeset(routineN, handle)
5714 :
5715 16 : num_integ_points = SIZE(grid%imaginary_time)
5716 :
5717 16 : NULLIFY (propagator)
5718 :
5719 16 : memory_info = mp2_env%ri_rpa_im_time%memory_info
5720 16 : IF (memory_info) THEN
5721 0 : unit_nr_prv = unit_nr
5722 : ELSE
5723 16 : unit_nr_prv = 0
5724 : END IF
5725 :
5726 16 : cut_memory = mp2_env%ri_rpa_im_time%cut_memory
5727 :
5728 34 : DO ispin = 1, nspins
5729 18 : mo_start(ispin) = homo(ispin) - gw_corr_lev_occ(ispin) + 1
5730 18 : mo_end(ispin) = homo(ispin) + gw_corr_lev_virt(ispin)
5731 34 : CPASSERT(mo_end(ispin) - mo_start(ispin) + 1 == gw_corr_lev_tot)
5732 : END DO
5733 :
5734 16 : nkp_self_energy = mp2_env%ri_g0w0%nkp_self_energy
5735 :
5736 112 : ALLOCATE (samples_tau(gw_corr_lev_tot, num_integ_points, 2, nkp_self_energy, nspins), SOURCE=0.0_dp)
5737 :
5738 : CALL dbcsr_create(matrix=mat_greens_fct_occ, &
5739 : template=matrix_s(1)%matrix, &
5740 16 : matrix_type=dbcsr_type_no_symmetry)
5741 :
5742 : CALL dbcsr_create(matrix=mat_greens_fct_virt, &
5743 : template=matrix_s(1)%matrix, &
5744 16 : matrix_type=dbcsr_type_no_symmetry)
5745 :
5746 : CALL dbcsr_create(matrix=mat_self_energy_ao_ao_neg_tau, &
5747 : template=matrix_s(1)%matrix, &
5748 16 : matrix_type=dbcsr_type_no_symmetry)
5749 :
5750 : CALL dbcsr_create(matrix=mat_self_energy_ao_ao_pos_tau, &
5751 : template=matrix_s(1)%matrix, &
5752 16 : matrix_type=dbcsr_type_no_symmetry)
5753 :
5754 : CALL dbcsr_create(matrix=mat_mo_coeff, &
5755 : template=matrix_s(1)%matrix, &
5756 16 : matrix_type=dbcsr_type_no_symmetry)
5757 :
5758 16 : CALL copy_fm_to_dbcsr(fm_mo_coeff, mat_mo_coeff, keep_sparsity=.FALSE.)
5759 :
5760 34 : DO ispin = 1, nspins
5761 664 : e_fermi(ispin) = 0.5_dp*(MAXVAL(Eigenval(homo, :, ispin)) + MINVAL(Eigenval(homo + 1, :, ispin)))
5762 : END DO
5763 :
5764 16 : pdims_2d = 0
5765 16 : CALL dbt_pgrid_create(para_env, pdims_2d, pgrid_2d)
5766 48 : ALLOCATE (sizes_RI(dbt_nblks_total(t_3c_O(1, 1), 1)))
5767 16 : CALL dbt_get_info(t_3c_O(1, 1), blk_size_1=sizes_RI)
5768 :
5769 16 : CALL create_2c_tensor(t_W, dist1, dist2, pgrid_2d, sizes_RI, sizes_RI, name="(RI|RI)")
5770 16 : DEALLOCATE (dist1, dist2)
5771 :
5772 16 : CALL dbt_create(mat_W, t_RI_tmp, name="(RI|RI)")
5773 :
5774 48 : ALLOCATE (sizes_AO(dbt_nblks_total(t_3c_O(1, 1), 2)))
5775 16 : CALL dbt_get_info(t_3c_O(1, 1), blk_size_2=sizes_AO)
5776 16 : CALL create_2c_tensor(t_greens_fct_occ, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
5777 :
5778 16 : DEALLOCATE (dist1, dist2)
5779 16 : CALL create_2c_tensor(t_greens_fct_virt, dist1, dist2, pgrid_2d, sizes_AO, sizes_AO, name="(AO|AO)")
5780 16 : DEALLOCATE (dist1, dist2)
5781 :
5782 16 : CALL dbt_get_info(t_3c_M, nfull_total=dims_3c)
5783 :
5784 16 : CALL dbt_create(t_3c_O(1, 1), t_3c_O_all, name="O (RI AO | AO)")
5785 :
5786 : ! get full 3c tensor
5787 74 : DO i_mem = 1, cut_memory
5788 : CALL decompress_tensor(t_3c_O(1, 1), &
5789 : t_3c_O_ind(1, 1, i_mem)%ind, &
5790 : t_3c_O_compressed(1, 1, i_mem), &
5791 58 : mp2_env%ri_rpa_im_time%eps_compress)
5792 74 : CALL dbt_copy(t_3c_O(1, 1), t_3c_O_all, summation=.TRUE., move_data=.TRUE.)
5793 : END DO
5794 :
5795 16 : CALL dbt_create(t_3c_M, t_3c_M_W_tmp, name="M W (RI | AO AO)")
5796 16 : CALL dbt_create(t_3c_O(1, 1), t_3c_O_W, name="M W (RI AO | AO)")
5797 :
5798 16 : CALL dbt_create(mat_greens_fct_occ, t_AO_tmp, name="(AO|AO)")
5799 :
5800 16 : IF (count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1 .AND. do_ri_Sigma_x) THEN
5801 12 : num_points = num_integ_points + 1
5802 : ELSE
5803 4 : num_points = num_integ_points
5804 : END IF
5805 :
5806 124 : DO jquad = 1, num_points
5807 :
5808 108 : t1 = m_walltime()
5809 :
5810 108 : IF (jquad <= num_integ_points) THEN
5811 96 : tau = grid%imaginary_time(jquad)
5812 :
5813 96 : IF (unit_nr > 0) WRITE (unit_nr, '(/T3,A,1X,I3)') &
5814 48 : 'GW_INFO| Computing self-energy time point', jquad
5815 : ELSE
5816 12 : tau = 0.0_dp
5817 :
5818 12 : IF (unit_nr > 0) WRITE (unit_nr, '(/T3,A,1X,I3)') &
5819 6 : 'GW_INFO| Computing exchange self-energy'
5820 : END IF
5821 :
5822 108 : IF (jquad <= num_integ_points) THEN
5823 96 : CALL dbcsr_set(mat_W, 0.0_dp)
5824 96 : CALL copy_fm_to_dbcsr(fm_mat_W(jquad), mat_W, keep_sparsity=.FALSE.)
5825 96 : CALL dbt_copy_matrix_to_tensor(mat_W, t_RI_tmp)
5826 : ELSE
5827 12 : CALL dbt_copy_matrix_to_tensor(mat_MinvVMinv%matrix, t_RI_tmp)
5828 : END IF
5829 :
5830 108 : CALL dbt_copy(t_RI_tmp, t_W)
5831 :
5832 230 : DO ispin = 1, nspins
5833 :
5834 : CALL compute_periodic_dm(propagator, qs_env, &
5835 : ispin, num_points, jquad, e_fermi(ispin), tau, &
5836 122 : sector=propagator_sector_occupied)
5837 :
5838 : CALL compute_periodic_dm(propagator, qs_env, &
5839 : ispin, num_points, jquad, e_fermi(ispin), tau, &
5840 122 : sector=propagator_sector_virtual)
5841 :
5842 122 : CALL dbcsr_set(mat_greens_fct_occ, 0.0_dp)
5843 : CALL dbcsr_copy(mat_greens_fct_occ, &
5844 122 : propagator(propagator_sector_occupied, jquad, 1)%matrix)
5845 :
5846 122 : CALL dbcsr_set(mat_greens_fct_virt, 0.0_dp)
5847 : CALL dbcsr_copy(mat_greens_fct_virt, &
5848 122 : propagator(propagator_sector_virtual, jquad, 1)%matrix)
5849 :
5850 122 : CALL dbt_copy_matrix_to_tensor(mat_greens_fct_occ, t_AO_tmp)
5851 122 : CALL dbt_copy(t_AO_tmp, t_greens_fct_occ)
5852 :
5853 122 : CALL dbt_copy_matrix_to_tensor(mat_greens_fct_virt, t_AO_tmp)
5854 122 : CALL dbt_copy(t_AO_tmp, t_greens_fct_virt)
5855 :
5856 122 : CALL dbcsr_set(mat_self_energy_ao_ao_neg_tau, 0.0_dp)
5857 122 : CALL dbcsr_set(mat_self_energy_ao_ao_pos_tau, 0.0_dp)
5858 :
5859 122 : CALL dbt_copy(t_3c_O_all, t_3c_M)
5860 :
5861 122 : CALL dbt_batched_contract_init(t_3c_O_W)
5862 : ! CALL dbt_batched_contract_init(t_3c_O_G)
5863 : ! CALL dbt_batched_contract_init(t_self_energy)
5864 :
5865 554 : DO i_mem = 1, cut_memory ! memory cut for RI index
5866 :
5867 : ! CALL dbt_batched_contract_init(t_W)
5868 : ! CALL dbt_batched_contract_init(t_3c_M)
5869 : ! CALL dbt_batched_contract_init(t_3c_M_W_tmp)
5870 :
5871 : bounds_RI_i(:, 1) = [qs_env%mp2_env%ri_rpa_im_time%starts_array_mc_RI(i_mem), &
5872 1296 : qs_env%mp2_env%ri_rpa_im_time%ends_array_mc_RI(i_mem)]
5873 :
5874 2142 : DO j_mem = 1, cut_memory ! memory cut for ao index
5875 :
5876 4764 : bounds_ao_ao_j(:, 1) = [starts_array_mc(j_mem), ends_array_mc(j_mem)]
5877 4764 : bounds_ao_ao_j(:, 2) = [1, dims_3c(3)]
5878 :
5879 1588 : CALL timeset("tensor_operation_3c_W", handle2)
5880 :
5881 : CALL dbt_contract(1.0_dp, t_W, t_3c_M, 0.0_dp, &
5882 : t_3c_M_W_tmp, &
5883 : contract_1=[2], notcontract_1=[1], &
5884 : contract_2=[1], notcontract_2=[2, 3], &
5885 : map_1=[1], map_2=[2, 3], &
5886 : bounds_2=bounds_RI_i, &
5887 : bounds_3=bounds_ao_ao_j, &
5888 : filter_eps=eps_filter, &
5889 1588 : unit_nr=unit_nr_prv)
5890 :
5891 1588 : CALL dbt_copy(t_3c_M_W_tmp, t_3c_O_W, order=[1, 2, 3], move_data=.TRUE.)
5892 :
5893 1588 : CALL timestop(handle2)
5894 :
5895 : CALL contract_to_self_energy(t_3c_O_all, t_greens_fct_occ, t_3c_O_W, &
5896 : mat_self_energy_ao_ao_neg_tau, &
5897 : bounds_ao_ao_j, bounds_RI_i, unit_nr_prv, &
5898 1588 : eps_filter, do_occ=.TRUE., do_virt=.FALSE.)
5899 :
5900 : CALL contract_to_self_energy(t_3c_O_all, t_greens_fct_virt, t_3c_O_W, &
5901 : mat_self_energy_ao_ao_pos_tau, &
5902 : bounds_ao_ao_j, bounds_RI_i, unit_nr_prv, &
5903 3608 : eps_filter, do_occ=.FALSE., do_virt=.TRUE.)
5904 :
5905 : END DO ! j_mem
5906 :
5907 : ! CALL dbt_batched_contract_finalize(t_W)
5908 : ! CALL dbt_batched_contract_finalize(t_3c_M)
5909 : ! CALL dbt_batched_contract_finalize(t_3c_M_W_tmp)
5910 :
5911 : END DO ! i_mem
5912 :
5913 122 : CALL dbt_batched_contract_finalize(t_3c_O_W)
5914 : ! CALL dbt_batched_contract_finalize(t_3c_O_G)
5915 : ! CALL dbt_batched_contract_finalize(t_self_energy)
5916 :
5917 230 : IF (jquad <= num_integ_points) THEN
5918 :
5919 : CALL trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao_neg_tau, &
5920 : samples_tau(:, jquad, negative_time, :, ispin), &
5921 108 : homo(ispin), gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), ispin)
5922 :
5923 : CALL trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao_pos_tau, &
5924 : samples_tau(:, jquad, positive_time, :, ispin), &
5925 108 : homo(ispin), gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), ispin)
5926 : ELSE
5927 :
5928 : CALL trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao_neg_tau, &
5929 : vec_Sigma_x_gw(mo_start(ispin):mo_end(ispin), :, ispin), &
5930 14 : homo(ispin), gw_corr_lev_occ(ispin), gw_corr_lev_virt(ispin), ispin)
5931 :
5932 : END IF
5933 :
5934 : END DO ! spins
5935 :
5936 108 : t2 = m_walltime()
5937 :
5938 124 : IF (unit_nr > 0) WRITE (unit_nr, '(T6,A,T56,F25.1)') 'Execution time (s):', t2 - t1
5939 :
5940 : END DO ! jquad (tau)
5941 :
5942 16 : IF (count_ev_sc_GW == 1 .AND. count_sc_GW0 == 1) THEN
5943 :
5944 16 : CALL compute_minus_vxc_kpoints(qs_env)
5945 :
5946 16 : IF (do_ri_Sigma_x) THEN
5947 26 : DO ispin = 1, nspins
5948 : mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, :) = mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, :) + &
5949 2154 : vec_Sigma_x_gw(:, :, ispin)
5950 : END DO
5951 : END IF
5952 :
5953 : END IF
5954 :
5955 34 : DO ispin = 1, nspins
5956 154 : DO ikp = 1, nkp_self_energy
5957 : CALL transform_time_to_frequency(grid, samples_tau(:, :, :, ikp, ispin), &
5958 154 : vec_Sigma_c_gw(:, :, ikp, ispin))
5959 : END DO
5960 : ! Occupied levels use negative frequencies; the time-domain samples are real.
5961 : vec_Sigma_c_gw(1:gw_corr_lev_occ(ispin), :, :, ispin) = &
5962 954 : CONJG(vec_Sigma_c_gw(1:gw_corr_lev_occ(ispin), :, :, ispin))
5963 : END DO
5964 :
5965 16 : CALL dbt_pgrid_destroy(pgrid_2d)
5966 :
5967 16 : CALL dbcsr_release(mat_greens_fct_occ)
5968 16 : CALL dbcsr_release(mat_greens_fct_virt)
5969 16 : CALL dbcsr_release(mat_self_energy_ao_ao_neg_tau)
5970 16 : CALL dbcsr_release(mat_self_energy_ao_ao_pos_tau)
5971 16 : CALL dbcsr_release(mat_mo_coeff)
5972 :
5973 16 : CALL dbcsr_deallocate_matrix_set(propagator)
5974 :
5975 16 : CALL dbt_destroy(t_W)
5976 16 : CALL dbt_destroy(t_RI_tmp)
5977 16 : CALL dbt_destroy(t_greens_fct_occ)
5978 16 : CALL dbt_destroy(t_greens_fct_virt)
5979 16 : CALL dbt_destroy(t_AO_tmp)
5980 16 : CALL dbt_destroy(t_3c_O_all)
5981 16 : CALL dbt_destroy(t_3c_M_W_tmp)
5982 16 : CALL dbt_destroy(t_3c_O_W)
5983 :
5984 16 : CALL timestop(handle)
5985 :
5986 64 : END SUBROUTINE compute_self_energy_cubic_gw_kpoints
5987 :
5988 : ! **************************************************************************************************
5989 : !> \brief ...
5990 : !> \param qs_env ...
5991 : ! **************************************************************************************************
5992 16 : SUBROUTINE compute_minus_vxc_kpoints(qs_env)
5993 : TYPE(qs_environment_type), POINTER :: qs_env
5994 :
5995 : CHARACTER(LEN=*), PARAMETER :: routineN = 'compute_minus_vxc_kpoints'
5996 :
5997 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: diag_Sigma_x_minus_vxc_mo_mo
5998 : INTEGER :: handle, ikp, ispin, nkp_self_energy, &
5999 : nmo, nspins
6000 : TYPE(cp_cfm_type) :: cfm_dummy, cfm_mo_coeff, cfm_work, vxc
6001 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
6002 : TYPE(cp_fm_type) :: fm_dummy, fm_tmp_im, fm_tmp_re
6003 : TYPE(dft_control_type), POINTER :: dft_control
6004 : TYPE(kpoint_type), POINTER :: kpoints_Sigma, kpoints_Sigma_no_xc
6005 : TYPE(mp_para_env_type), POINTER :: para_env
6006 :
6007 16 : CALL timeset(routineN, handle)
6008 :
6009 16 : CALL get_qs_env(qs_env, para_env=para_env, dft_control=dft_control)
6010 :
6011 16 : kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
6012 :
6013 16 : kpoints_Sigma_no_xc => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma_no_xc
6014 :
6015 16 : nkp_self_energy = kpoints_Sigma%nkp
6016 :
6017 16 : nspins = dft_control%nspins
6018 :
6019 16 : matrix_struct => kpoints_Sigma%kp_env(1)%kpoint_env%wmat(1, 1)%matrix_struct
6020 :
6021 16 : CALL cp_cfm_create(vxc, matrix_struct)
6022 16 : CALL cp_cfm_create(cfm_mo_coeff, matrix_struct)
6023 16 : CALL cp_cfm_create(cfm_work, matrix_struct)
6024 16 : CALL cp_fm_create(fm_tmp_re, matrix_struct)
6025 16 : CALL cp_fm_create(fm_tmp_im, matrix_struct)
6026 :
6027 16 : CALL cp_cfm_get_info(cfm_mo_coeff, nrow_global=nmo)
6028 48 : ALLOCATE (diag_Sigma_x_minus_vxc_mo_mo(nmo))
6029 :
6030 16 : DEALLOCATE (qs_env%mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw)
6031 :
6032 64 : ALLOCATE (qs_env%mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(nmo, 2, nkp_self_energy))
6033 :
6034 136 : DO ikp = 1, nkp_self_energy
6035 :
6036 272 : DO ispin = 1, nspins
6037 :
6038 : ASSOCIATE (mo_set => kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(ispin))
6039 136 : IF (kpoints_Sigma%use_real_wfn) THEN
6040 0 : IF (ASSOCIATED(mo_set%mo_coeff)) THEN
6041 0 : CALL cp_fm_copy_general(mo_set%mo_coeff, fm_tmp_re, para_env)
6042 : ELSE
6043 0 : CALL cp_fm_copy_general(fm_dummy, fm_tmp_re, para_env)
6044 : END IF
6045 0 : CALL cp_fm_set_all(fm_tmp_im, 0.0_dp)
6046 0 : CALL cp_fm_to_cfm(fm_tmp_re, fm_tmp_im, cfm_mo_coeff)
6047 : ELSE
6048 136 : IF (ASSOCIATED(mo_set%cmo_coeff)) THEN
6049 136 : CALL cp_cfm_copy_general(mo_set%cmo_coeff, cfm_mo_coeff, para_env)
6050 : ELSE
6051 0 : CALL cp_cfm_copy_general(cfm_dummy, cfm_mo_coeff, para_env)
6052 : END IF
6053 : END IF
6054 : END ASSOCIATE
6055 :
6056 : ASSOCIATE (wmat => kpoints_Sigma_no_xc%kp_env(ikp)%kpoint_env%wmat)
6057 136 : IF (ASSOCIATED(wmat(1, ispin)%matrix_struct)) THEN
6058 136 : CALL cp_fm_copy_general(wmat(1, ispin), fm_tmp_re, para_env)
6059 : ELSE
6060 0 : CALL cp_fm_copy_general(fm_dummy, fm_tmp_re, para_env)
6061 : END IF
6062 272 : IF (ASSOCIATED(wmat(2, ispin)%matrix_struct)) THEN
6063 136 : CALL cp_fm_copy_general(wmat(2, ispin), fm_tmp_im, para_env)
6064 : ELSE
6065 0 : CALL cp_fm_copy_general(fm_dummy, fm_tmp_im, para_env)
6066 : END IF
6067 : END ASSOCIATE
6068 :
6069 136 : CALL cp_fm_to_cfm(fm_tmp_re, fm_tmp_im, vxc)
6070 :
6071 136 : CALL cfm_contract_ABA(cfm_mo_coeff, vxc, workspace=cfm_work)
6072 :
6073 136 : CALL cp_cfm_get_diag(vxc, diag_Sigma_x_minus_vxc_mo_mo)
6074 :
6075 : qs_env%mp2_env%ri_g0w0%vec_Sigma_x_minus_vxc_gw(:, ispin, ikp) = &
6076 3016 : REAL(diag_Sigma_x_minus_vxc_mo_mo, KIND=dp)
6077 :
6078 : END DO
6079 :
6080 : END DO
6081 :
6082 16 : CALL cp_cfm_release(vxc)
6083 16 : CALL cp_cfm_release(cfm_mo_coeff)
6084 16 : CALL cp_cfm_release(cfm_work)
6085 16 : CALL cp_fm_release(fm_tmp_re)
6086 16 : CALL cp_fm_release(fm_tmp_im)
6087 :
6088 16 : DEALLOCATE (diag_Sigma_x_minus_vxc_mo_mo)
6089 :
6090 16 : CALL timestop(handle)
6091 :
6092 32 : END SUBROUTINE compute_minus_vxc_kpoints
6093 :
6094 : ! **************************************************************************************************
6095 : !> \brief ...
6096 : !> \param qs_env ...
6097 : !> \param mat_self_energy_ao_ao ...
6098 : !> \param vec_Sigma ...
6099 : !> \param homo ...
6100 : !> \param gw_corr_lev_occ ...
6101 : !> \param gw_corr_lev_virt ...
6102 : !> \param ispin ...
6103 : ! **************************************************************************************************
6104 230 : SUBROUTINE trafo_to_mo_and_kpoints(qs_env, mat_self_energy_ao_ao, vec_Sigma, &
6105 : homo, gw_corr_lev_occ, gw_corr_lev_virt, ispin)
6106 : TYPE(qs_environment_type), POINTER :: qs_env
6107 : TYPE(dbcsr_type), TARGET :: mat_self_energy_ao_ao
6108 : REAL(KIND=dp), DIMENSION(:, :) :: vec_Sigma
6109 : INTEGER :: homo, gw_corr_lev_occ, gw_corr_lev_virt, &
6110 : ispin
6111 :
6112 : CHARACTER(LEN=*), PARAMETER :: routineN = 'trafo_to_mo_and_kpoints'
6113 :
6114 : COMPLEX(KIND=dp), ALLOCATABLE, DIMENSION(:) :: diag_self_energy
6115 : INTEGER :: handle, ikp, nao, ncol_ao, &
6116 : nkp_self_energy
6117 : INTEGER, ALLOCATABLE, DIMENSION(:) :: atom_from_bf
6118 : TYPE(cell_type), POINTER :: cell
6119 : TYPE(cp_cfm_type) :: cfm_self_energy, cfm_work
6120 : TYPE(cp_cfm_type), POINTER :: cfm_mo_coeff
6121 : TYPE(cp_fm_struct_type), POINTER :: matrix_struct
6122 : TYPE(cp_fm_type) :: fm_gamma
6123 : TYPE(kpoint_type), POINTER :: kpoints_Sigma
6124 230 : TYPE(particle_type), DIMENSION(:), POINTER :: particle_set
6125 :
6126 230 : CALL timeset(routineN, handle)
6127 :
6128 230 : CALL get_qs_env(qs_env, cell=cell, particle_set=particle_set)
6129 230 : kpoints_Sigma => qs_env%mp2_env%ri_rpa_im_time%kpoints_Sigma
6130 230 : nkp_self_energy = kpoints_Sigma%nkp
6131 230 : CALL dbcsr_get_info(mat_self_energy_ao_ao, nfullrows_total=nao, nfullcols_total=ncol_ao)
6132 230 : CPASSERT(nao == ncol_ao)
6133 1150 : ALLOCATE (diag_self_energy(nao), atom_from_bf(nao))
6134 230 : CALL get_atom_index_from_basis_function_index(qs_env, atom_from_bf, nao, "ORB")
6135 :
6136 : ! Use the AO layout for the operator; the auxiliary k-point solver supplies all nao MOs.
6137 230 : matrix_struct => kpoints_Sigma%kp_env(1)%kpoint_env%wmat(1, ispin)%matrix_struct
6138 230 : CALL cp_fm_create(fm_gamma, matrix_struct)
6139 : ! The Gamma self-energy is real symmetric in exact arithmetic. Its general
6140 : ! DBCSR storage allows tensor batches to accumulate both matrix orientations.
6141 230 : CALL copy_dbcsr_to_fm(mat_self_energy_ao_ao, fm_gamma)
6142 230 : CALL cp_cfm_create(cfm_self_energy, matrix_struct)
6143 230 : CALL cp_cfm_create(cfm_work, kpoints_Sigma%kp_env(1)%kpoint_env%mos(ispin)%cmo_coeff%matrix_struct)
6144 :
6145 1966 : DO ikp = 1, nkp_self_energy
6146 : CALL fm_gamma_to_kp(cfm_self_energy, fm_gamma, cell, particle_set, atom_from_bf, &
6147 1736 : kpoints_Sigma%index_to_cell, kpoints_Sigma%xkp(:, ikp))
6148 1736 : cfm_mo_coeff => kpoints_Sigma%kp_env(ikp)%kpoint_env%mos(ispin)%cmo_coeff
6149 1736 : CPASSERT(cfm_mo_coeff%matrix_struct%nrow_global == nao)
6150 1736 : CPASSERT(cfm_mo_coeff%matrix_struct%ncol_global == nao)
6151 1736 : CALL cfm_contract_ABA(cfm_mo_coeff, cfm_self_energy, workspace=cfm_work)
6152 1736 : CALL cp_cfm_get_diag(cfm_self_energy, diag_self_energy)
6153 : ! Taking the real MO diagonal selects the Hermitian part of the operator.
6154 5438 : vec_Sigma(:, ikp) = REAL(diag_self_energy(homo - gw_corr_lev_occ + 1:homo + gw_corr_lev_virt), KIND=dp)
6155 : END DO
6156 :
6157 230 : CALL cp_fm_release(fm_gamma)
6158 230 : CALL cp_cfm_release(cfm_self_energy)
6159 230 : CALL cp_cfm_release(cfm_work)
6160 :
6161 230 : CALL timestop(handle)
6162 :
6163 1150 : END SUBROUTINE trafo_to_mo_and_kpoints
6164 :
6165 : ! **************************************************************************************************
6166 : !> \brief ...
6167 : !> \param mat_set ...
6168 : !> \param mat_size ...
6169 : !> \param template ...
6170 : !> \param explicitly_no_symmetry ...
6171 : ! **************************************************************************************************
6172 0 : SUBROUTINE alloc_mat_set(mat_set, mat_size, template, explicitly_no_symmetry)
6173 : TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mat_set
6174 : INTEGER, INTENT(IN) :: mat_size
6175 : TYPE(dbcsr_type), TARGET :: template
6176 : LOGICAL, OPTIONAL :: explicitly_no_symmetry
6177 :
6178 : CHARACTER(LEN=*), PARAMETER :: routineN = 'alloc_mat_set'
6179 :
6180 : INTEGER :: handle, i_size
6181 : LOGICAL :: my_explicitly_no_symmetry
6182 :
6183 0 : CALL timeset(routineN, handle)
6184 :
6185 0 : my_explicitly_no_symmetry = .FALSE.
6186 0 : IF (PRESENT(explicitly_no_symmetry)) my_explicitly_no_symmetry = explicitly_no_symmetry
6187 :
6188 0 : NULLIFY (mat_set)
6189 0 : CALL dbcsr_allocate_matrix_set(mat_set, mat_size)
6190 0 : DO i_size = 1, mat_size
6191 0 : ALLOCATE (mat_set(i_size)%matrix)
6192 0 : IF (my_explicitly_no_symmetry) THEN
6193 : CALL dbcsr_create(matrix=mat_set(i_size)%matrix, template=template, &
6194 0 : matrix_type=dbcsr_type_no_symmetry)
6195 : ELSE
6196 0 : CALL dbcsr_create(matrix=mat_set(i_size)%matrix, template=template)
6197 : END IF
6198 0 : CALL dbcsr_copy(mat_set(i_size)%matrix, template)
6199 0 : CALL dbcsr_set(mat_set(i_size)%matrix, 0.0_dp)
6200 : END DO
6201 :
6202 0 : CALL timestop(handle)
6203 :
6204 0 : END SUBROUTINE alloc_mat_set
6205 :
6206 : ! **************************************************************************************************
6207 : !> \brief ...
6208 : !> \param mat_set ...
6209 : !> \param mat_size_1 ...
6210 : !> \param mat_size_2 ...
6211 : !> \param template ...
6212 : !> \param explicitly_no_symmetry ...
6213 : ! **************************************************************************************************
6214 4 : SUBROUTINE alloc_mat_set_2d(mat_set, mat_size_1, mat_size_2, template, explicitly_no_symmetry)
6215 : TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER :: mat_set
6216 : INTEGER, INTENT(IN) :: mat_size_1, mat_size_2
6217 : TYPE(dbcsr_type), TARGET :: template
6218 : LOGICAL, OPTIONAL :: explicitly_no_symmetry
6219 :
6220 : CHARACTER(LEN=*), PARAMETER :: routineN = 'alloc_mat_set_2d'
6221 :
6222 : INTEGER :: handle, i_size, j_size
6223 : LOGICAL :: my_explicitly_no_symmetry
6224 :
6225 4 : CALL timeset(routineN, handle)
6226 :
6227 4 : my_explicitly_no_symmetry = .FALSE.
6228 4 : IF (PRESENT(explicitly_no_symmetry)) my_explicitly_no_symmetry = explicitly_no_symmetry
6229 :
6230 4 : NULLIFY (mat_set)
6231 4 : CALL dbcsr_allocate_matrix_set(mat_set, mat_size_1, mat_size_2)
6232 16 : DO i_size = 1, mat_size_1
6233 124 : DO j_size = 1, mat_size_2
6234 108 : ALLOCATE (mat_set(i_size, j_size)%matrix)
6235 108 : IF (my_explicitly_no_symmetry) THEN
6236 : CALL dbcsr_create(matrix=mat_set(i_size, j_size)%matrix, template=template, &
6237 108 : matrix_type=dbcsr_type_no_symmetry)
6238 : ELSE
6239 0 : CALL dbcsr_create(matrix=mat_set(i_size, j_size)%matrix, template=template)
6240 : END IF
6241 108 : CALL dbcsr_copy(mat_set(i_size, j_size)%matrix, template)
6242 120 : CALL dbcsr_set(mat_set(i_size, j_size)%matrix, 0.0_dp)
6243 : END DO
6244 : END DO
6245 :
6246 4 : CALL timestop(handle)
6247 :
6248 4 : END SUBROUTINE alloc_mat_set_2d
6249 :
6250 : ! **************************************************************************************************
6251 : !> \brief ...
6252 : !> \param t_3c_O_all ...
6253 : !> \param t_greens_fct ...
6254 : !> \param t_3c_O_W ...
6255 : !> \param mat_self_energy_ao_ao ...
6256 : !> \param bounds_ao_ao_j ...
6257 : !> \param bounds_RI_i ...
6258 : !> \param unit_nr ...
6259 : !> \param eps_filter ...
6260 : !> \param do_occ ...
6261 : !> \param do_virt ...
6262 : ! **************************************************************************************************
6263 3176 : SUBROUTINE contract_to_self_energy(t_3c_O_all, t_greens_fct, t_3c_O_W, &
6264 : mat_self_energy_ao_ao, bounds_ao_ao_j, bounds_RI_i, &
6265 : unit_nr, eps_filter, do_occ, do_virt)
6266 :
6267 : TYPE(dbt_type) :: t_3c_O_all, t_greens_fct, t_3c_O_W
6268 : TYPE(dbcsr_type), TARGET :: mat_self_energy_ao_ao
6269 : INTEGER, DIMENSION(2, 2) :: bounds_ao_ao_j
6270 : INTEGER, DIMENSION(2, 1) :: bounds_RI_i
6271 : INTEGER :: unit_nr
6272 : REAL(KIND=dp) :: eps_filter
6273 : LOGICAL :: do_occ, do_virt
6274 :
6275 : CHARACTER(LEN=*), PARAMETER :: routineN = 'contract_to_self_energy'
6276 :
6277 : INTEGER :: handle
6278 : INTEGER, DIMENSION(2, 1) :: bounds_ao_j
6279 : INTEGER, DIMENSION(2, 2) :: bounds_ao_all_RI_i, bounds_RI_i_ao_j
6280 : REAL(KIND=dp) :: sign_self_energy
6281 79400 : TYPE(dbt_type) :: t_3c_O_G, t_3c_O_G_tmp, t_self_energy, &
6282 28584 : t_self_energy_tmp
6283 :
6284 3176 : CALL timeset(routineN, handle)
6285 :
6286 3176 : CPASSERT(do_occ .EQV. (.NOT. do_virt))
6287 :
6288 3176 : CALL dbt_create(t_3c_O_all, t_3c_O_G, name="M occ (RI AO | AO)")
6289 3176 : CALL dbt_create(t_3c_O_all, t_3c_O_G_tmp, name="M occ (RI AO | AO)")
6290 3176 : CALL dbt_create(t_greens_fct, t_self_energy, name="(AO|AO)")
6291 3176 : CALL dbt_create(mat_self_energy_ao_ao, t_self_energy_tmp)
6292 :
6293 9528 : bounds_ao_j(:, 1) = bounds_ao_ao_j(:, 1)
6294 9528 : bounds_ao_all_RI_i(:, 1) = bounds_RI_i(:, 1)
6295 9528 : bounds_ao_all_RI_i(:, 2) = bounds_ao_ao_j(:, 2)
6296 :
6297 : CALL dbt_contract(1.0_dp, t_greens_fct, t_3c_O_all, 0.0_dp, &
6298 : t_3c_O_G_tmp, &
6299 : contract_1=[2], notcontract_1=[1], &
6300 : contract_2=[3], notcontract_2=[1, 2], &
6301 : map_1=[3], map_2=[1, 2], &
6302 : bounds_2=bounds_ao_j, &
6303 : bounds_3=bounds_ao_all_RI_i, &
6304 : filter_eps=eps_filter, &
6305 3176 : unit_nr=unit_nr)
6306 :
6307 3176 : CALL dbt_copy(t_3c_O_G_tmp, t_3c_O_G, order=[1, 3, 2], move_data=.TRUE.)
6308 :
6309 3176 : IF (do_occ) sign_self_energy = -1.0_dp
6310 3176 : IF (do_virt) sign_self_energy = 1.0_dp
6311 :
6312 9528 : bounds_RI_i_ao_j(:, 1) = bounds_RI_i(:, 1)
6313 9528 : bounds_RI_i_ao_j(:, 2) = bounds_ao_ao_j(:, 1)
6314 :
6315 : CALL dbt_contract(sign_self_energy, t_3c_O_W, t_3c_O_G, 0.0_dp, &
6316 : t_self_energy, &
6317 : contract_1=[1, 2], notcontract_1=[3], &
6318 : contract_2=[1, 2], notcontract_2=[3], &
6319 : map_1=[1], map_2=[2], &
6320 : bounds_1=bounds_RI_i_ao_j, &
6321 : filter_eps=eps_filter, &
6322 3176 : unit_nr=unit_nr)
6323 :
6324 3176 : CALL dbt_copy(t_self_energy, t_self_energy_tmp)
6325 3176 : CALL dbt_clear(t_self_energy)
6326 :
6327 3176 : CALL dbt_copy_tensor_to_matrix(t_self_energy_tmp, mat_self_energy_ao_ao, summation=.TRUE.)
6328 :
6329 3176 : CALL dbt_destroy(t_3c_O_G)
6330 3176 : CALL dbt_destroy(t_3c_O_G_tmp)
6331 3176 : CALL dbt_destroy(t_self_energy)
6332 3176 : CALL dbt_destroy(t_self_energy_tmp)
6333 :
6334 3176 : CALL timestop(handle)
6335 :
6336 3176 : END SUBROUTINE contract_to_self_energy
6337 :
6338 : ! **************************************************************************************************
6339 : !> \brief ...
6340 : !> \param t_3c_overl_int_gw_AO ...
6341 : !> \param t_3c_overl_int_gw_RI ...
6342 : !> \param t_AO ...
6343 : !> \param t_RI ...
6344 : !> \param prefac ...
6345 : !> \param mo_bounds ...
6346 : !> \param unit_nr ...
6347 : !> \param t_3c_ctr_RI ...
6348 : !> \param t_3c_ctr_AO ...
6349 : !> \param calculate_ctr_RI ...
6350 : ! **************************************************************************************************
6351 1898 : SUBROUTINE contract_cubic_gw(t_3c_overl_int_gw_AO, t_3c_overl_int_gw_RI, &
6352 : t_AO, t_RI, prefac, &
6353 : mo_bounds, unit_nr, &
6354 : t_3c_ctr_RI, t_3c_ctr_AO, calculate_ctr_RI)
6355 : TYPE(dbt_type), INTENT(INOUT) :: t_3c_overl_int_gw_AO, &
6356 : t_3c_overl_int_gw_RI, t_AO, t_RI
6357 : REAL(dp), DIMENSION(2), INTENT(IN) :: prefac
6358 : INTEGER, DIMENSION(2), INTENT(IN) :: mo_bounds
6359 : INTEGER, INTENT(IN) :: unit_nr
6360 : TYPE(dbt_type), INTENT(INOUT) :: t_3c_ctr_RI, t_3c_ctr_AO
6361 : LOGICAL, INTENT(IN) :: calculate_ctr_RI
6362 :
6363 : CHARACTER(LEN=*), PARAMETER :: routineN = 'contract_cubic_gw'
6364 :
6365 : INTEGER :: handle
6366 : INTEGER, DIMENSION(2, 2) :: ctr_bounds_mo
6367 : INTEGER, DIMENSION(3) :: bounds_3c
6368 :
6369 1898 : CALL timeset(routineN, handle)
6370 :
6371 1898 : IF (calculate_ctr_RI) THEN
6372 950 : CALL dbt_get_info(t_3c_overl_int_gw_RI, nfull_total=bounds_3c)
6373 2850 : ctr_bounds_mo(:, 1) = [1, bounds_3c(2)]
6374 2850 : ctr_bounds_mo(:, 2) = mo_bounds
6375 :
6376 : CALL dbt_contract(prefac(1), t_RI, t_3c_overl_int_gw_RI, 0.0_dp, &
6377 : t_3c_ctr_RI, &
6378 : contract_1=[2], notcontract_1=[1], &
6379 : contract_2=[1], notcontract_2=[2, 3], &
6380 : map_1=[1], map_2=[2, 3], &
6381 : bounds_3=ctr_bounds_mo, &
6382 950 : unit_nr=unit_nr)
6383 :
6384 : END IF
6385 :
6386 1898 : CALL dbt_get_info(t_3c_overl_int_gw_AO, nfull_total=bounds_3c)
6387 5694 : ctr_bounds_mo(:, 1) = [1, bounds_3c(2)]
6388 5694 : ctr_bounds_mo(:, 2) = mo_bounds
6389 :
6390 : CALL dbt_contract(prefac(2), t_AO, t_3c_overl_int_gw_AO, 0.0_dp, &
6391 : t_3c_ctr_AO, &
6392 : contract_1=[2], notcontract_1=[1], &
6393 : contract_2=[1], notcontract_2=[2, 3], &
6394 : map_1=[1], map_2=[2, 3], &
6395 : bounds_3=ctr_bounds_mo, &
6396 1898 : unit_nr=unit_nr)
6397 :
6398 1898 : CALL timestop(handle)
6399 :
6400 1898 : END SUBROUTINE contract_cubic_gw
6401 :
6402 : ! **************************************************************************************************
6403 : !> \brief ...
6404 : !> \param t3c_1 ...
6405 : !> \param t3c_2 ...
6406 : !> \param vec_sigma ...
6407 : !> \param mo_offset ...
6408 : !> \param mo_bounds ...
6409 : !> \param para_env ...
6410 : ! **************************************************************************************************
6411 1898 : SUBROUTINE trace_sigma_gw(t3c_1, t3c_2, vec_sigma, mo_offset, mo_bounds, para_env)
6412 : TYPE(dbt_type), INTENT(INOUT) :: t3c_1, t3c_2
6413 : REAL(KIND=dp), DIMENSION(:), INTENT(INOUT) :: vec_Sigma
6414 : INTEGER, INTENT(IN) :: mo_offset
6415 : INTEGER, DIMENSION(2), INTENT(IN) :: mo_bounds
6416 : TYPE(mp_para_env_type), INTENT(IN) :: para_env
6417 :
6418 : CHARACTER(LEN=*), PARAMETER :: routineN = 'trace_sigma_gw'
6419 :
6420 : INTEGER :: handle, n, n_end, n_end_block, n_start, &
6421 : n_start_block
6422 : INTEGER, DIMENSION(1) :: trace_shape
6423 : INTEGER, DIMENSION(2) :: mo_bounds_off
6424 : INTEGER, DIMENSION(3) :: boff, bsize, ind
6425 : LOGICAL :: found
6426 1898 : REAL(KIND=dp), ALLOCATABLE, DIMENSION(:, :, :) :: block_1, block_2
6427 : REAL(KIND=dp), &
6428 3796 : DIMENSION(mo_bounds(2)-mo_bounds(1)+1) :: vec_Sigma_prv
6429 : TYPE(dbt_iterator_type) :: iter
6430 17082 : TYPE(dbt_type) :: t3c_1_redist
6431 :
6432 1898 : CALL timeset(routineN, handle)
6433 :
6434 1898 : CALL dbt_create(t3c_2, t3c_1_redist)
6435 1898 : CALL dbt_copy(t3c_1, t3c_1_redist, order=[2, 1, 3], move_data=.TRUE.)
6436 :
6437 24638 : vec_Sigma_prv = 0.0_dp
6438 :
6439 : !$OMP PARALLEL DEFAULT(NONE) REDUCTION(+:vec_Sigma_prv) &
6440 : !$OMP SHARED(t3c_1_redist,t3c_2,mo_bounds) &
6441 : !$OMP PRIVATE(iter,ind,bsize,boff,block_1,block_2,found) &
6442 1898 : !$OMP PRIVATE(n_start_block,n_start,n_end_block,n_end,trace_shape)
6443 : CALL dbt_iterator_start(iter, t3c_1_redist)
6444 : DO WHILE (dbt_iterator_blocks_left(iter))
6445 : CALL dbt_iterator_next_block(iter, ind, blk_size=bsize, blk_offset=boff)
6446 : CALL dbt_get_block(t3c_1_redist, ind, block_1, found)
6447 : CPASSERT(found)
6448 : CALL dbt_get_block(t3c_2, ind, block_2, found)
6449 : IF (.NOT. found) CYCLE
6450 :
6451 : IF (boff(3) < mo_bounds(1)) THEN
6452 : n_start_block = mo_bounds(1) - boff(3) + 1
6453 : n_start = 1
6454 : ELSE
6455 : n_start_block = 1
6456 : n_start = boff(3) - mo_bounds(1) + 1
6457 : END IF
6458 :
6459 : IF (boff(3) + bsize(3) - 1 > mo_bounds(2)) THEN
6460 : n_end_block = mo_bounds(2) - boff(3) + 1
6461 : n_end = mo_bounds(2) - mo_bounds(1) + 1
6462 : ELSE
6463 : n_end_block = bsize(3)
6464 : n_end = boff(3) + bsize(3) - mo_bounds(1)
6465 : END IF
6466 :
6467 : trace_shape(1) = SIZE(block_1, 1)*SIZE(block_1, 2)
6468 : vec_Sigma_prv(n_start:n_end) = &
6469 : vec_Sigma_prv(n_start:n_end) + &
6470 : [(DOT_PRODUCT(RESHAPE(block_1(:, :, n), trace_shape), &
6471 : RESHAPE(block_2(:, :, n), trace_shape)), &
6472 : n=n_start_block, n_end_block)]
6473 : DEALLOCATE (block_1, block_2)
6474 : END DO
6475 : CALL dbt_iterator_stop(iter)
6476 : !$OMP END PARALLEL
6477 :
6478 1898 : CALL dbt_destroy(t3c_1_redist)
6479 :
6480 1898 : CALL para_env%sum(vec_Sigma_prv)
6481 :
6482 5694 : mo_bounds_off = mo_bounds - mo_offset + 1
6483 : vec_Sigma(mo_bounds_off(1):mo_bounds_off(2)) = &
6484 24638 : vec_Sigma(mo_bounds_off(1):mo_bounds_off(2)) + vec_Sigma_prv
6485 :
6486 1898 : CALL timestop(handle)
6487 3796 : END SUBROUTINE trace_sigma_gw
6488 :
6489 : END MODULE rpa_gw
|