(git:ed6f26b)
Loading...
Searching...
No Matches
bse_full_diag.F
Go to the documentation of this file.
1!--------------------------------------------------------------------------------------------------!
2! CP2K: A general program to perform molecular dynamics simulations !
3! Copyright 2000-2025 CP2K developers group <https://cp2k.org> !
4! !
5! SPDX-License-Identifier: GPL-2.0-or-later !
6!--------------------------------------------------------------------------------------------------!
7
8! **************************************************************************************************
9!> \brief Routines for the full diagonalization of GW + Bethe-Salpeter for computing
10!> electronic excitations
11!> \par History
12!> 10.2023 created [Maximilian Graml]
13! **************************************************************************************************
15
38 USE cp_fm_types, ONLY: cp_fm_create,&
48 USE kinds, ONLY: dp
50 USE mp2_types, ONLY: mp2_type
53#include "./base/base_uses.f90"
54
55 IMPLICIT NONE
56
57 PRIVATE
58
59 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'bse_full_diag'
60
63
64CONTAINS
65
66! **************************************************************************************************
67!> \brief Matrix A constructed from GW energies and 3c-B-matrices (cf. subroutine mult_B_with_W)
68!> A_ia,jb = (ε_a-ε_i) δ_ij δ_ab + α * v_ia,jb - W_ij,ab
69!> ε_a, ε_i are GW singleparticle energies from Eigenval_reduced
70!> α is a spin-dependent factor
71!> v_ia,jb = \sum_P B^P_ia B^P_jb (unscreened Coulomb interaction)
72!> W_ij,ab = \sum_P \bar{B}^P_ij B^P_ab (screened Coulomb interaction)
73!> \param fm_mat_S_ia_bse ...
74!> \param fm_mat_S_bar_ij_bse ...
75!> \param fm_mat_S_ab_bse ...
76!> \param fm_A ...
77!> \param Eigenval ...
78!> \param unit_nr ...
79!> \param homo ...
80!> \param virtual ...
81!> \param dimen_RI ...
82!> \param mp2_env ...
83!> \param para_env ...
84! **************************************************************************************************
85 SUBROUTINE create_a(fm_mat_S_ia_bse, fm_mat_S_bar_ij_bse, fm_mat_S_ab_bse, &
86 fm_A, Eigenval, unit_nr, &
87 homo, virtual, dimen_RI, mp2_env, &
88 para_env)
89
90 TYPE(cp_fm_type), INTENT(IN) :: fm_mat_s_ia_bse, fm_mat_s_bar_ij_bse, &
91 fm_mat_s_ab_bse
92 TYPE(cp_fm_type), INTENT(INOUT) :: fm_a
93 REAL(kind=dp), DIMENSION(:) :: eigenval
94 INTEGER, INTENT(IN) :: unit_nr, homo, virtual, dimen_ri
95 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
96 TYPE(mp_para_env_type), INTENT(INOUT) :: para_env
97
98 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_A'
99
100 INTEGER :: a_virt_row, handle, i_occ_row, &
101 i_row_global, ii, j_col_global, jj, &
102 ncol_local_a, nrow_local_a
103 INTEGER, DIMENSION(4) :: reordering
104 INTEGER, DIMENSION(:), POINTER :: col_indices_a, row_indices_a
105 REAL(kind=dp) :: alpha, alpha_screening, eigen_diff
106 TYPE(cp_blacs_env_type), POINTER :: blacs_env
107 TYPE(cp_fm_struct_type), POINTER :: fm_struct_a, fm_struct_w
108 TYPE(cp_fm_type) :: fm_w
109
110 CALL timeset(routinen, handle)
111
112 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print) THEN
113 WRITE (unit_nr, '(T2,A10,T13,A10)') 'BSE|DEBUG|', 'Creating A'
114 END IF
115
116 !Determines factor of exchange term, depending on requested spin configuration (cf. input_constants.F)
117 SELECT CASE (mp2_env%bse%bse_spin_config)
118 CASE (bse_singlet)
119 alpha = 2.0_dp
120 CASE (bse_triplet)
121 alpha = 0.0_dp
122 END SELECT
123
124 IF (mp2_env%bse%screening_method == bse_screening_alpha) THEN
125 alpha_screening = mp2_env%bse%screening_factor
126 ELSE
127 alpha_screening = 1.0_dp
128 END IF
129
130 ! create the blacs env for ij matrices (NOT fm_mat_S_ia_bse%matrix_struct related parallel_gemms!)
131 NULLIFY (blacs_env)
132 CALL cp_blacs_env_create(blacs_env=blacs_env, para_env=para_env)
133
134 ! We have to use the same blacs_env for A as for the matrices fm_mat_S_ia_bse from RPA
135 ! Logic: A_ia,jb = (ε_a-ε_i) δ_ij δ_ab + α * v_ia,jb - W_ij,ab
136 ! We create v_ia,jb and W_ij,ab, then we communicate entries from local W_ij,ab
137 ! to the full matrix v_ia,jb. By adding these and the energy diffenences: v_ia,jb -> A_ia,jb
138 ! We use the A matrix already from the start instead of v
139 CALL cp_fm_struct_create(fm_struct_a, context=fm_mat_s_ia_bse%matrix_struct%context, nrow_global=homo*virtual, &
140 ncol_global=homo*virtual, para_env=fm_mat_s_ia_bse%matrix_struct%para_env)
141 CALL cp_fm_create(fm_a, fm_struct_a, name="fm_A_iajb")
142 CALL cp_fm_set_all(fm_a, 0.0_dp)
143
144 CALL cp_fm_struct_create(fm_struct_w, context=fm_mat_s_ab_bse%matrix_struct%context, nrow_global=homo**2, &
145 ncol_global=virtual**2, para_env=fm_mat_s_ab_bse%matrix_struct%para_env)
146 CALL cp_fm_create(fm_w, fm_struct_w, name="fm_W_ijab")
147 CALL cp_fm_set_all(fm_w, 0.0_dp)
148
149 ! Create A matrix from GW Energies, v_ia,jb and W_ij,ab (different blacs_env!)
150 ! v_ia,jb, which is directly initialized in A (with a factor of alpha)
151 ! v_ia,jb = \sum_P B^P_ia B^P_jb
152 CALL parallel_gemm(transa="T", transb="N", m=homo*virtual, n=homo*virtual, k=dimen_ri, alpha=alpha, &
153 matrix_a=fm_mat_s_ia_bse, matrix_b=fm_mat_s_ia_bse, beta=0.0_dp, &
154 matrix_c=fm_a)
155
156 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print) THEN
157 WRITE (unit_nr, '(T2,A10,T13,A16)') 'BSE|DEBUG|', 'Allocated A_iajb'
158 END IF
159
160 ! If infinite screening is applied, fm_W is simply 0 - Otherwise it needs to be computed from 3c integrals
161 IF (mp2_env%bse%screening_method /= bse_screening_rpa) THEN
162 !W_ij,ab = \sum_P \bar{B}^P_ij B^P_ab
163 CALL parallel_gemm(transa="T", transb="N", m=homo**2, n=virtual**2, k=dimen_ri, alpha=alpha_screening, &
164 matrix_a=fm_mat_s_bar_ij_bse, matrix_b=fm_mat_s_ab_bse, beta=0.0_dp, &
165 matrix_c=fm_w)
166 END IF
167
168 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print) THEN
169 WRITE (unit_nr, '(T2,A10,T13,A16)') 'BSE|DEBUG|', 'Allocated W_ijab'
170 END IF
171
172 ! We start by moving data from local parts of W_ij,ab to the full matrix A_ia,jb using buffers
173 CALL cp_fm_get_info(matrix=fm_a, &
174 nrow_local=nrow_local_a, &
175 ncol_local=ncol_local_a, &
176 row_indices=row_indices_a, &
177 col_indices=col_indices_a)
178 ! Writing -1.0_dp * W_ij,ab to A_ia,jb, i.e. beta = -1.0_dp,
179 ! W_ij,ab: nrow_secidx_in = homo, ncol_secidx_in = virtual
180 ! A_ia,jb: nrow_secidx_out = virtual, ncol_secidx_out = virtual
181
182 ! If infinite screening is applied, fm_W is simply 0 - Otherwise it needs to be computed from 3c integrals
183 IF (mp2_env%bse%screening_method /= bse_screening_rpa) THEN
184 reordering = (/1, 3, 2, 4/)
185 CALL fm_general_add_bse(fm_a, fm_w, -1.0_dp, homo, virtual, &
186 virtual, virtual, unit_nr, reordering, mp2_env)
187 END IF
188 !full matrix W is not needed anymore, release it to save memory
189 CALL cp_fm_release(fm_w)
190
191 !Now add the energy differences (ε_a-ε_i) on the diagonal (i.e. δ_ij δ_ab) of A_ia,jb
192 DO ii = 1, nrow_local_a
193
194 i_row_global = row_indices_a(ii)
195
196 DO jj = 1, ncol_local_a
197
198 j_col_global = col_indices_a(jj)
199
200 IF (i_row_global == j_col_global) THEN
201 i_occ_row = (i_row_global - 1)/virtual + 1
202 a_virt_row = mod(i_row_global - 1, virtual) + 1
203 eigen_diff = eigenval(a_virt_row + homo) - eigenval(i_occ_row)
204 fm_a%local_data(ii, jj) = fm_a%local_data(ii, jj) + eigen_diff
205
206 END IF
207 END DO
208 END DO
209
210 CALL cp_fm_struct_release(fm_struct_a)
211 CALL cp_fm_struct_release(fm_struct_w)
212
213 CALL cp_blacs_env_release(blacs_env)
214
215 CALL timestop(handle)
216
217 END SUBROUTINE create_a
218
219! **************************************************************************************************
220!> \brief Matrix B constructed from 3c-B-matrices (cf. subroutine mult_B_with_W)
221!> B_ia,jb = α * v_ia,jb - W_ib,aj
222!> α is a spin-dependent factor
223!> v_ia,jb = \sum_P B^P_ia B^P_jb (unscreened Coulomb interaction)
224!> W_ib,aj = \sum_P \bar{B}^P_ib B^P_aj (screened Coulomb interaction)
225!> \param fm_mat_S_ia_bse ...
226!> \param fm_mat_S_bar_ia_bse ...
227!> \param fm_B ...
228!> \param homo ...
229!> \param virtual ...
230!> \param dimen_RI ...
231!> \param unit_nr ...
232!> \param mp2_env ...
233! **************************************************************************************************
234 SUBROUTINE create_b(fm_mat_S_ia_bse, fm_mat_S_bar_ia_bse, fm_B, &
235 homo, virtual, dimen_RI, unit_nr, mp2_env)
236
237 TYPE(cp_fm_type), INTENT(IN) :: fm_mat_s_ia_bse, fm_mat_s_bar_ia_bse
238 TYPE(cp_fm_type), INTENT(INOUT) :: fm_b
239 INTEGER, INTENT(IN) :: homo, virtual, dimen_ri, unit_nr
240 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
241
242 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_B'
243
244 INTEGER :: handle
245 INTEGER, DIMENSION(4) :: reordering
246 REAL(kind=dp) :: alpha, alpha_screening
247 TYPE(cp_fm_struct_type), POINTER :: fm_struct_v
248 TYPE(cp_fm_type) :: fm_w
249
250 CALL timeset(routinen, handle)
251
252 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print) THEN
253 WRITE (unit_nr, '(T2,A10,T13,A10)') 'BSE|DEBUG|', 'Creating B'
254 END IF
255
256 ! Determines factor of exchange term, depending on requested spin configuration (cf. input_constants.F)
257 SELECT CASE (mp2_env%bse%bse_spin_config)
258 CASE (bse_singlet)
259 alpha = 2.0_dp
260 CASE (bse_triplet)
261 alpha = 0.0_dp
262 END SELECT
263
264 IF (mp2_env%bse%screening_method == bse_screening_alpha) THEN
265 alpha_screening = mp2_env%bse%screening_factor
266 ELSE
267 alpha_screening = 1.0_dp
268 END IF
269
270 CALL cp_fm_struct_create(fm_struct_v, context=fm_mat_s_ia_bse%matrix_struct%context, nrow_global=homo*virtual, &
271 ncol_global=homo*virtual, para_env=fm_mat_s_ia_bse%matrix_struct%para_env)
272 CALL cp_fm_create(fm_b, fm_struct_v, name="fm_B_iajb")
273 CALL cp_fm_set_all(fm_b, 0.0_dp)
274
275 CALL cp_fm_create(fm_w, fm_struct_v, name="fm_W_ibaj")
276 CALL cp_fm_set_all(fm_w, 0.0_dp)
277
278 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print) THEN
279 WRITE (unit_nr, '(T2,A10,T13,A16)') 'BSE|DEBUG|', 'Allocated B_iajb'
280 END IF
281 ! v_ia,jb = \sum_P B^P_ia B^P_jb
282 CALL parallel_gemm(transa="T", transb="N", m=homo*virtual, n=homo*virtual, k=dimen_ri, alpha=alpha, &
283 matrix_a=fm_mat_s_ia_bse, matrix_b=fm_mat_s_ia_bse, beta=0.0_dp, &
284 matrix_c=fm_b)
285
286 ! If infinite screening is applied, fm_W is simply 0 - Otherwise it needs to be computed from 3c integrals
287 IF (mp2_env%bse%screening_method /= bse_screening_rpa) THEN
288 ! W_ib,aj = \sum_P \bar{B}^P_ib B^P_aj
289 CALL parallel_gemm(transa="T", transb="N", m=homo*virtual, n=homo*virtual, k=dimen_ri, alpha=alpha_screening, &
290 matrix_a=fm_mat_s_bar_ia_bse, matrix_b=fm_mat_s_ia_bse, beta=0.0_dp, &
291 matrix_c=fm_w)
292
293 ! from W_ib,ja to A_ia,jb (formally: W_ib,aj, but our internal indexorder is different)
294 ! Writing -1.0_dp * W_ib,ja to A_ia,jb, i.e. beta = -1.0_dp,
295 ! W_ib,ja: nrow_secidx_in = virtual, ncol_secidx_in = virtual
296 ! A_ia,jb: nrow_secidx_out = virtual, ncol_secidx_out = virtual
297 reordering = (/1, 4, 3, 2/)
298 CALL fm_general_add_bse(fm_b, fm_w, -1.0_dp, virtual, virtual, &
299 virtual, virtual, unit_nr, reordering, mp2_env)
300 END IF
301
302 CALL cp_fm_release(fm_w)
303 CALL cp_fm_struct_release(fm_struct_v)
304 CALL timestop(handle)
305
306 END SUBROUTINE create_b
307
308 ! **************************************************************************************************
309!> \brief Construct Matrix C=(A-B)^0.5 (A+B) (A-B)^0.5 to solve full BSE matrix as a hermitian problem
310!> (cf. Eq. (A7) in F. Furche J. Chem. Phys., Vol. 114, No. 14, (2001)).
311!> We keep fm_sqrt_A_minus_B and fm_inv_sqrt_A_minus_B for print of singleparticle transitions
312!> of ABBA as described in Eq. (A10) in F. Furche J. Chem. Phys., Vol. 114, No. 14, (2001).
313!> \param fm_A ...
314!> \param fm_B ...
315!> \param fm_C ...
316!> \param fm_sqrt_A_minus_B ...
317!> \param fm_inv_sqrt_A_minus_B ...
318!> \param homo ...
319!> \param virtual ...
320!> \param unit_nr ...
321!> \param mp2_env ...
322!> \param diag_est ...
323! **************************************************************************************************
324 SUBROUTINE create_hermitian_form_of_abba(fm_A, fm_B, fm_C, &
325 fm_sqrt_A_minus_B, fm_inv_sqrt_A_minus_B, &
326 homo, virtual, unit_nr, mp2_env, diag_est)
327
328 TYPE(cp_fm_type), INTENT(IN) :: fm_a, fm_b
329 TYPE(cp_fm_type), INTENT(INOUT) :: fm_c, fm_sqrt_a_minus_b, &
330 fm_inv_sqrt_a_minus_b
331 INTEGER, INTENT(IN) :: homo, virtual, unit_nr
332 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
333 REAL(kind=dp), INTENT(IN) :: diag_est
334
335 CHARACTER(LEN=*), PARAMETER :: routinen = 'create_hermitian_form_of_ABBA'
336
337 INTEGER :: dim_mat, handle, n_dependent
338 REAL(kind=dp), DIMENSION(2) :: eigvals_ab_diff
339 TYPE(cp_fm_type) :: fm_a_minus_b, fm_a_plus_b, fm_dummy, &
340 fm_work_product
341
342 CALL timeset(routinen, handle)
343
344 IF (unit_nr > 0) THEN
345 WRITE (unit_nr, '(T2,A4,T7,A25,A39,ES6.0,A3)') 'BSE|', 'Diagonalizing aux. matrix', &
346 ' with size of A. This will take around ', diag_est, " s."
347 END IF
348
349 ! Create work matrices, which will hold A+B and A-B and their powers
350 ! C is created afterwards to save memory
351 ! Final result: C = (A-B)^0.5 (A+B) (A-B)^0.5 EQ.I
352 ! \_______/ \___/ \______/
353 ! fm_sqrt_A_minus_B fm_A_plus_B fm_sqrt_A_minus_B
354 ! (EQ.Ia) (EQ.Ib) (EQ.Ia)
355 ! Intermediate work matrices:
356 ! fm_inv_sqrt_A_minus_B: (A-B)^-0.5 EQ.II
357 ! fm_A_minus_B: (A-B) EQ.III
358 ! fm_work_product: (A-B)^0.5 (A+B) from (EQ.Ia) and (EQ.Ib) EQ.IV
359 CALL cp_fm_create(fm_a_plus_b, fm_a%matrix_struct)
360 CALL cp_fm_to_fm(fm_a, fm_a_plus_b)
361 CALL cp_fm_create(fm_a_minus_b, fm_a%matrix_struct)
362 CALL cp_fm_to_fm(fm_a, fm_a_minus_b)
363 CALL cp_fm_create(fm_sqrt_a_minus_b, fm_a%matrix_struct)
364 CALL cp_fm_set_all(fm_sqrt_a_minus_b, 0.0_dp)
365 CALL cp_fm_create(fm_inv_sqrt_a_minus_b, fm_a%matrix_struct)
366 CALL cp_fm_set_all(fm_inv_sqrt_a_minus_b, 0.0_dp)
367
368 CALL cp_fm_create(fm_work_product, fm_a%matrix_struct)
369
370 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print) THEN
371 WRITE (unit_nr, '(T2,A10,T13,A19)') 'BSE|DEBUG|', 'Created work arrays'
372 END IF
373
374 ! Add/Substract B (cf. EQs. Ib and III)
375 CALL cp_fm_scale_and_add(1.0_dp, fm_a_plus_b, 1.0_dp, fm_b)
376 CALL cp_fm_scale_and_add(1.0_dp, fm_a_minus_b, -1.0_dp, fm_b)
377
378 ! cp_fm_power will overwrite matrix, therefore we create copies
379 CALL cp_fm_to_fm(fm_a_minus_b, fm_inv_sqrt_a_minus_b)
380
381 ! In order to avoid a second diagonalization (cp_fm_power), we create (A-B)^0.5 (EQ.Ia)
382 ! from (A-B)^-0.5 (EQ.II) by multiplication with (A-B) (EQ.III) afterwards.
383
384 ! Raise A-B to -0.5_dp, no quenching of eigenvectors, hence threshold=0.0_dp
385 CALL cp_fm_create(fm_dummy, fm_a%matrix_struct)
386 ! Create (A-B)^-0.5 (cf. EQ.II)
387 CALL cp_fm_power(fm_inv_sqrt_a_minus_b, fm_dummy, -0.5_dp, 0.0_dp, n_dependent, eigvals=eigvals_ab_diff)
388 CALL cp_fm_release(fm_dummy)
389 ! Raise an error in case the the matrix A-B is not positive definite (i.e. negative eigenvalues)
390 ! In this case, the procedure for hermitian form of ABBA is not applicable
391 IF (eigvals_ab_diff(1) < 0) THEN
392 CALL cp_abort(__location__, &
393 "Matrix (A-B) is not positive definite. "// &
394 "Hermitian diagonalization of full ABBA matrix is ill-defined.")
395 END IF
396
397 ! We keep fm_inv_sqrt_A_minus_B for print of singleparticle transitions of ABBA
398 ! We further create (A-B)^0.5 for the singleparticle transitions of ABBA
399 ! Create (A-B)^0.5= (A-B)^-0.5 * (A-B) (EQ.Ia)
400 dim_mat = homo*virtual
401 CALL parallel_gemm("N", "N", dim_mat, dim_mat, dim_mat, 1.0_dp, fm_inv_sqrt_a_minus_b, fm_a_minus_b, 0.0_dp, &
402 fm_sqrt_a_minus_b)
403
404 ! Compute and store LHS of C, i.e. (A-B)^0.5 (A+B) (EQ.IV)
405 CALL parallel_gemm("N", "N", dim_mat, dim_mat, dim_mat, 1.0_dp, fm_sqrt_a_minus_b, fm_a_plus_b, 0.0_dp, &
406 fm_work_product)
407
408 ! Release to save memory
409 CALL cp_fm_release(fm_a_plus_b)
410 CALL cp_fm_release(fm_a_minus_b)
411
412 ! Now create full
413 CALL cp_fm_create(fm_c, fm_a%matrix_struct)
414 CALL cp_fm_set_all(fm_c, 0.0_dp)
415 ! Compute C=(A-B)^0.5 (A+B) (A-B)^0.5 (EQ.I)
416 CALL parallel_gemm("N", "N", dim_mat, dim_mat, dim_mat, 1.0_dp, fm_work_product, fm_sqrt_a_minus_b, 0.0_dp, &
417 fm_c)
418 CALL cp_fm_release(fm_work_product)
419
420 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print) THEN
421 WRITE (unit_nr, '(T2,A10,T13,A36)') 'BSE|DEBUG|', 'Filled C=(A-B)^0.5 (A+B) (A-B)^0.5'
422 END IF
423
424 CALL timestop(handle)
425 END SUBROUTINE
426
427! **************************************************************************************************
428!> \brief Solving eigenvalue equation C Z^n = (Ω^n)^2 Z^n .
429!> Here, the eigenvectors Z^n relate to X^n via
430!> Eq. (A10) in F. Furche J. Chem. Phys., Vol. 114, No. 14, (2001).
431!> \param fm_C ...
432!> \param homo ...
433!> \param virtual ...
434!> \param homo_irred ...
435!> \param fm_sqrt_A_minus_B ...
436!> \param fm_inv_sqrt_A_minus_B ...
437!> \param unit_nr ...
438!> \param diag_est ...
439!> \param mp2_env ...
440!> \param qs_env ...
441!> \param mo_coeff ...
442! **************************************************************************************************
443 SUBROUTINE diagonalize_c(fm_C, homo, virtual, homo_irred, &
444 fm_sqrt_A_minus_B, fm_inv_sqrt_A_minus_B, &
445 unit_nr, diag_est, mp2_env, qs_env, mo_coeff)
446
447 TYPE(cp_fm_type), INTENT(INOUT) :: fm_c
448 INTEGER, INTENT(IN) :: homo, virtual, homo_irred
449 TYPE(cp_fm_type), INTENT(INOUT) :: fm_sqrt_a_minus_b, fm_inv_sqrt_a_minus_b
450 INTEGER, INTENT(IN) :: unit_nr
451 REAL(kind=dp), INTENT(IN) :: diag_est
452 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
453 TYPE(qs_environment_type), POINTER :: qs_env
454 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
455
456 CHARACTER(LEN=*), PARAMETER :: routinen = 'diagonalize_C'
457
458 INTEGER :: diag_info, handle
459 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: exc_ens
460 TYPE(cp_fm_type) :: fm_eigvec_x, fm_eigvec_y, fm_eigvec_z, &
461 fm_mat_eigvec_transform_diff, &
462 fm_mat_eigvec_transform_sum
463
464 CALL timeset(routinen, handle)
465
466 IF (unit_nr > 0) THEN
467 WRITE (unit_nr, '(T2,A4,T7,A17,A22,ES6.0,A3)') 'BSE|', 'Diagonalizing C. ', &
468 'This will take around ', diag_est, ' s.'
469 END IF
470
471 !We have now the full matrix C=(A-B)^0.5 (A+B) (A-B)^0.5
472 !Now: Diagonalize it
473 CALL cp_fm_create(fm_eigvec_z, fm_c%matrix_struct)
474
475 ALLOCATE (exc_ens(homo*virtual))
476
477 CALL choose_eigv_solver(fm_c, fm_eigvec_z, exc_ens, diag_info)
478
479 IF (diag_info /= 0) THEN
480 CALL cp_abort(__location__, &
481 "Diagonalization of C=(A-B)^0.5 (A+B) (A-B)^0.5 failed in BSE")
482 END IF
483
484 ! C could have negative eigenvalues, since we do not explicitly check A+B
485 ! for positive definiteness (would make another O(N^6) Diagon. necessary)
486 ! Instead, we include a check here
487 IF (exc_ens(1) < 0) THEN
488 IF (unit_nr > 0) THEN
489 CALL cp_abort(__location__, &
490 "Matrix C=(A-B)^0.5 (A+B) (A-B)^0.5 has negative eigenvalues, i.e. "// &
491 "(A+B) is not positive definite.")
492 END IF
493 END IF
494 exc_ens = sqrt(exc_ens)
495
496 ! Prepare eigenvector for interpretation of singleparticle transitions
497 ! Compare: F. Furche J. Chem. Phys., Vol. 114, No. 14, (2001)
498 ! We aim for the upper part of the vector (X,Y) for a direct comparison with the TDA result
499
500 ! Following Furche, we basically use Eqs. (A10): First, we multiply
501 ! the (A-B)^+-0.5 with eigenvectors and then the eigenvalues
502 ! One has to be careful about the index structure, since the eigenvector matrix is not symmetric anymore!
503
504 ! First, Eq. I from (A10) from Furche: (X+Y)_n = (Ω_n)^-0.5 (A-B)^0.5 T_n
505 CALL cp_fm_create(fm_mat_eigvec_transform_sum, fm_c%matrix_struct)
506 CALL cp_fm_set_all(fm_mat_eigvec_transform_sum, 0.0_dp)
507 CALL parallel_gemm(transa="N", transb="N", m=homo*virtual, n=homo*virtual, k=homo*virtual, alpha=1.0_dp, &
508 matrix_a=fm_sqrt_a_minus_b, matrix_b=fm_eigvec_z, beta=0.0_dp, &
509 matrix_c=fm_mat_eigvec_transform_sum)
510 CALL cp_fm_release(fm_sqrt_a_minus_b)
511 ! This normalizes the eigenvectors
512 CALL comp_eigvec_coeff_bse(fm_mat_eigvec_transform_sum, exc_ens, -0.5_dp, gamma=2.0_dp, do_transpose=.true.)
513
514 ! Second, Eq. II from (A10) from Furche: (X-Y)_n = (Ω_n)^0.5 (A-B)^-0.5 T_n
515 CALL cp_fm_create(fm_mat_eigvec_transform_diff, fm_c%matrix_struct)
516 CALL cp_fm_set_all(fm_mat_eigvec_transform_diff, 0.0_dp)
517 CALL parallel_gemm(transa="N", transb="N", m=homo*virtual, n=homo*virtual, k=homo*virtual, alpha=1.0_dp, &
518 matrix_a=fm_inv_sqrt_a_minus_b, matrix_b=fm_eigvec_z, beta=0.0_dp, &
519 matrix_c=fm_mat_eigvec_transform_diff)
520 CALL cp_fm_release(fm_inv_sqrt_a_minus_b)
521 CALL cp_fm_release(fm_eigvec_z)
522
523 ! This normalizes the eigenvectors
524 CALL comp_eigvec_coeff_bse(fm_mat_eigvec_transform_diff, exc_ens, 0.5_dp, gamma=2.0_dp, do_transpose=.true.)
525
526 ! Now, we add the two equations to obtain X_n
527 ! Add overwrites the first argument, therefore we copy it beforehand
528 CALL cp_fm_create(fm_eigvec_x, fm_c%matrix_struct)
529 CALL cp_fm_to_fm(fm_mat_eigvec_transform_sum, fm_eigvec_x)
530 CALL cp_fm_scale_and_add(1.0_dp, fm_eigvec_x, 1.0_dp, fm_mat_eigvec_transform_diff)
531
532 ! Now, we subtract the two equations to obtain Y_n
533 ! Add overwrites the first argument, therefore we copy it beforehand
534 CALL cp_fm_create(fm_eigvec_y, fm_c%matrix_struct)
535 CALL cp_fm_to_fm(fm_mat_eigvec_transform_sum, fm_eigvec_y)
536 CALL cp_fm_scale_and_add(1.0_dp, fm_eigvec_y, -1.0_dp, fm_mat_eigvec_transform_diff)
537
538 !Cleanup
539 CALL cp_fm_release(fm_mat_eigvec_transform_diff)
540 CALL cp_fm_release(fm_mat_eigvec_transform_sum)
541
542 CALL postprocess_bse(exc_ens, fm_eigvec_x, mp2_env, qs_env, mo_coeff, &
543 homo, virtual, homo_irred, unit_nr, &
544 .false., fm_eigvec_y)
545
546 DEALLOCATE (exc_ens)
547 CALL cp_fm_release(fm_eigvec_x)
548 CALL cp_fm_release(fm_eigvec_y)
549
550 CALL timestop(handle)
551
552 END SUBROUTINE diagonalize_c
553
554! **************************************************************************************************
555!> \brief Solving hermitian eigenvalue equation A X^n = Ω^n X^n
556!> \param fm_A ...
557!> \param homo ...
558!> \param virtual ...
559!> \param homo_irred ...
560!> \param unit_nr ...
561!> \param diag_est ...
562!> \param mp2_env ...
563!> \param qs_env ...
564!> \param mo_coeff ...
565! **************************************************************************************************
566 SUBROUTINE diagonalize_a(fm_A, homo, virtual, homo_irred, &
567 unit_nr, diag_est, mp2_env, qs_env, mo_coeff)
568
569 TYPE(cp_fm_type), INTENT(INOUT) :: fm_a
570 INTEGER, INTENT(IN) :: homo, virtual, homo_irred, unit_nr
571 REAL(kind=dp), INTENT(IN) :: diag_est
572 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
573 TYPE(qs_environment_type), POINTER :: qs_env
574 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
575
576 CHARACTER(LEN=*), PARAMETER :: routinen = 'diagonalize_A'
577
578 INTEGER :: diag_info, handle
579 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: exc_ens
580 TYPE(cp_fm_type) :: fm_eigvec
581
582 CALL timeset(routinen, handle)
583
584 !Continue with formatting of subroutine create_A
585 IF (unit_nr > 0) THEN
586 WRITE (unit_nr, '(T2,A4,T7,A17,A22,ES6.0,A3)') 'BSE|', 'Diagonalizing A. ', &
587 'This will take around ', diag_est, ' s.'
588 END IF
589
590 !We have now the full matrix A_iajb, distributed over all ranks
591 !Now: Diagonalize it
592 CALL cp_fm_create(fm_eigvec, fm_a%matrix_struct)
593
594 ALLOCATE (exc_ens(homo*virtual))
595
596 CALL choose_eigv_solver(fm_a, fm_eigvec, exc_ens, diag_info)
597
598 IF (diag_info /= 0) THEN
599 CALL cp_abort(__location__, &
600 "Diagonalization of A failed in TDA-BSE")
601 END IF
602
603 CALL postprocess_bse(exc_ens, fm_eigvec, mp2_env, qs_env, mo_coeff, &
604 homo, virtual, homo_irred, unit_nr, .true.)
605
606 CALL cp_fm_release(fm_eigvec)
607 DEALLOCATE (exc_ens)
608
609 CALL timestop(handle)
610
611 END SUBROUTINE diagonalize_a
612
613! **************************************************************************************************
614!> \brief Prints the success message (incl. energies) for full diag of BSE (TDA/full ABBA via flag)
615!> \param Exc_ens ...
616!> \param fm_eigvec_X ...
617!> \param mp2_env ...
618!> \param qs_env ...
619!> \param mo_coeff ...
620!> \param homo ...
621!> \param virtual ...
622!> \param homo_irred ...
623!> \param unit_nr ...
624!> \param flag_TDA ...
625!> \param fm_eigvec_Y ...
626! **************************************************************************************************
627 SUBROUTINE postprocess_bse(Exc_ens, fm_eigvec_X, mp2_env, qs_env, mo_coeff, &
628 homo, virtual, homo_irred, unit_nr, &
629 flag_TDA, fm_eigvec_Y)
630
631 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: exc_ens
632 TYPE(cp_fm_type), INTENT(IN) :: fm_eigvec_x
633 TYPE(mp2_type), INTENT(INOUT) :: mp2_env
634 TYPE(qs_environment_type), POINTER :: qs_env
635 TYPE(cp_fm_type), DIMENSION(:), INTENT(IN) :: mo_coeff
636 INTEGER :: homo, virtual, homo_irred, unit_nr
637 LOGICAL, OPTIONAL :: flag_tda
638 TYPE(cp_fm_type), INTENT(IN), OPTIONAL :: fm_eigvec_y
639
640 CHARACTER(LEN=*), PARAMETER :: routinen = 'postprocess_bse'
641
642 CHARACTER(LEN=10) :: info_approximation, multiplet
643 INTEGER :: handle, i_exc, idir, n_moments_di, &
644 n_moments_quad
645 REAL(kind=dp) :: alpha
646 REAL(kind=dp), ALLOCATABLE, DIMENSION(:) :: oscill_str, ref_point_multipole
647 REAL(kind=dp), ALLOCATABLE, DIMENSION(:, :, :) :: polarizability_residues, trans_mom_bse
648 TYPE(cp_fm_type) :: fm_x_ia, fm_y_ia
649 TYPE(cp_fm_type), ALLOCATABLE, DIMENSION(:) :: fm_dipole_ab_trunc, fm_dipole_ai_trunc, &
650 fm_dipole_ij_trunc, fm_quadpole_ab_trunc, fm_quadpole_ai_trunc, fm_quadpole_ij_trunc
651 TYPE(exciton_descr_type), ALLOCATABLE, &
652 DIMENSION(:) :: exc_descr
653
654 CALL timeset(routinen, handle)
655
656 !Prepare variables for printing
657 IF (mp2_env%bse%bse_spin_config == 0) THEN
658 multiplet = "Singlet"
659 alpha = 2.0_dp
660 ELSE
661 multiplet = "Triplet"
662 alpha = 0.0_dp
663 END IF
664 IF (.NOT. PRESENT(flag_tda)) THEN
665 flag_tda = .false.
666 END IF
667 IF (flag_tda) THEN
668 info_approximation = " -TDA- "
669 ELSE
670 info_approximation = "-ABBA-"
671 END IF
672
673 n_moments_di = 3
674 n_moments_quad = 9
675 ! Compute BSE dipoles and oscillator strengths - Keep in memory for later usage
676 ! Need dipoles also for spatial expectation values, which are well-defined also for triplets
677 ALLOCATE (fm_dipole_ij_trunc(n_moments_di))
678 ALLOCATE (fm_dipole_ab_trunc(n_moments_di))
679 ALLOCATE (fm_dipole_ai_trunc(n_moments_di))
680 ALLOCATE (ref_point_multipole(3))
681 ! Obtain dipoles in MO basis
682 CALL get_multipoles_mo(fm_dipole_ai_trunc, fm_dipole_ij_trunc, fm_dipole_ab_trunc, &
683 qs_env, mo_coeff, ref_point_multipole, 1, &
684 homo, virtual, fm_eigvec_x%matrix_struct%context)
685 ! Compute exciton descriptors from these multipoles
686 IF (mp2_env%bse%num_print_exc_descr > 0) THEN
687 ! Obtain quadrupoles in MO basis
688 ALLOCATE (fm_quadpole_ij_trunc(n_moments_quad))
689 ALLOCATE (fm_quadpole_ab_trunc(n_moments_quad))
690 ALLOCATE (fm_quadpole_ai_trunc(n_moments_quad))
691 CALL get_multipoles_mo(fm_quadpole_ai_trunc, fm_quadpole_ij_trunc, fm_quadpole_ab_trunc, &
692 qs_env, mo_coeff, ref_point_multipole, 2, &
693 homo, virtual, fm_eigvec_x%matrix_struct%context)
694 ! Iterate over excitation index outside of routine to make it compatible with tddft module
695 ALLOCATE (exc_descr(mp2_env%bse%num_print_exc_descr))
696 DO i_exc = 1, mp2_env%bse%num_print_exc_descr
697 CALL reshuffle_eigvec(fm_eigvec_x, fm_x_ia, homo, virtual, i_exc, &
698 .false., unit_nr, mp2_env)
699 IF (.NOT. flag_tda) THEN
700 CALL reshuffle_eigvec(fm_eigvec_y, fm_y_ia, homo, virtual, i_exc, &
701 .false., unit_nr, mp2_env)
702
703 CALL get_exciton_descriptors(exc_descr, fm_x_ia, &
704 fm_quadpole_ij_trunc, fm_quadpole_ab_trunc, &
705 fm_quadpole_ai_trunc, &
706 i_exc, homo, virtual, &
707 fm_y_ia)
708 ELSE
709 CALL get_exciton_descriptors(exc_descr, fm_x_ia, &
710 fm_quadpole_ij_trunc, fm_quadpole_ab_trunc, &
711 fm_quadpole_ai_trunc, &
712 i_exc, homo, virtual)
713 END IF
714 CALL cp_fm_release(fm_x_ia)
715 IF (.NOT. flag_tda) THEN
716 CALL cp_fm_release(fm_y_ia)
717 END IF
718 END DO
719 END IF
720
721 IF (mp2_env%bse%bse_spin_config == 0) THEN
722 CALL get_oscillator_strengths(fm_eigvec_x, exc_ens, fm_dipole_ai_trunc, &
723 trans_mom_bse, oscill_str, polarizability_residues, &
724 mp2_env, homo, virtual, unit_nr, &
725 fm_eigvec_y)
726 END IF
727
728 ! Prints basic definitions used in BSE calculation
729 CALL print_output_header(homo, virtual, homo_irred, flag_tda, &
730 multiplet, alpha, mp2_env, unit_nr)
731
732 ! Prints excitation energies up to user-specified number
733 CALL print_excitation_energies(exc_ens, homo, virtual, flag_tda, multiplet, &
734 info_approximation, mp2_env, unit_nr)
735
736 ! Print single particle transition amplitudes, i.e. components of eigenvectors X and Y
737 CALL print_transition_amplitudes(fm_eigvec_x, homo, virtual, homo_irred, &
738 info_approximation, mp2_env, unit_nr, fm_eigvec_y)
739
740 ! Prints optical properties, if state is a singlet
741 CALL print_optical_properties(exc_ens, oscill_str, trans_mom_bse, polarizability_residues, &
742 homo, virtual, homo_irred, flag_tda, &
743 info_approximation, mp2_env, unit_nr)
744 ! Print exciton descriptors if keyword is invoked
745 IF (mp2_env%bse%num_print_exc_descr > 0) THEN
746 CALL print_exciton_descriptors(exc_descr, ref_point_multipole, unit_nr, &
747 mp2_env%bse%num_print_exc_descr, mp2_env%bse%bse_debug_print, &
748 mp2_env%bse%print_directional_exc_descr, &
749 'BSE|', qs_env)
750 END IF
751
752 ! Compute and print excitation wavefunctions
753 IF (mp2_env%bse%do_nto_analysis) THEN
754 IF (unit_nr > 0) THEN
755 WRITE (unit_nr, '(T2,A4)') 'BSE|'
756 WRITE (unit_nr, '(T2,A4,T7,A47)') &
757 'BSE|', "Calculating Natural Transition Orbitals (NTOs)."
758 WRITE (unit_nr, '(T2,A4)') 'BSE|'
759 END IF
760 CALL calculate_ntos(fm_eigvec_x, fm_eigvec_y, &
761 mo_coeff, homo, virtual, &
762 info_approximation, &
763 oscill_str, &
764 qs_env, unit_nr, mp2_env)
765 END IF
766
767 DO idir = 1, n_moments_di
768 CALL cp_fm_release(fm_dipole_ai_trunc(idir))
769 CALL cp_fm_release(fm_dipole_ij_trunc(idir))
770 CALL cp_fm_release(fm_dipole_ab_trunc(idir))
771 END DO
772 IF (mp2_env%bse%num_print_exc_descr > 0) THEN
773 DO idir = 1, n_moments_quad
774 CALL cp_fm_release(fm_quadpole_ai_trunc(idir))
775 CALL cp_fm_release(fm_quadpole_ij_trunc(idir))
776 CALL cp_fm_release(fm_quadpole_ab_trunc(idir))
777 END DO
778 DEALLOCATE (fm_quadpole_ai_trunc, fm_quadpole_ij_trunc, fm_quadpole_ab_trunc)
779 DEALLOCATE (exc_descr)
780 END IF
781 DEALLOCATE (fm_dipole_ai_trunc, fm_dipole_ij_trunc, fm_dipole_ab_trunc)
782 DEALLOCATE (ref_point_multipole)
783 IF (mp2_env%bse%bse_spin_config == 0) THEN
784 DEALLOCATE (oscill_str, trans_mom_bse, polarizability_residues)
785 END IF
786 IF (unit_nr > 0) THEN
787 WRITE (unit_nr, '(T2,A4)') 'BSE|'
788 WRITE (unit_nr, '(T2,A4)') 'BSE|'
789 END IF
790
791 CALL timestop(handle)
792
793 END SUBROUTINE postprocess_bse
794
795END MODULE bse_full_diag
Routines for the full diagonalization of GW + Bethe-Salpeter for computing electronic excitations.
subroutine, public diagonalize_a(fm_a, homo, virtual, homo_irred, unit_nr, diag_est, mp2_env, qs_env, mo_coeff)
Solving hermitian eigenvalue equation A X^n = Ω^n X^n.
subroutine, public diagonalize_c(fm_c, homo, virtual, homo_irred, fm_sqrt_a_minus_b, fm_inv_sqrt_a_minus_b, unit_nr, diag_est, mp2_env, qs_env, mo_coeff)
Solving eigenvalue equation C Z^n = (Ω^n)^2 Z^n . Here, the eigenvectors Z^n relate to X^n via Eq....
subroutine, public create_a(fm_mat_s_ia_bse, fm_mat_s_bar_ij_bse, fm_mat_s_ab_bse, fm_a, eigenval, unit_nr, homo, virtual, dimen_ri, mp2_env, para_env)
Matrix A constructed from GW energies and 3c-B-matrices (cf. subroutine mult_B_with_W) A_ia,...
subroutine, public create_b(fm_mat_s_ia_bse, fm_mat_s_bar_ia_bse, fm_b, homo, virtual, dimen_ri, unit_nr, mp2_env)
Matrix B constructed from 3c-B-matrices (cf. subroutine mult_B_with_W) B_ia,jb = α * v_ia,...
subroutine, public create_hermitian_form_of_abba(fm_a, fm_b, fm_c, fm_sqrt_a_minus_b, fm_inv_sqrt_a_minus_b, homo, virtual, unit_nr, mp2_env, diag_est)
Construct Matrix C=(A-B)^0.5 (A+B) (A-B)^0.5 to solve full BSE matrix as a hermitian problem (cf....
Routines for printing information in context of the BSE calculation.
Definition bse_print.F:13
subroutine, public print_output_header(homo, virtual, homo_irred, flag_tda, multiplet, alpha, mp2_env, unit_nr)
...
Definition bse_print.F:98
subroutine, public print_optical_properties(exc_ens, oscill_str, trans_mom_bse, polarizability_residues, homo, virtual, homo_irred, flag_tda, info_approximation, mp2_env, unit_nr)
...
Definition bse_print.F:339
subroutine, public print_exciton_descriptors(exc_descr, ref_point_multipole, unit_nr, num_print_exc_descr, print_checkvalue, print_directional_exc_descr, prefix_output, qs_env)
Prints exciton descriptors, cf. Mewes et al., JCTC 14, 710-725 (2018)
Definition bse_print.F:507
subroutine, public print_transition_amplitudes(fm_eigvec_x, homo, virtual, homo_irred, info_approximation, mp2_env, unit_nr, fm_eigvec_y)
...
Definition bse_print.F:264
subroutine, public print_excitation_energies(exc_ens, homo, virtual, flag_tda, multiplet, info_approximation, mp2_env, unit_nr)
...
Definition bse_print.F:215
Routines for computing excitonic properties, e.g. exciton diameter, from the BSE.
subroutine, public get_oscillator_strengths(fm_eigvec_x, exc_ens, fm_dipole_ai_trunc, trans_mom_bse, oscill_str, polarizability_residues, mp2_env, homo_red, virtual_red, unit_nr, fm_eigvec_y)
Compute and return BSE dipoles d_r^n = sqrt(2) sum_ia < ψ_i | r | ψ_a > ( X_ia^n + Y_ia^n ) and oscil...
subroutine, public get_exciton_descriptors(exc_descr, fm_x_ia, fm_multipole_ij_trunc, fm_multipole_ab_trunc, fm_multipole_ai_trunc, i_exc, homo, virtual, fm_y_ia)
...
subroutine, public calculate_ntos(fm_x, fm_y, mo_coeff, homo, virtual, info_approximation, oscill_str, qs_env, unit_nr, mp2_env)
...
Auxiliary routines for GW + Bethe-Salpeter for computing electronic excitations.
Definition bse_util.F:13
subroutine, public get_multipoles_mo(fm_multipole_ai_trunc, fm_multipole_ij_trunc, fm_multipole_ab_trunc, qs_env, mo_coeff, rpoint, n_moments, homo_red, virtual_red, context_bse)
...
Definition bse_util.F:1715
subroutine, public reshuffle_eigvec(fm_eigvec, fm_eigvec_reshuffled, homo, virtual, n_exc, do_transpose, unit_nr, mp2_env)
...
Definition bse_util.F:1351
subroutine, public comp_eigvec_coeff_bse(fm_work, eig_vals, beta, gamma, do_transpose)
Routine for computing the coefficients of the eigenvectors of the BSE matrix from a multiplication wi...
Definition bse_util.F:787
subroutine, public fm_general_add_bse(fm_out, fm_in, beta, nrow_secidx_in, ncol_secidx_in, nrow_secidx_out, ncol_secidx_out, unit_nr, reordering, mp2_env)
Adds and reorders full matrices with a combined index structure, e.g. adding W_ij,...
Definition bse_util.F:199
methods related to the blacs parallel environment
subroutine, public cp_blacs_env_release(blacs_env)
releases the given blacs_env
subroutine, public cp_blacs_env_create(blacs_env, para_env, blacs_grid_layout, blacs_repeatable, row_major, grid_2d)
allocates and initializes a type that represent a blacs context
basic linear algebra operations for full matrices
subroutine, public cp_fm_scale_and_add(alpha, matrix_a, beta, matrix_b)
calc A <- alpha*A + beta*B optimized for alpha == 1.0 (just add beta*B) and beta == 0....
used for collecting some of the diagonalization schemes available for cp_fm_type. cp_fm_power also mo...
Definition cp_fm_diag.F:17
subroutine, public cp_fm_power(matrix, work, exponent, threshold, n_dependent, verbose, eigvals)
...
subroutine, public choose_eigv_solver(matrix, eigenvectors, eigenvalues, info)
Choose the Eigensolver depending on which library is available ELPA seems to be unstable for small sy...
Definition cp_fm_diag.F:229
represent the structure of a full matrix
subroutine, public cp_fm_struct_create(fmstruct, para_env, context, nrow_global, ncol_global, nrow_block, ncol_block, descriptor, first_p_pos, local_leading_dimension, template_fmstruct, square_blocks, force_block)
allocates and initializes a full matrix structure
subroutine, public cp_fm_struct_release(fmstruct)
releases a full matrix structure
represent a full matrix distributed on many processors
Definition cp_fm_types.F:15
subroutine, public cp_fm_get_info(matrix, name, nrow_global, ncol_global, nrow_block, ncol_block, nrow_local, ncol_local, row_indices, col_indices, local_data, context, nrow_locals, ncol_locals, matrix_struct, para_env)
returns all kind of information about the full matrix
subroutine, public cp_fm_set_all(matrix, alpha, beta)
set all elements of a matrix to the same value, and optionally the diagonal to a different one
subroutine, public cp_fm_create(matrix, matrix_struct, name, use_sp)
creates a new full matrix with the given structure
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Definition gamma.F:15
collects all constants needed in input so that they can be used without circular dependencies
integer, parameter, public bse_singlet
integer, parameter, public bse_triplet
integer, parameter, public bse_screening_alpha
integer, parameter, public bse_screening_rpa
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Interface to the message passing library MPI.
Types needed for MP2 calculations.
Definition mp2_types.F:14
basic linear algebra operations for full matrixes
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
represent a full matrix
stores all the informations relevant to an mpi environment