Convert a sparse matrix to a dense matrix
Type | Intent | Optional | 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. |
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