Computes various functions (defined by func) of matrix elements
Note
sign(A,B) returns the value of A with the sign of B dbcsr_func_inverse: 1/(a1x+a0) fails if the inversion produces infinite numbers dbcsr_func_inverse_special: 1/(x+sign(a0,x)) safe inverse: if a0>0 then the denominator is never zero dbcsr_func_tanh: tanh(a1x+a0) dbcsr_func_dtanh: d(tanh(a1x+a0)) / dx dbcsr_func_ddtanh: d2(tanh(a1x+a0)) / dx2 dbcsr_func_artanh: artanh(a1x+a0)=ln[(1+(a1x+a0))/(1-(a1x+a0))]/2 fails if |a1x+a0| >= 1 dbcsr_func_sread_from_zero: if |x|<|a0| then x=sign(a0,x) dbcsr_func_truncate: if |x|>|a0| then x=sign(a0,x) dbcsr_func_sin: sin(a1x+a0) dbcsr_func_cos: cos(a1x+a0) dbcsr_func_dsin: d(sin(a1x+a0)) / dx = a1cos(a1x+a0) dbcsr_func_ddsin: d2(sin(a1x+a0)) / dx2 = -a1a1sin(a1x+a0) dbcsr_func_asin: asin(a1x+a0) fails if |a1*x+a0| > 1
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
type(dbcsr_type), | intent(inout) | :: | matrix_a |
DBCSR matrix |
||
integer, | intent(in) | :: | func | |||
real(kind=dp), | intent(in), | optional | :: | a0 | ||
real(kind=dp), | intent(in), | optional | :: | a1 | ||
real(kind=dp), | intent(in), | optional | :: | a2 |
SUBROUTINE dbcsr_function_of_elements(matrix_a, func, a0, a1, a2) !! Computes various functions (defined by func) of matrix elements !! @note sign(A,B) returns the value of A with the sign of B !! dbcsr_func_inverse: 1/(a1*x+a0) !! fails if the inversion produces infinite numbers !! dbcsr_func_inverse_special: 1/(x+sign(a0,x)) !! safe inverse: if a0>0 then the denominator is never zero !! dbcsr_func_tanh: tanh(a1*x+a0) !! dbcsr_func_dtanh: d(tanh(a1*x+a0)) / dx !! dbcsr_func_ddtanh: d2(tanh(a1*x+a0)) / dx2 !! dbcsr_func_artanh: artanh(a1*x+a0)=ln[(1+(a1*x+a0))/(1-(a1*x+a0))]/2 !! fails if |a1*x+a0| >= 1 !! dbcsr_func_sread_from_zero: if |x|<|a0| then x=sign(a0,x) !! dbcsr_func_truncate: if |x|>|a0| then x=sign(a0,x) !! dbcsr_func_sin: sin(a1*x+a0) !! dbcsr_func_cos: cos(a1*x+a0) !! dbcsr_func_dsin: d(sin(a1*x+a0)) / dx = a1*cos(a1*x+a0) !! dbcsr_func_ddsin: d2(sin(a1*x+a0)) / dx2 = -a1*a1*sin(a1*x+a0) !! dbcsr_func_asin: asin(a1*x+a0) !! fails if |a1*x+a0| > 1 TYPE(dbcsr_type), INTENT(INOUT) :: matrix_a !! DBCSR matrix INTEGER, INTENT(IN) :: func REAL(kind=dp), INTENT(IN), OPTIONAL :: a0, a1, a2 CHARACTER(len=*), PARAMETER :: routineN = 'dbcsr_function_of_elements' INTEGER :: blk, col, col_size, data_type, handle, & ielem, nze, row, row_size LOGICAL :: tr_a REAL(kind=dp) :: p0, p1, p2 TYPE(dbcsr_data_obj) :: a_data TYPE(dbcsr_iterator) :: iter ! --------------------------------------------------------------------------- CALL timeset(routineN, handle) IF (PRESENT(a0)) THEN p0 = a0 ELSE p0 = 0.0_dp END IF IF (PRESENT(a1)) THEN p1 = a1 ELSE p1 = 1.0_dp END IF IF (PRESENT(a2)) THEN p2 = a2 ELSE p2 = 0.0_dp END IF data_type = dbcsr_get_data_type(matrix_a) CALL dbcsr_data_init(a_data) CALL dbcsr_data_new(a_data, data_type) CALL dbcsr_iterator_start(iter, matrix_a) DO WHILE (dbcsr_iterator_blocks_left(iter)) CALL dbcsr_iterator_next_block(iter, row, col, a_data, tr_a, blk, & row_size=row_size, col_size=col_size) nze = row_size*col_size SELECT CASE (data_type) !CASE (dbcsr_type_real_4) ! a_data%d%r_sp(1:nze) = 1.0_real_4/a_data%d%r_sp(1:nze) ! IF(MAXVAL(ABS(a_data%d%r_sp)).GE.HUGE(0.0_real_4))& ! DBCSR_ABORT("Division by zero") CASE (dbcsr_type_real_8) SELECT CASE (func) CASE (dbcsr_func_spread_from_zero) ! if |x|<|a0| then x=|a0|*sign(x) DO ielem = 1, nze IF (ABS(a_data%d%r_dp(ielem)) .LT. ABS(p0)) THEN a_data%d%r_dp(ielem) = SIGN(p0, a_data%d%r_dp(ielem)) END IF END DO CASE (dbcsr_func_truncate) ! if |x|>|a0| then x=|a0|*sign(x) DO ielem = 1, nze IF (ABS(a_data%d%r_dp(ielem)) .GT. ABS(p0)) THEN a_data%d%r_dp(ielem) = SIGN(p0, a_data%d%r_dp(ielem)) END IF END DO CASE (dbcsr_func_inverse_special) !IF (MINVAL(ABS(a_data%d%r_dp)).le.ABS(p2)) THEN ! ! there is at least one near-zero element, ! ! invert element-by-element ! DO ielem=1,nze ! IF (a_data%d%r_dp(ielem).le.ABS(p2)) THEN ! a_data%d%r_dp(ielem) = 0.0_real_8 ! ELSE ! a_data%d%r_dp(ielem) = & ! 1.0_real_8/(p1*a_data%d%r_dp(ielem)+p0) ! ENDIF ! ENDDO !ELSE ! a_data%d%r_dp(1:nze) = 1.0_real_8/(p1*a_data%d%r_dp(1:nze)+p0) !ENDIF a_data%d%r_dp(1:nze) = 1.0_real_8/(a_data%d%r_dp(1:nze) + SIGN(p0, a_data%d%r_dp(1:nze))) CASE (dbcsr_func_inverse) a_data%d%r_dp(1:nze) = 1.0_real_8/(p1*a_data%d%r_dp(1:nze) + p0) IF (MAXVAL(ABS(a_data%d%r_dp)) .GE. HUGE(0.0_real_8)) & DBCSR_ABORT("Division by zero") CASE (dbcsr_func_tanh) a_data%d%r_dp(1:nze) = TANH(p1*a_data%d%r_dp(1:nze) + p0) CASE (dbcsr_func_dtanh) a_data%d%r_dp(1:nze) = TANH(p1*a_data%d%r_dp(1:nze) + p0) a_data%d%r_dp(1:nze) = a_data%d%r_dp(1:nze)**2 a_data%d%r_dp(1:nze) = p1*(1.0_real_8 - a_data%d%r_dp(1:nze)) CASE (dbcsr_func_ddtanh) a_data%d%r_dp(1:nze) = TANH(p1*a_data%d%r_dp(1:nze) + p0) a_data%d%r_dp(1:nze) = a_data%d%r_dp(1:nze)**3 - a_data%d%r_dp(1:nze) a_data%d%r_dp(1:nze) = 2.0_real_8*(p1**2)*a_data%d%r_dp(1:nze) CASE (dbcsr_func_artanh) a_data%d%r_dp(1:nze) = p1*a_data%d%r_dp(1:nze) + p0 IF (MAXVAL(ABS(a_data%d%r_dp)) .GE. 1.0_real_8) & DBCSR_ABORT("ARTANH is undefined for |x|>=1") a_data%d%r_dp(1:nze) = (1.0_real_8 + a_data%d%r_dp(1:nze)) & /(1.0_real_8 - a_data%d%r_dp(1:nze)) a_data%d%r_dp(1:nze) = 0.5_real_8*LOG(a_data%d%r_dp(1:nze)) CASE (dbcsr_func_sin) a_data%d%r_dp(1:nze) = SIN(p1*a_data%d%r_dp(1:nze) + p0) CASE (dbcsr_func_cos) a_data%d%r_dp(1:nze) = COS(p1*a_data%d%r_dp(1:nze) + p0) CASE (dbcsr_func_dsin) a_data%d%r_dp(1:nze) = p1*COS(p1*a_data%d%r_dp(1:nze) + p0) CASE (dbcsr_func_ddsin) a_data%d%r_dp(1:nze) = -p1*p1*SIN(p1*a_data%d%r_dp(1:nze) + p0) CASE (dbcsr_func_asin) a_data%d%r_dp(1:nze) = p1*a_data%d%r_dp(1:nze) + p0 IF (MAXVAL(ABS(a_data%d%r_dp)) .GT. 1.0_real_8) & DBCSR_ABORT("ASIN is undefined for |x|>1") a_data%d%r_dp(1:nze) = ASIN(a_data%d%r_dp(1:nze)) CASE DEFAULT DBCSR_ABORT("Unknown function of matrix elements") END SELECT !CASE (dbcsr_type_complex_4) !CASE (dbcsr_type_complex_8) CASE DEFAULT DBCSR_ABORT("Operation is implemented only for dp real values") END SELECT END DO CALL dbcsr_iterator_stop(iter) CALL dbcsr_data_clear_pointer(a_data) CALL dbcsr_data_release(a_data) CALL timestop(handle) END SUBROUTINE dbcsr_function_of_elements