14 USE dbcsr_api,
ONLY: dbcsr_type
16 dbt_contract, dbt_copy, dbt_copy_matrix_to_tensor, dbt_create, dbt_destroy, dbt_get_block, &
17 dbt_get_info, dbt_iterator_blocks_left, dbt_iterator_next_block, dbt_iterator_start, &
18 dbt_iterator_stop, dbt_iterator_type, dbt_nblks_total, dbt_pgrid_create, &
19 dbt_pgrid_destroy, dbt_pgrid_type, dbt_type
25 #include "./base/base_uses.f90"
31 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'rpa_gw_ic'
54 t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, gw_corr_lev_tot, &
55 gw_corr_lev_occ, gw_corr_lev_virt, homo, unit_nr, &
56 print_ic_values, para_env, &
59 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: eigenval
60 TYPE(dbcsr_type),
INTENT(IN),
TARGET :: mat_sinvvsinv
61 TYPE(dbt_type) :: t_3c_overl_nnp_ic, &
62 t_3c_overl_nnp_ic_reflected
63 INTEGER,
INTENT(IN) :: gw_corr_lev_tot, gw_corr_lev_occ, &
64 gw_corr_lev_virt, homo, unit_nr
65 LOGICAL,
INTENT(IN) :: print_ic_values
66 TYPE(mp_para_env_type),
INTENT(IN) :: para_env
67 LOGICAL,
INTENT(IN),
OPTIONAL :: do_alpha, do_beta
69 CHARACTER(LEN=*),
PARAMETER :: routinen =
'calculate_ic_correction'
71 CHARACTER(4) :: occ_virt
72 INTEGER :: handle, mo_end, mo_start, n_level_gw, &
74 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: dist_1, dist_2, sizes_ri_split
75 INTEGER,
DIMENSION(2) :: pdims
76 LOGICAL :: do_closed_shell, my_do_alpha, my_do_beta
77 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: delta_sigma_neaton
78 TYPE(dbt_pgrid_type) :: pgrid_2d
79 TYPE(dbt_type) :: t_3c_overl_nnp_ic_reflected_ctr, t_sinvvsinv, t_sinvvsinv_tmp
81 CALL timeset(routinen, handle)
83 IF (
PRESENT(do_alpha))
THEN
84 my_do_alpha = do_alpha
89 IF (
PRESENT(do_beta))
THEN
95 do_closed_shell = .NOT. (my_do_alpha .OR. my_do_beta)
97 ALLOCATE (delta_sigma_neaton(gw_corr_lev_tot))
98 delta_sigma_neaton = 0.0_dp
100 mo_start = homo - gw_corr_lev_occ + 1
101 mo_end = homo + gw_corr_lev_virt
102 cpassert(mo_end - mo_start + 1 == gw_corr_lev_tot)
104 ALLOCATE (sizes_ri_split(dbt_nblks_total(t_3c_overl_nnp_ic_reflected, 1)))
105 CALL dbt_get_info(t_3c_overl_nnp_ic_reflected, blk_size_1=sizes_ri_split)
107 CALL dbt_create(mat_sinvvsinv, t_sinvvsinv_tmp)
108 CALL dbt_copy_matrix_to_tensor(mat_sinvvsinv, t_sinvvsinv_tmp)
111 CALL dbt_pgrid_create(para_env, pdims, pgrid_2d)
112 CALL create_2c_tensor(t_sinvvsinv, dist_1, dist_2, pgrid_2d, sizes_ri_split, sizes_ri_split, &
114 DEALLOCATE (dist_1, dist_2)
115 CALL dbt_pgrid_destroy(pgrid_2d)
117 CALL dbt_copy(t_sinvvsinv_tmp, t_sinvvsinv)
118 CALL dbt_destroy(t_sinvvsinv_tmp)
119 CALL dbt_create(t_3c_overl_nnp_ic_reflected, t_3c_overl_nnp_ic_reflected_ctr)
120 CALL dbt_contract(0.5_dp, t_sinvvsinv, t_3c_overl_nnp_ic_reflected, &
121 0.0_dp, t_3c_overl_nnp_ic_reflected_ctr, &
122 contract_1=[2], notcontract_1=[1], &
123 contract_2=[1], notcontract_2=[2, 3], &
124 map_1=[1], map_2=[2, 3])
126 CALL trace_ic_gw(t_3c_overl_nnp_ic, t_3c_overl_nnp_ic_reflected_ctr, delta_sigma_neaton, [mo_start, mo_end], para_env)
128 delta_sigma_neaton(gw_corr_lev_occ + 1:) = -delta_sigma_neaton(gw_corr_lev_occ + 1:)
130 CALL dbt_destroy(t_sinvvsinv)
131 CALL dbt_destroy(t_3c_overl_nnp_ic_reflected_ctr)
133 IF (unit_nr > 0)
THEN
135 WRITE (unit_nr, *)
' '
137 IF (do_closed_shell)
THEN
138 WRITE (unit_nr,
'(T3,A)')
'Single-electron energies with image charge (ic) correction'
139 WRITE (unit_nr,
'(T3,A)')
'----------------------------------------------------------'
140 ELSE IF (my_do_alpha)
THEN
141 WRITE (unit_nr,
'(T3,A)')
'Single-electron energies of alpha spins with image charge (ic) correction'
142 WRITE (unit_nr,
'(T3,A)')
'-------------------------------------------------------------------------'
143 ELSE IF (my_do_beta)
THEN
144 WRITE (unit_nr,
'(T3,A)')
'Single-electron energies of beta spins with image charge (ic) correction'
145 WRITE (unit_nr,
'(T3,A)')
'------------------------------------------------------------------------'
148 WRITE (unit_nr, *)
' '
149 WRITE (unit_nr,
'(T3,A)')
'Reference for the ic: Neaton et al., PRL 97, 216405 (2006)'
150 WRITE (unit_nr, *)
' '
152 WRITE (unit_nr,
'(T3,A)')
' '
153 WRITE (unit_nr,
'(T14,2A)')
'MO E_n before ic corr Delta E_ic', &
156 DO n_level_gw = 1, gw_corr_lev_tot
157 n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
158 IF (n_level_gw <= gw_corr_lev_occ)
THEN
164 WRITE (unit_nr,
'(T4,I4,3A,3F21.3)') &
165 n_level_gw_ref,
' ( ', occ_virt,
') ', &
166 eigenval(n_level_gw_ref)*
evolt, &
167 delta_sigma_neaton(n_level_gw)*
evolt, &
168 (eigenval(n_level_gw_ref) + delta_sigma_neaton(n_level_gw))*
evolt
172 IF (do_closed_shell)
THEN
173 WRITE (unit_nr,
'(T3,A)')
' '
174 WRITE (unit_nr,
'(T3,A,F57.2)')
'IC HOMO-LUMO gap (eV)', (eigenval(homo + 1) + &
175 delta_sigma_neaton(gw_corr_lev_occ + 1) - &
177 delta_sigma_neaton(gw_corr_lev_occ))*
evolt
178 ELSE IF (my_do_alpha)
THEN
179 WRITE (unit_nr,
'(T3,A)')
' '
180 WRITE (unit_nr,
'(T3,A,F51.2)')
'Alpha IC HOMO-LUMO gap (eV)', (eigenval(homo + 1) + &
181 delta_sigma_neaton(gw_corr_lev_occ + 1) - &
183 delta_sigma_neaton(gw_corr_lev_occ))*
evolt
184 ELSE IF (my_do_beta)
THEN
185 WRITE (unit_nr,
'(T3,A)')
' '
186 WRITE (unit_nr,
'(T3,A,F52.2)')
'Beta IC HOMO-LUMO gap (eV)', (eigenval(homo + 1) + &
187 delta_sigma_neaton(gw_corr_lev_occ + 1) - &
189 delta_sigma_neaton(gw_corr_lev_occ))*
evolt
192 IF (print_ic_values)
THEN
194 WRITE (unit_nr,
'(T3,A)')
' '
195 WRITE (unit_nr,
'(T3,A)')
'Horizontal list for copying the image charge corrections for use as input:'
196 WRITE (unit_nr,
'(*(F7.3))') (delta_sigma_neaton(n_level_gw)*
evolt, &
197 n_level_gw=1, gw_corr_lev_tot)
203 eigenval(homo - gw_corr_lev_occ + 1:homo + gw_corr_lev_virt) = eigenval(homo - gw_corr_lev_occ + 1: &
204 homo + gw_corr_lev_virt) &
205 + delta_sigma_neaton(1:gw_corr_lev_tot)
207 CALL timestop(handle)
219 SUBROUTINE trace_ic_gw(t3c_1, t3c_2, Delta_Sigma_Neaton, mo_bounds, para_env)
220 TYPE(dbt_type),
INTENT(INOUT) :: t3c_1, t3c_2
221 REAL(
dp),
DIMENSION(:),
INTENT(INOUT) :: delta_sigma_neaton
222 INTEGER,
DIMENSION(2),
INTENT(IN) :: mo_bounds
223 TYPE(mp_para_env_type),
INTENT(IN) :: para_env
225 CHARACTER(LEN=*),
PARAMETER :: routinen =
'trace_ic_gw'
227 INTEGER :: handle, n, n_end, n_end_block, n_start, &
229 INTEGER,
DIMENSION(3) :: boff, bsize, ind
231 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :, :) :: block_1, block_2
233 DIMENSION(mo_bounds(2)-mo_bounds(1)+1) :: delta_sigma_neaton_prv
234 TYPE(dbt_iterator_type) :: iter
236 CALL timeset(routinen, handle)
238 cpassert(
SIZE(delta_sigma_neaton_prv) ==
SIZE(delta_sigma_neaton))
239 delta_sigma_neaton_prv = 0.0_dp
245 CALL dbt_iterator_start(iter, t3c_1)
246 DO WHILE (dbt_iterator_blocks_left(iter))
247 CALL dbt_iterator_next_block(iter, ind, blk_size=bsize, blk_offset=boff)
248 IF (ind(2) /= ind(3)) cycle
249 CALL dbt_get_block(t3c_1, ind, block_1, found)
251 CALL dbt_get_block(t3c_2, ind, block_2, found)
252 IF (.NOT. found) cycle
254 IF (boff(3) < mo_bounds(1))
THEN
255 n_start_block = mo_bounds(1) - boff(3) + 1
259 n_start = boff(3) - mo_bounds(1) + 1
262 IF (boff(3) + bsize(3) - 1 > mo_bounds(2))
THEN
263 n_end_block = mo_bounds(2) - boff(3) + 1
264 n_end = mo_bounds(2) - mo_bounds(1) + 1
266 n_end_block = bsize(3)
267 n_end = boff(3) + bsize(3) - mo_bounds(1)
270 delta_sigma_neaton_prv(n_start:n_end) = &
271 delta_sigma_neaton_prv(n_start:n_end) + &
272 (/(dot_product(block_1(:, n, n), &
274 n=n_start_block, n_end_block)/)
275 DEALLOCATE (block_1, block_2)
277 CALL dbt_iterator_stop(iter)
280 delta_sigma_neaton = delta_sigma_neaton + delta_sigma_neaton_prv
281 CALL para_env%sum(delta_sigma_neaton)
283 CALL timestop(handle)
302 gw_corr_lev_occ, gw_corr_lev_virt, gw_corr_lev_tot, &
303 homo, nmo, unit_nr, do_alpha, do_beta)
305 REAL(kind=
dp),
DIMENSION(:),
INTENT(INOUT) :: eigenval, eigenval_scf
306 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: ic_corr_list
307 INTEGER,
INTENT(IN) :: gw_corr_lev_occ, gw_corr_lev_virt, &
308 gw_corr_lev_tot, homo, nmo, unit_nr
309 LOGICAL,
INTENT(IN),
OPTIONAL :: do_alpha, do_beta
311 CHARACTER(LEN=*),
PARAMETER :: routinen =
'apply_ic_corr'
313 CHARACTER(4) :: occ_virt
314 INTEGER :: handle, n_level_gw, n_level_gw_ref
315 LOGICAL :: do_closed_shell, my_do_alpha, my_do_beta
316 REAL(kind=
dp) :: eigen_diff
318 CALL timeset(routinen, handle)
320 IF (
PRESENT(do_alpha))
THEN
321 my_do_alpha = do_alpha
323 my_do_alpha = .false.
326 IF (
PRESENT(do_beta))
THEN
332 do_closed_shell = .NOT. (my_do_alpha .OR. my_do_beta)
335 cpassert(
SIZE(ic_corr_list) == gw_corr_lev_tot)
337 IF (unit_nr > 0)
THEN
339 WRITE (unit_nr, *)
' '
341 IF (do_closed_shell)
THEN
342 WRITE (unit_nr,
'(T3,A)')
'GW quasiparticle energies with image charge (ic) correction'
343 WRITE (unit_nr,
'(T3,A)')
'-----------------------------------------------------------'
344 ELSE IF (my_do_alpha)
THEN
345 WRITE (unit_nr,
'(T3,A)')
'GW quasiparticle energies of alpha spins with image charge (ic) correction'
346 WRITE (unit_nr,
'(T3,A)')
'--------------------------------------------------------------------------'
347 ELSE IF (my_do_beta)
THEN
348 WRITE (unit_nr,
'(T3,A)')
'GW quasiparticle energies of beta spins with image charge (ic) correction'
349 WRITE (unit_nr,
'(T3,A)')
'-------------------------------------------------------------------------'
352 WRITE (unit_nr, *)
' '
354 DO n_level_gw = 1, gw_corr_lev_tot
355 n_level_gw_ref = n_level_gw + homo - gw_corr_lev_occ
356 IF (n_level_gw <= gw_corr_lev_occ)
THEN
362 WRITE (unit_nr,
'(T4,I4,3A,3F21.3)') &
363 n_level_gw_ref,
' ( ', occ_virt,
') ', &
364 eigenval(n_level_gw_ref)*
evolt, &
365 ic_corr_list(n_level_gw)*
evolt, &
366 (eigenval(n_level_gw_ref) + ic_corr_list(n_level_gw))*
evolt
370 WRITE (unit_nr, *)
' '
374 eigenval(homo - gw_corr_lev_occ + 1:homo + gw_corr_lev_virt) = eigenval(homo - gw_corr_lev_occ + 1: &
375 homo + gw_corr_lev_virt) &
376 + ic_corr_list(1:gw_corr_lev_tot)
378 eigenval_scf(homo - gw_corr_lev_occ + 1:homo + gw_corr_lev_virt) = eigenval_scf(homo - gw_corr_lev_occ + 1: &
379 homo + gw_corr_lev_virt) &
380 + ic_corr_list(1:gw_corr_lev_tot)
382 IF (unit_nr > 0)
THEN
384 IF (do_closed_shell)
THEN
385 WRITE (unit_nr,
'(T3,A,F52.2)')
'G0W0 IC HOMO-LUMO gap (eV)', eigenval(homo + 1) - eigenval(homo)
386 ELSE IF (my_do_alpha)
THEN
387 WRITE (unit_nr,
'(T3,A,F46.2)')
'G0W0 Alpha IC HOMO-LUMO gap (eV)', eigenval(homo + 1) - eigenval(homo)
388 ELSE IF (my_do_beta)
THEN
389 WRITE (unit_nr,
'(T3,A,F47.2)')
'G0W0 Beta IC HOMO-LUMO gap (eV)', eigenval(homo + 1) - eigenval(homo)
392 WRITE (unit_nr, *)
' '
398 IF (gw_corr_lev_occ < homo .AND. gw_corr_lev_occ > 0)
THEN
403 DO n_level_gw = 1, gw_corr_lev_occ
404 eigen_diff = eigen_diff + ic_corr_list(n_level_gw)
406 eigen_diff = eigen_diff/gw_corr_lev_occ
409 DO n_level_gw = 1, homo - gw_corr_lev_occ
410 eigenval(n_level_gw) = eigenval(n_level_gw) + eigen_diff
411 eigenval_scf(n_level_gw) = eigenval_scf(n_level_gw) + eigen_diff
417 IF (gw_corr_lev_virt < nmo - homo .AND. gw_corr_lev_virt > 0)
THEN
421 DO n_level_gw = gw_corr_lev_occ + 1, gw_corr_lev_tot
422 eigen_diff = eigen_diff + ic_corr_list(n_level_gw)
424 eigen_diff = eigen_diff/gw_corr_lev_virt
427 DO n_level_gw = homo + gw_corr_lev_virt + 1, nmo
428 eigenval(n_level_gw) = eigenval(n_level_gw) + eigen_diff
429 eigenval_scf(n_level_gw) = eigenval_scf(n_level_gw) + eigen_diff
434 CALL timestop(handle)
This is the start of a dbt_api, all publically needed functions are exported here....
Defines the basic variable types.
integer, parameter, public dp
Interface to the message passing library MPI.
subroutine, public mp_dims_create(nodes, dims)
wrapper to MPI_Dims_create
Definition of physical constants:
real(kind=dp), parameter, public evolt
Utility methods to build 3-center integral tensors of various types.
subroutine, public create_2c_tensor(t2c, dist_1, dist_2, pgrid, sizes_1, sizes_2, order, name)
...
Routines to calculate image charge corrections.
subroutine, public calculate_ic_correction(Eigenval, mat_SinvVSinv, t_3c_overl_nnP_ic, t_3c_overl_nnP_ic_reflected, gw_corr_lev_tot, gw_corr_lev_occ, gw_corr_lev_virt, homo, unit_nr, print_ic_values, para_env, do_alpha, do_beta)
...
subroutine, public apply_ic_corr(Eigenval, Eigenval_scf, ic_corr_list, gw_corr_lev_occ, gw_corr_lev_virt, gw_corr_lev_tot, homo, nmo, unit_nr, do_alpha, do_beta)
...