19#include "./base/base_uses.f90"
25 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_charge_mixing'
41 SUBROUTINE charge_mixing(mixing_method, mixing_store, charges, para_env, iter_count)
42 INTEGER,
INTENT(IN) :: mixing_method
44 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: charges
46 INTEGER,
INTENT(IN) :: iter_count
48 CHARACTER(len=*),
PARAMETER :: routinen =
'charge_mixing'
50 INTEGER :: handle, ia, ii,
imin, inow, nbuffer, ns, &
54 CALL timeset(routinen, handle)
57 cpassert(
ASSOCIATED(mixing_store))
58 mixing_store%ncall = mixing_store%ncall + 1
60 ns = min(ns, mixing_store%max_shell)
61 alpha = mixing_store%alpha
62 nbuffer = mixing_store%nbuffer
63 inow = mod(mixing_store%ncall - 1, nbuffer) + 1
66 IF (mixing_store%ncall > nbuffer)
THEN
69 nvec = mixing_store%ncall - 1
71 IF (mixing_store%ncall > 1)
THEN
73 DO ia = 1, mixing_store%nat_local
74 ii = mixing_store%atlist(ia)
75 mixing_store%dacharge(ia, 1:ns,
imin) = mixing_store%acharge(ia, 1:ns,
imin) - charges(ii, 1:ns)
78 IF ((iter_count == 1) .OR. (iter_count + 1 <= mixing_store%nskip_mixing))
THEN
80 mixing_store%iter_method =
"NoMix"
81 ELSEIF (((iter_count + 1 - mixing_store%nskip_mixing) <= mixing_store%n_simple_mix) .OR. (nvec == 1))
THEN
82 CALL mix_charges_only(mixing_store, charges, alpha,
imin, ns, para_env)
83 mixing_store%iter_method =
"Mixing"
85 cpabort(
"Kerker method not available for Charge Mixing")
87 cpabort(
"Pulay method not available for Charge Mixing")
89 CALL broyden_mixing(mixing_store, charges,
imin, nvec, ns, para_env)
90 mixing_store%iter_method =
"Broy."
92 cpabort(
"Multisecant_mixing method not available for Charge Mixing")
96 DO ia = 1, mixing_store%nat_local
97 ii = mixing_store%atlist(ia)
98 mixing_store%acharge(ia, 1:ns, inow) = charges(ii, 1:ns)
103 CALL timestop(handle)
117 SUBROUTINE mix_charges_only(mixing_store, charges, alpha, imin, ns, para_env)
119 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: charges
120 REAL(kind=
dp),
INTENT(IN) :: alpha
121 INTEGER,
INTENT(IN) ::
imin, ns
128 DO ia = 1, mixing_store%nat_local
129 ii = mixing_store%atlist(ia)
130 charges(ii, 1:ns) = alpha*mixing_store%dacharge(ia, 1:ns,
imin) - mixing_store%acharge(ia, 1:ns,
imin)
133 CALL para_env%sum(charges)
135 END SUBROUTINE mix_charges_only
147 SUBROUTINE broyden_mixing(mixing_store, charges, inow, nvec, ns, para_env)
149 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: charges
150 INTEGER,
INTENT(IN) :: inow, nvec, ns
153 INTEGER :: i, ia, ii,
imin, j, nbuffer, nv
154 REAL(kind=
dp) :: alpha, maxw, minw, omega0, rskip, wdf, &
156 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cvec, gammab
157 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: amat, beta
158 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dq_last, dq_now, q_last, q_now
162 nbuffer = mixing_store%nbuffer
163 alpha = mixing_store%alpha
169 q_now => mixing_store%acharge(:, :, inow)
170 q_last => mixing_store%acharge(:, :,
imin)
171 dq_now => mixing_store%dacharge(:, :, inow)
172 dq_last => mixing_store%dacharge(:, :,
imin)
174 IF (nvec == nbuffer)
THEN
177 mixing_store%wbroy(i) = mixing_store%wbroy(i + 1)
178 mixing_store%dfbroy(:, :, i) = mixing_store%dfbroy(:, :, i + 1)
179 mixing_store%ubroy(:, :, i) = mixing_store%ubroy(:, :, i + 1)
183 mixing_store%abroy(i, j) = mixing_store%abroy(i + 1, j + 1)
193 mixing_store%wbroy(nv) = sum(dq_now(:, :)**2)
194 CALL para_env%sum(mixing_store%wbroy(nv))
195 mixing_store%wbroy(nv) = sqrt(mixing_store%wbroy(nv))
196 IF (mixing_store%wbroy(nv) > (wfac/maxw))
THEN
197 mixing_store%wbroy(nv) = wfac/mixing_store%wbroy(nv)
199 mixing_store%wbroy(nv) = maxw
201 IF (mixing_store%wbroy(nv) < minw) mixing_store%wbroy(nv) = minw
204 mixing_store%dfbroy(:, :, nv) = dq_now(:, :) - dq_last(:, :)
205 wdf = sum(mixing_store%dfbroy(:, :, nv)**2)
206 CALL para_env%sum(wdf)
207 wdf = 1.0_dp/sqrt(wdf)
208 mixing_store%dfbroy(:, :, nv) = wdf*mixing_store%dfbroy(:, :, nv)
212 wfac = sum(mixing_store%dfbroy(:, :, i)*mixing_store%dfbroy(:, :, nv))
213 CALL para_env%sum(wfac)
214 mixing_store%abroy(i, nv) = wfac
215 mixing_store%abroy(nv, i) = wfac
219 ALLOCATE (amat(nv, nv), beta(nv, nv), cvec(nv), gammab(nv))
221 wfac = sum(mixing_store%dfbroy(:, :, i)*dq_now(:, :))
222 CALL para_env%sum(wfac)
223 cvec(i) = mixing_store%wbroy(i)*wfac
228 beta(j, i) = mixing_store%wbroy(j)*mixing_store%wbroy(i)*mixing_store%abroy(j, i)
230 beta(i, i) = beta(i, i) + omega0*omega0
235 gammab(1:nv) = matmul(cvec(1:nv), amat(1:nv, 1:nv))
238 mixing_store%ubroy(:, :, nv) = alpha*mixing_store%dfbroy(:, :, nv) + wdf*(q_now(:, :) - q_last(:, :))
241 DO ia = 1, mixing_store%nat_local
242 ii = mixing_store%atlist(ia)
243 charges(ii, 1:ns) = q_now(ia, 1:ns) + alpha*dq_now(ia, 1:ns)
246 DO ia = 1, mixing_store%nat_local
247 ii = mixing_store%atlist(ia)
248 charges(ii, 1:ns) = charges(ii, 1:ns) - mixing_store%wbroy(i)*gammab(i)*mixing_store%ubroy(ia, 1:ns, i)
251 CALL para_env%sum(charges)
253 DEALLOCATE (amat, beta, cvec, gammab)
255 END SUBROUTINE broyden_mixing
static int imin(int x, int y)
Returns the smaller of the two integers (missing from the C standard).
Defines the basic variable types.
integer, parameter, public dp
Collection of simple mathematical functions and subroutines.
subroutine, public get_pseudo_inverse_svd(a, a_pinverse, rskip, determinant, sval)
returns the pseudoinverse of a real, square matrix using singular value decomposition
Interface to the message passing library MPI.
subroutine, public charge_mixing(mixing_method, mixing_store, charges, para_env, iter_count)
Driver for the charge mixing, calls the proper routine given the requested method.
module that contains the definitions of the scf types
integer, parameter, public broyden_mixing_nr
integer, parameter, public multisecant_mixing_nr
integer, parameter, public pulay_mixing_nr
integer, parameter, public gspace_mixing_nr
stores all the informations relevant to an mpi environment