LCOV - code coverage report
Current view: top level - src - qs_scf_csr_write.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:07c9450) Lines: 96.4 % 247 238
Test Date: 2025-12-13 06:52:47 Functions: 100.0 % 7 7

            Line data    Source code
       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 Functions to print the KS and S matrix in the CSR format to file
      10              : !> \par History
      11              : !>      Started as a copy from the relevant part of qs_scf_post_gpw
      12              : !> \author Fabian Ducry (05.2020)
      13              : ! **************************************************************************************************
      14              : MODULE qs_scf_csr_write
      15              :    USE cp_dbcsr_api,                    ONLY: &
      16              :         dbcsr_convert_dbcsr_to_csr, dbcsr_copy, dbcsr_create, &
      17              :         dbcsr_csr_create_and_convert_complex, dbcsr_csr_create_from_dbcsr, &
      18              :         dbcsr_csr_dbcsr_blkrow_dist, dbcsr_csr_destroy, dbcsr_csr_type, dbcsr_csr_write, &
      19              :         dbcsr_desymmetrize, dbcsr_finalize, dbcsr_get_block_p, dbcsr_has_symmetry, dbcsr_p_type, &
      20              :         dbcsr_put_block, dbcsr_release, dbcsr_set, dbcsr_type, dbcsr_type_antisymmetric, &
      21              :         dbcsr_type_no_symmetry, dbcsr_type_symmetric
      22              :    USE cp_dbcsr_cp2k_link,              ONLY: cp_dbcsr_alloc_block_from_nbl
      23              :    USE cp_dbcsr_operations,             ONLY: dbcsr_allocate_matrix_set,&
      24              :                                               dbcsr_deallocate_matrix_set
      25              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      26              :                                               cp_logger_get_default_io_unit,&
      27              :                                               cp_logger_type
      28              :    USE cp_output_handling,              ONLY: cp_p_file,&
      29              :                                               cp_print_key_finished_output,&
      30              :                                               cp_print_key_should_output,&
      31              :                                               cp_print_key_unit_nr
      32              :    USE input_section_types,             ONLY: section_vals_get_subs_vals,&
      33              :                                               section_vals_type,&
      34              :                                               section_vals_val_get
      35              :    USE kinds,                           ONLY: default_path_length,&
      36              :                                               dp
      37              :    USE kpoint_methods,                  ONLY: rskp_transform
      38              :    USE kpoint_types,                    ONLY: get_kpoint_info,&
      39              :                                               kpoint_type
      40              :    USE qs_environment_types,            ONLY: get_qs_env,&
      41              :                                               qs_environment_type
      42              :    USE qs_neighbor_list_types,          ONLY: get_iterator_info,&
      43              :                                               get_neighbor_list_set_p,&
      44              :                                               neighbor_list_iterate,&
      45              :                                               neighbor_list_iterator_create,&
      46              :                                               neighbor_list_iterator_p_type,&
      47              :                                               neighbor_list_iterator_release,&
      48              :                                               neighbor_list_set_p_type
      49              :    USE qs_rho_types,                    ONLY: qs_rho_get,&
      50              :                                               qs_rho_type
      51              : #include "./base/base_uses.f90"
      52              : 
      53              :    IMPLICIT NONE
      54              :    PRIVATE
      55              : 
      56              :    ! Global parameters
      57              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'qs_scf_csr_write'
      58              :    PUBLIC :: write_ks_matrix_csr, &
      59              :              write_s_matrix_csr, &
      60              :              write_p_matrix_csr, &
      61              :              write_hcore_matrix_csr
      62              : 
      63              : ! **************************************************************************************************
      64              : 
      65              : CONTAINS
      66              : 
      67              : !**************************************************************************************************
      68              : !> \brief writing the KS matrix in csr format into a file
      69              : !> \param qs_env qs environment
      70              : !> \param input the input
      71              : !> \par History
      72              : !>       Moved to module qs_scf_csr_write (05.2020)
      73              : !> \author Mohammad Hossein Bani-Hashemian
      74              : ! **************************************************************************************************
      75        17565 :    SUBROUTINE write_ks_matrix_csr(qs_env, input)
      76              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      77              :       TYPE(section_vals_type), POINTER                   :: input
      78              : 
      79              :       CHARACTER(len=*), PARAMETER :: routineN = 'write_ks_matrix_csr'
      80              : 
      81              :       INTEGER                                            :: handle, output_unit
      82              :       LOGICAL                                            :: do_kpoints, do_ks_csr_write, real_space
      83              :       TYPE(cp_logger_type), POINTER                      :: logger
      84        17565 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_ks
      85              :       TYPE(kpoint_type), POINTER                         :: kpoints
      86              :       TYPE(section_vals_type), POINTER                   :: dft_section
      87              : 
      88        17565 :       CALL timeset(routineN, handle)
      89              : 
      90              :       NULLIFY (dft_section)
      91              : 
      92        17565 :       logger => cp_get_default_logger()
      93        17565 :       output_unit = cp_logger_get_default_io_unit(logger)
      94              : 
      95        17565 :       dft_section => section_vals_get_subs_vals(input, "DFT")
      96              :       do_ks_csr_write = BTEST(cp_print_key_should_output(logger%iter_info, dft_section, &
      97        17565 :                                                          "PRINT%KS_CSR_WRITE"), cp_p_file)
      98              : 
      99        17565 :       IF (do_ks_csr_write) THEN
     100           54 :          CALL get_qs_env(qs_env=qs_env, kpoints=kpoints, matrix_ks_kp=matrix_ks, do_kpoints=do_kpoints)
     101              :          CALL section_vals_val_get(dft_section, "PRINT%KS_CSR_WRITE%REAL_SPACE", &
     102           54 :                                    l_val=real_space)
     103              : 
     104           54 :          IF (do_kpoints .AND. .NOT. real_space) THEN
     105              :             CALL write_matrix_kp_csr(mat=matrix_ks, dft_section=dft_section, &
     106           10 :                                      kpoints=kpoints, prefix="KS")
     107              :          ELSE
     108              :             CALL write_matrix_csr(dft_section, mat=matrix_ks, kpoints=kpoints, do_kpoints=do_kpoints, &
     109           44 :                                   prefix="KS")
     110              :          END IF
     111              :       END IF
     112              : 
     113        17565 :       CALL timestop(handle)
     114              : 
     115        17565 :    END SUBROUTINE write_ks_matrix_csr
     116              : 
     117              : !**************************************************************************************************
     118              : !> \brief writing the overlap matrix in csr format into a file
     119              : !> \param qs_env qs environment
     120              : !> \param input the input
     121              : !> \par History
     122              : !>      Moved to module qs_scf_csr_write
     123              : !> \author Mohammad Hossein Bani-Hashemian
     124              : ! **************************************************************************************************
     125        17565 :    SUBROUTINE write_s_matrix_csr(qs_env, input)
     126              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     127              :       TYPE(section_vals_type), POINTER                   :: input
     128              : 
     129              :       CHARACTER(len=*), PARAMETER :: routineN = 'write_s_matrix_csr'
     130              : 
     131              :       INTEGER                                            :: handle, output_unit
     132              :       LOGICAL                                            :: do_kpoints, do_s_csr_write, real_space
     133              :       TYPE(cp_logger_type), POINTER                      :: logger
     134        17565 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_s
     135              :       TYPE(kpoint_type), POINTER                         :: kpoints
     136              :       TYPE(section_vals_type), POINTER                   :: dft_section
     137              : 
     138        17565 :       CALL timeset(routineN, handle)
     139              : 
     140              :       NULLIFY (dft_section)
     141              : 
     142        17565 :       logger => cp_get_default_logger()
     143        17565 :       output_unit = cp_logger_get_default_io_unit(logger)
     144              : 
     145        17565 :       dft_section => section_vals_get_subs_vals(input, "DFT")
     146              :       do_s_csr_write = BTEST(cp_print_key_should_output(logger%iter_info, dft_section, &
     147        17565 :                                                         "PRINT%S_CSR_WRITE"), cp_p_file)
     148              : 
     149        17565 :       IF (do_s_csr_write) THEN
     150           52 :          CALL get_qs_env(qs_env=qs_env, kpoints=kpoints, matrix_s_kp=matrix_s, do_kpoints=do_kpoints)
     151              :          CALL section_vals_val_get(dft_section, "PRINT%S_CSR_WRITE%REAL_SPACE", &
     152           52 :                                    l_val=real_space)
     153              : 
     154           52 :          IF (do_kpoints .AND. .NOT. real_space) THEN
     155              :             CALL write_matrix_kp_csr(mat=matrix_s, dft_section=dft_section, &
     156           10 :                                      kpoints=kpoints, prefix="S")
     157              :          ELSE
     158              :             CALL write_matrix_csr(dft_section, mat=matrix_s, kpoints=kpoints, do_kpoints=do_kpoints, &
     159           42 :                                   prefix="S")
     160              :          END IF
     161              :       END IF
     162              : 
     163        17565 :       CALL timestop(handle)
     164              : 
     165        17565 :    END SUBROUTINE write_s_matrix_csr
     166              : 
     167              : !**************************************************************************************************
     168              : !> \brief writing the density matrix in csr format into a file
     169              : !> \param qs_env qs environment
     170              : !> \param input the input
     171              : !> \par History
     172              : !> \author Mohammad Hossein Bani-Hashemian
     173              : ! **************************************************************************************************
     174        17565 :    SUBROUTINE write_p_matrix_csr(qs_env, input)
     175              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     176              :       TYPE(section_vals_type), POINTER                   :: input
     177              : 
     178              :       CHARACTER(len=*), PARAMETER :: routineN = 'write_p_matrix_csr'
     179              : 
     180              :       INTEGER                                            :: handle, output_unit
     181              :       LOGICAL                                            :: do_kpoints, do_p_csr_write, real_space
     182              :       TYPE(cp_logger_type), POINTER                      :: logger
     183        17565 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: rho_ao_kp
     184              :       TYPE(kpoint_type), POINTER                         :: kpoints
     185              :       TYPE(qs_rho_type), POINTER                         :: rho
     186              :       TYPE(section_vals_type), POINTER                   :: dft_section
     187              : 
     188        17565 :       CALL timeset(routineN, handle)
     189              : 
     190              :       NULLIFY (dft_section)
     191              : 
     192        17565 :       logger => cp_get_default_logger()
     193        17565 :       output_unit = cp_logger_get_default_io_unit(logger)
     194              : 
     195        17565 :       dft_section => section_vals_get_subs_vals(input, "DFT")
     196              :       do_p_csr_write = BTEST(cp_print_key_should_output(logger%iter_info, dft_section, &
     197        17565 :                                                         "PRINT%P_CSR_WRITE"), cp_p_file)
     198              : 
     199        17565 :       IF (do_p_csr_write) THEN
     200           28 :          CALL get_qs_env(qs_env=qs_env, kpoints=kpoints, rho=rho, do_kpoints=do_kpoints)
     201           28 :          CALL qs_rho_get(rho, rho_ao_kp=rho_ao_kp)
     202              :          CALL section_vals_val_get(dft_section, "PRINT%P_CSR_WRITE%REAL_SPACE", &
     203           28 :                                    l_val=real_space)
     204              : 
     205           28 :          IF (do_kpoints .AND. .NOT. real_space) THEN
     206              :             CALL write_matrix_kp_csr(mat=rho_ao_kp, dft_section=dft_section, &
     207            0 :                                      kpoints=kpoints, prefix="P")
     208              :          ELSE
     209              :             CALL write_matrix_csr(dft_section, mat=rho_ao_kp, kpoints=kpoints, do_kpoints=do_kpoints, &
     210           28 :                                   prefix="P")
     211              :          END IF
     212              :       END IF
     213              : 
     214        17565 :       CALL timestop(handle)
     215              : 
     216        17565 :    END SUBROUTINE write_p_matrix_csr
     217              : 
     218              : !**************************************************************************************************
     219              : !> \brief writing the core Hamiltonian matrix in csr format into a file
     220              : !> \param qs_env qs environment
     221              : !> \param input the input
     222              : !> \par History
     223              : !> \author Mohammad Hossein Bani-Hashemian
     224              : ! **************************************************************************************************
     225        17565 :    SUBROUTINE write_hcore_matrix_csr(qs_env, input)
     226              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     227              :       TYPE(section_vals_type), POINTER                   :: input
     228              : 
     229              :       CHARACTER(len=*), PARAMETER :: routineN = 'write_hcore_matrix_csr'
     230              : 
     231              :       INTEGER                                            :: handle, output_unit
     232              :       LOGICAL                                            :: do_h_csr_write, do_kpoints, real_space
     233              :       TYPE(cp_logger_type), POINTER                      :: logger
     234        17565 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: matrix_h
     235              :       TYPE(kpoint_type), POINTER                         :: kpoints
     236              :       TYPE(section_vals_type), POINTER                   :: dft_section
     237              : 
     238        17565 :       CALL timeset(routineN, handle)
     239              : 
     240              :       NULLIFY (dft_section)
     241              : 
     242        17565 :       logger => cp_get_default_logger()
     243        17565 :       output_unit = cp_logger_get_default_io_unit(logger)
     244              : 
     245        17565 :       dft_section => section_vals_get_subs_vals(input, "DFT")
     246              :       do_h_csr_write = BTEST(cp_print_key_should_output(logger%iter_info, dft_section, &
     247        17565 :                                                         "PRINT%HCORE_CSR_WRITE"), cp_p_file)
     248              : 
     249        17565 :       IF (do_h_csr_write) THEN
     250           28 :          CALL get_qs_env(qs_env=qs_env, kpoints=kpoints, matrix_h_kp=matrix_h, do_kpoints=do_kpoints)
     251              :          CALL section_vals_val_get(dft_section, "PRINT%HCORE_CSR_WRITE%REAL_SPACE", &
     252           28 :                                    l_val=real_space)
     253              : 
     254           28 :          IF (do_kpoints .AND. .NOT. real_space) THEN
     255              :             CALL write_matrix_kp_csr(mat=matrix_h, dft_section=dft_section, &
     256            0 :                                      kpoints=kpoints, prefix="HCORE")
     257              :          ELSE
     258              :             CALL write_matrix_csr(dft_section, mat=matrix_h, kpoints=kpoints, do_kpoints=do_kpoints, &
     259           28 :                                   prefix="HCORE")
     260              :          END IF
     261              :       END IF
     262              : 
     263        17565 :       CALL timestop(handle)
     264              : 
     265        17565 :    END SUBROUTINE write_hcore_matrix_csr
     266              : 
     267              : ! **************************************************************************************************
     268              : !> \brief helper function to print the real space representation of KS or S matrix to file
     269              : !> \param dft_section the dft_section
     270              : !> \param mat Hamiltonian or overlap matrix
     271              : !> \param kpoints Kpoint environment
     272              : !> \param prefix string to distinguish between KS and S matrix
     273              : !> \param do_kpoints Whether it is a gamma-point or k-point calculation
     274              : !> \par History
     275              : !>       Moved most of the code from write_ks_matrix_csr and write_s_matrix_csr
     276              : !>       Removed the code for printing k-point dependent matrices and added
     277              : !>              printing of the real space representation
     278              : ! **************************************************************************************************
     279          142 :    SUBROUTINE write_matrix_csr(dft_section, mat, kpoints, prefix, do_kpoints)
     280              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: dft_section
     281              :       TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(IN), &
     282              :          POINTER                                         :: mat
     283              :       TYPE(kpoint_type), INTENT(IN), POINTER             :: kpoints
     284              :       CHARACTER(*), INTENT(in)                           :: prefix
     285              :       LOGICAL, INTENT(IN)                                :: do_kpoints
     286              : 
     287              :       CHARACTER(len=*), PARAMETER                        :: routineN = 'write_matrix_csr'
     288              : 
     289              :       CHARACTER(LEN=default_path_length)                 :: file_name, fileformat, subs_string
     290              :       INTEGER                                            :: handle, ic, ispin, ncell, nspin, &
     291              :                                                             output_unit, unit_nr
     292          142 :       INTEGER, ALLOCATABLE, DIMENSION(:, :)              :: index_to_cell
     293          142 :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :)           :: cell_to_index
     294          142 :       INTEGER, DIMENSION(:, :), POINTER                  :: i2c
     295          142 :       INTEGER, DIMENSION(:, :, :), POINTER               :: c2i
     296              :       LOGICAL                                            :: bin, do_symmetric, uptr
     297              :       REAL(KIND=dp)                                      :: thld
     298              :       TYPE(cp_logger_type), POINTER                      :: logger
     299              :       TYPE(dbcsr_csr_type)                               :: mat_csr
     300          142 :       TYPE(dbcsr_p_type), DIMENSION(:, :), POINTER       :: mat_nosym
     301              :       TYPE(dbcsr_type)                                   :: matrix_nosym
     302              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     303          142 :          POINTER                                         :: sab_nl
     304              : 
     305          142 :       CALL timeset(routineN, handle)
     306              : 
     307          142 :       logger => cp_get_default_logger()
     308          142 :       output_unit = cp_logger_get_default_io_unit(logger)
     309              : 
     310          142 :       subs_string = "PRINT%"//prefix//"_CSR_WRITE"
     311              : 
     312          142 :       CALL section_vals_val_get(dft_section, subs_string//"%THRESHOLD", r_val=thld)
     313          142 :       CALL section_vals_val_get(dft_section, subs_string//"%UPPER_TRIANGULAR", l_val=uptr)
     314          142 :       CALL section_vals_val_get(dft_section, subs_string//"%BINARY", l_val=bin)
     315              : 
     316          142 :       IF (bin) THEN
     317            2 :          fileformat = "UNFORMATTED"
     318              :       ELSE
     319          140 :          fileformat = "FORMATTED"
     320              :       END IF
     321              : 
     322          142 :       nspin = SIZE(mat, 1)
     323          142 :       ncell = SIZE(mat, 2)
     324              : 
     325          142 :       IF (do_kpoints) THEN
     326              : 
     327            2 :          i2c => kpoints%index_to_cell
     328            2 :          c2i => kpoints%cell_to_index
     329              : 
     330            2 :          NULLIFY (sab_nl)
     331            2 :          CALL get_kpoint_info(kpoints, sab_nl=sab_nl)
     332            2 :          CALL get_neighbor_list_set_p(neighbor_list_sets=sab_nl, symmetric=do_symmetric)
     333              : 
     334              :          ! desymmetrize the KS or S matrices if necessary
     335            2 :          IF (do_symmetric) THEN
     336              :             CALL desymmetrize_rs_matrix(mat, mat_nosym, cell_to_index, index_to_cell, kpoints)
     337            2 :             ncell = SIZE(index_to_cell, 2) ! update the number of cells
     338              :          ELSE
     339              :             ALLOCATE (cell_to_index(LBOUND(c2i, 1):UBOUND(c2i, 1), &
     340              :                                     LBOUND(c2i, 2):UBOUND(c2i, 2), &
     341            0 :                                     LBOUND(c2i, 3):UBOUND(c2i, 3)))
     342              :             cell_to_index(LBOUND(c2i, 1):UBOUND(c2i, 1), &
     343              :                           LBOUND(c2i, 2):UBOUND(c2i, 2), &
     344            0 :                           LBOUND(c2i, 3):UBOUND(c2i, 3)) = c2i
     345              : 
     346            0 :             ALLOCATE (index_to_cell(3, ncell))
     347            0 :             index_to_cell(1:3, 1:ncell) = i2c
     348              : 
     349            0 :             mat_nosym => mat
     350              :          END IF
     351              : 
     352              :          ! print the index to cell mapping to the output
     353            2 :          IF (output_unit > 0) THEN
     354            1 :             WRITE (output_unit, "(/,A15,T15,I4,A)") prefix//" CSR write| ", &
     355            2 :                ncell, " periodic images"
     356            1 :             WRITE (output_unit, "(T7,A,T17,A,T24,A,T31,A)") "Number", "X", "Y", "Z"
     357           28 :             DO ic = 1, ncell
     358           28 :                WRITE (output_unit, "(T8,I3,T15,I3,T22,I3,T29,I3)") ic, index_to_cell(:, ic)
     359              :             END DO
     360              :          END IF
     361              :       END IF
     362              : 
     363              :       ! write the csr file(s)
     364          284 :       DO ispin = 1, nspin
     365          478 :          DO ic = 1, ncell
     366          194 :             IF (do_kpoints) THEN
     367           54 :                CALL dbcsr_copy(matrix_nosym, mat_nosym(ispin, ic)%matrix)
     368           54 :                WRITE (file_name, '(2(A,I0))') prefix//"_SPIN_", ispin, "_R_", ic
     369              :             ELSE
     370          140 :                IF (dbcsr_has_symmetry(mat(ispin, ic)%matrix)) THEN
     371          140 :                   CALL dbcsr_desymmetrize(mat(ispin, ic)%matrix, matrix_nosym)
     372              :                ELSE
     373            0 :                   CALL dbcsr_copy(matrix_nosym, mat(ispin, ic)%matrix)
     374              :                END IF
     375          140 :                WRITE (file_name, '(A,I0)') prefix//"_SPIN_", ispin
     376              :             END IF
     377              :             ! Convert dbcsr to csr
     378              :             CALL dbcsr_csr_create_from_dbcsr(matrix_nosym, &
     379          194 :                                              mat_csr, dbcsr_csr_dbcsr_blkrow_dist)
     380          194 :             CALL dbcsr_convert_dbcsr_to_csr(matrix_nosym, mat_csr)
     381              :             ! Write to file
     382              :             unit_nr = cp_print_key_unit_nr(logger, dft_section, subs_string, &
     383              :                                            extension=".csr", middle_name=TRIM(file_name), &
     384          194 :                                            file_status="REPLACE", file_form=fileformat)
     385          194 :             CALL dbcsr_csr_write(mat_csr, unit_nr, upper_triangle=uptr, threshold=thld, binary=bin)
     386              : 
     387          194 :             CALL cp_print_key_finished_output(unit_nr, logger, dft_section, subs_string)
     388          194 :             CALL dbcsr_csr_destroy(mat_csr)
     389          336 :             CALL dbcsr_release(matrix_nosym)
     390              :          END DO
     391              :       END DO
     392              : 
     393              :       ! clean up
     394          142 :       IF (do_kpoints) THEN
     395            2 :          DEALLOCATE (cell_to_index, index_to_cell)
     396            2 :          IF (do_symmetric) THEN
     397            4 :             DO ispin = 1, nspin
     398           58 :                DO ic = 1, ncell
     399           56 :                   CALL dbcsr_release(mat_nosym(ispin, ic)%matrix)
     400              :                END DO
     401              :             END DO
     402            2 :             CALL dbcsr_deallocate_matrix_set(mat_nosym)
     403              :          END IF
     404              :       END IF
     405          142 :       CALL timestop(handle)
     406              : 
     407          284 :    END SUBROUTINE write_matrix_csr
     408              : 
     409              : ! **************************************************************************************************
     410              : !> \brief helper function to print the k-dependent KS or S matrix to file
     411              : !> \param mat Hamiltonian or overlap matrix for k-point calculations
     412              : !> \param dft_section the dft_section
     413              : !> \param kpoints Kpoint environment
     414              : !> \param prefix string to distinguish between KS and S matrix
     415              : !> \par History
     416              : !>       Moved the code from write_matrix_csr to write_matrix_kp_csr
     417              : !> \author Fabian Ducry
     418              : ! **************************************************************************************************
     419           20 :    SUBROUTINE write_matrix_kp_csr(mat, dft_section, kpoints, prefix)
     420              :       TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(IN), &
     421              :          POINTER                                         :: mat
     422              :       TYPE(section_vals_type), INTENT(IN), POINTER       :: dft_section
     423              :       TYPE(kpoint_type), INTENT(IN), POINTER             :: kpoints
     424              :       CHARACTER(*), INTENT(in)                           :: prefix
     425              : 
     426              :       CHARACTER(len=*), PARAMETER :: routineN = 'write_matrix_kp_csr'
     427              : 
     428              :       CHARACTER(LEN=default_path_length)                 :: file_name, fileformat, subs_string
     429              :       INTEGER                                            :: handle, igroup, ik, ikp, ispin, kplocal, &
     430              :                                                             nkp_groups, output_unit, unit_nr
     431              :       INTEGER, DIMENSION(2)                              :: kp_range
     432           20 :       INTEGER, DIMENSION(:, :), POINTER                  :: kp_dist
     433              :       LOGICAL                                            :: bin, uptr, use_real_wfn
     434              :       REAL(KIND=dp)                                      :: thld
     435           20 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: xkp
     436              :       TYPE(cp_logger_type), POINTER                      :: logger
     437              :       TYPE(dbcsr_csr_type)                               :: mat_csr
     438              :       TYPE(dbcsr_type)                                   :: matrix_nosym
     439              :       TYPE(dbcsr_type), POINTER                          :: imatrix, imatrix_nosym, rmatrix, &
     440              :                                                             rmatrix_nosym
     441              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     442           20 :          POINTER                                         :: sab_nl
     443              : 
     444           20 :       CALL timeset(routineN, handle)
     445              : 
     446           20 :       logger => cp_get_default_logger()
     447           20 :       output_unit = cp_logger_get_default_io_unit(logger)
     448              : 
     449           20 :       subs_string = "PRINT%"//prefix//"_CSR_WRITE"
     450              : 
     451           20 :       CALL section_vals_val_get(dft_section, subs_string//"%THRESHOLD", r_val=thld)
     452           20 :       CALL section_vals_val_get(dft_section, subs_string//"%UPPER_TRIANGULAR", l_val=uptr)
     453           20 :       CALL section_vals_val_get(dft_section, subs_string//"%BINARY", l_val=bin)
     454              : 
     455           20 :       IF (bin) THEN
     456           20 :          fileformat = "UNFORMATTED"
     457              :       ELSE
     458            0 :          fileformat = "FORMATTED"
     459              :       END IF
     460              : 
     461           20 :       NULLIFY (sab_nl)
     462              : 
     463              :       !  Calculate the Hamiltonian at the k-points
     464              :       CALL get_kpoint_info(kpoints, xkp=xkp, use_real_wfn=use_real_wfn, kp_range=kp_range, &
     465           20 :                            nkp_groups=nkp_groups, kp_dist=kp_dist, sab_nl=sab_nl)
     466              : 
     467           20 :       ALLOCATE (rmatrix)
     468              :       CALL dbcsr_create(rmatrix, template=mat(1, 1)%matrix, &
     469           20 :                         matrix_type=dbcsr_type_symmetric)
     470           20 :       CALL cp_dbcsr_alloc_block_from_nbl(rmatrix, sab_nl)
     471              : 
     472           20 :       IF (.NOT. use_real_wfn) THEN
     473              :          ! Allocate temporary variables
     474           16 :          ALLOCATE (rmatrix_nosym, imatrix, imatrix_nosym)
     475              :          CALL dbcsr_create(rmatrix_nosym, template=mat(1, 1)%matrix, &
     476           16 :                            matrix_type=dbcsr_type_no_symmetry)
     477              :          CALL dbcsr_create(imatrix, template=mat(1, 1)%matrix, &
     478           16 :                            matrix_type=dbcsr_type_antisymmetric)
     479              :          CALL dbcsr_create(imatrix_nosym, template=mat(1, 1)%matrix, &
     480           16 :                            matrix_type=dbcsr_type_no_symmetry)
     481           16 :          CALL cp_dbcsr_alloc_block_from_nbl(rmatrix_nosym, sab_nl)
     482           16 :          CALL cp_dbcsr_alloc_block_from_nbl(imatrix, sab_nl)
     483           16 :          CALL cp_dbcsr_alloc_block_from_nbl(imatrix_nosym, sab_nl)
     484              :       END IF
     485              : 
     486           20 :       kplocal = kp_range(2) - kp_range(1) + 1
     487           56 :       DO ikp = 1, kplocal
     488           92 :          DO ispin = 1, SIZE(mat, 1)
     489          140 :             DO igroup = 1, nkp_groups
     490              :                ! number of current kpoint
     491           68 :                ik = kp_dist(1, igroup) + ikp - 1
     492           68 :                CALL dbcsr_set(rmatrix, 0.0_dp)
     493           68 :                IF (use_real_wfn) THEN
     494              :                   ! FT of the matrix
     495              :                   CALL rskp_transform(rmatrix=rmatrix, rsmat=mat, ispin=ispin, &
     496            4 :                                       xkp=xkp(1:3, ik), cell_to_index=kpoints%cell_to_index, sab_nl=sab_nl)
     497              :                   ! Convert to desymmetrized csr matrix
     498            4 :                   CALL dbcsr_desymmetrize(rmatrix, matrix_nosym)
     499            4 :                   CALL dbcsr_csr_create_from_dbcsr(matrix_nosym, mat_csr, dbcsr_csr_dbcsr_blkrow_dist)
     500            4 :                   CALL dbcsr_convert_dbcsr_to_csr(matrix_nosym, mat_csr)
     501            4 :                   CALL dbcsr_release(matrix_nosym)
     502              :                ELSE
     503              :                   ! FT of the matrix
     504           64 :                   CALL dbcsr_set(imatrix, 0.0_dp)
     505              :                   CALL rskp_transform(rmatrix=rmatrix, cmatrix=imatrix, rsmat=mat, ispin=ispin, &
     506           64 :                                       xkp=xkp(1:3, ik), cell_to_index=kpoints%cell_to_index, sab_nl=sab_nl)
     507              : 
     508              :                   ! Desymmetrize and sum the real and imaginary part into
     509              :                   ! cmatrix
     510           64 :                   CALL dbcsr_desymmetrize(rmatrix, rmatrix_nosym)
     511           64 :                   CALL dbcsr_desymmetrize(imatrix, imatrix_nosym)
     512              :                   ! Convert to csr
     513              :                   CALL dbcsr_csr_create_and_convert_complex(rmatrix=rmatrix_nosym, &
     514              :                                                             imatrix=imatrix_nosym, &
     515              :                                                             csr_mat=mat_csr, &
     516           64 :                                                             dist_format=dbcsr_csr_dbcsr_blkrow_dist)
     517              :                END IF
     518              :                ! Write to file
     519           68 :                WRITE (file_name, '(2(A,I0))') prefix//"_SPIN_", ispin, "_K_", ik
     520              :                unit_nr = cp_print_key_unit_nr(logger, dft_section, subs_string, &
     521              :                                               extension=".csr", middle_name=TRIM(file_name), &
     522           68 :                                               file_status="REPLACE", file_form=fileformat)
     523           68 :                CALL dbcsr_csr_write(mat_csr, unit_nr, upper_triangle=uptr, threshold=thld, binary=bin)
     524              : 
     525           68 :                CALL cp_print_key_finished_output(unit_nr, logger, dft_section, subs_string)
     526              : 
     527          104 :                CALL dbcsr_csr_destroy(mat_csr)
     528              :             END DO
     529              :          END DO
     530              :       END DO
     531           20 :       CALL dbcsr_release(rmatrix)
     532           20 :       DEALLOCATE (rmatrix)
     533           20 :       IF (.NOT. use_real_wfn) THEN
     534           16 :          CALL dbcsr_release(rmatrix_nosym)
     535           16 :          CALL dbcsr_release(imatrix)
     536           16 :          CALL dbcsr_release(imatrix_nosym)
     537           16 :          DEALLOCATE (rmatrix_nosym, imatrix, imatrix_nosym)
     538              :       END IF
     539           20 :       CALL timestop(handle)
     540              : 
     541           20 :    END SUBROUTINE write_matrix_kp_csr
     542              : 
     543              : ! **************************************************************************************************
     544              : !> \brief Desymmetrizes the KS or S matrices which are stored in symmetric !matrices
     545              : !> \param mat Hamiltonian or overlap matrices
     546              : !> \param mat_nosym Desymmetrized Hamiltonian or overlap matrices
     547              : !> \param cell_to_index Mapping of cell indices to linear RS indices
     548              : !> \param index_to_cell Mapping of linear RS indices to cell indices
     549              : !> \param kpoints Kpoint environment
     550              : !> \author Fabian Ducry
     551              : ! **************************************************************************************************
     552            2 :    SUBROUTINE desymmetrize_rs_matrix(mat, mat_nosym, cell_to_index, index_to_cell, kpoints)
     553              :       TYPE(dbcsr_p_type), DIMENSION(:, :), INTENT(IN), &
     554              :          POINTER                                         :: mat
     555              :       TYPE(dbcsr_p_type), DIMENSION(:, :), &
     556              :          INTENT(INOUT), POINTER                          :: mat_nosym
     557              :       INTEGER, ALLOCATABLE, DIMENSION(:, :, :), &
     558              :          INTENT(OUT)                                     :: cell_to_index
     559              :       INTEGER, ALLOCATABLE, DIMENSION(:, :), INTENT(OUT) :: index_to_cell
     560              :       TYPE(kpoint_type), INTENT(IN), POINTER             :: kpoints
     561              : 
     562              :       CHARACTER(len=*), PARAMETER :: routineN = 'desymmetrize_rs_matrix'
     563              : 
     564              :       INTEGER                                            :: handle, iatom, ic, icn, icol, irow, &
     565              :                                                             ispin, jatom, ncell, nomirror, nspin, &
     566              :                                                             nx, ny, nz
     567              :       INTEGER, DIMENSION(3)                              :: cell
     568            2 :       INTEGER, DIMENSION(:, :), POINTER                  :: i2c
     569            2 :       INTEGER, DIMENSION(:, :, :), POINTER               :: c2i
     570              :       LOGICAL                                            :: found, lwtr
     571            2 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: block
     572              :       TYPE(neighbor_list_iterator_p_type), &
     573            2 :          DIMENSION(:), POINTER                           :: nl_iterator
     574              :       TYPE(neighbor_list_set_p_type), DIMENSION(:), &
     575            2 :          POINTER                                         :: sab_nl
     576              : 
     577            2 :       CALL timeset(routineN, handle)
     578              : 
     579            2 :       i2c => kpoints%index_to_cell
     580            2 :       c2i => kpoints%cell_to_index
     581              : 
     582            2 :       ncell = SIZE(i2c, 2)
     583            2 :       nspin = SIZE(mat, 1)
     584              : 
     585            2 :       nx = MAX(ABS(LBOUND(c2i, 1)), ABS(UBOUND(c2i, 1)))
     586            2 :       ny = MAX(ABS(LBOUND(c2i, 2)), ABS(UBOUND(c2i, 3)))
     587            2 :       nz = MAX(ABS(LBOUND(c2i, 3)), ABS(UBOUND(c2i, 3)))
     588           10 :       ALLOCATE (cell_to_index(-nx:nx, -ny:ny, -nz:nz))
     589              :       cell_to_index(LBOUND(c2i, 1):UBOUND(c2i, 1), &
     590              :                     LBOUND(c2i, 2):UBOUND(c2i, 2), &
     591           84 :                     LBOUND(c2i, 3):UBOUND(c2i, 3)) = c2i
     592              : 
     593              :       ! identify cells with no mirror img
     594              :       nomirror = 0
     595           52 :       DO ic = 1, ncell
     596          200 :          cell = i2c(:, ic)
     597           50 :          IF (cell_to_index(-cell(1), -cell(2), -cell(3)) == 0) &
     598            6 :             nomirror = nomirror + 1
     599              :       END DO
     600              : 
     601              :       ! create the mirror imgs
     602            6 :       ALLOCATE (index_to_cell(3, ncell + nomirror))
     603          202 :       index_to_cell(:, 1:ncell) = i2c
     604              : 
     605              :       nomirror = 0 ! count the imgs without mirror
     606           52 :       DO ic = 1, ncell
     607          200 :          cell = index_to_cell(:, ic)
     608           52 :          IF (cell_to_index(-cell(1), -cell(2), -cell(3)) == 0) THEN
     609            4 :             nomirror = nomirror + 1
     610           16 :             index_to_cell(:, ncell + nomirror) = -cell
     611            4 :             cell_to_index(-cell(1), -cell(2), -cell(3)) = ncell + nomirror
     612              :          END IF
     613              :       END DO
     614            2 :       ncell = ncell + nomirror
     615              : 
     616            2 :       CALL get_kpoint_info(kpoints, sab_nl=sab_nl)
     617              :       ! allocate the nonsymmetric matrices
     618            2 :       NULLIFY (mat_nosym)
     619            2 :       CALL dbcsr_allocate_matrix_set(mat_nosym, nspin, ncell)
     620            4 :       DO ispin = 1, nspin
     621           58 :          DO ic = 1, ncell
     622           54 :             ALLOCATE (mat_nosym(ispin, ic)%matrix)
     623              :             CALL dbcsr_create(matrix=mat_nosym(ispin, ic)%matrix, &
     624              :                               template=mat(1, 1)%matrix, &
     625           54 :                               matrix_type=dbcsr_type_no_symmetry)
     626              :             CALL cp_dbcsr_alloc_block_from_nbl(mat_nosym(ispin, ic)%matrix, &
     627           54 :                                                sab_nl, desymmetrize=.TRUE.)
     628           56 :             CALL dbcsr_set(mat_nosym(ispin, ic)%matrix, 0.0_dp)
     629              :          END DO
     630              :       END DO
     631              : 
     632            4 :       DO ispin = 1, nspin
     633              :          ! desymmetrize the matrix for real space printing
     634            2 :          CALL neighbor_list_iterator_create(nl_iterator, sab_nl)
     635          506 :          DO WHILE (neighbor_list_iterate(nl_iterator) == 0)
     636          504 :             CALL get_iterator_info(nl_iterator, iatom=iatom, jatom=jatom, cell=cell)
     637              : 
     638          504 :             ic = cell_to_index(cell(1), cell(2), cell(3))
     639          504 :             icn = cell_to_index(-cell(1), -cell(2), -cell(3))
     640          504 :             CPASSERT(icn > 0)
     641              : 
     642          504 :             irow = iatom
     643          504 :             icol = jatom
     644          504 :             lwtr = .FALSE.
     645              :             ! always copy from the top
     646          504 :             IF (iatom > jatom) THEN
     647          216 :                irow = jatom
     648          216 :                icol = iatom
     649          216 :                lwtr = .TRUE.
     650              :             END IF
     651              : 
     652              :             CALL dbcsr_get_block_p(matrix=mat(ispin, ic)%matrix, &
     653          504 :                                    row=irow, col=icol, block=block, found=found)
     654          504 :             CPASSERT(found)
     655              : 
     656              :             ! copy to M(R) at (iatom,jatom)
     657              :             ! copy to M(-R) at (jatom,iatom)
     658          506 :             IF (lwtr) THEN
     659              :                CALL dbcsr_put_block(matrix=mat_nosym(ispin, ic)%matrix, &
     660         4536 :                                     row=iatom, col=jatom, block=TRANSPOSE(block))
     661              :                CALL dbcsr_put_block(matrix=mat_nosym(ispin, icn)%matrix, &
     662          216 :                                     row=jatom, col=iatom, block=block)
     663              :             ELSE
     664              :                CALL dbcsr_put_block(matrix=mat_nosym(ispin, ic)%matrix, &
     665          288 :                                     row=iatom, col=jatom, block=block)
     666              :                CALL dbcsr_put_block(matrix=mat_nosym(ispin, icn)%matrix, &
     667         6048 :                                     row=jatom, col=iatom, block=TRANSPOSE(block))
     668              :             END IF
     669              :          END DO
     670            4 :          CALL neighbor_list_iterator_release(nl_iterator)
     671              :       END DO
     672              : 
     673            4 :       DO ispin = 1, nspin
     674           58 :          DO ic = 1, ncell
     675           56 :             CALL dbcsr_finalize(mat_nosym(ispin, ic)%matrix)
     676              :          END DO
     677              :       END DO
     678              : 
     679            2 :       CALL timestop(handle)
     680              : 
     681            2 :    END SUBROUTINE desymmetrize_rs_matrix
     682              : 
     683              : END MODULE qs_scf_csr_write
        

Generated by: LCOV version 2.0-1