dbcsr_to_dense_local Subroutine

public subroutine dbcsr_to_dense_local(sparse, dense)

Convert a sparse matrix to a dense matrix

Arguments

Type IntentOptional Attributes Name
type(dbcsr_type), intent(in) :: sparse

sparse matrix

type(dbcsr_data_obj), intent(inout) :: dense

dense matrix Take into account the symmetry of the sparse matrix. The dense matrix need to be valid. The operation is done locally.


Source Code

   SUBROUTINE dbcsr_to_dense_local(sparse, dense)
      !! Convert a sparse matrix to a dense matrix

      TYPE(dbcsr_type), INTENT(in)                       :: sparse
         !! sparse matrix
      TYPE(dbcsr_data_obj), INTENT(inout)                :: dense
         !! dense matrix Take into account the symmetry of the sparse matrix. The dense matrix need to be valid. The operation is
         !! done locally.

      CHARACTER(len=*), PARAMETER :: routineN = 'dbcsr_to_dense_local'

      CHARACTER                                          :: symm
      INTEGER                                            :: col, col_offset, col_size, data_type, &
                                                            dense_col_size, dense_row_size, &
                                                            handle, row, row_offset, row_size
      LOGICAL                                            :: tr, valid
      TYPE(dbcsr_data_obj)                               :: block
      TYPE(dbcsr_iterator)                               :: iter

      CALL timeset(routineN, handle)

      CALL dbcsr_data_get_sizes(dense, dense_row_size, dense_col_size, valid)
      IF (.NOT. valid) &
         DBCSR_ABORT("dense matrix not valid")

      symm = dbcsr_get_matrix_type(sparse)
      data_type = dbcsr_data_get_type(dense)

      CALL dbcsr_data_clear(dense)
      CALL dbcsr_data_init(block)
      CALL dbcsr_data_new(block, dbcsr_type_1d_to_2d(data_type))
      CALL dbcsr_iterator_start(iter, sparse)
      DO WHILE (dbcsr_iterator_blocks_left(iter))
         CALL dbcsr_iterator_next_block(iter, row, col, block, tr, &
                                        row_size=row_size, col_size=col_size, &
                                        row_offset=row_offset, col_offset=col_offset)
         CALL dbcsr_block_partial_copy(dst=dense, &
                                       dst_rs=dense_row_size, dst_cs=dense_col_size, dst_tr=.FALSE., &
                                       dst_r_lb=row_offset, dst_c_lb=col_offset, &
                                       src=block, src_rs=row_size, src_cs=col_size, src_tr=tr, &
                                       src_r_lb=1, src_c_lb=1, nrow=row_size, ncol=col_size)
         IF (symm .NE. dbcsr_type_no_symmetry .AND. row .NE. col) THEN
            SELECT CASE (symm)
            CASE (dbcsr_type_symmetric)
               CALL dbcsr_block_partial_copy(dst=dense, &
                                             dst_rs=dense_row_size, dst_cs=dense_col_size, dst_tr=.TRUE., &
                                             dst_r_lb=row_offset, dst_c_lb=col_offset, &
                                             src=block, src_rs=row_size, src_cs=col_size, src_tr=tr, &
                                             src_r_lb=1, src_c_lb=1, nrow=row_size, ncol=col_size)
            CASE (dbcsr_type_antisymmetric)
               CALL dbcsr_block_partial_copy(dst=dense, &
                                             dst_rs=dense_row_size, dst_cs=dense_col_size, dst_tr=.TRUE., &
                                             dst_r_lb=row_offset, dst_c_lb=col_offset, &
                                             src=block, src_rs=row_size, src_cs=col_size, src_tr=tr, &
                                             src_r_lb=1, src_c_lb=1, nrow=row_size, ncol=col_size)
               CALL dbcsr_block_scale(dense, dbcsr_scalar_negative(dbcsr_scalar_one( &
                                                                   dbcsr_type_2d_to_1d(data_type))), &
                                      row_size=col_size, col_size=row_size, &
                                      lb=col_offset, lb2=row_offset)
            CASE (dbcsr_type_hermitian)
               CALL dbcsr_block_partial_copy(dst=dense, &
                                             dst_rs=dense_row_size, dst_cs=dense_col_size, dst_tr=.TRUE., &
                                             dst_r_lb=row_offset, dst_c_lb=col_offset, &
                                             src=block, src_rs=row_size, src_cs=col_size, src_tr=tr, &
                                             src_r_lb=1, src_c_lb=1, nrow=row_size, ncol=col_size)
               CALL dbcsr_block_conjg(dense, row_size=col_size, col_size=row_size, &
                                      lb=col_offset, lb2=row_offset)
            CASE (dbcsr_type_antihermitian)
               CALL dbcsr_block_partial_copy(dst=dense, &
                                             dst_rs=dense_row_size, dst_cs=dense_col_size, dst_tr=.TRUE., &
                                             dst_r_lb=row_offset, dst_c_lb=col_offset, &
                                             src=block, src_rs=row_size, src_cs=col_size, src_tr=tr, &
                                             src_r_lb=1, src_c_lb=1, nrow=row_size, ncol=col_size)
               CALL dbcsr_block_scale(dense, dbcsr_scalar_negative(dbcsr_scalar_one( &
                                                                   dbcsr_type_2d_to_1d(data_type))), &
                                      row_size=col_size, col_size=row_size, &
                                      lb=col_offset, lb2=row_offset)
               CALL dbcsr_block_conjg(dense, row_size=col_size, col_size=row_size, &
                                      lb=col_offset, lb2=row_offset)
            CASE DEFAULT
               DBCSR_ABORT("wrong matrix symmetry")
            END SELECT
         END IF
      END DO
      CALL dbcsr_iterator_stop(iter)
      CALL dbcsr_data_clear_pointer(block)
      CALL dbcsr_data_release(block)

      CALL timestop(handle)

   END SUBROUTINE dbcsr_to_dense_local