54 SUBROUTINE mao_optimize(mao_coef, matrix_q, matrix_smm, electra, max_iter, eps_grad, eps1, &
56 TYPE(
dbcsr_p_type),
DIMENSION(:),
POINTER :: mao_coef, matrix_q, matrix_smm
57 REAL(kind=
dp),
DIMENSION(:),
INTENT(IN) :: electra
58 INTEGER,
INTENT(IN) :: max_iter
59 REAL(kind=
dp),
INTENT(IN) :: eps_grad, eps1
60 INTEGER,
INTENT(IN) :: iolevel, iw
62 CHARACTER(len=*),
PARAMETER :: routinen =
'mao_optimize'
64 INTEGER :: handle, i, ispin, iter, nspin
65 INTEGER,
DIMENSION(:),
POINTER :: col_blk_sizes, mao_sizes_a, mao_sizes_b
66 LOGICAL :: spin_warning
67 REAL(kind=
dp) :: a1, a2, alpha, an, beta, eps_fun, fa1, &
68 fa2, fnnew, fnold, fval, grad_norm
73 CALL timeset(routinen, handle)
75 eps_fun = 10._dp*eps_grad
77 nspin =
SIZE(mao_coef, 1)
80 WRITE (iw,
'(/,T2,A)')
'!-----------------------------------------------------------------------------!'
81 WRITE (unit=iw, fmt=
"(T32,A)")
"MAO BASIS GENERATION"
82 WRITE (iw,
'(T2,A)')
'!-----------------------------------------------------------------------------!'
88 matrix_q(ispin)%matrix, matrix_smm(1)%matrix, eps1, iolevel, iw)
91 spin_warning = .false.
92 CALL dbcsr_get_info(mao_coef(1)%matrix, col_blk_size=mao_sizes_a, distribution=dbcsr_dist)
94 CALL dbcsr_get_info(mao_coef(2)%matrix, col_blk_size=mao_sizes_b, distribution=dbcsr_dist)
95 DO i = 1,
SIZE(mao_sizes_a)
96 IF (mao_sizes_a(i) /= mao_sizes_b(i)) spin_warning = .true.
99 IF (iw > 0 .AND. spin_warning)
THEN
100 WRITE (unit=iw, fmt=
"(/,A)")
">>>> WARNING: Different number of MAOs for different spins"
105 WRITE (unit=iw, fmt=
"(/,A,I2,T70,I11)")
" MAO's for SPIN ", ispin, sum(mao_sizes_a)
106 WRITE (unit=iw, fmt=
"(20I4)") mao_sizes_a(:)
107 ELSE IF (ispin == 2)
THEN
108 WRITE (unit=iw, fmt=
"(/,A,I2,T70,I11)")
" MAO's for SPIN ", ispin, sum(mao_sizes_b)
109 WRITE (unit=iw, fmt=
"(20I4)") mao_sizes_b(:)
112 WRITE (unit=iw, fmt=
"(A)")
115 IF (max_iter < 1)
THEN
118 CALL dbcsr_get_info(mao_coef(ispin)%matrix, col_blk_size=col_blk_sizes, distribution=dbcsr_dist)
119 CALL dbcsr_create(binv, name=
"Binv", dist=dbcsr_dist, matrix_type=dbcsr_type_symmetric, &
120 row_blk_size=col_blk_sizes, col_blk_size=col_blk_sizes)
121 CALL mao_function(mao_coef(ispin)%matrix, fval, matrix_q(ispin)%matrix, &
122 matrix_smm(1)%matrix, binv, .false.)
124 WRITE (unit=iw, fmt=
"(T2,A,T31,A,I2,T56,A,F12.8)") &
125 "MAO Projection",
"Spin:", ispin,
"Completeness:", fval/electra(ispin)
129 IF (iw > 0)
WRITE (unit=iw, fmt=
"(A)")
135 ALLOCATE (mao_grad(ispin)%matrix)
136 CALL dbcsr_create(matrix=mao_grad(ispin)%matrix, name=
"MAO_GRAD", template=mao_coef(1)%matrix)
139 CALL dbcsr_get_info(mao_coef(1)%matrix, col_blk_size=col_blk_sizes, distribution=dbcsr_dist)
140 CALL dbcsr_create(binv, name=
"Binv", dist=dbcsr_dist, matrix_type=dbcsr_type_symmetric, &
141 row_blk_size=col_blk_sizes, col_blk_size=col_blk_sizes)
148 matrix_q(ispin)%matrix, matrix_smm(1)%matrix, binv, .false.)
149 CALL dbcsr_copy(cgmat, mao_grad(ispin)%matrix)
153 WRITE (unit=iw, fmt=
"(/,T2,A,T73,A,I2)")
"MAO OPTIMIZATION",
"Spin =", ispin
154 WRITE (unit=iw, fmt=
"(T2,A,T24,A,F11.8,T48,A,F11.8,T69,A,F6.3)") &
155 "Initialization",
"fval =", fval/electra(ispin),
"grad =", grad_norm,
"step =", alpha
157 DO iter = 1, max_iter
158 IF (grad_norm < eps_grad)
EXIT
159 IF ((1.0_dp - fval/electra(ispin)) < eps_fun)
EXIT
160 CALL dbcsr_add(mao_coef(ispin)%matrix, cgmat, 1.0_dp, alpha)
163 matrix_q(ispin)%matrix, matrix_smm(1)%matrix, binv, .true.)
166 WRITE (unit=iw, fmt=
"(T2,A,i8,T24,A,F11.8,T48,A,F11.8,T69,A,F6.3)") &
167 "iter=", iter,
"fval =", fval/electra(ispin),
"grad =", grad_norm,
"step =", alpha
171 CALL dbcsr_add(cgmat, mao_grad(ispin)%matrix, beta, 1.0_dp)
175 CALL dbcsr_add(amat, cgmat, 1.0_dp, 0.5_dp*alpha)
177 CALL mao_function(amat, fa1, matrix_q(ispin)%matrix, matrix_smm(1)%matrix, binv, .true.)
179 CALL dbcsr_add(amat, cgmat, 1.0_dp, alpha)
181 CALL mao_function(amat, fa2, matrix_q(ispin)%matrix, matrix_smm(1)%matrix, binv, .true.)
182 a2 = (4._dp*fa1 - fa2 - 3._dp*fval)/alpha
183 a1 = (fa2 - fval - a2*alpha)/(alpha*alpha)
184 IF (abs(a1) > 1.e-14_dp)
THEN
186 an = min(an, 2.0_dp*alpha)
190 IF (an < 0.05_dp .OR. a1 > 0.0_dp)
THEN
191 CALL dbcsr_copy(cgmat, mao_grad(ispin)%matrix)
204 CALL timestop(handle)
subroutine, public dbcsr_get_info(matrix, nblkrows_total, nblkcols_total, nfullrows_total, nfullcols_total, nblkrows_local, nblkcols_local, nfullrows_local, nfullcols_local, my_prow, my_pcol, local_rows, local_cols, proc_row_dist, proc_col_dist, row_blk_size, col_blk_size, row_blk_offset, col_blk_offset, distribution, name, matrix_type, group)
...