12 USE mctc_env,
ONLY: error_type
34#include "./base/base_uses.f90"
40 CHARACTER(len=*),
PARAMETER,
PRIVATE :: moduleN =
'qs_charge_mixing'
44 REAL(KIND=
dp),
PARAMETER,
PRIVATE :: tblite_scc_pconv = 2.0e-5_dp
66 SUBROUTINE charge_mixing(mixing_method, mixing_store, charges, para_env, iter_count, &
67 scc_mixer, tblite_mixer_iterations, tblite_mixer_damping, &
68 tblite_mixer_memory, tblite_mixer_omega0, tblite_mixer_min_weight, &
69 tblite_mixer_max_weight, tblite_mixer_weight_factor)
70 INTEGER,
INTENT(IN) :: mixing_method
72 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: charges
74 INTEGER,
INTENT(IN) :: iter_count
75 INTEGER,
INTENT(IN),
OPTIONAL :: scc_mixer, tblite_mixer_iterations
76 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: tblite_mixer_damping
77 INTEGER,
INTENT(IN),
OPTIONAL :: tblite_mixer_memory
78 REAL(kind=
dp),
INTENT(IN),
OPTIONAL :: tblite_mixer_omega0, &
79 tblite_mixer_min_weight, &
80 tblite_mixer_max_weight, &
81 tblite_mixer_weight_factor
83 CHARACTER(len=*),
PARAMETER :: routinen =
'charge_mixing'
85 INTEGER :: effective_scc_mixer, handle, ia, ii, &
86 imin, inow, nbuffer, ns, nvec
89 INTEGER :: mixer_iterations, mixer_memory
90 REAL(
dp) :: mixer_damping, mixer_max_weight, &
91 mixer_min_weight, mixer_omega0, &
95 CALL timeset(routinen, handle)
98 IF (
PRESENT(scc_mixer)) effective_scc_mixer = scc_mixer
99 IF (
ASSOCIATED(mixing_store)) mixing_store%tb_scc_mixer_error = 0.0_dp
101 SELECT CASE (effective_scc_mixer)
105 cpassert(
ASSOCIATED(mixing_store))
108 IF (
PRESENT(tblite_mixer_damping)) mixer_damping = tblite_mixer_damping
109 IF (mixer_damping <= 0.0_dp) cpabort(
"tblite SCC mixer DAMPING must be positive")
111 IF (
PRESENT(tblite_mixer_omega0)) mixer_omega0 = tblite_mixer_omega0
112 IF (mixer_omega0 <= 0.0_dp) cpabort(
"tblite SCC mixer OMEGA0 must be positive")
114 IF (
PRESENT(tblite_mixer_min_weight)) mixer_min_weight = tblite_mixer_min_weight
115 IF (mixer_min_weight <= 0.0_dp) cpabort(
"tblite SCC mixer MIN_WEIGHT must be positive")
117 IF (
PRESENT(tblite_mixer_max_weight)) mixer_max_weight = tblite_mixer_max_weight
118 IF (mixer_max_weight <= 0.0_dp) cpabort(
"tblite SCC mixer MAX_WEIGHT must be positive")
119 IF (mixer_max_weight < mixer_min_weight) &
120 cpabort(
"tblite SCC mixer MAX_WEIGHT must not be smaller than MIN_WEIGHT")
122 IF (
PRESENT(tblite_mixer_weight_factor)) mixer_weight_factor = tblite_mixer_weight_factor
123 IF (mixer_weight_factor <= 0.0_dp) cpabort(
"tblite SCC mixer WEIGHT_FACTOR must be positive")
125 IF (
PRESENT(tblite_mixer_iterations)) mixer_iterations = tblite_mixer_iterations
126 IF (mixer_iterations < 1) cpabort(
"tblite SCC mixer ITERATIONS must be positive")
127 IF (iter_count > mixer_iterations) cpabort(
"tblite SCC mixer exceeded ITERATIONS")
128 mixer_memory = max(1, mixing_store%nbuffer)
129 IF (
PRESENT(tblite_mixer_memory)) mixer_memory = tblite_mixer_memory
130 IF (mixer_memory < 1) cpabort(
"tblite SCC mixer MEMORY must be positive")
131 CALL tblite_charge_mixing(mixing_store, charges, para_env, iter_count, &
132 mixer_damping, mixer_memory, mixer_omega0, mixer_min_weight, &
133 mixer_max_weight, mixer_weight_factor)
134 CALL timestop(handle)
137 mark_used(tblite_mixer_damping)
138 mark_used(tblite_mixer_iterations)
139 mark_used(tblite_mixer_max_weight)
140 mark_used(tblite_mixer_memory)
141 mark_used(tblite_mixer_min_weight)
142 mark_used(tblite_mixer_omega0)
143 mark_used(tblite_mixer_weight_factor)
144 IF (iter_count == 1)
THEN
145 CALL cp_warn(__location__, &
146 "SCC_MIXER TBLITE requested but CP2K was built without tblite; "// &
147 "falling back to the CP2K SCC mixer.")
151 IF (
ASSOCIATED(mixing_store)) mixing_store%iter_method =
"NoMix"
152 CALL timestop(handle)
155 cpabort(
"Unknown SCC mixer for TB charge mixing")
159 cpassert(
ASSOCIATED(mixing_store))
160 mixing_store%ncall = mixing_store%ncall + 1
161 ns =
SIZE(charges, 2)
162 IF (ns > mixing_store%max_shell)
THEN
163 cpabort(
"Mixing storage too small for TB SCC variables")
165 alpha = mixing_store%alpha
166 nbuffer = mixing_store%nbuffer
167 inow = mod(mixing_store%ncall - 1, nbuffer) + 1
170 IF (mixing_store%ncall > nbuffer)
THEN
173 nvec = mixing_store%ncall - 1
175 IF (mixing_store%ncall > 1)
THEN
177 DO ia = 1, mixing_store%nat_local
178 ii = mixing_store%atlist(ia)
179 mixing_store%dacharge(ia, 1:ns,
imin) = mixing_store%acharge(ia, 1:ns,
imin) - charges(ii, 1:ns)
182 IF ((iter_count == 1) .OR. (iter_count + 1 <= mixing_store%nskip_mixing))
THEN
184 mixing_store%iter_method =
"NoMix"
185 ELSEIF (((iter_count + 1 - mixing_store%nskip_mixing) <= mixing_store%n_simple_mix) .OR. (nvec == 1))
THEN
186 CALL mix_charges_only(mixing_store, charges, alpha,
imin, ns, para_env)
187 mixing_store%iter_method =
"Mixing"
189 cpabort(
"Kerker method not available for Charge Mixing")
191 cpabort(
"Pulay method not available for Charge Mixing")
193 CALL broyden_mixing(mixing_store, charges,
imin, nvec, ns, para_env)
194 mixing_store%iter_method =
"Broy."
196 cpabort(
"Modified Broyden mixing is only available for DFT density mixing")
198 cpabort(
"Multisecant_mixing method not available for Charge Mixing")
202 DO ia = 1, mixing_store%nat_local
203 ii = mixing_store%atlist(ia)
204 mixing_store%acharge(ia, 1:ns, inow) = charges(ii, 1:ns)
209 CALL timestop(handle)
221 REAL(kind=
dp),
INTENT(IN) :: eps_scf
222 REAL(kind=
dp) :: mixer_error
225 IF (.NOT.
ASSOCIATED(mixing_store))
RETURN
226 IF (mixing_store%tb_scc_mixer_step <= 1)
RETURN
228 IF (eps_scf > 0.0_dp)
THEN
229 mixer_error = eps_scf*mixing_store%tb_scc_mixer_error/tblite_scc_pconv
231 mixer_error = mixing_store%tb_scc_mixer_error
249 SUBROUTINE tblite_charge_mixing(mixing_store, charges, para_env, iter_count, damping, memory, omega0, &
250 min_weight, max_weight, weight_factor)
252 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: charges
254 INTEGER,
INTENT(IN) :: iter_count, memory
255 REAL(kind=
dp),
INTENT(IN) :: damping, max_weight, min_weight, omega0, &
259 TYPE(error_type),
ALLOCATABLE :: error
261 INTEGER :: natom, ndim, ns
262 LOGICAL :: on_source, reset_mixer
263 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: qvec
265 natom =
SIZE(charges, 1)
266 ns =
SIZE(charges, 2)
268 ALLOCATE (qvec(ndim))
269 qvec(:) = reshape(charges, [ndim])
270 on_source = para_env%mepos == para_env%source
271 reset_mixer = (iter_count == 1) .OR. (mixing_store%tb_scc_mixer_step == 0) .OR. &
272 (mixing_store%tb_scc_mixer_natom /= natom) .OR. &
273 (mixing_store%tb_scc_mixer_ns /= ns) .OR. &
274 (mixing_store%tb_scc_mixer_memory /= memory)
275 mixing_store%tb_scc_mixer_error = 0.0_dp
278 IF (reset_mixer)
THEN
279 IF (
ALLOCATED(mixing_store%tb_scc_mixer))
DEALLOCATE (mixing_store%tb_scc_mixer)
281 CALL new_cp2k_tblite_mixer(mixing_store%tb_scc_mixer, memory, ndim, damping, omega0, &
282 min_weight, max_weight, weight_factor)
283 CALL mixing_store%tb_scc_mixer%set(qvec)
285 mixing_store%tb_scc_mixer_natom = natom
286 mixing_store%tb_scc_mixer_ns = ns
287 mixing_store%tb_scc_mixer_memory = memory
288 mixing_store%tb_scc_mixer_step = 1
289 mixing_store%iter_method =
"NoMix"
290 CALL para_env%bcast(qvec)
291 charges = reshape(qvec, shape(charges))
296 cpassert(
ALLOCATED(mixing_store%tb_scc_mixer))
297 CALL mixing_store%tb_scc_mixer%diff(qvec)
298 mixing_store%tb_scc_mixer_error = real(mixing_store%tb_scc_mixer%get_error(), kind=
dp)
299 CALL mixing_store%tb_scc_mixer%next(error)
300 IF (
ALLOCATED(error)) cpabort(
"tblite SCC mixer failed")
301 CALL mixing_store%tb_scc_mixer%get(qvec)
303 CALL para_env%bcast(qvec)
304 CALL para_env%bcast(mixing_store%tb_scc_mixer_error)
305 charges = reshape(qvec, shape(charges))
306 mixing_store%tb_scc_mixer_step = mixing_store%tb_scc_mixer_step + 1
307 mixing_store%iter_method =
"TBLITE"
309 mark_used(mixing_store)
312 mark_used(iter_count)
316 mark_used(min_weight)
317 mark_used(max_weight)
318 mark_used(weight_factor)
319 cpabort(
"SCC_MIXER TBLITE requires CP2K to be built with tblite")
322 END SUBROUTINE tblite_charge_mixing
334 SUBROUTINE mix_charges_only(mixing_store, charges, alpha, imin, ns, para_env)
336 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: charges
337 REAL(kind=
dp),
INTENT(IN) :: alpha
338 INTEGER,
INTENT(IN) ::
imin, ns
345 DO ia = 1, mixing_store%nat_local
346 ii = mixing_store%atlist(ia)
347 charges(ii, 1:ns) = alpha*mixing_store%dacharge(ia, 1:ns,
imin) - mixing_store%acharge(ia, 1:ns,
imin)
350 CALL para_env%sum(charges)
352 END SUBROUTINE mix_charges_only
364 SUBROUTINE broyden_mixing(mixing_store, charges, inow, nvec, ns, para_env)
366 REAL(kind=
dp),
DIMENSION(:, :),
INTENT(INOUT) :: charges
367 INTEGER,
INTENT(IN) :: inow, nvec, ns
370 INTEGER :: i, ia, ii,
imin, j, nbuffer, nv
371 REAL(kind=
dp) :: alpha, broy_w0, rskip, wdf, wprod
372 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:) :: cvec, gammab
373 REAL(kind=
dp),
ALLOCATABLE,
DIMENSION(:, :) :: amat, beta
374 REAL(kind=
dp),
DIMENSION(:, :),
POINTER :: dq_last, dq_now, q_last, q_now
378 nbuffer = mixing_store%nbuffer
379 alpha = mixing_store%alpha
385 q_now => mixing_store%acharge(:, :, inow)
386 q_last => mixing_store%acharge(:, :,
imin)
387 dq_now => mixing_store%dacharge(:, :, inow)
388 dq_last => mixing_store%dacharge(:, :,
imin)
390 IF (nvec == nbuffer)
THEN
393 mixing_store%wbroy(i) = mixing_store%wbroy(i + 1)
394 mixing_store%dfbroy(:, :, i) = mixing_store%dfbroy(:, :, i + 1)
395 mixing_store%ubroy(:, :, i) = mixing_store%ubroy(:, :, i + 1)
399 mixing_store%abroy(i, j) = mixing_store%abroy(i + 1, j + 1)
404 broy_w0 = mixing_store%broy_w0
405 mixing_store%wbroy(nv) = 1.0_dp
408 mixing_store%dfbroy(:, :, nv) = 0.0_dp
409 mixing_store%dfbroy(:, 1:ns, nv) = dq_now(:, 1:ns) - dq_last(:, 1:ns)
410 wdf = sum(mixing_store%dfbroy(:, 1:ns, nv)**2)
411 CALL para_env%sum(wdf)
412 wdf = 1.0_dp/sqrt(wdf)
413 mixing_store%dfbroy(:, 1:ns, nv) = wdf*mixing_store%dfbroy(:, 1:ns, nv)
417 wprod = sum(mixing_store%dfbroy(:, 1:ns, i)*mixing_store%dfbroy(:, 1:ns, nv))
418 CALL para_env%sum(wprod)
419 mixing_store%abroy(i, nv) = wprod
420 mixing_store%abroy(nv, i) = wprod
424 ALLOCATE (amat(nv, nv), beta(nv, nv), cvec(nv), gammab(nv))
426 wprod = sum(mixing_store%dfbroy(:, 1:ns, i)*dq_now(:, 1:ns))
427 CALL para_env%sum(wprod)
428 cvec(i) = mixing_store%wbroy(i)*wprod
433 beta(j, i) = mixing_store%wbroy(j)*mixing_store%wbroy(i)*mixing_store%abroy(j, i)
435 beta(i, i) = beta(i, i) + broy_w0
440 gammab(1:nv) = matmul(cvec(1:nv), amat(1:nv, 1:nv))
443 mixing_store%ubroy(:, :, nv) = 0.0_dp
444 mixing_store%ubroy(:, 1:ns, nv) = alpha*mixing_store%dfbroy(:, 1:ns, nv) + &
445 wdf*(q_now(:, 1:ns) - q_last(:, 1:ns))
448 DO ia = 1, mixing_store%nat_local
449 ii = mixing_store%atlist(ia)
450 charges(ii, 1:ns) = q_now(ia, 1:ns) + alpha*dq_now(ia, 1:ns)
453 DO ia = 1, mixing_store%nat_local
454 ii = mixing_store%atlist(ia)
455 charges(ii, 1:ns) = charges(ii, 1:ns) - mixing_store%wbroy(i)*gammab(i)*mixing_store%ubroy(ia, 1:ns, i)
458 CALL para_env%sum(charges)
460 DEALLOCATE (amat, beta, cvec, gammab)
462 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.
real(kind=dp) function, public charge_mixing_scc_error(mixing_store, eps_scf)
Return the CP2K-side tblite SCC-mixer residual on the CP2K EPS_SCF scale.
subroutine, public charge_mixing(mixing_method, mixing_store, charges, para_env, iter_count, scc_mixer, tblite_mixer_iterations, tblite_mixer_damping, tblite_mixer_memory, tblite_mixer_omega0, tblite_mixer_min_weight, tblite_mixer_max_weight, tblite_mixer_weight_factor)
Driver for TB SCC variable mixing, calls the requested method.
module that contains the definitions of the scf types
integer, parameter, public broyden_mixing_nr
integer, parameter, public modified_broyden_mixing_nr
integer, parameter, public multisecant_mixing_nr
integer, parameter, public pulay_mixing_nr
integer, parameter, public gspace_mixing_nr
CP2K-side tblite-compatible SCC Broyden mixer.
stores all the informations relevant to an mpi environment