LCOV - code coverage report
Current view: top level - src - cp_dbcsr_output.F (source / functions) Coverage Total Hit
Test: CP2K Regtests (git:936074a) Lines: 77.3 % 251 194
Test Date: 2025-12-04 06:27:48 Functions: 83.3 % 6 5

            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   DBCSR output in CP2K
      10              : !> \author  VW
      11              : !> \date    2009-09-09
      12              : !> \version 0.1
      13              : !>
      14              : !> <b>Modification history:</b>
      15              : !> - Created 2009-09-09
      16              : ! **************************************************************************************************
      17              : MODULE cp_dbcsr_output
      18              :    USE atomic_kind_types,               ONLY: atomic_kind_type,&
      19              :                                               get_atomic_kind
      20              :    USE basis_set_types,                 ONLY: get_gto_basis_set,&
      21              :                                               gto_basis_set_type
      22              :    USE cp_dbcsr_api,                    ONLY: &
      23              :         dbcsr_get_data_size, dbcsr_get_info, dbcsr_get_matrix_type, dbcsr_get_num_blocks, &
      24              :         dbcsr_iterator_blocks_left, dbcsr_iterator_next_block, dbcsr_iterator_start, &
      25              :         dbcsr_iterator_stop, dbcsr_iterator_type, dbcsr_type, dbcsr_type_antisymmetric, &
      26              :         dbcsr_type_no_symmetry, dbcsr_type_symmetric
      27              :    USE cp_fm_types,                     ONLY: cp_fm_get_info,&
      28              :                                               cp_fm_get_submatrix,&
      29              :                                               cp_fm_type
      30              :    USE cp_log_handling,                 ONLY: cp_get_default_logger,&
      31              :                                               cp_logger_type
      32              :    USE kinds,                           ONLY: default_string_length,&
      33              :                                               dp,&
      34              :                                               int_8
      35              :    USE machine,                         ONLY: m_flush
      36              :    USE mathlib,                         ONLY: symmetrize_matrix
      37              :    USE message_passing,                 ONLY: mp_para_env_type
      38              :    USE orbital_pointers,                ONLY: nso
      39              :    USE particle_methods,                ONLY: get_particle_set
      40              :    USE particle_types,                  ONLY: particle_type
      41              :    USE qs_environment_types,            ONLY: get_qs_env,&
      42              :                                               qs_environment_type
      43              :    USE qs_kind_types,                   ONLY: get_qs_kind,&
      44              :                                               get_qs_kind_set,&
      45              :                                               qs_kind_type
      46              : #include "./base/base_uses.f90"
      47              : 
      48              :    IMPLICIT NONE
      49              : 
      50              :    CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'cp_dbcsr_output'
      51              : 
      52              :    PUBLIC :: cp_dbcsr_write_sparse_matrix
      53              :    PUBLIC :: cp_dbcsr_write_matrix_dist
      54              :    PUBLIC :: write_fm_with_basis_info
      55              : 
      56              :    PRIVATE
      57              : 
      58              : CONTAINS
      59              : 
      60              : ! **************************************************************************************************
      61              : !> \brief Print a spherical matrix of blacs type.
      62              : !> \param blacs_matrix ...
      63              : !> \param before ...
      64              : !> \param after ...
      65              : !> \param qs_env ...
      66              : !> \param para_env ...
      67              : !> \param first_row ...
      68              : !> \param last_row ...
      69              : !> \param first_col ...
      70              : !> \param last_col ...
      71              : !> \param output_unit ...
      72              : !> \param omit_headers Write only the matrix data, not the row/column headers
      73              : !> \author Creation (12.06.2001,MK)
      74              : !>       Allow for printing of a sub-matrix (01.07.2003,MK)
      75              : ! **************************************************************************************************
      76            8 :    SUBROUTINE write_fm_with_basis_info(blacs_matrix, before, after, qs_env, para_env, &
      77              :                                        first_row, last_row, first_col, last_col, output_unit, omit_headers)
      78              : 
      79              :       TYPE(cp_fm_type), INTENT(IN)                       :: blacs_matrix
      80              :       INTEGER, INTENT(IN)                                :: before, after
      81              :       TYPE(qs_environment_type), POINTER                 :: qs_env
      82              :       TYPE(mp_para_env_type), POINTER                    :: para_env
      83              :       INTEGER, INTENT(IN), OPTIONAL                      :: first_row, last_row, first_col, last_col
      84              :       INTEGER, INTENT(IN)                                :: output_unit
      85              :       LOGICAL, INTENT(IN), OPTIONAL                      :: omit_headers
      86              : 
      87              :       CHARACTER(LEN=60)                                  :: matrix_name
      88              :       INTEGER                                            :: col1, col2, ncol_global, nrow_global, &
      89              :                                                             nsgf, row1, row2
      90              :       LOGICAL                                            :: my_omit_headers
      91            8 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: matrix
      92            8 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
      93              : 
      94            0 :       IF (.NOT. ASSOCIATED(blacs_matrix%matrix_struct)) RETURN
      95              :       CALL cp_fm_get_info(blacs_matrix, name=matrix_name, nrow_global=nrow_global, &
      96            8 :                           ncol_global=ncol_global)
      97              : 
      98           32 :       ALLOCATE (matrix(nrow_global, ncol_global))
      99            8 :       CALL cp_fm_get_submatrix(blacs_matrix, matrix)
     100              : 
     101              :       ! *** Get the matrix dimension and check the optional arguments ***
     102            8 :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set)
     103            8 :       CALL get_qs_kind_set(qs_kind_set=qs_kind_set, nsgf=nsgf)
     104              : 
     105            8 :       IF (PRESENT(first_row)) THEN
     106            0 :          row1 = MAX(1, first_row)
     107              :       ELSE
     108            8 :          row1 = 1
     109              :       END IF
     110              : 
     111            8 :       IF (PRESENT(last_row)) THEN
     112            0 :          row2 = MIN(nsgf, last_row)
     113              :       ELSE
     114            8 :          row2 = nsgf
     115              :       END IF
     116              : 
     117            8 :       IF (PRESENT(first_col)) THEN
     118            0 :          col1 = MAX(1, first_col)
     119              :       ELSE
     120            8 :          col1 = 1
     121              :       END IF
     122              : 
     123            8 :       IF (PRESENT(last_col)) THEN
     124            0 :          col2 = MIN(nsgf, last_col)
     125              :       ELSE
     126            8 :          col2 = nsgf
     127              :       END IF
     128              : 
     129            8 :       IF (PRESENT(omit_headers)) THEN
     130            4 :          my_omit_headers = omit_headers
     131              :       ELSE
     132            4 :          my_omit_headers = .FALSE.
     133              :       END IF
     134              : 
     135              :       CALL write_matrix_sym(matrix, matrix_name, before, after, qs_env, para_env, &
     136            8 :                             row1, row2, col1, col2, output_unit, omit_headers=my_omit_headers)
     137              : 
     138              :       ! *** Release work storage ***
     139            8 :       IF (ASSOCIATED(matrix)) THEN
     140            8 :          DEALLOCATE (matrix)
     141              :       END IF
     142              : 
     143           16 :    END SUBROUTINE write_fm_with_basis_info
     144              : 
     145              : ! **************************************************************************************************
     146              : !> \brief ...
     147              : !> \param sparse_matrix ...
     148              : !> \param before ...
     149              : !> \param after ...
     150              : !> \param qs_env ...
     151              : !> \param para_env ...
     152              : !> \param first_row ...
     153              : !> \param last_row ...
     154              : !> \param first_col ...
     155              : !> \param last_col ...
     156              : !> \param scale ...
     157              : !> \param output_unit ...
     158              : !> \param omit_headers Write only the matrix data, not the row/column headers
     159              : ! **************************************************************************************************
     160        15896 :    SUBROUTINE cp_dbcsr_write_sparse_matrix(sparse_matrix, before, after, qs_env, para_env, &
     161              :                                            first_row, last_row, first_col, last_col, scale, &
     162              :                                            output_unit, omit_headers)
     163              : 
     164              :       TYPE(dbcsr_type)                                   :: sparse_matrix
     165              :       INTEGER, INTENT(IN)                                :: before, after
     166              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     167              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     168              :       INTEGER, INTENT(IN), OPTIONAL                      :: first_row, last_row, first_col, last_col
     169              :       REAL(dp), INTENT(IN), OPTIONAL                     :: scale
     170              :       INTEGER, INTENT(IN)                                :: output_unit
     171              :       LOGICAL, INTENT(IN), OPTIONAL                      :: omit_headers
     172              : 
     173              :       CHARACTER(LEN=default_string_length)               :: matrix_name
     174              :       INTEGER                                            :: col1, col2, dim_col, dim_row, row1, row2
     175              :       LOGICAL                                            :: my_omit_headers, print_sym
     176        15896 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: matrix
     177        15896 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     178              : 
     179        15896 :       NULLIFY (matrix)
     180              : 
     181        15896 :       CALL copy_repl_dbcsr_to_repl_fm(sparse_matrix, matrix)
     182              : 
     183      3459768 :       CALL para_env%sum(matrix)
     184              : 
     185        15860 :       SELECT CASE (dbcsr_get_matrix_type(sparse_matrix))
     186              :       CASE (dbcsr_type_symmetric)
     187        15860 :          CALL symmetrize_matrix(matrix, "upper_to_lower")
     188        15860 :          print_sym = .TRUE.
     189              :       CASE (dbcsr_type_antisymmetric)
     190           36 :          CALL symmetrize_matrix(matrix, "anti_upper_to_lower")
     191           36 :          print_sym = .TRUE.
     192              :       CASE (dbcsr_type_no_symmetry)
     193            0 :          print_sym = .FALSE.
     194              :       CASE DEFAULT
     195        15896 :          CPABORT("WRONG")
     196              :       END SELECT
     197              : 
     198              :       ! *** Get the matrix dimension and check the optional arguments ***
     199        15896 :       CALL get_qs_env(qs_env=qs_env, qs_kind_set=qs_kind_set)
     200        15896 :       dim_row = SIZE(matrix, 1)
     201        15896 :       dim_col = SIZE(matrix, 2)
     202              : 
     203        15896 :       IF (PRESENT(first_row)) THEN
     204            0 :          row1 = MAX(1, first_row)
     205              :       ELSE
     206        15896 :          row1 = 1
     207              :       END IF
     208              : 
     209        15896 :       IF (PRESENT(last_row)) THEN
     210            0 :          row2 = MIN(dim_row, last_row)
     211              :       ELSE
     212        15896 :          row2 = dim_row
     213              :       END IF
     214              : 
     215        15896 :       IF (PRESENT(first_col)) THEN
     216            0 :          col1 = MAX(1, first_col)
     217              :       ELSE
     218        15896 :          col1 = 1
     219              :       END IF
     220              : 
     221        15896 :       IF (PRESENT(last_col)) THEN
     222            0 :          col2 = MIN(dim_col, last_col)
     223              :       ELSE
     224        15896 :          col2 = dim_col
     225              :       END IF
     226              : 
     227        15896 :       IF (PRESENT(scale)) THEN
     228       810710 :          matrix = matrix*scale
     229              :       END IF
     230              : 
     231        15896 :       IF (PRESENT(omit_headers)) THEN
     232        15696 :          my_omit_headers = omit_headers
     233              :       ELSE
     234          200 :          my_omit_headers = .FALSE.
     235              :       END IF
     236              : 
     237        15896 :       CALL dbcsr_get_info(sparse_matrix, name=matrix_name)
     238        15896 :       IF (print_sym) THEN
     239              :          CALL write_matrix_sym(matrix, matrix_name, before, after, qs_env, para_env, &
     240        15896 :                                row1, row2, col1, col2, output_unit, my_omit_headers)
     241              :       ELSE
     242              :          CALL write_matrix_gen(matrix, matrix_name, before, after, para_env, &
     243            0 :                                row1, row2, col1, col2, output_unit, my_omit_headers)
     244              :       END IF
     245              : 
     246        15896 :       IF (ASSOCIATED(matrix)) THEN
     247        15896 :          DEALLOCATE (matrix)
     248              :       END IF
     249              : 
     250        15896 :    END SUBROUTINE cp_dbcsr_write_sparse_matrix
     251              : 
     252              : ! **************************************************************************************************
     253              : !> \brief ...
     254              : !> \param sparse_matrix ...
     255              : !> \param fm ...
     256              : ! **************************************************************************************************
     257        15896 :    SUBROUTINE copy_repl_dbcsr_to_repl_fm(sparse_matrix, fm)
     258              : 
     259              :       TYPE(dbcsr_type)                                   :: sparse_matrix
     260              :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: fm
     261              : 
     262              :       CHARACTER(len=*), PARAMETER :: routineN = 'copy_repl_dbcsr_to_repl_fm'
     263              : 
     264              :       INTEGER                                            :: col, handle, i, j, nblkcols_total, &
     265              :                                                             nblkrows_total, nc, nr, row
     266        15896 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: c_offset, r_offset
     267        15896 :       INTEGER, DIMENSION(:), POINTER                     :: col_blk_size, row_blk_size
     268        15896 :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: block
     269              :       TYPE(dbcsr_iterator_type)                          :: iter
     270              : 
     271        15896 :       CALL timeset(routineN, handle)
     272              : 
     273        15896 :       IF (ASSOCIATED(fm)) DEALLOCATE (fm)
     274              : 
     275              :       CALL dbcsr_get_info(matrix=sparse_matrix, &
     276              :                           col_blk_size=col_blk_size, &
     277              :                           row_blk_size=row_blk_size, &
     278              :                           nblkrows_total=nblkrows_total, &
     279        15896 :                           nblkcols_total=nblkcols_total)
     280              : 
     281              :       !> this should be precomputed somewhere else
     282        79480 :       ALLOCATE (r_offset(nblkrows_total), c_offset(nblkcols_total))
     283              : 
     284        15896 :       r_offset(1) = 1
     285        33492 :       DO row = 2, nblkrows_total
     286        33492 :          r_offset(row) = r_offset(row - 1) + row_blk_size(row - 1)
     287              :       END DO
     288        49388 :       nr = SUM(row_blk_size)
     289        15896 :       c_offset(1) = 1
     290        33492 :       DO col = 2, nblkcols_total
     291        33492 :          c_offset(col) = c_offset(col - 1) + col_blk_size(col - 1)
     292              :       END DO
     293        49388 :       nc = SUM(col_blk_size)
     294              :       !<
     295              : 
     296        63584 :       ALLOCATE (fm(nr, nc))
     297              : 
     298      1737832 :       fm(:, :) = 0.0_dp
     299              : 
     300        15896 :       CALL dbcsr_iterator_start(iter, sparse_matrix)
     301        42505 :       DO WHILE (dbcsr_iterator_blocks_left(iter))
     302        26609 :          CALL dbcsr_iterator_next_block(iter, row, col, block)
     303       187367 :          DO j = 1, SIZE(block, 2)
     304       866713 :          DO i = 1, SIZE(block, 1)
     305       840104 :             fm(r_offset(row) + i - 1, c_offset(col) + j - 1) = block(i, j)
     306              :          END DO
     307              :          END DO
     308              :       END DO
     309        15896 :       CALL dbcsr_iterator_stop(iter)
     310              : 
     311        15896 :       DEALLOCATE (r_offset, c_offset)
     312              : 
     313        15896 :       CALL timestop(handle)
     314              : 
     315        47688 :    END SUBROUTINE copy_repl_dbcsr_to_repl_fm
     316              : 
     317              : ! **************************************************************************************************
     318              : !> \brief Write a matrix or a sub-matrix to the output unit (symmetric)
     319              : !> \param matrix ...
     320              : !> \param matrix_name ...
     321              : !> \param before ...
     322              : !> \param after ...
     323              : !> \param qs_env ...
     324              : !> \param para_env ...
     325              : !> \param first_row ...
     326              : !> \param last_row ...
     327              : !> \param first_col ...
     328              : !> \param last_col ...
     329              : !> \param output_unit ...
     330              : !> \param omit_headers Write only the matrix data, not the row/column headers
     331              : !> \author Creation (01.07.2003,MK)
     332              : ! **************************************************************************************************
     333        15904 :    SUBROUTINE write_matrix_sym(matrix, matrix_name, before, after, qs_env, para_env, &
     334              :                                first_row, last_row, first_col, last_col, output_unit, omit_headers)
     335              : 
     336              :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: matrix
     337              :       CHARACTER(LEN=*), INTENT(IN)                       :: matrix_name
     338              :       INTEGER, INTENT(IN)                                :: before, after
     339              :       TYPE(qs_environment_type), POINTER                 :: qs_env
     340              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     341              :       INTEGER, INTENT(IN)                                :: first_row, last_row, first_col, &
     342              :                                                             last_col, output_unit
     343              :       LOGICAL, INTENT(IN)                                :: omit_headers
     344              : 
     345              :       CHARACTER(LEN=2)                                   :: element_symbol
     346              :       CHARACTER(LEN=25)                                  :: fmtstr1
     347              :       CHARACTER(LEN=35)                                  :: fmtstr2
     348        15904 :       CHARACTER(LEN=6), DIMENSION(:), POINTER            :: sgf_symbol
     349              :       INTEGER                                            :: from, iatom, icol, ikind, irow, iset, &
     350              :                                                             isgf, ishell, iso, jcol, l, left, &
     351              :                                                             natom, ncol, ndigits, nset, nsgf, &
     352              :                                                             right, to, width
     353        15904 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: first_sgf, last_sgf
     354        15904 :       INTEGER, DIMENSION(:), POINTER                     :: nshell
     355        15904 :       INTEGER, DIMENSION(:, :), POINTER                  :: lshell
     356        15904 :       TYPE(atomic_kind_type), DIMENSION(:), POINTER      :: atomic_kind_set
     357              :       TYPE(gto_basis_set_type), POINTER                  :: orb_basis_set
     358        15904 :       TYPE(particle_type), DIMENSION(:), POINTER         :: particle_set
     359        15904 :       TYPE(qs_kind_type), DIMENSION(:), POINTER          :: qs_kind_set
     360              : 
     361        15904 :       IF (output_unit > 0) THEN
     362         7952 :          CALL m_flush(output_unit)
     363              : 
     364              :          CALL get_qs_env(qs_env=qs_env, &
     365              :                          qs_kind_set=qs_kind_set, &
     366              :                          atomic_kind_set=atomic_kind_set, &
     367         7952 :                          particle_set=particle_set)
     368              : 
     369         7952 :          natom = SIZE(particle_set)
     370              : 
     371         7952 :          CALL get_qs_kind_set(qs_kind_set=qs_kind_set, nsgf=nsgf)
     372              : 
     373        23856 :          ALLOCATE (first_sgf(natom))
     374        15904 :          ALLOCATE (last_sgf(natom))
     375              :          CALL get_particle_set(particle_set, qs_kind_set, &
     376              :                                first_sgf=first_sgf, &
     377         7952 :                                last_sgf=last_sgf)
     378              : 
     379              :          ! *** Definition of the variable formats ***
     380         7952 :          fmtstr1 = "(/,T2,23X,  (  X,I5,  X))"
     381         7952 :          IF (omit_headers) THEN
     382           46 :             fmtstr2 = "(T2,   (1X,F  .  ))"
     383              :          ELSE
     384         7906 :             fmtstr2 = "(T2,2I5,2X,A2,1X,A8,   (1X,F  .  ))"
     385              :          END IF
     386              : 
     387              :          ! *** Write headline ***
     388         7952 :          WRITE (UNIT=output_unit, FMT="(/,/,T2,A)") TRIM(matrix_name)
     389              : 
     390              :          ! *** Write the variable format strings ***
     391         7952 :          ndigits = after
     392              : 
     393         7952 :          width = before + ndigits + 3
     394         7952 :          ncol = INT(56/width)
     395              : 
     396         7952 :          right = MAX((ndigits - 2), 1)
     397         7952 :          left = width - right - 5
     398              : 
     399         7952 :          WRITE (UNIT=fmtstr1(11:12), FMT="(I2)") ncol
     400         7952 :          WRITE (UNIT=fmtstr1(14:15), FMT="(I2)") left
     401         7952 :          WRITE (UNIT=fmtstr1(21:22), FMT="(I2)") right
     402              : 
     403         7952 :          IF (omit_headers) THEN
     404           46 :             WRITE (UNIT=fmtstr2(6:7), FMT="(I2)") ncol
     405           46 :             WRITE (UNIT=fmtstr2(13:14), FMT="(I2)") width - 1
     406           46 :             WRITE (UNIT=fmtstr2(16:17), FMT="(I2)") ndigits
     407              :          ELSE
     408         7906 :             WRITE (UNIT=fmtstr2(22:23), FMT="(I2)") ncol
     409         7906 :             WRITE (UNIT=fmtstr2(29:30), FMT="(I2)") width - 1
     410         7906 :             WRITE (UNIT=fmtstr2(32:33), FMT="(I2)") ndigits
     411              :          END IF
     412              : 
     413              :          ! *** Write the matrix in the selected format ***
     414        31339 :          DO icol = first_col, last_col, ncol
     415        23387 :             from = icol
     416        23387 :             to = MIN((from + ncol - 1), last_col)
     417        23387 :             IF (.NOT. omit_headers) THEN
     418        99958 :                WRITE (UNIT=output_unit, FMT=fmtstr1) (jcol, jcol=from, to)
     419              :             END IF
     420        23387 :             irow = 1
     421        80814 :             DO iatom = 1, natom
     422        49475 :                NULLIFY (orb_basis_set)
     423              :                CALL get_atomic_kind(particle_set(iatom)%atomic_kind, &
     424        49475 :                                     kind_number=ikind, element_symbol=element_symbol)
     425        49475 :                CALL get_qs_kind(qs_kind_set(ikind), basis_set=orb_basis_set)
     426       122337 :                IF (ASSOCIATED(orb_basis_set)) THEN
     427              :                   CALL get_gto_basis_set(gto_basis_set=orb_basis_set, &
     428        49475 :                                          nset=nset, nshell=nshell, l=lshell, sgf_symbol=sgf_symbol)
     429        49475 :                   isgf = 1
     430       146030 :                   DO iset = 1, nset
     431       244645 :                      DO ishell = 1, nshell(iset)
     432        98615 :                         l = lshell(ishell, iset)
     433       432393 :                         DO iso = 1, nso(l)
     434       237223 :                            IF ((irow >= first_row) .AND. (irow <= last_row)) THEN
     435       237223 :                               IF (omit_headers) THEN
     436              :                                  WRITE (UNIT=output_unit, FMT=fmtstr2) &
     437         3604 :                                     (matrix(irow, jcol), jcol=from, to)
     438              :                               ELSE
     439              :                                  WRITE (UNIT=output_unit, FMT=fmtstr2) &
     440       233619 :                                     irow, iatom, element_symbol, sgf_symbol(isgf), &
     441       467238 :                                     (matrix(irow, jcol), jcol=from, to)
     442              :                               END IF
     443              :                            END IF
     444       237223 :                            isgf = isgf + 1
     445       335838 :                            irow = irow + 1
     446              :                         END DO
     447              :                      END DO
     448              :                   END DO
     449        49475 :                   IF ((irow >= first_row) .AND. (irow <= last_row)) THEN
     450        26088 :                      WRITE (UNIT=output_unit, FMT="(A)")
     451              :                   END IF
     452              :                ELSE
     453            0 :                   DO iso = first_sgf(iatom), last_sgf(iatom)
     454            0 :                      IF ((irow >= first_row) .AND. (irow <= last_row)) THEN
     455            0 :                         IF (omit_headers) THEN
     456              :                            WRITE (UNIT=output_unit, FMT=fmtstr2) &
     457            0 :                               (matrix(irow, jcol), jcol=from, to)
     458              :                         ELSE
     459              :                            WRITE (UNIT=output_unit, FMT=fmtstr2) &
     460            0 :                               irow, iatom, element_symbol, " ", &
     461            0 :                               (matrix(irow, jcol), jcol=from, to)
     462              :                         END IF
     463              :                      END IF
     464            0 :                      irow = irow + 1
     465              :                   END DO
     466            0 :                   IF ((irow >= first_row) .AND. (irow <= last_row)) THEN
     467            0 :                      WRITE (UNIT=output_unit, FMT="(A)")
     468              :                   END IF
     469              :                END IF
     470              :             END DO
     471              :          END DO
     472              : 
     473         7952 :          WRITE (UNIT=output_unit, FMT="(/)")
     474         7952 :          DEALLOCATE (first_sgf)
     475        15904 :          DEALLOCATE (last_sgf)
     476              :       END IF
     477              : 
     478        15904 :       CALL para_env%sync()
     479        15904 :       IF (output_unit > 0) CALL m_flush(output_unit)
     480              : 
     481        31808 :    END SUBROUTINE write_matrix_sym
     482              : 
     483              : ! **************************************************************************************************
     484              : !> \brief Write a matrix not necessarily symmetric (no index with atomic labels)
     485              : !> \param matrix ...
     486              : !> \param matrix_name ...
     487              : !> \param before ...
     488              : !> \param after ...
     489              : !> \param para_env ...
     490              : !> \param first_row ...
     491              : !> \param last_row ...
     492              : !> \param first_col ...
     493              : !> \param last_col ...
     494              : !> \param output_unit ...
     495              : !> \param omit_headers Write only the matrix data, not the row/column headers
     496              : !> \author Teodoro Laino [tlaino] - 10.2007 - University of Zurich
     497              : ! **************************************************************************************************
     498            0 :    SUBROUTINE write_matrix_gen(matrix, matrix_name, before, after, para_env, &
     499              :                                first_row, last_row, first_col, last_col, output_unit, omit_headers)
     500              : 
     501              :       REAL(KIND=dp), DIMENSION(:, :), POINTER            :: matrix
     502              :       CHARACTER(LEN=*), INTENT(IN)                       :: matrix_name
     503              :       INTEGER, INTENT(IN)                                :: before, after
     504              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     505              :       INTEGER, INTENT(IN)                                :: first_row, last_row, first_col, &
     506              :                                                             last_col, output_unit
     507              :       LOGICAL, INTENT(IN)                                :: omit_headers
     508              : 
     509              :       CHARACTER(LEN=25)                                  :: fmtstr1
     510              :       CHARACTER(LEN=35)                                  :: fmtstr2
     511              :       INTEGER                                            :: from, icol, irow, jcol, left, ncol, &
     512              :                                                             ndigits, right, to, width
     513              : 
     514            0 :       IF (output_unit > 0) THEN
     515            0 :          CALL m_flush(output_unit)
     516              : 
     517              :          ! *** Definition of the variable formats ***
     518            0 :          fmtstr1 = "(/,T2,23X,  (  X,I5,  X))"
     519            0 :          IF (omit_headers) THEN
     520            0 :             fmtstr2 = "(T2,   (1X,F  .  ))"
     521              :          ELSE
     522            0 :             fmtstr2 = "(T2, I5,        18X,   (1X,F  .  ))"
     523              :          END IF
     524              : 
     525              :          ! *** Write headline ***
     526            0 :          WRITE (UNIT=output_unit, FMT="(/,/,T2,A)") TRIM(matrix_name)
     527              : 
     528              :          ! *** Write the variable format strings ***
     529            0 :          ndigits = after
     530              : 
     531            0 :          width = before + ndigits + 3
     532            0 :          ncol = INT(56/width)
     533              : 
     534            0 :          right = MAX((ndigits - 2), 1)
     535            0 :          left = width - right - 5
     536              : 
     537            0 :          WRITE (UNIT=fmtstr1(11:12), FMT="(I2)") ncol
     538            0 :          WRITE (UNIT=fmtstr1(14:15), FMT="(I2)") left
     539            0 :          WRITE (UNIT=fmtstr1(21:22), FMT="(I2)") right
     540              : 
     541            0 :          IF (omit_headers) THEN
     542            0 :             WRITE (UNIT=fmtstr2(6:7), FMT="(I2)") ncol
     543            0 :             WRITE (UNIT=fmtstr2(13:14), FMT="(I2)") width - 1
     544            0 :             WRITE (UNIT=fmtstr2(16:17), FMT="(I2)") ndigits
     545              :          ELSE
     546            0 :             WRITE (UNIT=fmtstr2(22:23), FMT="(I2)") ncol
     547            0 :             WRITE (UNIT=fmtstr2(29:30), FMT="(I2)") width - 1
     548            0 :             WRITE (UNIT=fmtstr2(32:33), FMT="(I2)") ndigits
     549              :          END IF
     550              : 
     551              :          ! *** Write the matrix in the selected format ***
     552            0 :          DO icol = first_col, last_col, ncol
     553            0 :             from = icol
     554            0 :             to = MIN((from + ncol - 1), last_col)
     555            0 :             IF (.NOT. omit_headers) THEN
     556            0 :                WRITE (UNIT=output_unit, FMT=fmtstr1) (jcol, jcol=from, to)
     557              :             END IF
     558              :             irow = 1
     559            0 :             DO irow = first_row, last_row
     560            0 :                IF (omit_headers) THEN
     561              :                   WRITE (UNIT=output_unit, FMT=fmtstr2) &
     562            0 :                      irow, (matrix(irow, jcol), jcol=from, to)
     563              :                ELSE
     564              :                   WRITE (UNIT=output_unit, FMT=fmtstr2) &
     565            0 :                      (matrix(irow, jcol), jcol=from, to)
     566              :                END IF
     567              :             END DO
     568              :          END DO
     569              : 
     570            0 :          WRITE (UNIT=output_unit, FMT="(/)")
     571              :       END IF
     572              : 
     573            0 :       CALL para_env%sync()
     574            0 :       IF (output_unit > 0) CALL m_flush(output_unit)
     575              : 
     576            0 :    END SUBROUTINE write_matrix_gen
     577              : 
     578              : ! **************************************************************************************************
     579              : !> \brief Print the distribution of a sparse matrix.
     580              : !> \param matrix ...
     581              : !> \param output_unit ...
     582              : !> \param para_env ...
     583              : !> \par History
     584              : !>      Creation (25.06.2003,MK)
     585              : ! **************************************************************************************************
     586           92 :    SUBROUTINE cp_dbcsr_write_matrix_dist(matrix, output_unit, para_env)
     587              :       TYPE(dbcsr_type)                                   :: matrix
     588              :       INTEGER, INTENT(IN)                                :: output_unit
     589              :       TYPE(mp_para_env_type), POINTER                    :: para_env
     590              : 
     591              :       CHARACTER(LEN=*), PARAMETER :: routineN = 'cp_dbcsr_write_matrix_dist'
     592              :       LOGICAL, PARAMETER                                 :: full_output = .FALSE.
     593              : 
     594              :       CHARACTER                                          :: matrix_type
     595              :       CHARACTER(LEN=default_string_length)               :: matrix_name
     596              :       INTEGER                                            :: handle, ipe, mype, natom, nblock_max, &
     597              :                                                             nelement_max, npe, nrow, tmp(2)
     598              :       INTEGER(KIND=int_8)                                :: nblock_sum, nblock_tot, nelement_sum
     599           92 :       INTEGER, ALLOCATABLE, DIMENSION(:)                 :: nblock, nelement
     600              :       LOGICAL                                            :: ionode
     601              :       REAL(KIND=dp)                                      :: occupation
     602              :       TYPE(cp_logger_type), POINTER                      :: logger
     603              : 
     604           92 :       NULLIFY (logger)
     605           92 :       logger => cp_get_default_logger()
     606              : 
     607           92 :       CALL timeset(routineN, handle)
     608              : 
     609           92 :       ionode = para_env%is_source()
     610           92 :       mype = para_env%mepos + 1
     611           92 :       npe = para_env%num_pe
     612              : 
     613              :       ! *** Allocate work storage ***
     614          276 :       ALLOCATE (nblock(npe))
     615          276 :       nblock(:) = 0
     616              : 
     617          184 :       ALLOCATE (nelement(npe))
     618          276 :       nelement(:) = 0
     619              : 
     620           92 :       nblock(mype) = dbcsr_get_num_blocks(matrix)
     621           92 :       nelement(mype) = dbcsr_get_data_size(matrix)
     622              : 
     623              :       CALL dbcsr_get_info(matrix=matrix, &
     624              :                           name=matrix_name, &
     625              :                           matrix_type=matrix_type, &
     626              :                           nblkrows_total=natom, &
     627           92 :                           nfullrows_total=nrow)
     628              : 
     629              :       IF (full_output) THEN
     630              :          ! XXXXXXXX should gather/scatter this on ionode
     631              :          CALL para_env%sum(nblock)
     632              :          CALL para_env%sum(nelement)
     633              : 
     634              :          nblock_sum = SUM(INT(nblock, KIND=int_8))
     635              :          nelement_sum = SUM(INT(nelement, KIND=int_8))
     636              :       ELSE
     637           92 :          nblock_sum = nblock(mype)
     638              :          nblock_max = nblock(mype)
     639           92 :          nelement_sum = nelement(mype)
     640              :          nelement_max = nelement(mype)
     641           92 :          CALL para_env%sum(nblock_sum)
     642           92 :          CALL para_env%sum(nelement_sum)
     643          276 :          tmp = [nblock_max, nelement_max]
     644           92 :          CALL para_env%max(tmp)
     645           92 :          nblock_max = tmp(1); nelement_max = tmp(2)
     646              :       END IF
     647              : 
     648           92 :       IF (matrix_type == dbcsr_type_symmetric .OR. &
     649              :           matrix_type == dbcsr_type_antisymmetric) THEN
     650           92 :          nblock_tot = INT(natom, KIND=int_8)*INT(natom + 1, KIND=int_8)/2
     651              :       ELSE
     652            0 :          nblock_tot = INT(natom, KIND=int_8)**2
     653              :       END IF
     654              : 
     655           92 :       occupation = -1.0_dp
     656           92 :       IF (nblock_tot /= 0) occupation = 100.0_dp*REAL(nblock_sum, dp)/REAL(nblock_tot, dp)
     657              : 
     658           92 :       IF (ionode) THEN
     659              :          WRITE (UNIT=output_unit, FMT="(/,/,T2,A)") &
     660           46 :             "DISTRIBUTION OF THE "//TRIM(matrix_name)
     661              :          IF (full_output) THEN
     662              :             WRITE (UNIT=output_unit, FMT="(/,T3,A,/,/,(I9,T27,I10,T55,I10))") &
     663              :                "Process    Number of matrix blocks   Number of matrix elements", &
     664              :                (ipe - 1, nblock(ipe), nelement(ipe), ipe=1, npe)
     665              :             WRITE (UNIT=output_unit, FMT="(/,T7,A3,T27,I10,T55,I10)") &
     666              :                "Sum", nblock_sum, nelement_sum
     667              :             WRITE (UNIT=output_unit, FMT="(/,T7,A3,T27,I10,A,F5.1,A,T55,I10,A,F5.1,A)") &
     668              :                " of", nblock_tot, " (", occupation, " % occupation)"
     669              :          ELSE
     670           46 :             WRITE (UNIT=output_unit, FMT="(T15,A,T68,I13)") "Number  of non-zero blocks:", nblock_sum
     671           46 :             WRITE (UNIT=output_unit, FMT="(T15,A,T75,F6.2)") "Percentage non-zero blocks:", occupation
     672           46 :             WRITE (UNIT=output_unit, FMT="(T15,A,T68,I13)") "Average number of blocks per CPU:", &
     673           92 :                (nblock_sum + npe - 1)/npe
     674           46 :             WRITE (UNIT=output_unit, FMT="(T15,A,T68,I13)") "Maximum number of blocks per CPU:", nblock_max
     675           46 :             WRITE (UNIT=output_unit, FMT="(T15,A,T68,I13)") "Average number of matrix elements per CPU:", &
     676           92 :                (nelement_sum + npe - 1)/npe
     677           46 :             WRITE (UNIT=output_unit, FMT="(T15,A,T68,I13)") "Maximum number of matrix elements per CPU:", &
     678           92 :                nelement_max
     679              :          END IF
     680              :       END IF
     681              : 
     682              :       ! *** Release work storage ***
     683           92 :       DEALLOCATE (nblock)
     684              : 
     685           92 :       DEALLOCATE (nelement)
     686              : 
     687           92 :       CALL timestop(handle)
     688              : 
     689          184 :    END SUBROUTINE cp_dbcsr_write_matrix_dist
     690              : 
     691              : END MODULE cp_dbcsr_output
        

Generated by: LCOV version 2.0-1