Octopus
mix.F90
Go to the documentation of this file.
1!! Copyright (C) 2002-2014 M. Marques, A. Castro, A. Rubio, G. Bertsch, M. Oliveira
2!! Copyright (C) 2024 A. Buccheri
3!!
4!! This program is free software; you can redistribute it and/or modify
5!! it under the terms of the GNU General Public License as published by
6!! the Free Software Foundation; either version 2, or (at your option)
7!! any later version.
8!!
9!! This program is distributed in the hope that it will be useful,
10!! but WITHOUT ANY WARRANTY; without even the implied warranty of
11!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12!! GNU General Public License for more details.
13!!
14!! You should have received a copy of the GNU General Public License
15!! along with this program; if not, write to the Free Software
16!! Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17!! 02110-1301, USA.
18!!
19
20#include "global.h"
21
22module mix_oct_m
23 use debug_oct_m
25 use global_oct_m
26 use, intrinsic :: iso_fortran_env
29 use math_oct_m
30 use mesh_oct_m
35 use parser_oct_m
40 use space_oct_m
42 use types_oct_m
44
45 implicit none
46
47 private
48 public :: &
49 mix_t, &
50 mix_init, &
51 mix_clear, &
52 mix_end, &
53 mix_dump, &
54 mix_load, &
55 mixing, &
56 dmixing, &
57 zmixing, &
59 mix_scheme, &
60 mix_d3, &
62 mixfield_t, &
70
71 ! A better design would be to have mixfield_t and mixfield_ptr_t separate from mix_t:
72 ! mix_t would contain constants, and should be immutable with only getters.
73 ! mixfield_type encapsulates the data used in mixing, and has bound procedures for
74 ! operating on this data.
75
77 type mixfield_t
78 private
79 ! Real versions of the data
80 real(real64), allocatable :: ddf(:, :, :)
81 real(real64), allocatable :: ddv(:, :, :)
82 real(real64), allocatable :: df_old(:, :)
83 real(real64), allocatable :: dvin_old(:, :)
84 real(real64), allocatable :: dvin(:, :)
85 real(real64), allocatable :: dvout(:, :)
86 real(real64), allocatable :: dvnew(:, :)
87 real(real64), allocatable :: dresidual(:, :)
88
89 ! Complex versions of the data
90 complex(real64), allocatable :: zdf(:, :, :)
91 complex(real64), allocatable :: zdv(:, :, :)
92 complex(real64), allocatable :: zf_old(:, :)
93 complex(real64), allocatable :: zvin_old(:, :)
94 complex(real64), allocatable :: zvin(:, :)
95 complex(real64), allocatable :: zvout(:, :)
96 complex(real64), allocatable :: zvnew(:, :)
97 complex(real64), allocatable :: zresidual(:, :)
98
99 type(type_t) :: func_type
100 integer :: d1, d2, d3
101 ! d1 is mesh%np, d2 vary depending on where this called
102 ! d3 is for SCF history of a quantity.
103 logical :: mix_spin_density_matrix
104 real(real64) :: last_residue
105 end type mixfield_t
106
107 type mixfield_ptr_t
108 private
109 type(mixfield_t), pointer :: p
110 end type mixfield_ptr_t
111
112 integer, parameter :: MAX_AUXMIXFIELD = 5
113
121 type mix_t
122 private
123 type(derivatives_t), pointer :: der
124
125 integer :: scheme
126 real(real64), allocatable :: coeff(:)
127 real(real64) :: adaptive_damping
128 real(real64) :: residual_coeff
129 integer :: iter
130 ! !< include the iterations done in previous calculations.
131 integer, public :: ns
132 integer, public :: ns_restart
133 integer :: interval
134
135 integer :: last_ipos
136 ! This should have been an attribute of type(mixfield_t)
137
138 ! Fields
139 type(mixfield_t) :: mixfield
140 integer :: nauxmixfield
141 type(mixfield_ptr_t) :: auxmixfield(MAX_AUXMIXFIELD)
142 integer :: ipos
143 ! This should have been an attribute of type(mixfield_ptr_t)
144
145 ! Preconditioning
146 logical :: kerker
147 real(real64) :: kerker_factor
148 logical :: precondition
149 type(nl_operator_t) :: preconditioner
150 ! [GPAW](https://wiki.fysik.dtu.dk/gpaw/documentation/densitymix/densitymix.html)
151
152 logical :: mix_spin_density_matrix
153 contains
154 procedure :: compute_residuals_aux_field
155
156 end type mix_t
157
158 interface mixfield_set_vin
159 module procedure dmixfield_set_vin, zmixfield_set_vin
160 end interface mixfield_set_vin
161
162 interface mixfield_set_vout
163 module procedure dmixfield_set_vout, zmixfield_set_vout
164 end interface mixfield_set_vout
165
166 interface mixfield_get_vnew
167 module procedure dmixfield_get_vnew, zmixfield_get_vnew
168 end interface mixfield_get_vnew
169
170contains
171
173 subroutine mix_init(smix, namespace, space, der, d1, d2, def_, func_type_, prefix_)
174 type(mix_t), intent(out) :: smix
175 type(namespace_t), intent(in) :: namespace
176 class(space_t), intent(in) :: space
177 type(derivatives_t), target, intent(in) :: der
178 integer, intent(in) :: d1
179 integer, intent(in) :: d2
180 integer, optional, intent(in) :: def_
181 type(type_t), optional, intent(in) :: func_type_
182 character(len=*), optional, intent(in) :: prefix_
183
184 integer :: def, ii
185 character(len=32) :: prefix
186 type(type_t) :: func_type
187 real(real64) :: coeff
189 push_sub(mix_init)
191 smix%der => der
193 def = option__mixingscheme__broyden
194 if (present(def_)) def = def_
195 if (present(func_type_)) then
196 func_type = func_type_
197 else
198 func_type = type_float
199 end if
200 prefix = ''
201 if (present(prefix_)) prefix = prefix_
203 call messages_obsolete_variable(namespace, 'TypeOfMixing', 'MixingScheme')
205 !%Variable MixingScheme
206 !%Type integer
207 !%Default broyden
208 !%Section SCF::Mixing
209 !%Description
210 !% The scheme used to produce, at each iteration in the self-consistent cycle
211 !% that attempts to solve the Kohn-Sham equations, the input density from the value
212 !% of the input and output densities of previous iterations.
213 !%Option linear 0
214 !% Simple linear mixing.
215 !%Option broyden 2
216 !% Broyden scheme [C. G Broyden, <i>Math. Comp.</i> <b>19</b>, 577 (1965);
217 !% D. D. Johnson, <i>Phys. Rev. B</i> <b>38</b>, 12807 (1988)].
218 !% The scheme is slightly adapted, see the comments in the code.
219 !% For complex functions (e.g. Sternheimer with <tt>EMEta</tt> > 0), we use the generalization
220 !% with a complex dot product.
221 !%Option diis 9
222 !% Direct inversion in the iterative subspace (diis)
223 !% scheme [P. Pulay, <i>Chem. Phys. Lett.</i>, <b>73</b>, 393
224 !% (1980)] as described in [G. Kresse, and J. Furthmueller,
225 !% <i>Phys. Rev. B</i> <b>54</b>, 11169 (1996)].
226 !%Option broyden_adaptive 11
227 !% Broyden mixing with adaptive damping. The Broyden update follows
228 !% [C. G. Broyden, <i>Math. Comp.</i> <b>19</b>, 577 (1965);
229 !% D. D. Johnson, <i>Phys. Rev. B</i> <b>38</b>, 12807 (1988)].
230 !% The adaptive damping logic is inspired by
231 !% [M. F. Herbst and A. Levitt, <i>J. Comput. Phys.</i> <b>459</b>, 111127 (2022)]
232 !% and by the adaptive-coefficient analysis of
233 !% [M. Novak et al., <i>Comput. Phys. Commun.</i> <b>292</b>, 108865 (2023)].
234 !%End
235 call parse_variable(namespace, trim(prefix)//'MixingScheme', def, smix%scheme)
236 if (.not. varinfo_valid_option('MixingScheme', smix%scheme)) then
237 call messages_input_error(namespace, 'MixingScheme', 'invalid option')
238 end if
239 call messages_print_var_option("MixingScheme", smix%scheme, namespace=namespace)
240
241 !%Variable MixingPreconditioner
242 !%Type logical
243 !%Default false
244 !%Section SCF::Mixing
245 !%Description
246 !% (Experimental) If set to yes, Octopus will use a preconditioner
247 !% for the mixing operator.
248 !% This preconditioner is disabled for systems with dimension other than 3.
249 !%End
250 call parse_variable(namespace, trim(prefix)+'MixingPreconditioner', .false., smix%precondition)
251 if (der%dim /= 3) smix%precondition = .false.
252 if (smix%precondition) call messages_experimental('MixingPreconditioner', namespace=namespace)
254 !%Variable Mixing
255 !%Type float
256 !%Default 0.3
257 !%Section SCF::Mixing
258 !%Description
259 !% The linear, Broyden, adaptive Broyden, and DIIS scheme depend on a "mixing parameter", set by this variable.
260 !% Must be 0 < <tt>Mixing</tt> <= 1.
261 !% For adaptive Broyden this is the maximum damping, which may be reduced automatically.
262 !%End
263 call parse_variable(namespace, trim(prefix)+'Mixing', 0.3_real64, coeff)
264 if (coeff <= m_zero .or. coeff > m_one) then
265 call messages_input_error(namespace, 'Mixing', 'Value should be positive and smaller than one')
266 end if
267 safe_allocate(smix%coeff(1:d2))
268 smix%coeff = coeff
269 smix%adaptive_damping = m_one
270
271 if (d2 > 1) then
272 !%Variable MixingSpinDensityMatrix
273 !%Type logical
274 !%Default false
275 !%Section SCF::Mixing
276 !%Description
277 !% If set to yes, Octopus mixes the components up, down, and real and imaginary parts of
278 !% the up down (for spinor calculations) of the density or potential.
279 !% By default, Octopus mixes the magnetization and the charge density with a different weight,
280 !% where the magnetization mixing coefficient is given by <tt>MixingMagnetization</tt>
281 !%End
282 call parse_variable(namespace, trim(prefix)+'MixingSpinDensityMatrix', .false., smix%mix_spin_density_matrix)
283
284 !%Variable MixingMagnetization
285 !%Type float
286 !%Default 1.5
287 !%Section SCF::Mixing
288 !%Description
289 !% Same as <tt>Mixing</tt>, but for the "magnetization".
290 !% The default value is taken from D. D. Johnson, <i>Phys. Rev. B</i> <b>38</b>, 12807 (1988).
291 !%End
292 call parse_variable(namespace, trim(prefix)+'MixingMagnetization', 1.5_real64, coeff)
293
294 if (.not. smix%mix_spin_density_matrix) smix%coeff(2:d2) = coeff
295 else
296 smix%mix_spin_density_matrix = .true.
297 end if
298
299 !%Variable MixingResidual
300 !%Type float
301 !%Default 0.05
302 !%Section SCF::Mixing
303 !%Description
304 !% In the DIIS mixing it is benefitial to include a bit of
305 !% residual into the mixing. This parameter controls this amount.
306 !%End
307 call parse_variable(namespace, trim(prefix)+'MixingResidual', 0.05_real64, smix%residual_coeff)
308 if (smix%residual_coeff <= m_zero .or. smix%residual_coeff > m_one) then
309 call messages_input_error(namespace, 'MixingResidual', 'Value should be positive and smaller than one.')
310 end if
311
312 !%Variable MixNumberSteps
313 !%Type integer
314 !%Default 4
315 !%Section SCF::Mixing
316 !%Description
317 !% In the Broyden scheme, the new input density or potential is constructed
318 !% from the values of the densities/potentials of a given number of previous iterations.
319 !% This number is set by this variable. Must be greater than 1.
320 !%End
321 if (smix%scheme /= option__mixingscheme__linear) then
322 call parse_variable(namespace, trim(prefix)//'MixNumberSteps', 4, smix%ns)
323 if (smix%ns <= 1) call messages_input_error(namespace, 'MixNumberSteps')
324 else
325 smix%ns = 0
326 end if
327
328 !%Variable MixingRestart
329 !%Type integer
330 !%Default 20
331 !%Section SCF::Mixing
332 !%Description
333 !% In the Broyden scheme, the mixing is restarted after
334 !% the number of iterations given by this variable.
335 !% Set this to zero to disable restarting the mixing.
336 !%End
337 if (smix%scheme /= option__mixingscheme__linear) then
338 call parse_variable(namespace, trim(prefix)//'MixingRestart', 20, smix%ns_restart)
339 if (smix%ns_restart < 0) call messages_input_error(namespace, 'MixingRestart')
340 else
341 smix%ns_restart = 0
342 end if
343
344 write(message(1), '(A,I4,A,I4,A)') "Info: Mixing uses ", smix%ns, " steps and restarts after ", &
345 smix%ns_restart, " steps."
346 call messages_info(1, namespace=namespace)
347
348 !%Variable MixInterval
349 !%Type integer
350 !%Default 1
351 !%Section SCF::Mixing
352 !%Description
353 !% When this variable is set to a value different than 1 (the
354 !% default) a combined mixing scheme will be used, with MixInterval
355 !% - 1 steps of linear mixing followed by 1 step of the selected
356 !% mixing. For the moment this variable only works with DIIS mixing.
357 !%End
358 call parse_variable(namespace, trim(prefix)//'MixInterval', 1, smix%interval)
359 if (smix%interval < 1) call messages_input_error(namespace, 'MixInterval', 'MixInterval must be larger or equal than 1')
360
361 smix%iter = 0
362
363 !%Variable MixingKerker
364 !%Type logical
365 !%Default false
366 !%Section SCF::Mixing
367 !%Description
368 !% (Experimental) If set to yes, Octopus will use the Kerker preconditioner
369 !% for the mixing operator applied in the linear and Broyden mixing schemes.
370 !% When using preconditioning with the Broyden scheme, the user should increase the <tt>Mixing</tt> from its default
371 !% to between 0.5 and 0.8, for optimal results.
372 !% The implementation follows Yoshinori Shiihara et al., Modelling Simul. Mater. Sci. Eng. 16 (2008), 035004
373 !%End
374 call parse_variable(namespace, trim(prefix)+'MixingKerker', .false., smix%kerker)
375 if(smix%kerker) call messages_experimental('MixingKerker')
376
377 !%Variable MixingKerkerFactor
378 !%Type float
379 !%Default 1.0
380 !%Section SCF::Mixing
381 !%Description
382 !% The screening factor, $q_0$ in the Kerker preconditioner in units of inverse length.
383 !% For small wave vectors, q, screening behaves like $\frac{Aq}{q_0}$, where A is the mixing coefficient.
384 !% An optimal value is determined empirically for a given system and mixing coeffient, however the default
385 !% is a reasonable choice in many cases.
386 !%End
387 call parse_variable(namespace, trim(prefix)+'MixingKerkerFactor', 1._real64, smix%kerker_factor)
388
389 smix%nauxmixfield = 0
390 do ii = 1,max_auxmixfield
391 nullify(smix%auxmixfield(ii)%p)
392 end do
393
394 call mixfield_init(smix, smix%mixfield, d1, d2, smix%ns, func_type)
395 call mix_clear(smix)
396 if (smix%precondition) call init_preconditioner()
397
398 pop_sub(mix_init)
399
400 contains
401
402 subroutine init_preconditioner()
403
404 integer :: ns, maxp, ip, is
405 real(real64), parameter :: weight = 50.0_real64
406
407 ! This the mixing preconditioner from GPAW:
408 !
409 ! https://wiki.fysik.dtu.dk/gpaw/documentation/densitymix/densitymix.html
410 !
411
412 assert(.not. der%mesh%use_curvilinear)
413 assert(der%dim == 3)
414
415 call nl_operator_init(smix%preconditioner, "Mixing preconditioner")
416 call stencil_cube_get_lapl(smix%preconditioner%stencil, der%dim, 1)
417 call nl_operator_build(space, der%mesh, smix%preconditioner, der%mesh%np, const_w = .not. der%mesh%use_curvilinear)
418
419 ns = smix%preconditioner%stencil%size
420
421 if (smix%preconditioner%const_w) then
422 maxp = 1
423 else
424 maxp = der%mesh%np
425 end if
426
427 do ip = 1, maxp
428
429 do is = 1, ns
430 select case (sum(abs(smix%preconditioner%stencil%points(1:der%dim, is))))
431 case (0)
432 smix%preconditioner%w(is, ip) = m_one + weight/8.0_real64
433 case (1)
434 smix%preconditioner%w(is, ip) = weight/16.0_real64
435 case (2)
436 smix%preconditioner%w(is, ip) = weight/32.0_real64
437 case (3)
438 smix%preconditioner%w(is, ip) = weight/64.0_real64
439 case default
440 assert(.false.)
441 end select
442
443 end do
444 end do
445
446 call nl_operator_allocate_gpu_buffers(smix%preconditioner)
447 call nl_operator_update_gpu_buffers(smix%preconditioner)
448 call nl_operator_output_weights(smix%preconditioner)
449
450 end subroutine init_preconditioner
451
452 end subroutine mix_init
453
454
455 ! ---------------------------------------------------------
456 subroutine mix_clear(smix)
457 type(mix_t), intent(inout) :: smix
458
459 push_sub(mix_clear)
460
461 call mixfield_clear(smix%scheme, smix%mixfield)
462
463 smix%iter = 0
464 smix%last_ipos = 0
465 smix%adaptive_damping = m_one
466
467 pop_sub(mix_clear)
468 end subroutine mix_clear
469
470
471 ! ---------------------------------------------------------
472 subroutine mix_end(smix)
473 type(mix_t), intent(inout) :: smix
474
475 integer :: ii
476
477 push_sub(mix_end)
478
479 if (smix%precondition) call nl_operator_end(smix%preconditioner)
480
481 call mixfield_end(smix, smix%mixfield)
482
483 smix%nauxmixfield = 0
484 do ii = 1,max_auxmixfield
485 nullify(smix%auxmixfield(ii)%p)
486 end do
487
488 safe_deallocate_a(smix%coeff)
489
490 pop_sub(mix_end)
491 end subroutine mix_end
492
493
494 ! ---------------------------------------------------------
495 subroutine mix_dump(namespace, restart, smix, mesh, ierr)
496 type(namespace_t), intent(in) :: namespace
497 class(restart_t), intent(in) :: restart
498 type(mix_t), intent(in) :: smix
499 class(mesh_t), intent(in) :: mesh
500 integer, intent(out) :: ierr
501
502 integer :: iunit, id2, id3, err, err2(4)
503 character(len=40) :: lines(7)
504 character(len=80) :: filename
505
506 push_sub(mix_dump)
507
508 ierr = 0
509
510 if (restart%skip()) then
511 pop_sub(mix_dump)
512 return
513 end if
514
515 message(1) = "Debug: Writing mixing restart."
516 call messages_info(1, namespace=namespace, debug_only=.true.)
517
518 ! functions to be written need to be compatible with the mesh
519 assert(mesh%np == smix%mixfield%d1)
520
521 ! First we write some information about the mixing
522 iunit = restart%open('mixing')
523 if(restart%do_i_write()) then
524 write(lines(1), '(a11,i1)') 'scheme= ', smix%scheme
525 ! Number of global mesh points have to be written, not only smix%d1
526 write(lines(2), '(a11,i10)') 'd1= ', mesh%np_global
527 write(lines(3), '(a11,i10)') 'd2= ', smix%mixfield%d2
528 write(lines(4), '(a11,i10)') 'd3= ', smix%mixfield%d3
529 write(lines(5), '(a11,i10)') 'iter= ', smix%iter
530 write(lines(6), '(a11,i10)') 'ns= ', smix%ns
531 write(lines(7), '(a11,i10)') 'last_ipos= ', smix%last_ipos
532 call restart%write(iunit, lines, 7, err)
533 ierr = ierr + err
534 end if
535 call restart%close(iunit)
536
537 ! Now we write the different functions.
538 ! These are not needed when using linear mixing, so we will make sure we skip this step in that case.
539 err2 = 0
540 if (smix%scheme /= option__mixingscheme__linear) then
541 do id2 = 1, smix%mixfield%d2
542 do id3 = 1, smix%mixfield%d3
543
544 write(filename,'(a3,i2.2,i2.2)') 'df_', id2, id3
545 if (smix%mixfield%func_type == type_float) then
546 call restart%write_mesh_function(filename, mesh, smix%mixfield%ddf(1:mesh%np, id2, id3), err)
547 else
548 call restart%write_mesh_function(filename, mesh, smix%mixfield%zdf(1:mesh%np, id2, id3), err)
549 end if
550 err2(1) = err2(1) + err
552 write(filename,'(a3,i2.2,i2.2)') 'dv_', id2, id3
553 if (smix%mixfield%func_type == type_float) then
554 call restart%write_mesh_function(filename, mesh, smix%mixfield%ddv(1:mesh%np, id2, id3), err)
555 else
556 call restart%write_mesh_function(filename, mesh, smix%mixfield%zdv(1:mesh%np, id2, id3), err)
557 end if
558 err2(2) = err2(2) + err
559
560 end do
561
562 write(filename,'(a6,i2.2)') 'f_old_', id2
563 if (smix%mixfield%func_type == type_float) then
564 call restart%write_mesh_function(filename, mesh, smix%mixfield%df_old(1:mesh%np, id2), err)
565 else
566 call restart%write_mesh_function(filename, mesh, smix%mixfield%zf_old(1:mesh%np, id2), err)
567 end if
568 err2(3) = err2(3) + err
569
570 write(filename,'(a8,i2.2)') 'vin_old_', id2
571 if (smix%mixfield%func_type == type_float) then
572 call restart%write_mesh_function(filename, mesh, smix%mixfield%dvin_old(1:mesh%np, id2), err)
573 else
574 call restart%write_mesh_function(filename, mesh, smix%mixfield%zvin_old(1:mesh%np, id2), err)
575 end if
576 err2(4) = err2(4) + err
577
578 end do
579
580 if (err2(1) /= 0) ierr = ierr + 2
581 if (err2(2) /= 0) ierr = ierr + 4
582 if (err2(3) /= 0) ierr = ierr + 8
583 if (err2(4) /= 0) ierr = ierr + 16
584 end if
585
586 message(1) = "Debug: Writing mixing restart done."
587 call messages_info(1, namespace=namespace, debug_only=.true.)
588
589 pop_sub(mix_dump)
590 end subroutine mix_dump
591
592
593 !---------------------------------------------------------
594 subroutine mix_load(namespace, restart, smix, mesh, ierr)
595 type(namespace_t), intent(in) :: namespace
596 type(restart_t), intent(in) :: restart
597 type(mix_t), intent(inout) :: smix
598 class(mesh_t), intent(in) :: mesh
599 integer, intent(out) :: ierr
600
601 integer :: iunit, err, err2(4)
602 integer :: scheme, d1, d2, d3, ns
603 integer :: id2, id3
604 character(len=11) :: str
605 character(len=80) :: filename
606 character(len=256) :: lines(7)
607
608 push_sub(mix_load)
609
610 ierr = 0
611
612 if (restart%skip()) then
613 ierr = -1
614 pop_sub(mix_load)
615 return
616 end if
617
618 message(1) = "Debug: Reading mixing restart."
619 call messages_info(1, namespace=namespace, debug_only=.true.)
620
621 ! First we read some information about the mixing
622 iunit = restart%open('mixing')
623 call restart%read(iunit, lines, 7, err)
624 if (err /= 0) then
625 ierr = ierr + 1
626 else
627 read(lines(1), *) str, scheme
628 read(lines(2), *) str, d1
629 read(lines(3), *) str, d2
630 read(lines(4), *) str, d3
631 read(lines(5), *) str, smix%iter
632 read(lines(6), *) str, ns
633 read(lines(7), *) str, smix%last_ipos
634 end if
635 call restart%close(iunit)
636
637
638 if (ierr == 0) then
639 ! We can only use the restart information if the mixing scheme and the number of steps used remained the same
640 if (scheme /= smix%scheme .or. ns /= smix%ns) then
641 message(1) = "The mixing scheme from the restart data is not the same as the one used in the current calculation."
642 call messages_warning(1, namespace=namespace)
643 ierr = ierr + 2
644 end if
645
646 ! Check the dimensions of the arrays to be read
647 if (mesh%np_global /= d1 .or. mesh%np /= smix%mixfield%d1 .or. d2 /= smix%mixfield%d2) then
648 message(1) = "The dimensions of the arrays from the mixing restart data"
649 message(2) = "are not the same as the ones used in this calculation."
650 call messages_warning(2, namespace=namespace)
651 ierr = ierr + 4
652 end if
653 end if
654
655
656 ! Now we read the different functions.
657 ! Note that we may have more or less functions than the ones needed (d3 /= smix%d3)
658 if (ierr == 0) then
659 if (smix%scheme /= option__mixingscheme__linear) then
660 err2 = 0
661 do id2 = 1, smix%mixfield%d2
662 do id3 = 1, smix%mixfield%d3
663
664 write(filename,'(a3,i2.2,i2.2)') 'df_', id2, id3
665 if (smix%mixfield%func_type == type_float) then
666 call restart%read_mesh_function(filename, mesh, smix%mixfield%ddf(1:mesh%np, id2, id3), err)
667 else
668 call restart%read_mesh_function(filename, mesh, smix%mixfield%zdf(1:mesh%np, id2, id3), err)
669 end if
670 if (err /= 0) err2(1) = err2(1) + 1
671
672 write(filename,'(a3,i2.2,i2.2)') 'dv_', id2, id3
673 if (smix%mixfield%func_type == type_float) then
674 call restart%read_mesh_function(filename, mesh, smix%mixfield%ddv(1:mesh%np, id2, id3), err)
675 else
676 call restart%read_mesh_function(filename, mesh, smix%mixfield%zdv(1:mesh%np, id2, id3), err)
677 end if
678 if (err /= 0) err2(2) = err2(2) + 1
679
680 end do
681
682 write(filename,'(a6,i2.2)') 'f_old_', id2
683 if (smix%mixfield%func_type == type_float) then
684 call restart%read_mesh_function(filename, mesh, smix%mixfield%df_old(1:mesh%np, id2), err)
685 else
686 call restart%read_mesh_function(filename, mesh, smix%mixfield%zf_old(1:mesh%np, id2), err)
687 end if
688 if (err /= 0) err2(3) = err2(3) + 1
690 write(filename,'(a8,i2.2)') 'vin_old_', id2
691 if (smix%mixfield%func_type == type_float) then
692 call restart%read_mesh_function(filename, mesh, smix%mixfield%dvin_old(1:mesh%np, id2), err)
693 else
694 call restart%read_mesh_function(filename, mesh, smix%mixfield%zvin_old(1:mesh%np, id2), err)
695 end if
696 if (err /= 0) err2(4) = err2(4) + 1
697
698 end do
699
700 if (err2(1) /= 0) ierr = ierr + 8
701 if (err2(2) /= 0) ierr = ierr + 16
702 if (err2(3) /= 0) ierr = ierr + 32
703 if (err2(4) /= 0) ierr = ierr + 64
704 end if
705 end if
706
707 if (ierr /= 0) then
708 ! Something went wront, so make sure we start from scratch
709 call mix_clear(smix)
710 end if
711
712 if (ierr == 0 .and. smix%scheme == option__mixingscheme__broyden_adaptive) then
713 smix%adaptive_damping = m_one
714 smix%mixfield%last_residue = m_zero
715 end if
716
717
718 message(1) = "Debug: Reading mixing restart done."
719 call messages_info(1, namespace=namespace, debug_only=.true.)
720
721 pop_sub(mix_load)
722 end subroutine mix_load
723
724 real(real64) pure function mix_coefficient(this) result(coefficient)
725 type(mix_t), intent(in) :: this
726
727 coefficient = this%coeff(1)
728 end function mix_coefficient
729
730 integer pure function mix_scheme(this) result(scheme)
731 type(mix_t), intent(in) :: this
732
733 scheme = this%scheme
734 end function mix_scheme
735
736 integer pure function mix_d3(this)
737 type(mix_t), intent(in) :: this
738
739 mix_d3 = this%mixfield%d3
740 end function mix_d3
741
742 subroutine mix_get_field(this, mixfield)
743 type(mix_t), target, intent(in) :: this
744 type(mixfield_t), pointer, intent(out) :: mixfield
745
746 mixfield => this%mixfield
747 end subroutine mix_get_field
748
750 subroutine mixing(namespace, smix)
751 type(namespace_t), intent(in) :: namespace
752 type(mix_t), intent(inout) :: smix
753
754 push_sub(mixing)
755
756 if (smix%mixfield%func_type == type_float) then
757 call dmixing(namespace, smix, smix%mixfield%dvin, smix%mixfield%dvout, smix%mixfield%dvnew)
758 else
759 call zmixing(namespace, smix, smix%mixfield%zvin, smix%mixfield%zvout, smix%mixfield%zvnew)
760 end if
761
762 pop_sub(mixing)
763 end subroutine mixing
764
765 subroutine mix_add_auxmixfield(namespace, smix, mixfield)
766 type(namespace_t), intent(in) :: namespace
767 type(mix_t), intent(inout) :: smix
768 type(mixfield_t), target, intent(in) :: mixfield
769
770 push_sub(mix_add_auxmixfield)
771
772 smix%nauxmixfield = smix%nauxmixfield + 1
773 smix%auxmixfield(smix%nauxmixfield)%p => mixfield
774
775 if (smix%scheme == option__mixingscheme__diis) then
776 message(1) = 'Mixing scheme DIIS is not implemented for auxiliary mixing fields'
777 call messages_fatal(1, namespace=namespace)
778 end if
779
780 pop_sub(mix_add_auxmixfield)
781 end subroutine mix_add_auxmixfield
782
784 subroutine mixfield_init(smix, mixfield, d1, d2, d3, func_type)
785 type(mix_t), intent(in) :: smix
786 type(mixfield_t), intent(inout) :: mixfield
787 integer, intent(in) :: d1, d2, d3
788 type(type_t), intent(in) :: func_type
789
790 push_sub(mixfield_init)
791
792 mixfield%d1 = d1
793 mixfield%d2 = d2
794 mixfield%d3 = d3
795
796 mixfield%func_type = func_type
797
798 mixfield%mix_spin_density_matrix = smix%mix_spin_density_matrix
799 mixfield%last_residue = m_zero
800
801 if (smix%scheme /= option__mixingscheme__linear) then
802 if (mixfield%func_type == type_float) then
803 safe_allocate( mixfield%ddf(1:d1, 1:d2, 1:d3))
804 safe_allocate( mixfield%ddv(1:d1, 1:d2, 1:d3))
805 safe_allocate(mixfield%dvin_old(1:d1, 1:d2))
806 safe_allocate( mixfield%df_old(1:d1, 1:d2))
807 else
808 safe_allocate( mixfield%zdf(1:d1, 1:d2, 1:d3))
809 safe_allocate( mixfield%zdv(1:d1, 1:d2, 1:d3))
810 safe_allocate(mixfield%zvin_old(1:d1, 1:d2))
811 safe_allocate( mixfield%zf_old(1:d1, 1:d2))
812 end if
813 end if
814
815 if (mixfield%func_type == type_float) then
816 safe_allocate(mixfield%dvin(1:d1, 1:d2))
817 safe_allocate(mixfield%dvout(1:d1, 1:d2))
818 safe_allocate(mixfield%dvnew(1:d1, 1:d2))
819 safe_allocate(mixfield%dresidual(1:d1, 1:d2))
820 else
821 safe_allocate(mixfield%zvin(1:d1, 1:d2))
822 safe_allocate(mixfield%zvout(1:d1, 1:d2))
823 safe_allocate(mixfield%zvnew(1:d1, 1:d2))
824 safe_allocate(mixfield%zresidual(1:d1, 1:d2))
825 end if
826
827 pop_sub(mixfield_init)
828 end subroutine mixfield_init
829
831 subroutine mixfield_end(smix, mixfield)
832 type(mix_t), intent(inout) :: smix
833 type(mixfield_t), intent(inout) :: mixfield
834
835 push_sub(mixfield_end)
836
837 ! Arrays got allocated for all mixing schemes, except linear mixing
838 if (smix%scheme /= option__mixingscheme__linear) then
839 if (mixfield%func_type == type_float) then
840 safe_deallocate_a(mixfield%ddf)
841 safe_deallocate_a(mixfield%ddv)
842 safe_deallocate_a(mixfield%dvin_old)
843 safe_deallocate_a(mixfield%df_old)
844 else
845 safe_deallocate_a(mixfield%zdf)
846 safe_deallocate_a(mixfield%zdv)
847 safe_deallocate_a(mixfield%zvin_old)
848 safe_deallocate_a(mixfield%zf_old)
849 end if
850 end if
851
852 if (mixfield%func_type == type_float) then
853 safe_deallocate_a(mixfield%dvin)
854 safe_deallocate_a(mixfield%dvout)
855 safe_deallocate_a(mixfield%dvnew)
856 safe_deallocate_a(mixfield%dresidual)
857 else
858 safe_deallocate_a(mixfield%zvin)
859 safe_deallocate_a(mixfield%zvout)
860 safe_deallocate_a(mixfield%zvnew)
861 safe_deallocate_a(mixfield%zresidual)
862 end if
863
864 pop_sub(mixfield_end)
865 end subroutine mixfield_end
866
868 subroutine mixfield_clear(scheme, mixfield)
869 integer, intent(in) :: scheme
870 type(mixfield_t), intent(inout) :: mixfield
871 integer :: d1, d2, d3
872
873 push_sub(mixfield_clear)
874
875 d1 = mixfield%d1
876 d2 = mixfield%d2
877 d3 = mixfield%d3
878
879 if (scheme /= option__mixingscheme__linear) then
880 if (mixfield%func_type == type_float) then
881 assert(allocated(mixfield%ddf))
882 mixfield%ddf(1:d1, 1:d2, 1:d3) = m_zero
883 mixfield%ddv(1:d1, 1:d2, 1:d3) = m_zero
884 mixfield%dvin_old(1:d1, 1:d2) = m_zero
885 mixfield%df_old(1:d1, 1:d2) = m_zero
886 else
887 assert(allocated(mixfield%zdf))
888 mixfield%zdf(1:d1, 1:d2, 1:d3) = m_z0
889 mixfield%zdv(1:d1, 1:d2, 1:d3) = m_z0
890 mixfield%zvin_old(1:d1, 1:d2) = m_z0
891 mixfield%zf_old(1:d1, 1:d2) = m_z0
892 end if
893 end if
894
895 if (mixfield%func_type == type_float) then
896 mixfield%dvin(1:d1, 1:d2) = m_zero
897 mixfield%dvout(1:d1, 1:d2) = m_zero
898 mixfield%dvnew(1:d1, 1:d2) = m_zero
899 mixfield%dresidual(1:d1, 1:d2) = m_zero
900 else
901 mixfield%zvin(1:d1, 1:d2) = m_z0
902 mixfield%zvout(1:d1, 1:d2) = m_z0
903 mixfield%zvnew(1:d1, 1:d2) = m_z0
904 mixfield%zresidual(1:d1, 1:d2) = m_z0
905 end if
906
907 pop_sub(mixfield_clear)
908 end subroutine mixfield_clear
909
918 subroutine compute_residuals_aux_field(this)
919 class(mix_t), intent(inout) :: this
920
921 type(mixfield_t), pointer :: aux_field
922 integer :: dims(2)
923 integer :: i
924
927 do i = 1, this%nauxmixfield
928 aux_field => this%auxmixfield(i)%p
929 dims = [aux_field%d1, aux_field%d2]
930
931 if (aux_field%func_type == type_float) then
932 call dcompute_residual(this, dims, aux_field%dvin, aux_field%dvout, aux_field%dresidual)
933 else
934 call zcompute_residual(this, dims, aux_field%zvin, aux_field%zvout, aux_field%zresidual)
935 end if
936
937 end do
938 nullify(aux_field)
939
941
942 end subroutine compute_residuals_aux_field
943
955 subroutine linear_mixing_aux_field(smix)
956 type(mix_t), intent(inout) :: smix
957
958 type(mixfield_t), pointer :: field
959 integer :: i
960
962
963 call smix%compute_residuals_aux_field()
964
965 do i = 1, smix%nauxmixfield
966 field => smix%auxmixfield(i)%p
967
968 if (field%func_type == type_float) then
969 call dmixing_linear(field%d1, field%d2, smix%coeff, field%dvin, field%dresidual, field%dvnew)
970 else
971 call zmixing_linear(field%d1, field%d2, smix%coeff, field%zvin, field%zresidual, field%zvnew)
972 end if
973
974 end do
975
976 nullify(field)
977
979 end subroutine linear_mixing_aux_field
980
981#include "undef.F90"
982#include "real.F90"
983
984#include "mix_inc.F90"
985
986#include "undef.F90"
987#include "complex.F90"
988
989#include "mix_inc.F90"
990
991end module mix_oct_m
992
993!! Local Variables:
994!! mode: f90
995!! coding: utf-8
996!! End:
subroutine init_preconditioner()
Definition: mix.F90:498
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
Definition: global.F90:200
real(real64), parameter, public m_one
Definition: global.F90:201
This module is intended to contain "only mathematical" functions and procedures.
Definition: math.F90:117
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
Definition: mesh.F90:120
subroutine, public messages_warning(no_lines, all_nodes, namespace)
Definition: messages.F90:525
subroutine, public messages_obsolete_variable(namespace, name, rep)
Definition: messages.F90:1000
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
Definition: messages.F90:162
subroutine, public messages_input_error(namespace, var, details, row, column)
Definition: messages.F90:691
subroutine, public messages_experimental(name, namespace)
Definition: messages.F90:1040
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
Definition: messages.F90:594
subroutine, public mixfield_end(smix, mixfield)
Deallocate all arrays of a mixfield instance.
Definition: mix.F90:927
integer pure function, public mix_scheme(this)
Definition: mix.F90:826
subroutine dmixfield_set_vin(mixfield, vin)
Definition: mix.F90:1940
real(real64) pure function, public mix_coefficient(this)
Definition: mix.F90:820
subroutine, public mixing(namespace, smix)
Main entry-point to SCF mixer.
Definition: mix.F90:846
subroutine, public mixfield_init(smix, mixfield, d1, d2, d3, func_type)
Initialise all attributes of a mixfield instance.
Definition: mix.F90:880
subroutine zmixfield_get_vnew(mixfield, vnew)
Definition: mix.F90:2946
subroutine dcompute_residual(smix, dims, vin, vout, residual)
Compute the residual of the potential (or density) for SCF mixing.
Definition: mix.F90:1239
subroutine, public mix_get_field(this, mixfield)
Definition: mix.F90:838
subroutine compute_residuals_aux_field(this)
Compute the residuals of the auxilliary fields.
Definition: mix.F90:1014
subroutine zmixfield_set_vout(mixfield, vout)
Definition: mix.F90:2927
subroutine, public mix_add_auxmixfield(namespace, smix, mixfield)
Definition: mix.F90:861
subroutine dmixfield_get_vnew(mixfield, vnew)
Definition: mix.F90:2006
subroutine dmixing_linear(d1, d2, coeff, vin, residual, vnew)
Linear mixing of the input and output potentials.
Definition: mix.F90:1207
subroutine, public mix_dump(namespace, restart, smix, mesh, ierr)
Definition: mix.F90:591
subroutine, public mixfield_clear(scheme, mixfield)
Zero all potential and field attributes of a mixfield instance.
Definition: mix.F90:964
subroutine, public mix_init(smix, namespace, space, der, d1, d2, def_, func_type_, prefix_)
Initialise mix_t instance.
Definition: mix.F90:269
subroutine zmixfield_set_vin(mixfield, vin)
Definition: mix.F90:2908
subroutine, public zmixing(namespace, smix, vin, vout, vnew)
Mix the input and output potentials (or densities) according to some scheme.
Definition: mix.F90:2118
integer pure function, public mix_d3(this)
Definition: mix.F90:832
subroutine, public mix_load(namespace, restart, smix, mesh, ierr)
Definition: mix.F90:690
subroutine dmixfield_set_vout(mixfield, vout)
Definition: mix.F90:1973
subroutine zcompute_residual(smix, dims, vin, vout, residual)
Compute the residual of the potential (or density) for SCF mixing.
Definition: mix.F90:2207
subroutine, public dmixing(namespace, smix, vin, vout, vnew)
Mix the input and output potentials (or densities) according to some scheme.
Definition: mix.F90:1150
subroutine linear_mixing_aux_field(smix)
Linear mixing of the auxilliary fields.
Definition: mix.F90:1051
subroutine zmixing_linear(d1, d2, coeff, vin, residual, vnew)
Linear mixing of the input and output potentials.
Definition: mix.F90:2175
subroutine, public mix_end(smix)
Definition: mix.F90:568
subroutine, public mix_clear(smix)
Definition: mix.F90:552
This module defines non-local operators.
subroutine, public nl_operator_init(op, label, symm)
initialize an instance of a non-local operator by setting the label
subroutine, public nl_operator_update_gpu_buffers(op)
subroutine, public nl_operator_output_weights(this)
subroutine, public nl_operator_end(op)
subroutine, public nl_operator_build(space, mesh, op, np, const_w, regenerate)
Creates the nonlocal operators for the stencils used for finite differences.
subroutine, public nl_operator_allocate_gpu_buffers(op)
This module is intended to contain "only mathematical" functions and procedures.
Definition: solvers.F90:117
This module defines routines, generating operators for a cubic stencil.
subroutine, public stencil_cube_get_lapl(this, dim, order)
type(type_t), parameter, public type_float
Definition: types.F90:135
class representing derivatives
Describes mesh distribution to nodes.
Definition: mesh.F90:187
God class for mixing.
Definition: mix.F90:216
Quantities used in mixing: Input, output and new potentials, and the residuals.
Definition: mix.F90:172
int true(void)