83#include "./base/base_uses.f90"
89 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'bse_util'
111 SUBROUTINE mult_b_with_w(fm_mat_S_ij_bse, fm_mat_S_ia_bse, fm_mat_S_bar_ia_bse, &
112 fm_mat_S_bar_ij_bse, fm_mat_Q_static_bse_gemm, &
113 dimen_RI, homo, virtual)
115 TYPE(
cp_fm_type),
INTENT(IN) :: fm_mat_s_ij_bse, fm_mat_s_ia_bse
116 TYPE(
cp_fm_type),
INTENT(OUT) :: fm_mat_s_bar_ia_bse, fm_mat_s_bar_ij_bse
117 TYPE(
cp_fm_type),
INTENT(IN) :: fm_mat_q_static_bse_gemm
118 INTEGER,
INTENT(IN) :: dimen_ri, homo, virtual
120 CHARACTER(LEN=*),
PARAMETER :: routinen =
'mult_B_with_W'
122 INTEGER :: handle, i_global, iib, info_chol, &
123 j_global, jjb, ncol_local, nrow_local
124 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
127 CALL timeset(routinen, handle)
129 CALL cp_fm_create(fm_mat_s_bar_ia_bse, fm_mat_s_ia_bse%matrix_struct)
132 CALL cp_fm_create(fm_mat_s_bar_ij_bse, fm_mat_s_ij_bse%matrix_struct)
135 CALL cp_fm_create(fm_work, fm_mat_q_static_bse_gemm%matrix_struct)
140 nrow_local=nrow_local, &
141 ncol_local=ncol_local, &
142 row_indices=row_indices, &
143 col_indices=col_indices)
145 DO jjb = 1, ncol_local
146 j_global = col_indices(jjb)
147 DO iib = 1, nrow_local
148 i_global = row_indices(iib)
149 IF (j_global == i_global .AND. i_global <= dimen_ri)
THEN
150 fm_mat_q_static_bse_gemm%local_data(iib, jjb) = fm_mat_q_static_bse_gemm%local_data(iib, jjb) + 1.0_dp
158 IF (info_chol /= 0)
THEN
159 CALL cp_abort(__location__,
'Cholesky decomposition failed for static polarization in BSE')
168 CALL parallel_gemm(transa=
"N", transb=
"N", m=dimen_ri, n=homo**2, k=dimen_ri, alpha=1.0_dp, &
169 matrix_a=fm_mat_q_static_bse_gemm, matrix_b=fm_mat_s_ij_bse, beta=0.0_dp, &
170 matrix_c=fm_mat_s_bar_ij_bse)
174 CALL parallel_gemm(transa=
"N", transb=
"N", m=dimen_ri, n=homo*virtual, k=dimen_ri, alpha=1.0_dp, &
175 matrix_a=fm_mat_q_static_bse_gemm, matrix_b=fm_mat_s_ia_bse, beta=0.0_dp, &
176 matrix_c=fm_mat_s_bar_ia_bse)
180 CALL timestop(handle)
201 nrow_secidx_out, ncol_secidx_out, unit_nr, reordering, mp2_env, &
202 row_offset, col_offset)
206 REAL(kind=
dp) :: beta
207 INTEGER,
INTENT(IN) :: nrow_secidx_in, ncol_secidx_in, &
208 nrow_secidx_out, ncol_secidx_out
210 INTEGER,
DIMENSION(4) :: reordering
211 TYPE(
mp2_type),
INTENT(IN) :: mp2_env
212 INTEGER,
INTENT(IN),
OPTIONAL :: row_offset, col_offset
214 CHARACTER(LEN=*),
PARAMETER :: routinen =
'fm_general_add_bse'
216 INTEGER :: col_idx_loc, dummy, handle, handle2, i_entry_rec, idx_col_out, idx_row_out, ii, &
217 iproc, jj, my_col_offset, my_row_offset, ncol_block_in, ncol_block_out, ncol_local_in, &
218 ncol_local_out, nprocs, nrow_block_in, nrow_block_out, nrow_local_in, nrow_local_out, &
219 proc_send, row_idx_loc, send_pcol, send_prow
220 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: entry_counter, num_entries_rec, &
222 INTEGER,
DIMENSION(4) :: indices_in
223 INTEGER,
DIMENSION(:),
POINTER :: col_indices_in, col_indices_out, &
224 row_indices_in, row_indices_out
226 DIMENSION(:) :: buffer_rec, buffer_send
235 IF (
PRESENT(row_offset)) my_row_offset = row_offset
236 IF (
PRESENT(col_offset)) my_col_offset = col_offset
238 CALL timeset(routinen, handle)
239 CALL timeset(routinen//
"_1_setup", handle2)
241 para_env_out => fm_out%matrix_struct%para_env
245 nrow_local=nrow_local_out, &
246 ncol_local=ncol_local_out, &
247 row_indices=row_indices_out, &
248 col_indices=col_indices_out, &
249 nrow_block=nrow_block_out, &
250 ncol_block=ncol_block_out)
252 ALLOCATE (num_entries_rec(0:para_env_out%num_pe - 1))
253 ALLOCATE (num_entries_send(0:para_env_out%num_pe - 1))
255 num_entries_rec(:) = 0
256 num_entries_send(:) = 0
261 nrow_local=nrow_local_in, &
262 ncol_local=ncol_local_in, &
263 row_indices=row_indices_in, &
264 col_indices=col_indices_in, &
265 nrow_block=nrow_block_in, &
266 ncol_block=ncol_block_in)
268 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
269 WRITE (unit_nr,
'(T2,A10,T13,A14,A10,T71,I10)')
'BSE|DEBUG|',
'Row number of ', fm_out%name, &
270 fm_out%matrix_struct%nrow_global
271 WRITE (unit_nr,
'(T2,A10,T13,A17,A10,T71,I10)')
'BSE|DEBUG|',
'Column number of ', fm_out%name, &
272 fm_out%matrix_struct%ncol_global
274 WRITE (unit_nr,
'(T2,A10,T13,A18,A10,T71,I10)')
'BSE|DEBUG|',
'Row block size of ', fm_out%name, nrow_block_out
275 WRITE (unit_nr,
'(T2,A10,T13,A21,A10,T71,I10)')
'BSE|DEBUG|',
'Column block size of ', fm_out%name, ncol_block_out
277 WRITE (unit_nr,
'(T2,A10,T13,A14,A10,T71,I10)')
'BSE|DEBUG|',
'Row number of ', fm_in%name, &
278 fm_in%matrix_struct%nrow_global
279 WRITE (unit_nr,
'(T2,A10,T13,A17,A10,T71,I10)')
'BSE|DEBUG|',
'Column number of ', fm_in%name, &
280 fm_in%matrix_struct%ncol_global
282 WRITE (unit_nr,
'(T2,A10,T13,A18,A10,T71,I10)')
'BSE|DEBUG|',
'Row block size of ', fm_in%name, nrow_block_in
283 WRITE (unit_nr,
'(T2,A10,T13,A21,A10,T71,I10)')
'BSE|DEBUG|',
'Column block size of ', fm_in%name, ncol_block_in
289 DO row_idx_loc = 1, nrow_local_in
290 indices_in(1) = (row_indices_in(row_idx_loc) - 1)/nrow_secidx_in + 1
291 indices_in(2) = mod(row_indices_in(row_idx_loc) - 1, nrow_secidx_in) + 1
292 DO col_idx_loc = 1, ncol_local_in
293 indices_in(3) = (col_indices_in(col_idx_loc) - 1)/ncol_secidx_in + 1
294 indices_in(4) = mod(col_indices_in(col_idx_loc) - 1, ncol_secidx_in) + 1
296 idx_row_out = my_row_offset + indices_in(reordering(2)) + (indices_in(reordering(1)) - 1)*nrow_secidx_out
297 idx_col_out = my_col_offset + indices_in(reordering(4)) + (indices_in(reordering(3)) - 1)*ncol_secidx_out
299 send_prow = fm_out%matrix_struct%g2p_row(idx_row_out)
300 send_pcol = fm_out%matrix_struct%g2p_col(idx_col_out)
302 proc_send = fm_out%matrix_struct%context%blacs2mpi(send_prow, send_pcol)
304 num_entries_send(proc_send) = num_entries_send(proc_send) + 1
309 CALL timestop(handle2)
311 CALL timeset(routinen//
"_2_comm_entry_nums", handle2)
312 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
313 WRITE (unit_nr,
'(T2,A10,T13,A27)')
'BSE|DEBUG|',
'Communicating entry numbers'
316 CALL para_env_out%alltoall(num_entries_send, num_entries_rec, 1)
318 CALL timestop(handle2)
320 CALL timeset(routinen//
"_3_alloc_buffer", handle2)
321 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
322 WRITE (unit_nr,
'(T2,A10,T13,A18)')
'BSE|DEBUG|',
'Allocating buffers'
326 ALLOCATE (buffer_rec(0:para_env_out%num_pe - 1))
327 ALLOCATE (buffer_send(0:para_env_out%num_pe - 1))
330 DO iproc = 0, para_env_out%num_pe - 1
332 ALLOCATE (buffer_rec(iproc)%msg(num_entries_rec(iproc)))
333 buffer_rec(iproc)%msg = 0.0_dp
337 DO iproc = 0, para_env_out%num_pe - 1
339 ALLOCATE (buffer_send(iproc)%msg(num_entries_send(iproc)))
340 buffer_send(iproc)%msg = 0.0_dp
344 DO iproc = 0, para_env_out%num_pe - 1
346 ALLOCATE (buffer_rec(iproc)%indx(num_entries_rec(iproc), 2))
347 buffer_rec(iproc)%indx = 0
351 DO iproc = 0, para_env_out%num_pe - 1
353 ALLOCATE (buffer_send(iproc)%indx(num_entries_send(iproc), 2))
354 buffer_send(iproc)%indx = 0
358 CALL timestop(handle2)
360 CALL timeset(routinen//
"_4_buf_from_fmin_"//fm_out%name, handle2)
361 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
362 WRITE (unit_nr,
'(T2,A10,T13,A18,A10,A13)')
'BSE|DEBUG|',
'Writing data from ', fm_in%name,
' into buffers'
365 ALLOCATE (entry_counter(0:para_env_out%num_pe - 1))
369 DO row_idx_loc = 1, nrow_local_in
370 indices_in(1) = (row_indices_in(row_idx_loc) - 1)/nrow_secidx_in + 1
371 indices_in(2) = mod(row_indices_in(row_idx_loc) - 1, nrow_secidx_in) + 1
372 DO col_idx_loc = 1, ncol_local_in
373 indices_in(3) = (col_indices_in(col_idx_loc) - 1)/ncol_secidx_in + 1
374 indices_in(4) = mod(col_indices_in(col_idx_loc) - 1, ncol_secidx_in) + 1
376 idx_row_out = my_row_offset + indices_in(reordering(2)) + (indices_in(reordering(1)) - 1)*nrow_secidx_out
377 idx_col_out = my_col_offset + indices_in(reordering(4)) + (indices_in(reordering(3)) - 1)*ncol_secidx_out
379 send_prow = fm_out%matrix_struct%g2p_row(idx_row_out)
380 send_pcol = fm_out%matrix_struct%g2p_col(idx_col_out)
382 proc_send = fm_out%matrix_struct%context%blacs2mpi(send_prow, send_pcol)
383 entry_counter(proc_send) = entry_counter(proc_send) + 1
385 buffer_send(proc_send)%msg(entry_counter(proc_send)) = &
386 fm_in%local_data(row_idx_loc, col_idx_loc)
388 buffer_send(proc_send)%indx(entry_counter(proc_send), 1) = idx_row_out
389 buffer_send(proc_send)%indx(entry_counter(proc_send), 2) = idx_col_out
394 ALLOCATE (req_array(1:para_env_out%num_pe, 4))
396 CALL timestop(handle2)
398 CALL timeset(routinen//
"_5_comm_buffer", handle2)
399 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
400 WRITE (unit_nr,
'(T2,A10,T13,A21)')
'BSE|DEBUG|',
'Communicating buffers'
404 CALL communicate_buffer(para_env_out, num_entries_rec, num_entries_send, buffer_rec, &
405 buffer_send, req_array)
407 CALL timestop(handle2)
409 CALL timeset(routinen//
"_6_buffer_to_fmout"//fm_out%name, handle2)
410 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
411 WRITE (unit_nr,
'(T2,A10,T13,A24,A10)')
'BSE|DEBUG|',
'Writing from buffers to ', fm_out%name
415 nprocs = para_env_out%num_pe
420 DO iproc = 0, nprocs - 1
421 DO i_entry_rec = 1, num_entries_rec(iproc)
422 ii = fm_out%matrix_struct%g2l_row(buffer_rec(iproc)%indx(i_entry_rec, 1))
423 jj = fm_out%matrix_struct%g2l_col(buffer_rec(iproc)%indx(i_entry_rec, 2))
425 fm_out%local_data(ii, jj) = fm_out%local_data(ii, jj) + beta*buffer_rec(iproc)%msg(i_entry_rec)
430 CALL timestop(handle2)
432 CALL timeset(routinen//
"_7_cleanup", handle2)
433 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
434 WRITE (unit_nr,
'(T2,A10,T13,A41)')
'BSE|DEBUG|',
'Starting cleanup of communication buffers'
438 DO iproc = 0, para_env_out%num_pe - 1
439 DEALLOCATE (buffer_rec(iproc)%msg)
440 DEALLOCATE (buffer_rec(iproc)%indx)
441 DEALLOCATE (buffer_send(iproc)%msg)
442 DEALLOCATE (buffer_send(iproc)%indx)
444 DEALLOCATE (buffer_rec, buffer_send)
445 DEALLOCATE (req_array)
446 DEALLOCATE (entry_counter)
447 DEALLOCATE (num_entries_rec, num_entries_send)
449 CALL timestop(handle2)
450 CALL timestop(handle)
470 nrow_out, ncol_out, unit_nr, mp2_env, &
471 nrow_offset, ncol_offset)
475 INTEGER :: ncol_in, nrow_out, ncol_out, unit_nr
476 TYPE(
mp2_type),
INTENT(INOUT) :: mp2_env
477 INTEGER,
INTENT(IN),
OPTIONAL :: nrow_offset, ncol_offset
479 CHARACTER(LEN=*),
PARAMETER :: routinen =
'truncate_fm'
481 INTEGER :: col_idx_loc, dummy, handle, handle2, i_entry_rec, idx_col_first, idx_col_in, &
482 idx_col_out, idx_col_sec, idx_row_in, ii, iproc, jj, ncol_block_in, ncol_block_out, &
483 ncol_local_in, ncol_local_out, nprocs, nrow_block_in, nrow_block_out, nrow_local_in, &
484 nrow_local_out, proc_send, row_idx_loc, send_pcol, send_prow
485 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: entry_counter, num_entries_rec, &
487 INTEGER,
DIMENSION(:),
POINTER :: col_indices_in, col_indices_out, &
488 row_indices_in, row_indices_out
489 LOGICAL :: correct_ncol, correct_nrow
491 DIMENSION(:) :: buffer_rec, buffer_send
495 CALL timeset(routinen, handle)
496 CALL timeset(routinen//
"_1_setup", handle2)
498 correct_nrow = .false.
499 correct_ncol = .false.
501 IF (
PRESENT(nrow_offset))
THEN
502 correct_nrow = .true.
504 IF (
PRESENT(ncol_offset))
THEN
505 correct_ncol = .true.
508 para_env_out => fm_out%matrix_struct%para_env
511 nrow_local=nrow_local_out, &
512 ncol_local=ncol_local_out, &
513 row_indices=row_indices_out, &
514 col_indices=col_indices_out, &
515 nrow_block=nrow_block_out, &
516 ncol_block=ncol_block_out)
518 ALLOCATE (num_entries_rec(0:para_env_out%num_pe - 1))
519 ALLOCATE (num_entries_send(0:para_env_out%num_pe - 1))
521 num_entries_rec(:) = 0
522 num_entries_send(:) = 0
527 nrow_local=nrow_local_in, &
528 ncol_local=ncol_local_in, &
529 row_indices=row_indices_in, &
530 col_indices=col_indices_in, &
531 nrow_block=nrow_block_in, &
532 ncol_block=ncol_block_in)
534 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
535 WRITE (unit_nr,
'(T2,A10,T13,A14,A10,T71,I10)')
'BSE|DEBUG|',
'Row number of ', fm_out%name, &
536 fm_out%matrix_struct%nrow_global
537 WRITE (unit_nr,
'(T2,A10,T13,A17,A10,T71,I10)')
'BSE|DEBUG|',
'Column number of ', fm_out%name, &
538 fm_out%matrix_struct%ncol_global
540 WRITE (unit_nr,
'(T2,A10,T13,A18,A10,T71,I10)')
'BSE|DEBUG|',
'Row block size of ', fm_out%name, nrow_block_out
541 WRITE (unit_nr,
'(T2,A10,T13,A21,A10,T71,I10)')
'BSE|DEBUG|',
'Column block size of ', fm_out%name, ncol_block_out
543 WRITE (unit_nr,
'(T2,A10,T13,A14,A10,T71,I10)')
'BSE|DEBUG|',
'Row number of ', fm_in%name, &
544 fm_in%matrix_struct%nrow_global
545 WRITE (unit_nr,
'(T2,A10,T13,A17,A10,T71,I10)')
'BSE|DEBUG|',
'Column number of ', fm_in%name, &
546 fm_in%matrix_struct%ncol_global
548 WRITE (unit_nr,
'(T2,A10,T13,A18,A10,T71,I10)')
'BSE|DEBUG|',
'Row block size of ', fm_in%name, nrow_block_in
549 WRITE (unit_nr,
'(T2,A10,T13,A21,A10,T71,I10)')
'BSE|DEBUG|',
'Column block size of ', fm_in%name, ncol_block_in
553 DO col_idx_loc = 1, ncol_local_in
554 idx_col_in = col_indices_in(col_idx_loc)
556 idx_col_first = (idx_col_in - 1)/ncol_in + 1
557 idx_col_sec = mod(idx_col_in - 1, ncol_in) + 1
561 IF (correct_nrow)
THEN
562 idx_col_first = idx_col_first - nrow_offset + 1
563 IF (idx_col_first <= 0) cycle
565 IF (idx_col_first > nrow_out)
EXIT
567 IF (correct_ncol)
THEN
568 idx_col_sec = idx_col_sec - ncol_offset + 1
569 IF (idx_col_sec <= 0) cycle
571 IF (idx_col_sec > ncol_out) cycle
574 idx_col_out = idx_col_sec + (idx_col_first - 1)*ncol_out
576 DO row_idx_loc = 1, nrow_local_in
577 idx_row_in = row_indices_in(row_idx_loc)
579 send_prow = fm_out%matrix_struct%g2p_row(idx_row_in)
580 send_pcol = fm_out%matrix_struct%g2p_col(idx_col_out)
582 proc_send = fm_out%matrix_struct%context%blacs2mpi(send_prow, send_pcol)
584 num_entries_send(proc_send) = num_entries_send(proc_send) + 1
589 CALL timestop(handle2)
591 CALL timeset(routinen//
"_2_comm_entry_nums", handle2)
592 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
593 WRITE (unit_nr,
'(T2,A10,T13,A27)')
'BSE|DEBUG|',
'Communicating entry numbers'
596 CALL para_env_out%alltoall(num_entries_send, num_entries_rec, 1)
598 CALL timestop(handle2)
600 CALL timeset(routinen//
"_3_alloc_buffer", handle2)
601 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
602 WRITE (unit_nr,
'(T2,A10,T13,A18)')
'BSE|DEBUG|',
'Allocating buffers'
606 ALLOCATE (buffer_rec(0:para_env_out%num_pe - 1))
607 ALLOCATE (buffer_send(0:para_env_out%num_pe - 1))
610 DO iproc = 0, para_env_out%num_pe - 1
612 ALLOCATE (buffer_rec(iproc)%msg(num_entries_rec(iproc)))
613 buffer_rec(iproc)%msg = 0.0_dp
617 DO iproc = 0, para_env_out%num_pe - 1
619 ALLOCATE (buffer_send(iproc)%msg(num_entries_send(iproc)))
620 buffer_send(iproc)%msg = 0.0_dp
624 DO iproc = 0, para_env_out%num_pe - 1
626 ALLOCATE (buffer_rec(iproc)%indx(num_entries_rec(iproc), 2))
627 buffer_rec(iproc)%indx = 0
631 DO iproc = 0, para_env_out%num_pe - 1
633 ALLOCATE (buffer_send(iproc)%indx(num_entries_send(iproc), 2))
634 buffer_send(iproc)%indx = 0
638 CALL timestop(handle2)
640 CALL timeset(routinen//
"_4_buf_from_fmin_"//fm_out%name, handle2)
641 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
642 WRITE (unit_nr,
'(T2,A10,T13,A18,A10,A13)')
'BSE|DEBUG|',
'Writing data from ', fm_in%name,
' into buffers'
645 ALLOCATE (entry_counter(0:para_env_out%num_pe - 1))
649 DO col_idx_loc = 1, ncol_local_in
650 idx_col_in = col_indices_in(col_idx_loc)
652 idx_col_first = (idx_col_in - 1)/ncol_in + 1
653 idx_col_sec = mod(idx_col_in - 1, ncol_in) + 1
657 IF (correct_nrow)
THEN
658 idx_col_first = idx_col_first - nrow_offset + 1
659 IF (idx_col_first <= 0) cycle
661 IF (idx_col_first > nrow_out)
EXIT
663 IF (correct_ncol)
THEN
664 idx_col_sec = idx_col_sec - ncol_offset + 1
665 IF (idx_col_sec <= 0) cycle
667 IF (idx_col_sec > ncol_out) cycle
670 idx_col_out = idx_col_sec + (idx_col_first - 1)*ncol_out
672 DO row_idx_loc = 1, nrow_local_in
673 idx_row_in = row_indices_in(row_idx_loc)
675 send_prow = fm_out%matrix_struct%g2p_row(idx_row_in)
677 send_pcol = fm_out%matrix_struct%g2p_col(idx_col_out)
679 proc_send = fm_out%matrix_struct%context%blacs2mpi(send_prow, send_pcol)
680 entry_counter(proc_send) = entry_counter(proc_send) + 1
682 buffer_send(proc_send)%msg(entry_counter(proc_send)) = &
683 fm_in%local_data(row_idx_loc, col_idx_loc)
686 buffer_send(proc_send)%indx(entry_counter(proc_send), 1) = idx_row_in
687 buffer_send(proc_send)%indx(entry_counter(proc_send), 2) = idx_col_out
692 ALLOCATE (req_array(1:para_env_out%num_pe, 4))
694 CALL timestop(handle2)
696 CALL timeset(routinen//
"_5_comm_buffer", handle2)
697 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
698 WRITE (unit_nr,
'(T2,A10,T13,A21)')
'BSE|DEBUG|',
'Communicating buffers'
702 CALL communicate_buffer(para_env_out, num_entries_rec, num_entries_send, buffer_rec, &
703 buffer_send, req_array)
705 CALL timestop(handle2)
707 CALL timeset(routinen//
"_6_buffer_to_fmout"//fm_out%name, handle2)
708 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
709 WRITE (unit_nr,
'(T2,A10,T13,A24,A10)')
'BSE|DEBUG|',
'Writing from buffers to ', fm_out%name
713 nprocs = para_env_out%num_pe
718 DO iproc = 0, nprocs - 1
719 DO i_entry_rec = 1, num_entries_rec(iproc)
720 ii = fm_out%matrix_struct%g2l_row(buffer_rec(iproc)%indx(i_entry_rec, 1))
721 jj = fm_out%matrix_struct%g2l_col(buffer_rec(iproc)%indx(i_entry_rec, 2))
723 fm_out%local_data(ii, jj) = fm_out%local_data(ii, jj) + buffer_rec(iproc)%msg(i_entry_rec)
728 CALL timestop(handle2)
730 CALL timeset(routinen//
"_7_cleanup", handle2)
731 IF (unit_nr > 0 .AND. mp2_env%bse%bse_debug_print)
THEN
732 WRITE (unit_nr,
'(T2,A10,T13,A41)')
'BSE|DEBUG|',
'Starting cleanup of communication buffers'
736 DO iproc = 0, para_env_out%num_pe - 1
737 DEALLOCATE (buffer_rec(iproc)%msg)
738 DEALLOCATE (buffer_rec(iproc)%indx)
739 DEALLOCATE (buffer_send(iproc)%msg)
740 DEALLOCATE (buffer_send(iproc)%indx)
742 DEALLOCATE (buffer_rec, buffer_send)
743 DEALLOCATE (req_array)
744 DEALLOCATE (entry_counter)
745 DEALLOCATE (num_entries_rec, num_entries_send)
747 CALL timestop(handle2)
748 CALL timestop(handle)
763 fm_mat_S_trunc, fm_mat_S_ij_trunc, fm_mat_S_ab_trunc, &
764 fm_mat_Q_static_bse_gemm, mp2_env)
766 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_mat_s_bar_ia_bse, fm_mat_s_bar_ij_bse, fm_mat_s_trunc, &
767 fm_mat_s_ij_trunc, fm_mat_s_ab_trunc, fm_mat_q_static_bse_gemm
770 CHARACTER(LEN=*),
PARAMETER :: routinen =
'deallocate_matrices_bse'
774 CALL timeset(routinen, handle)
782 IF (mp2_env%bse%do_nto_analysis)
THEN
783 DEALLOCATE (mp2_env%bse%bse_nto_state_list_final)
786 CALL timestop(handle)
802 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:), &
803 INTENT(IN) :: eig_vals
804 REAL(kind=
dp),
INTENT(IN) :: beta
805 REAL(kind=
dp),
INTENT(IN),
OPTIONAL ::
gamma
806 LOGICAL,
INTENT(IN),
OPTIONAL :: do_transpose
808 CHARACTER(LEN=*),
PARAMETER :: routinen =
'comp_eigvec_coeff_BSE'
810 INTEGER :: handle, i_row_global, ii, j_col_global, &
811 jj, ncol_local, nrow_local
812 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
813 LOGICAL :: my_do_transpose
814 REAL(kind=
dp) :: coeff, my_gamma
816 CALL timeset(routinen, handle)
818 IF (
PRESENT(
gamma))
THEN
824 IF (
PRESENT(do_transpose))
THEN
825 my_do_transpose = do_transpose
827 my_do_transpose = .false.
831 nrow_local=nrow_local, &
832 ncol_local=ncol_local, &
833 row_indices=row_indices, &
834 col_indices=col_indices)
836 IF (my_do_transpose)
THEN
837 DO jj = 1, ncol_local
838 j_col_global = col_indices(jj)
839 DO ii = 1, nrow_local
840 coeff = (eig_vals(j_col_global)**beta)/my_gamma
841 fm_work%local_data(ii, jj) = fm_work%local_data(ii, jj)*coeff
845 DO jj = 1, ncol_local
846 DO ii = 1, nrow_local
847 i_row_global = row_indices(ii)
848 coeff = (eig_vals(i_row_global)**beta)/my_gamma
849 fm_work%local_data(ii, jj) = fm_work%local_data(ii, jj)*coeff
854 CALL timestop(handle)
868 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: idx_prim, idx_sec
869 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigvec_entries
870 INTEGER,
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: idx_spin
872 CHARACTER(LEN=*),
PARAMETER :: routinen =
'sort_excitations'
874 INTEGER :: handle, ii, kk, num_entries, num_mults
875 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: idx_prim_work, idx_sec_work, &
876 idx_spin_work, tmp_index
877 LOGICAL :: unique_entries
878 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigvec_entries_work
880 CALL timeset(routinen, handle)
882 num_entries =
SIZE(idx_prim)
884 ALLOCATE (tmp_index(num_entries))
886 CALL sort(idx_prim, num_entries, tmp_index)
888 ALLOCATE (idx_sec_work(num_entries))
889 ALLOCATE (eigvec_entries_work(num_entries))
890 IF (
PRESENT(idx_spin))
ALLOCATE (idx_spin_work(num_entries))
892 DO ii = 1, num_entries
893 idx_sec_work(ii) = idx_sec(tmp_index(ii))
894 eigvec_entries_work(ii) = eigvec_entries(tmp_index(ii))
895 IF (
PRESENT(idx_spin)) idx_spin_work(ii) = idx_spin(tmp_index(ii))
898 DEALLOCATE (tmp_index)
900 DEALLOCATE (eigvec_entries)
902 CALL move_alloc(idx_sec_work, idx_sec)
903 CALL move_alloc(eigvec_entries_work, eigvec_entries)
904 IF (
PRESENT(idx_spin))
THEN
905 DEALLOCATE (idx_spin)
906 CALL move_alloc(idx_spin_work, idx_spin)
911 IF (.NOT. unique_entries)
THEN
912 ALLOCATE (idx_prim_work(num_entries))
913 idx_prim_work(:) = idx_prim(:)
915 DO ii = 1, num_entries
916 IF (idx_prim_work(ii) == 0) cycle
917 num_mults = count(idx_prim_work == idx_prim_work(ii))
918 IF (num_mults > 1)
THEN
920 idx_prim_work(ii:ii + num_mults - 1) = 0
922 ALLOCATE (idx_sec_work(num_mults))
923 ALLOCATE (eigvec_entries_work(num_mults))
924 idx_sec_work(:) = idx_sec(ii:ii + num_mults - 1)
925 eigvec_entries_work(:) = eigvec_entries(ii:ii + num_mults - 1)
926 IF (
PRESENT(idx_spin))
THEN
927 ALLOCATE (idx_spin_work(num_mults))
928 idx_spin_work(:) = idx_spin(ii:ii + num_mults - 1)
930 ALLOCATE (tmp_index(num_mults))
931 CALL sort(idx_sec_work, num_mults, tmp_index)
934 DO kk = ii, ii + num_mults - 1
935 idx_sec(kk) = idx_sec_work(kk - ii + 1)
936 eigvec_entries(kk) = eigvec_entries_work(tmp_index(kk - ii + 1))
937 IF (
PRESENT(idx_spin)) idx_spin(kk) = idx_spin_work(tmp_index(kk - ii + 1))
940 DEALLOCATE (tmp_index)
941 DEALLOCATE (idx_sec_work)
942 DEALLOCATE (eigvec_entries_work)
943 IF (
PRESENT(idx_spin))
DEALLOCATE (idx_spin_work)
945 idx_prim_work(ii) = idx_prim(ii)
947 DEALLOCATE (idx_prim_work)
950 CALL timestop(handle)
963 para_env, diag_runtime_est)
965 INTEGER,
INTENT(IN) :: n_ov_joint, unit_nr
968 REAL(kind=
dp) :: diag_runtime_est
970 CHARACTER(LEN=*),
PARAMETER :: routinen =
'estimate_BSE_resources'
972 INTEGER :: handle, num_bse_matrices
973 INTEGER(KIND=int_8) :: full_dim
974 REAL(kind=
dp) :: mem_est, mem_est_per_rank
976 CALL timeset(routinen, handle)
983 num_bse_matrices = 10
986 full_dim = int(n_ov_joint, kind=
int_8)**2*int(num_bse_matrices, kind=
int_8)
987 mem_est = real(8*full_dim, kind=
dp)/real(1024**3, kind=
dp)
988 mem_est_per_rank = real(mem_est/para_env%num_pe, kind=
dp)
990 IF (unit_nr > 0)
THEN
993 WRITE (unit_nr,
'(T2,A4,T7,A40,T68,ES13.3)')
'BSE|',
'Total peak memory estimate from BSE [GB]', &
995 WRITE (unit_nr,
'(T2,A4,T7,A47,T68,F13.3)')
'BSE|',
'Peak memory estimate per MPI rank from BSE [GB]', &
997 WRITE (unit_nr,
'(T2,A4)')
'BSE|'
1001 diag_runtime_est = real(int(n_ov_joint, kind=
int_8)/11000_int_8, kind=
dp)**3* &
1002 10*32/real(para_env%num_pe, kind=
dp)
1004 CALL timestop(handle)
1024 i_exc, virtual, num_entries, mp2_env, &
1025 offsets, virtual_per_spin, idx_spin)
1028 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: idx_homo, idx_virt
1029 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigvec_entries
1030 INTEGER :: i_exc, virtual, num_entries
1031 TYPE(
mp2_type),
INTENT(INOUT) :: mp2_env
1032 INTEGER,
DIMENSION(:),
INTENT(IN),
OPTIONAL :: offsets, virtual_per_spin
1033 INTEGER,
ALLOCATABLE,
DIMENSION(:),
OPTIONAL :: idx_spin
1035 CHARACTER(LEN=*),
PARAMETER :: routinen =
'filter_eigvec_contrib'
1037 INTEGER :: eigvec_idx, handle, ii, iproc, isp, jj, &
1038 kk, ksp, ncol_local, nrow_local, &
1039 num_entries_local, r_local, v_local
1040 INTEGER,
ALLOCATABLE,
DIMENSION(:) :: num_entries_to_comm
1041 INTEGER,
DIMENSION(:),
POINTER :: col_indices, row_indices
1042 REAL(kind=
dp) :: eigvec_entry
1044 DIMENSION(:) :: buffer_entries
1047 CALL timeset(routinen, handle)
1049 para_env => fm_eigvec%matrix_struct%para_env
1052 nrow_local=nrow_local, &
1053 ncol_local=ncol_local, &
1054 row_indices=row_indices, &
1055 col_indices=col_indices)
1057 ALLOCATE (num_entries_to_comm(0:para_env%num_pe - 1))
1058 num_entries_to_comm(:) = 0
1060 DO jj = 1, ncol_local
1062 IF (col_indices(jj) /= i_exc)
THEN
1065 DO ii = 1, nrow_local
1066 eigvec_idx = row_indices(ii)
1067 eigvec_entry = fm_eigvec%local_data(ii, jj)
1068 IF (abs(eigvec_entry) > mp2_env%bse%eps_x)
THEN
1069 num_entries_to_comm(para_env%mepos) = num_entries_to_comm(para_env%mepos) + 1
1075 CALL para_env%sum(num_entries_to_comm)
1077 num_entries_local = num_entries_to_comm(para_env%mepos)
1079 ALLOCATE (buffer_entries(0:para_env%num_pe - 1))
1081 DO iproc = 0, para_env%num_pe - 1
1082 ALLOCATE (buffer_entries(iproc)%msg(num_entries_to_comm(iproc)))
1083 ALLOCATE (buffer_entries(iproc)%indx(num_entries_to_comm(iproc), 3))
1084 buffer_entries(iproc)%msg = 0.0_dp
1085 buffer_entries(iproc)%indx = 0
1089 DO jj = 1, ncol_local
1091 IF (col_indices(jj) /= i_exc)
THEN
1094 DO ii = 1, nrow_local
1095 eigvec_idx = row_indices(ii)
1096 eigvec_entry = fm_eigvec%local_data(ii, jj)
1097 IF (abs(eigvec_entry) > mp2_env%bse%eps_x)
THEN
1101 r_local = eigvec_idx
1103 IF (
PRESENT(offsets))
THEN
1104 DO ksp =
SIZE(offsets), 1, -1
1105 IF (eigvec_idx > offsets(ksp))
THEN
1110 r_local = eigvec_idx - offsets(isp)
1111 v_local = virtual_per_spin(isp)
1113 buffer_entries(para_env%mepos)%indx(kk, 1) = (r_local - 1)/v_local + 1
1114 buffer_entries(para_env%mepos)%indx(kk, 2) = mod(r_local - 1, v_local) + 1
1115 buffer_entries(para_env%mepos)%indx(kk, 3) = isp
1116 buffer_entries(para_env%mepos)%msg(kk) = eigvec_entry
1122 DO iproc = 0, para_env%num_pe - 1
1123 CALL para_env%sum(buffer_entries(iproc)%msg)
1124 CALL para_env%sum(buffer_entries(iproc)%indx)
1128 num_entries = sum(num_entries_to_comm)
1129 ALLOCATE (idx_homo(num_entries))
1130 ALLOCATE (idx_virt(num_entries))
1131 ALLOCATE (eigvec_entries(num_entries))
1132 IF (
PRESENT(idx_spin))
ALLOCATE (idx_spin(num_entries))
1135 DO iproc = 0, para_env%num_pe - 1
1136 IF (num_entries_to_comm(iproc) /= 0)
THEN
1137 DO ii = 1, num_entries_to_comm(iproc)
1138 idx_homo(kk) = buffer_entries(iproc)%indx(ii, 1)
1139 idx_virt(kk) = buffer_entries(iproc)%indx(ii, 2)
1140 IF (
PRESENT(idx_spin)) idx_spin(kk) = buffer_entries(iproc)%indx(ii, 3)
1141 eigvec_entries(kk) = buffer_entries(iproc)%msg(ii)
1148 DO iproc = 0, para_env%num_pe - 1
1149 DEALLOCATE (buffer_entries(iproc)%msg)
1150 DEALLOCATE (buffer_entries(iproc)%indx)
1152 DEALLOCATE (buffer_entries)
1153 DEALLOCATE (num_entries_to_comm)
1154 NULLIFY (row_indices)
1155 NULLIFY (col_indices)
1159 IF (
PRESENT(idx_spin))
THEN
1165 CALL timestop(handle)
1184 homo_red, virt_red, &
1185 homo_incl, virt_incl, &
1186 cutoff_occ, cutoff_empty)
1188 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: eigenval
1189 INTEGER,
INTENT(IN) :: homo, virtual
1190 INTEGER,
INTENT(OUT) :: homo_red, virt_red, homo_incl, virt_incl
1191 REAL(kind=
dp),
INTENT(IN) :: cutoff_occ, cutoff_empty
1193 CHARACTER(LEN=*),
PARAMETER :: routinen =
'determine_cutoff_indices'
1195 INTEGER :: handle, i_chk, i_homo, j_virt
1197 CALL timeset(routinen, handle)
1200 IF (cutoff_occ > 0 .OR. cutoff_empty > 0)
THEN
1204 DO i_chk = 2, homo + virtual
1205 IF (eigenval(i_chk) < eigenval(i_chk - 1))
THEN
1206 CALL cp_abort(__location__, &
1207 "determine_cutoff_indices: eigenvalues are not ascending. Take the "// &
1208 "energy cutoff on the DFT axis; the G0W0 axis is not ordered.")
1212 IF (-cutoff_occ < eigenval(1) - eigenval(homo) &
1213 .OR. cutoff_occ < 0)
THEN
1219 IF (eigenval(i_homo) - eigenval(homo) > -cutoff_occ)
THEN
1224 homo_red = homo - homo_incl + 1
1227 IF (cutoff_empty > eigenval(homo + virtual) - eigenval(homo + 1) &
1228 .OR. cutoff_empty < 0)
THEN
1232 virt_incl = homo + 1
1233 DO j_virt = 1, virtual
1234 IF (eigenval(homo + j_virt) - eigenval(homo + 1) > cutoff_empty)
THEN
1235 virt_incl = j_virt - 1
1239 virt_red = virt_incl
1248 CALL timestop(handle)
1262 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo_red, virt_red
1263 INTEGER,
DIMENSION(:),
INTENT(OUT) :: n_ov, offsets
1264 INTEGER,
INTENT(OUT) :: n_ov_joint
1269 DO isp = 1,
SIZE(homo_red)
1270 offsets(isp) = n_ov_joint
1271 n_ov(isp) = homo_red(isp)*virt_red(isp)
1272 n_ov_joint = n_ov_joint + n_ov(isp)
1292 cutoff_occ, cutoff_empty, &
1293 first_active_mo, last_active_mo)
1294 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(IN) :: eigenval_scf
1295 INTEGER,
DIMENSION(:),
INTENT(IN) :: homo, virtual
1296 REAL(kind=
dp),
INTENT(IN) :: cutoff_occ, cutoff_empty
1297 INTEGER,
INTENT(OUT) :: first_active_mo, last_active_mo
1299 CHARACTER(LEN=*),
PARAMETER :: routinen =
'determine_bse_combined_window'
1301 INTEGER :: first_occ_prev, handle, homo_incl, &
1302 homo_red, isp, last_virt_prev, &
1304 LOGICAL :: spins_differ
1306 CALL timeset(routinen, handle)
1308 first_active_mo = huge(0)
1312 spins_differ = .false.
1314 DO isp = 1,
SIZE(homo)
1316 homo_red, virt_red, homo_incl, virt_incl, &
1317 cutoff_occ, cutoff_empty)
1319 IF (homo_incl /= first_occ_prev .OR. homo(isp) + virt_incl /= last_virt_prev)
THEN
1320 spins_differ = .true.
1323 first_occ_prev = homo_incl
1324 last_virt_prev = homo(isp) + virt_incl
1325 first_active_mo = min(first_active_mo, homo_incl)
1326 last_active_mo = max(last_active_mo, homo(isp) + virt_incl)
1329 IF (spins_differ)
THEN
1330 cpwarn(
"BSE: spin-resolved active MO cutoff candidates differ; using combined window.")
1333 CALL timestop(handle)
1360 fm_mat_S_trunc, fm_mat_S_ij_trunc, fm_mat_S_ab_trunc, &
1361 Eigenval_scf, Eigenval, Eigenval_reduced, &
1362 homo, virtual, dimen_RI, unit_nr, &
1364 homo_red, virt_red, &
1366 homo_incl_in, virt_incl_in)
1368 TYPE(
cp_fm_type),
INTENT(IN) :: fm_mat_s_ia_bse, fm_mat_s_ij_bse, &
1370 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_mat_s_trunc, fm_mat_s_ij_trunc, &
1372 REAL(kind=
dp),
DIMENSION(:) :: eigenval_scf, eigenval
1373 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: eigenval_reduced
1374 INTEGER,
INTENT(IN) :: homo, virtual, dimen_ri, unit_nr, &
1376 INTEGER,
INTENT(OUT) :: homo_red, virt_red
1377 TYPE(
mp2_type),
INTENT(INOUT) :: mp2_env
1378 INTEGER,
INTENT(IN),
OPTIONAL :: homo_incl_in, virt_incl_in
1380 CHARACTER(LEN=*),
PARAMETER :: routinen =
'truncate_BSE_matrices'
1382 INTEGER :: handle, homo_incl, virt_incl
1387 CALL timeset(routinen, handle)
1392 IF (
PRESENT(homo_incl_in))
THEN
1393 homo_incl = homo_incl_in
1394 virt_incl = virt_incl_in
1395 homo_red = homo - homo_incl + 1
1396 virt_red = virt_incl
1400 homo_red, virt_red, &
1401 homo_incl, virt_incl, &
1402 mp2_env%bse%bse_cutoff_occ, mp2_env%bse%bse_cutoff_empty)
1404 IF (unit_nr > 0)
THEN
1405 IF (mp2_env%bse%bse_cutoff_occ > 0)
THEN
1406 WRITE (unit_nr,
'(T2,A4,T7,A29,T71,F10.3)')
'BSE|',
'Cutoff occupied orbitals [eV]', &
1407 mp2_env%bse%bse_cutoff_occ*
evolt
1409 WRITE (unit_nr,
'(T2,A4,T7,A37)')
'BSE|',
'No cutoff given for occupied orbitals'
1411 IF (mp2_env%bse%bse_cutoff_empty > 0)
THEN
1412 WRITE (unit_nr,
'(T2,A4,T7,A26,T71,F10.3)')
'BSE|',
'Cutoff empty orbitals [eV]', &
1413 mp2_env%bse%bse_cutoff_empty*
evolt
1415 WRITE (unit_nr,
'(T2,A4,T7,A34)')
'BSE|',
'No cutoff given for empty orbitals'
1417 WRITE (unit_nr,
'(T2,A4,T7,A20,T71,I10)')
'BSE|',
'First occupied index', homo_incl
1418 WRITE (unit_nr,
'(T2,A4,T7,A32,T71,I10)')
'BSE|',
'Last empty index (not MO index!)', virt_incl
1419 WRITE (unit_nr,
'(T2,A4,T7,A35,T71,F10.3)')
'BSE|',
'Energy of first occupied index [eV]', &
1420 eigenval(homo_incl)*
evolt
1421 WRITE (unit_nr,
'(T2,A4,T7,A31,T71,F10.3)')
'BSE|',
'Energy of last empty index [eV]', &
1422 eigenval(homo + virt_incl)*
evolt
1423 WRITE (unit_nr,
'(T2,A4,T7,A54,T71,F10.3)')
'BSE|', &
1424 'Energy difference of first occupied index to HOMO [eV]', &
1425 -(eigenval(homo_incl) - eigenval(homo))*
evolt
1426 WRITE (unit_nr,
'(T2,A4,T7,A50,T71,F10.3)')
'BSE|', &
1427 'Energy difference of last empty index to LUMO [eV]', &
1428 (eigenval(homo + virt_incl) - eigenval(homo + 1))*
evolt
1429 WRITE (unit_nr,
'(T2,A4,T7,A35,T71,I10)')
'BSE|',
'Number of GW-corrected occupied MOs', &
1430 mp2_env%ri_g0w0%corr_mos_occ
1431 WRITE (unit_nr,
'(T2,A4,T7,A32,T71,I10)')
'BSE|',
'Number of GW-corrected empty MOs', &
1433 WRITE (unit_nr,
'(T2,A4)')
'BSE|'
1436 IF (unit_nr > 0)
THEN
1437 IF (homo - homo_incl + 1 > mp2_env%ri_g0w0%corr_mos_occ)
THEN
1438 cpabort(
"Number of GW-corrected occupied MOs too small for chosen BSE cutoff")
1440 IF (virt_incl > bse_lev_virt)
THEN
1441 cpabort(
"Number of GW-corrected virtual MOs too small for chosen BSE cutoff")
1446 para_env => fm_mat_s_ia_bse%matrix_struct%para_env
1447 context => fm_mat_s_ia_bse%matrix_struct%context
1453 CALL cp_fm_create(fm_mat_s_trunc, fm_struct_ia, name=
"fm_S_trunc", set_zero=.true.)
1454 CALL cp_fm_create(fm_mat_s_ij_trunc, fm_struct_ij, name=
"fm_S_ij_trunc", set_zero=.true.)
1455 CALL cp_fm_create(fm_mat_s_ab_trunc, fm_struct_ab, name=
"fm_S_ab_trunc", set_zero=.true.)
1458 IF (mp2_env%bse%bse_cutoff_occ > 0 .OR. mp2_env%bse%bse_cutoff_empty > 0)
THEN
1460 ALLOCATE (eigenval_reduced(homo_red + virt_red))
1462 IF (mp2_env%bse%use_ks_energies)
THEN
1463 eigenval_reduced(:) = eigenval_scf(homo_incl:homo + virt_incl)
1465 eigenval_reduced(:) = eigenval(homo_incl:homo + virt_incl)
1468 CALL truncate_fm(fm_mat_s_trunc, fm_mat_s_ia_bse, virtual, &
1469 homo_red, virt_red, unit_nr, mp2_env, &
1470 nrow_offset=homo_incl)
1471 CALL truncate_fm(fm_mat_s_ij_trunc, fm_mat_s_ij_bse, homo, &
1472 homo_red, homo_red, unit_nr, mp2_env, &
1473 homo_incl, homo_incl)
1474 CALL truncate_fm(fm_mat_s_ab_trunc, fm_mat_s_ab_bse, bse_lev_virt, &
1475 virt_red, virt_red, unit_nr, mp2_env)
1478 IF (unit_nr > 0)
THEN
1479 WRITE (unit_nr,
'(T2,A4,T7,A37)')
'BSE|',
'No truncation of BSE matrices applied'
1480 WRITE (unit_nr,
'(T2,A4)')
'BSE|'
1482 ALLOCATE (eigenval_reduced(homo_red + virt_red))
1484 IF (mp2_env%bse%use_ks_energies)
THEN
1485 eigenval_reduced(:) = eigenval_scf(:)
1487 eigenval_reduced(:) = eigenval(:)
1490 1, 1, 1, 1, context)
1492 1, 1, 1, 1, context)
1494 1, 1, 1, 1, context)
1504 CALL timestop(handle)
1519 SUBROUTINE reshuffle_eigvec(fm_eigvec, fm_eigvec_reshuffled, homo, virtual, n_exc, do_transpose, &
1523 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_eigvec_reshuffled
1524 INTEGER,
INTENT(IN) :: homo, virtual, n_exc
1525 LOGICAL,
INTENT(IN) :: do_transpose
1526 INTEGER,
INTENT(IN) :: unit_nr
1527 TYPE(
mp2_type),
INTENT(INOUT) :: mp2_env
1529 CHARACTER(LEN=*),
PARAMETER :: routinen =
'reshuffle_eigvec'
1531 INTEGER :: handle, my_m_col, my_n_row
1532 INTEGER,
DIMENSION(4) :: reordering
1534 fm_struct_eigvec_reshuffled
1537 CALL timeset(routinen, handle)
1542 IF (do_transpose)
THEN
1543 reordering = [2, 3, 1, 4]
1547 reordering = [1, 3, 2, 4]
1553 fm_eigvec%matrix_struct%para_env, fm_eigvec%matrix_struct%context, &
1556 fm_eigvec%matrix_struct%para_env, fm_eigvec%matrix_struct%context, &
1560 CALL cp_fm_create(fm_eigvec_col, fm_struct_eigvec_col, name=
"BSE_column_vector")
1562 CALL cp_fm_create(fm_eigvec_reshuffled, fm_struct_eigvec_reshuffled, name=
"BSE_reshuffled_eigenvector")
1573 unit_nr, reordering, mp2_env)
1579 CALL timestop(handle)
1594 stride, append_cube, print_section)
1597 TYPE(
mo_set_type),
DIMENSION(:),
INTENT(IN) :: mos
1598 INTEGER,
INTENT(IN) :: istate
1599 CHARACTER(LEN=10) :: info_approximation
1600 INTEGER,
DIMENSION(:),
POINTER :: stride
1601 LOGICAL,
INTENT(IN) :: append_cube
1604 CHARACTER(LEN=*),
PARAMETER :: routinen =
'print_bse_nto_cubes'
1606 CHARACTER(LEN=default_path_length) :: filename, info_approx_trunc, &
1608 INTEGER :: handle, i, iset, nmo, unit_nr_cube
1622 TYPE(
qs_kind_type),
DIMENSION(:),
POINTER :: qs_kind_set
1626 CALL timeset(routinen, handle)
1628 CALL get_qs_env(qs_env=qs_env, dft_control=dft_control, pw_env=pw_env)
1629 CALL pw_env_get(pw_env, auxbas_pw_pool=auxbas_pw_pool, pw_pools=pw_pools)
1630 CALL auxbas_pw_pool%create_pw(wf_r)
1631 CALL auxbas_pw_pool%create_pw(wf_g)
1636 my_pos_cube =
"REWIND"
1637 IF (append_cube)
THEN
1638 my_pos_cube =
"APPEND"
1642 atomic_kind_set=atomic_kind_set, &
1643 qs_kind_set=qs_kind_set, &
1645 particle_set=particle_set)
1648 CALL get_mo_set(mo_set=mos(iset), mo_coeff=mo_coeff, nmo=nmo)
1651 cell, dft_control, particle_set, pw_env)
1653 WRITE (filename,
'(A6,I3.3,A5,I2.2,a11)')
"_NEXC_", istate,
"_NTO_", i,
"_Hole_State"
1654 ELSE IF (iset == 2)
THEN
1655 WRITE (filename,
'(A6,I3.3,A5,I2.2,a15)')
"_NEXC_", istate,
"_NTO_", i,
"_Particle_State"
1657 info_approx_trunc = trim(adjustl(info_approximation))
1658 info_approx_trunc = info_approx_trunc(2:len_trim(info_approx_trunc) - 1)
1659 filename = trim(info_approx_trunc)//trim(filename)
1662 middle_name=trim(filename), file_position=my_pos_cube, &
1663 log_filename=.false., ignore_should_output=.true., mpi_io=mpi_io)
1665 WRITE (title, *)
"Natural Transition Orbital Hole State", i
1666 ELSE IF (iset == 2)
THEN
1667 WRITE (title, *)
"Natural Transition Orbital Particle State", i
1669 CALL cp_pw_to_cube(wf_r, unit_nr_cube, title, particles=particles, stride=stride, mpi_io=mpi_io)
1671 ignore_should_output=.true., mpi_io=mpi_io)
1675 CALL auxbas_pw_pool%give_back_pw(wf_g)
1676 CALL auxbas_pw_pool%give_back_pw(wf_r)
1678 CALL timestop(handle)
1691 INTEGER,
INTENT(IN) :: homo, virtual, unit_nr
1695 CHARACTER(LEN=*),
PARAMETER :: routinen =
'adapt_BSE_input_params'
1697 INTEGER :: handle, i, j, n, ndim_periodic_cell, &
1698 ndim_periodic_poisson, &
1699 num_state_list_exceptions
1704 CALL timeset(routinen, handle)
1706 NULLIFY (pw_env, cell_ref, poisson_env)
1707 CALL get_qs_env(qs_env, pw_env=pw_env, cell_ref=cell_ref)
1708 CALL pw_env_get(pw_env, poisson_env=poisson_env)
1709 ndim_periodic_poisson = count(poisson_env%parameters%periodic == 1)
1710 ndim_periodic_cell = sum(cell_ref%perd(1:3))
1713 IF (mp2_env%bse%num_print_exc < 0 .OR. &
1714 mp2_env%bse%num_print_exc > homo*virtual)
THEN
1715 mp2_env%bse%num_print_exc = homo*virtual
1716 IF (unit_nr > 0)
THEN
1717 CALL cp_hint(__location__, &
1718 "Keyword NUM_PRINT_EXC is either negative or too large. "// &
1719 "Printing all computed excitations.")
1729 IF (mp2_env%bse%do_nto_analysis)
THEN
1730 IF (mp2_env%bse%explicit_nto_list)
THEN
1731 IF (mp2_env%bse%num_print_exc_ntos > 0)
THEN
1732 IF (unit_nr > 0)
THEN
1733 CALL cp_hint(__location__, &
1734 "Keywords NUM_PRINT_EXC_NTOS and STATE_LIST are both given in input. "// &
1735 "Overriding NUM_PRINT_EXC_NTOS.")
1740 num_state_list_exceptions = 0
1741 DO i = 1,
SIZE(mp2_env%bse%bse_nto_state_list)
1742 IF (mp2_env%bse%bse_nto_state_list(i) < 1 .OR. &
1743 mp2_env%bse%bse_nto_state_list(i) > mp2_env%bse%num_print_exc)
THEN
1744 num_state_list_exceptions = num_state_list_exceptions + 1
1747 IF (num_state_list_exceptions > 0)
THEN
1748 IF (unit_nr > 0)
THEN
1749 CALL cp_hint(__location__, &
1750 "STATE_LIST contains indices outside the range of included excitation levels. "// &
1751 "Ignoring these states.")
1754 n =
SIZE(mp2_env%bse%bse_nto_state_list) - num_state_list_exceptions
1755 ALLOCATE (mp2_env%bse%bse_nto_state_list_final(n))
1756 mp2_env%bse%bse_nto_state_list_final(:) = 0
1758 DO j = 1,
SIZE(mp2_env%bse%bse_nto_state_list)
1759 IF (mp2_env%bse%bse_nto_state_list(j) >= 1 .AND. &
1760 mp2_env%bse%bse_nto_state_list(j) <= mp2_env%bse%num_print_exc)
THEN
1761 mp2_env%bse%bse_nto_state_list_final(i) = mp2_env%bse%bse_nto_state_list(j)
1766 mp2_env%bse%num_print_exc_ntos =
SIZE(mp2_env%bse%bse_nto_state_list_final)
1768 IF (mp2_env%bse%num_print_exc_ntos > mp2_env%bse%num_print_exc .OR. &
1769 mp2_env%bse%num_print_exc_ntos < 0)
THEN
1770 mp2_env%bse%num_print_exc_ntos = mp2_env%bse%num_print_exc
1772 ALLOCATE (mp2_env%bse%bse_nto_state_list_final(mp2_env%bse%num_print_exc_ntos))
1773 DO i = 1, mp2_env%bse%num_print_exc_ntos
1774 mp2_env%bse%bse_nto_state_list_final(i) = i
1780 IF (mp2_env%bse%bse_spin_config /= 0 .AND. &
1781 mp2_env%bse%eps_nto_osc_str > 0)
THEN
1782 IF (unit_nr > 0)
THEN
1783 CALL cp_warn(__location__, &
1784 "Cannot apply EPS_OSC_STR for Triplet excitations. "// &
1785 "Resetting EPS_OSC_STR to default.")
1787 mp2_env%bse%eps_nto_osc_str = -1.0_dp
1791 IF (mp2_env%bse%num_print_exc_descr < 0 .OR. &
1792 mp2_env%bse%num_print_exc_descr > mp2_env%bse%num_print_exc)
THEN
1793 IF (unit_nr > 0)
THEN
1794 CALL cp_hint(__location__, &
1795 "Keyword NUM_PRINT_EXC_DESCR is either negative or too large. "// &
1796 "Printing exciton descriptors up to NUM_PRINT_EXC.")
1798 mp2_env%bse%num_print_exc_descr = mp2_env%bse%num_print_exc
1802 IF (mp2_env%BSE%screening_factor > 0.0_dp)
THEN
1804 IF (unit_nr > 0)
THEN
1805 CALL cp_warn(__location__, &
1806 "Screening factor is only supported for &SCREENING_IN_W ALPHA. "// &
1807 "Resetting SCREENING_IN_W to ALPHA.")
1811 IF (mp2_env%BSE%screening_factor > 1.0_dp)
THEN
1812 IF (unit_nr > 0)
THEN
1813 CALL cp_warn(__location__, &
1814 "Screening factor is larger than 1.0. ")
1819 IF (mp2_env%BSE%screening_factor < 0.0_dp .AND. &
1821 IF (unit_nr > 0)
THEN
1822 CALL cp_warn(__location__, &
1823 "Screening factor is negative. Defaulting to 0.25")
1825 mp2_env%BSE%screening_factor = 0.25_dp
1828 IF (mp2_env%BSE%screening_factor == 0.0_dp)
THEN
1832 IF (mp2_env%BSE%screening_factor == 1.0_dp)
THEN
1838 IF (mp2_env%bse%use_ks_energies)
THEN
1839 IF (unit_nr > 0)
THEN
1840 CALL cp_warn(__location__, &
1841 "Using KS energies for BSE calculations. Therefore, no quantities "// &
1842 "of the preceeding GW calculation enter the BSE.")
1847 IF (ndim_periodic_poisson /= 0)
THEN
1848 IF (unit_nr > 0)
THEN
1849 CALL cp_warn(__location__, &
1850 "Poisson solver should be invoked by PERIODIC NONE. "// &
1851 "The applied length gauge might give misleading results for "// &
1852 "oscillator strengths.")
1855 IF (ndim_periodic_cell /= 0)
THEN
1856 IF (unit_nr > 0)
THEN
1857 CALL cp_warn(__location__, &
1858 "CELL in SUBSYS should be invoked with PERIODIC NONE. "// &
1859 "The applied length gauge might give misleading results for "// &
1860 "oscillator strengths.")
1864 CALL timestop(handle)
1884 qs_env, mo_coeff, rpoint, n_moments, &
1885 homo_red, virtual_red, context_BSE, ispin)
1887 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:), &
1888 INTENT(INOUT) :: fm_multipole_ai_trunc, &
1889 fm_multipole_ij_trunc, &
1890 fm_multipole_ab_trunc
1892 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: mo_coeff
1893 REAL(
dp),
ALLOCATABLE,
DIMENSION(:),
INTENT(INOUT) :: rpoint
1894 INTEGER,
INTENT(IN) :: n_moments, homo_red, virtual_red
1896 INTEGER,
INTENT(IN),
OPTIONAL :: ispin
1898 CHARACTER(LEN=*),
PARAMETER :: routinen =
'get_multipoles_mo'
1900 INTEGER :: handle, idir, my_ispin, n_multipole, &
1901 n_occ, n_virt, nao, nmo_mp2
1902 REAL(kind=
dp),
DIMENSION(:),
POINTER :: ref_point
1903 TYPE(
cp_fm_struct_type),
POINTER :: fm_struct_mp_ab_trunc, fm_struct_mp_ai_trunc, &
1904 fm_struct_mp_ij_trunc, fm_struct_multipoles_ao, fm_struct_nao_nmo, fm_struct_nmo_nmo
1906 TYPE(
cp_fm_type),
ALLOCATABLE,
DIMENSION(:) :: fm_multipole_per_dir
1907 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: matrix_multipole, matrix_s
1913 CALL timeset(routinen, handle)
1916 IF (
PRESENT(ispin)) my_ispin = ispin
1919 NULLIFY (sab_orb, matrix_s)
1922 matrix_s=matrix_s, &
1926 fm_struct_multipoles_ao => mos(my_ispin)%mo_coeff%matrix_struct
1928 para_env_bse => context_bse%para_env
1930 n_multipole = (6 + 11*n_moments + 6*n_moments**2 + n_moments**3)/6 - 1
1931 NULLIFY (matrix_multipole)
1933 ALLOCATE (fm_multipole_per_dir(n_multipole))
1934 DO idir = 1, n_multipole
1936 CALL dbcsr_create(matrix_multipole(idir)%matrix, name=
"ao_multipole", &
1937 template=matrix_s(1)%matrix, matrix_type=dbcsr_type_symmetric)
1939 CALL dbcsr_set(matrix_multipole(idir)%matrix, 0._dp)
1952 CALL get_mo_set(mo_set=mos(my_ispin), homo=n_occ, nao=nao)
1954 nmo_mp2 = mo_coeff(1)%matrix_struct%ncol_global
1955 n_virt = nmo_mp2 - n_occ
1968 fm_struct_multipoles_ao%para_env, fm_struct_multipoles_ao%context, &
1971 fm_struct_multipoles_ao%para_env, fm_struct_multipoles_ao%context, &
1976 context_bse, virtual_red, homo_red)
1978 context_bse, homo_red, homo_red)
1980 context_bse, virtual_red, virtual_red)
1981 DO idir = 1, n_multipole
1982 CALL cp_fm_create(fm_multipole_ai_trunc(idir), matrix_struct=fm_struct_mp_ai_trunc, &
1983 name=
"dipoles_mo_ai_trunc")
1985 CALL cp_fm_create(fm_multipole_ij_trunc(idir), matrix_struct=fm_struct_mp_ij_trunc, &
1986 name=
"dipoles_mo_ij_trunc")
1988 CALL cp_fm_create(fm_multipole_ab_trunc(idir), matrix_struct=fm_struct_mp_ab_trunc, &
1989 name=
"dipoles_mo_ab_trunc")
1995 CALL cp_fm_create(fm_work, matrix_struct=fm_struct_nao_nmo, name=
"multipole_work")
1998 DO idir = 1, n_multipole
2000 CALL cp_fm_create(fm_multipole_per_dir(idir), matrix_struct=fm_struct_nmo_nmo, name=
"multipoles_mo")
2004 fm_work, ncol=nmo_mp2)
2007 CALL parallel_gemm(
'T',
'N', nmo_mp2, nmo_mp2, nao, 1.0_dp, mo_coeff(1), fm_work, 0.0_dp, fm_multipole_per_dir(idir))
2012 fm_multipole_ai_trunc(idir), &
2016 n_occ - homo_red + 1, &
2019 fm_multipole_per_dir(idir)%matrix_struct%context)
2022 fm_multipole_ij_trunc(idir), &
2025 n_occ - homo_red + 1, &
2026 n_occ - homo_red + 1, &
2029 fm_multipole_per_dir(idir)%matrix_struct%context)
2032 fm_multipole_ab_trunc(idir), &
2039 fm_multipole_per_dir(idir)%matrix_struct%context)
2043 NULLIFY (fm_struct_multipoles_ao)
2049 DO idir = 1, n_multipole
2052 DEALLOCATE (fm_multipole_per_dir)
2056 CALL timestop(handle)
2069 TYPE(
cp_fm_type),
INTENT(IN) :: fm_a, fm_b, fm_c
2070 REAL(kind=
dp),
INTENT(OUT) :: alpha
2072 CHARACTER(LEN=*),
PARAMETER :: routinen =
'trace_exciton_descr'
2074 INTEGER :: handle, ncol_a, ncol_b, ncol_c, nrow_a, &
2078 CALL timeset(routinen, handle)
2081 CALL cp_fm_get_info(fm_a, nrow_global=nrow_a, ncol_global=ncol_a)
2082 CALL cp_fm_get_info(fm_b, nrow_global=nrow_b, ncol_global=ncol_b)
2083 CALL cp_fm_get_info(fm_c, nrow_global=nrow_c, ncol_global=ncol_c)
2086 cpassert(nrow_a == nrow_b .AND. ncol_a == ncol_c .AND. ncol_b == nrow_c)
2090 CALL parallel_gemm(
"N",
"N", nrow_a, ncol_a, nrow_c, 1.0_dp, &
2091 fm_b, fm_c, 0.0_dp, fm_work_ia)
2097 CALL timestop(handle)
2112 TYPE(
cp_fm_type),
DIMENSION(:),
INTENT(IN) :: fm_s_ia
2113 INTEGER,
DIMENSION(:),
INTENT(IN) :: offsets, n_ov
2114 INTEGER,
INTENT(IN) :: dimen_ri
2115 TYPE(
cp_fm_type),
INTENT(INOUT) :: fm_s_joint
2117 CHARACTER(LEN=*),
PARAMETER :: routinen =
'assemble_joint_ov_slab'
2119 INTEGER :: handle, isp
2121 CALL timeset(routinen, handle)
2122 DO isp = 1,
SIZE(fm_s_ia)
2123 CALL cp_fm_to_fm_submat(fm_s_ia(isp), fm_s_joint, dimen_ri, n_ov(isp), 1, 1, 1, offsets(isp) + 1)
2125 CALL timestop(handle)
Define the atomic kind types and their sub types.
Auxiliary routines for GW + Bethe-Salpeter for computing electronic excitations.
subroutine, public assemble_joint_ov_slab(fm_s_ia, offsets, n_ov, dimen_ri, fm_s_joint)
Column-concatenate per-spin ia-slabs into the joint dimen_RI x n_ov_joint slab. Sigma-block of spin i...
subroutine, public truncate_bse_matrices(fm_mat_s_ia_bse, fm_mat_s_ij_bse, fm_mat_s_ab_bse, fm_mat_s_trunc, fm_mat_s_ij_trunc, fm_mat_s_ab_trunc, eigenval_scf, eigenval, eigenval_reduced, homo, virtual, dimen_ri, unit_nr, bse_lev_virt, homo_red, virt_red, mp2_env, homo_incl_in, virt_incl_in)
Determines indices within the given energy cutoffs and truncates Eigenvalues and matrices.
subroutine, public estimate_bse_resources(n_ov_joint, unit_nr, bse_abba, para_env, diag_runtime_est)
Roughly estimates the needed runtime and memory during the BSE run.
subroutine, public trace_exciton_descr(fm_a, fm_b, fm_c, alpha)
Computes trace of form Tr{A^T B C} for exciton descriptors.
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, row_offset, col_offset)
Adds and reorders full matrices with a combined index structure, e.g. adding W_ij,...
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, ispin)
...
subroutine, public truncate_fm(fm_out, fm_in, ncol_in, nrow_out, ncol_out, unit_nr, mp2_env, nrow_offset, ncol_offset)
Routine for truncating a full matrix as given by the energy cutoffs in the input file....
subroutine, public deallocate_matrices_bse(fm_mat_s_bar_ia_bse, fm_mat_s_bar_ij_bse, fm_mat_s_trunc, fm_mat_s_ij_trunc, fm_mat_s_ab_trunc, fm_mat_q_static_bse_gemm, mp2_env)
...
subroutine, public filter_eigvec_contrib(fm_eigvec, idx_homo, idx_virt, eigvec_entries, i_exc, virtual, num_entries, mp2_env, offsets, virtual_per_spin, idx_spin)
Filters eigenvector entries above a given threshold to describe excitations in the singleparticle bas...
subroutine, public reshuffle_eigvec(fm_eigvec, fm_eigvec_reshuffled, homo, virtual, n_exc, do_transpose, unit_nr, mp2_env)
...
subroutine, public mult_b_with_w(fm_mat_s_ij_bse, fm_mat_s_ia_bse, fm_mat_s_bar_ia_bse, fm_mat_s_bar_ij_bse, fm_mat_q_static_bse_gemm, dimen_ri, homo, virtual)
Multiplies B-matrix (RI-3c-Integrals) with W (screening) to obtain \bar{B}.
subroutine, public adapt_bse_input_params(homo, virtual, unit_nr, mp2_env, qs_env)
Checks BSE input section and adapts them if necessary.
subroutine, public get_bse_spin_block_layout(homo_red, virt_red, n_ov, offsets, n_ov_joint)
Spin-block layout for the open-shell (joint) BSE matrix: per-spin OV-pair counts and the block offset...
subroutine, public sort_excitations(idx_prim, idx_sec, eigvec_entries, idx_spin)
Sorts excitation entries by ascending primary index, reordering the secondary index,...
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...
subroutine, public print_bse_nto_cubes(qs_env, mos, istate, info_approximation, stride, append_cube, print_section)
Borrowed from the tddfpt module with slight adaptions.
subroutine, public determine_bse_combined_window(eigenval_scf, homo, virtual, cutoff_occ, cutoff_empty, first_active_mo, last_active_mo)
Determine a single combined active-MO window covering all spin channels for open-shell BSE truncation...
subroutine, public determine_cutoff_indices(eigenval, homo, virtual, homo_red, virt_red, homo_incl, virt_incl, cutoff_occ, cutoff_empty)
Reads cutoffs for BSE from mp2_env and compares to energies in Eigenval to extract reduced homo/virtu...
Handles all functions related to the CELL.
methods related to the blacs parallel environment
Defines control structures, which contain the parameters and the settings for the DFT-based calculati...
subroutine, public dbcsr_init_p(matrix)
...
subroutine, public dbcsr_set(matrix, alpha)
...
Routines that link DBCSR and CP2K concepts together.
subroutine, public cp_dbcsr_alloc_block_from_nbl(matrix, sab_orb, desymmetrize)
allocate the blocks of a dbcsr based on the neighbor list
DBCSR operations in CP2K.
subroutine, public cp_dbcsr_sm_fm_multiply(matrix, fm_in, fm_out, ncol, alpha, beta)
multiply a dbcsr with a fm matrix
Basic linear algebra operations for full matrices.
subroutine, public cp_fm_uplo_to_full(matrix, work, uplo)
given a triangular matrix according to uplo, computes the corresponding full matrix
various cholesky decomposition related routines
subroutine, public cp_fm_cholesky_invert(matrix, n, info_out)
used to replace the cholesky decomposition by the inverse
subroutine, public cp_fm_cholesky_decompose(matrix, n, info_out)
used to replace a symmetric positive def. matrix M with its cholesky decomposition U: M = U^T * U,...
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
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_to_fm_submat_general(source, destination, nrows, ncols, s_firstrow, s_firstcol, d_firstrow, d_firstcol, global_context)
General copy of a submatrix of fm matrix to a submatrix of another fm matrix. The two matrices can ha...
subroutine, public cp_fm_to_fm_submat(msource, mtarget, nrow, ncol, s_firstrow, s_firstcol, t_firstrow, t_firstcol)
copy just a part ot the 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, nrow, ncol, set_zero)
creates a new full matrix with the given structure
various routines to log and control the output. The idea is that decisions about where to log should ...
type(cp_logger_type) function, pointer, public cp_get_default_logger()
returns the default logger
routines to handle the output, The idea is to remove the decision of wheter to output and what to out...
integer function, public cp_print_key_unit_nr(logger, basis_section, print_key_path, extension, middle_name, local, log_filename, ignore_should_output, file_form, file_position, file_action, file_status, do_backup, on_file, is_new_file, mpi_io, fout)
...
subroutine, public cp_print_key_finished_output(unit_nr, logger, basis_section, print_key_path, local, ignore_should_output, on_file, mpi_io)
should be called after you finish working with a unit obtained with cp_print_key_unit_nr,...
A wrapper around pw_to_cube() which accepts particle_list_type.
subroutine, public cp_pw_to_cube(pw, unit_nr, title, particles, zeff, stride, max_file_size_mb, zero_tails, silent, mpi_io)
...
Calculation of the incomplete Gamma function F_n(t) for multi-center integrals over Cartesian Gaussia...
Defines the basic variable types.
integer, parameter, public int_8
integer, parameter, public dp
integer, parameter, public default_path_length
Interface to the message passing library MPI.
Calculates the moment integrals <a|r^m|b>
subroutine, public get_reference_point(rpoint, drpoint, qs_env, fist_env, reference, ref_point, ifirst, ilast)
...
Types needed for MP2 calculations.
basic linear algebra operations for full matrixes
represent a simple array based list of the given type
Define the data structure for the particle information.
Definition of physical constants:
real(kind=dp), parameter, public evolt
container for various plainwaves related things
subroutine, public pw_env_get(pw_env, pw_pools, cube_info, gridlevel_info, auxbas_pw_pool, auxbas_grid, auxbas_rs_desc, auxbas_rs_grid, rs_descs, rs_grids, xc_pw_pool, vdw_pw_pool, poisson_env, interp_section)
returns the various attributes of the pw env
functions related to the poisson solver on regular grids
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Calculate the plane wave density by collocating the primitive Gaussian functions (pgf).
subroutine, public calculate_wavefunction(mo_vectors, ivector, rho, rho_gspace, atomic_kind_set, qs_kind_set, cell, dft_control, particle_set, pw_env, basis_type)
maps a given wavefunction on the grid
subroutine, public get_qs_env(qs_env, atomic_kind_set, qs_kind_set, cell, super_cell, cell_ref, use_ref_cell, kpoints, dft_control, mos, sab_orb, sab_all, qmmm, qmmm_periodic, mimic, sac_ae, sac_ppl, sac_lri, sap_ppnl, sab_vdw, sab_scp, sap_oce, sab_lrc, sab_se, sab_xtbe, sab_tbe, sab_core, sab_xb, sab_xtb_pp, sab_xtb_nonbond, sab_almo, sab_kp, sab_kp_nosym, sab_cneo, particle_set, energy, force, matrix_h, matrix_h_im, matrix_ks, matrix_ks_im, matrix_vxc, run_rtp, rtp, matrix_h_kp, matrix_h_im_kp, matrix_ks_kp, matrix_ks_im_kp, matrix_vxc_kp, kinetic_kp, matrix_s_kp, matrix_w_kp, matrix_s_ri_aux_kp, matrix_s, matrix_s_ri_aux, matrix_w, matrix_p_mp2, matrix_p_mp2_admm, matrix_vhxc, rho, rho_xc, pw_env, ewald_env, ewald_pw, active_space, mpools, input, para_env, blacs_env, scf_control, rel_control, kinetic, qs_charges, vppl, xcint_weights, rho_core, rho_nlcc, rho_nlcc_g, ks_env, ks_qmmm_env, wf_history, scf_env, local_particles, local_molecules, distribution_2d, dbcsr_dist, molecule_kind_set, molecule_set, subsys, cp_subsys, oce, local_rho_set, rho_atom_set, task_list, task_list_soft, rho0_atom_set, rho0_mpole, rhoz_set, rhoz_cneo_set, ecoul_1c, rho0_s_rs, rho0_s_gs, rhoz_cneo_s_rs, rhoz_cneo_s_gs, do_kpoints, has_unit_metric, requires_mo_derivs, mo_derivs, mo_loc_history, nkind, natom, nelectron_total, nelectron_spin, efield, neighbor_list_id, linres_control, xas_env, virial, cp_ddapc_env, cp_ddapc_ewald, outer_scf_history, outer_scf_ihistory, x_data, et_coupling, dftb_potential, results, se_taper, se_store_int_env, se_nddo_mpole, se_nonbond_env, admm_env, lri_env, lri_density, exstate_env, ec_env, harris_env, dispersion_env, gcp_env, vee, rho_external, external_vxc, mask, mp2_env, bs_env, kg_env, wanniercentres, atprop, ls_scf_env, do_transport, transport_env, v_hartree_rspace, s_mstruct_changed, rho_changed, potential_changed, forces_up_to_date, mscfg_env, almo_scf_env, gradient_history, variable_history, embed_pot, spin_embed_pot, polar_env, mos_last_converged, eeq, rhs, do_rixs, tb_tblite)
Get the QUICKSTEP environment.
Define the quickstep kind type and their sub types.
Definition and initialisation of the mo data type.
subroutine, public get_mo_set(mo_set, maxocc, homo, lfomo, nao, nelectron, n_el_f, nmo, eigenvalues, occupation_numbers, mo_coeff, mo_coeff_b, uniform_occupation, kts, mu, flexible_electron_count)
Get the components of a MO set data structure.
Calculates the moment integrals <a|r^m|b> and <a|r x d/dr|b>
subroutine, public build_local_moment_matrix(qs_env, moments, nmoments, ref_point, ref_points, basis_type)
...
Define the neighbor list data types and the corresponding functionality.
types that represent a quickstep subsys
subroutine, public qs_subsys_get(subsys, atomic_kinds, atomic_kind_set, particles, particle_set, local_particles, molecules, molecule_set, molecule_kinds, molecule_kind_set, local_molecules, para_env, colvar_p, shell_particles, core_particles, gci, multipoles, natom, nparticle, ncore, nshell, nkind, atprop, virial, results, cell, cell_ref, use_ref_cell, energy, force, qs_kind_set, cp_subsys, nelectron_total, nelectron_spin)
...
Auxiliary routines necessary to redistribute an fm_matrix from a given blacs_env to another.
subroutine, public communicate_buffer(para_env, num_entries_rec, num_entries_send, buffer_rec, buffer_send, req_array, do_indx, do_msg)
...
All kind of helpful little routines.
Provides all information about an atomic kind.
Type defining parameters related to the simulation cell.
represent a blacs multidimensional parallel environment (for the mpi corrispective see cp_paratypes/m...
keeps the information about the structure of a full matrix
type of a logger, at the moment it contains just a print level starting at which level it should be l...
stores all the informations relevant to an mpi environment
represent a list of objects
contained for different pw related things
environment for the poisson solver
to create arrays of pools
Manages a pool of grids (to be used for example as tmp objects), but can also be used to instantiate ...
Provides all information about a quickstep kind.