(git:ed6f26b)
Loading...
Searching...
No Matches
mao_optimizer.F
Go to the documentation of this file.
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 Calculate MAO's and analyze wavefunctions
10!> \par History
11!> 03.2016 created [JGH]
12!> 12.2016 split into four modules [JGH]
13!> \author JGH
14! **************************************************************************************************
16 USE cp_dbcsr_api, ONLY: &
18 dbcsr_p_type, dbcsr_release, dbcsr_type, dbcsr_type_symmetric
23 USE kinds, ONLY: dp
24 USE mao_methods, ONLY: mao_function,&
29#include "./base/base_uses.f90"
30
31 IMPLICIT NONE
32 PRIVATE
33
34 CHARACTER(len=*), PARAMETER, PRIVATE :: moduleN = 'mao_optimizer'
35
36 PUBLIC :: mao_optimize
37
38! **************************************************************************************************
39
40CONTAINS
41
42! **************************************************************************************************
43!> \brief ...
44!> \param mao_coef ...
45!> \param matrix_q ...
46!> \param matrix_smm ...
47!> \param electra ...
48!> \param max_iter ...
49!> \param eps_grad ...
50!> \param eps1 ...
51!> \param iolevel ...
52!> \param iw ...
53! **************************************************************************************************
54 SUBROUTINE mao_optimize(mao_coef, matrix_q, matrix_smm, electra, max_iter, eps_grad, eps1, &
55 iolevel, iw)
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
61
62 CHARACTER(len=*), PARAMETER :: routinen = 'mao_optimize'
63
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
69 TYPE(dbcsr_distribution_type) :: dbcsr_dist
70 TYPE(dbcsr_p_type), DIMENSION(:), POINTER :: mao_grad
71 TYPE(dbcsr_type) :: amat, binv, cgmat
72
73 CALL timeset(routinen, handle)
74
75 eps_fun = 10._dp*eps_grad
76
77 nspin = SIZE(mao_coef, 1)
78
79 IF (iw > 0) THEN
80 WRITE (iw, '(/,T2,A)') '!-----------------------------------------------------------------------------!'
81 WRITE (unit=iw, fmt="(T32,A)") "MAO BASIS GENERATION"
82 WRITE (iw, '(T2,A)') '!-----------------------------------------------------------------------------!'
83 END IF
84
85 ! initialize MAO coeficients from diagonal blocks of the Q matrix
86 DO ispin = 1, nspin
87 CALL mao_initialization(mao_coef(ispin)%matrix, &
88 matrix_q(ispin)%matrix, matrix_smm(1)%matrix, eps1, iolevel, iw)
89 END DO
90 ! check for mao sizes
91 spin_warning = .false.
92 CALL dbcsr_get_info(mao_coef(1)%matrix, col_blk_size=mao_sizes_a, distribution=dbcsr_dist)
93 IF (nspin == 2) THEN
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.
97 END DO
98 END IF
99 IF (iw > 0 .AND. spin_warning) THEN
100 WRITE (unit=iw, fmt="(/,A)") ">>>> WARNING: Different number of MAOs for different spins"
101 END IF
102 IF (iw > 0) THEN
103 DO ispin = 1, nspin
104 IF (ispin == 1) THEN
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(:)
110 END IF
111 END DO
112 WRITE (unit=iw, fmt="(A)")
113 END IF
114
115 IF (max_iter < 1) THEN
116 ! projection only
117 DO ispin = 1, nspin
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.)
123 IF (iw > 0) THEN
124 WRITE (unit=iw, fmt="(T2,A,T31,A,I2,T56,A,F12.8)") &
125 "MAO Projection", "Spin:", ispin, "Completeness:", fval/electra(ispin)
126 END IF
127 CALL dbcsr_release(binv)
128 END DO
129 IF (iw > 0) WRITE (unit=iw, fmt="(A)")
130 ELSE
131 ! optimize MAOs
132 NULLIFY (mao_grad)
133 CALL dbcsr_allocate_matrix_set(mao_grad, nspin)
134 DO ispin = 1, nspin
135 ALLOCATE (mao_grad(ispin)%matrix)
136 CALL dbcsr_create(matrix=mao_grad(ispin)%matrix, name="MAO_GRAD", template=mao_coef(1)%matrix)
137 CALL dbcsr_reserve_diag_blocks(matrix=mao_grad(ispin)%matrix)
138 END DO
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)
142 CALL dbcsr_create(cgmat, template=mao_grad(1)%matrix)
143 CALL dbcsr_create(amat, template=mao_coef(1)%matrix)
144 DO ispin = 1, nspin
145 alpha = 0.25_dp
146 beta = 0.0_dp
147 CALL mao_function_gradient(mao_coef(ispin)%matrix, fval, mao_grad(ispin)%matrix, &
148 matrix_q(ispin)%matrix, matrix_smm(1)%matrix, binv, .false.)
149 CALL dbcsr_copy(cgmat, mao_grad(ispin)%matrix)
150 grad_norm = dbcsr_maxabs(mao_grad(ispin)%matrix)
151 fnold = mao_scalar_product(mao_grad(ispin)%matrix, mao_grad(ispin)%matrix)
152 IF (iw > 0) THEN
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
156 END IF
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)
161 CALL mao_orthogonalization(mao_coef(ispin)%matrix, matrix_smm(1)%matrix)
162 CALL mao_function_gradient(mao_coef(ispin)%matrix, fval, mao_grad(ispin)%matrix, &
163 matrix_q(ispin)%matrix, matrix_smm(1)%matrix, binv, .true.)
164 grad_norm = dbcsr_maxabs(mao_grad(ispin)%matrix)
165 IF (iw > 0) THEN
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
168 END IF
169 fnnew = mao_scalar_product(mao_grad(ispin)%matrix, mao_grad(ispin)%matrix)
170 beta = fnnew/fnold
171 CALL dbcsr_add(cgmat, mao_grad(ispin)%matrix, beta, 1.0_dp)
172 fnold = fnnew
173 ! line search, update alpha
174 CALL dbcsr_copy(amat, mao_coef(ispin)%matrix)
175 CALL dbcsr_add(amat, cgmat, 1.0_dp, 0.5_dp*alpha)
176 CALL mao_orthogonalization(amat, matrix_smm(1)%matrix)
177 CALL mao_function(amat, fa1, matrix_q(ispin)%matrix, matrix_smm(1)%matrix, binv, .true.)
178 CALL dbcsr_copy(amat, mao_coef(ispin)%matrix)
179 CALL dbcsr_add(amat, cgmat, 1.0_dp, alpha)
180 CALL mao_orthogonalization(amat, matrix_smm(1)%matrix)
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
185 an = -a2/(2._dp*a1)
186 an = min(an, 2.0_dp*alpha)
187 ELSE
188 an = 2.0_dp*alpha
189 END IF
190 IF (an < 0.05_dp .OR. a1 > 0.0_dp) THEN
191 CALL dbcsr_copy(cgmat, mao_grad(ispin)%matrix)
192 alpha = 0.25_dp
193 ELSE
194 alpha = an
195 END IF
196 END DO
197 END DO
198 CALL dbcsr_release(binv)
199 CALL dbcsr_release(cgmat)
200 CALL dbcsr_release(amat)
201 IF (ASSOCIATED(mao_grad)) CALL dbcsr_deallocate_matrix_set(mao_grad)
202 END IF
203
204 CALL timestop(handle)
205
206 END SUBROUTINE mao_optimize
207
208END MODULE mao_optimizer
subroutine, public dbcsr_copy(matrix_b, matrix_a, name, keep_sparsity, keep_imaginary)
...
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)
...
subroutine, public dbcsr_release(matrix)
...
subroutine, public dbcsr_add(matrix_a, matrix_b, alpha_scalar, beta_scalar)
...
real(dp) function, public dbcsr_maxabs(matrix)
Compute the maxabs norm of a dbcsr matrix.
subroutine, public dbcsr_reserve_diag_blocks(matrix)
Reserves all diagonal blocks.
DBCSR operations in CP2K.
Defines the basic variable types.
Definition kinds.F:23
integer, parameter, public dp
Definition kinds.F:34
Calculate MAO's and analyze wavefunctions.
Definition mao_methods.F:15
subroutine, public mao_function_gradient(mao_coef, fval, mao_grad, qmat, smat, binv, reuse)
...
subroutine, public mao_orthogonalization(mao_coef, smat)
...
subroutine, public mao_initialization(mao_coef, pmat, smat, eps1, iolevel, iw)
...
Definition mao_methods.F:90
real(kind=dp) function, public mao_scalar_product(fmat1, fmat2)
...
subroutine, public mao_function(mao_coef, fval, qmat, smat, binv, reuse)
...
Calculate MAO's and analyze wavefunctions.
subroutine, public mao_optimize(mao_coef, matrix_q, matrix_smm, electra, max_iter, eps_grad, eps1, iolevel, iw)
...