27 use,
intrinsic :: iso_fortran_env
81 real(real64),
allocatable :: ddf(:, :, :)
82 real(real64),
allocatable :: ddv(:, :, :)
83 real(real64),
allocatable :: df_old(:, :)
84 real(real64),
allocatable :: dvin_old(:, :)
85 real(real64),
allocatable :: dvin(:, :)
86 real(real64),
allocatable :: dvout(:, :)
87 real(real64),
allocatable :: dvnew(:, :)
88 real(real64),
allocatable :: dresidual(:, :)
91 complex(real64),
allocatable :: zdf(:, :, :)
92 complex(real64),
allocatable :: zdv(:, :, :)
93 complex(real64),
allocatable :: zf_old(:, :)
94 complex(real64),
allocatable :: zvin_old(:, :)
95 complex(real64),
allocatable :: zvin(:, :)
96 complex(real64),
allocatable :: zvout(:, :)
97 complex(real64),
allocatable :: zvnew(:, :)
98 complex(real64),
allocatable :: zresidual(:, :)
100 type(type_t) :: func_type
101 integer :: d1, d2, d3
104 logical :: mix_spin_density_matrix
109 type(mixfield_t),
pointer :: p
112 integer,
parameter :: MAX_AUXMIXFIELD = 5
123 type(derivatives_t),
pointer :: der
126 real(real64),
allocatable :: coeff(:)
127 real(real64) :: residual_coeff
130 integer,
public :: ns
131 integer,
public :: ns_restart
138 type(mixfield_t) :: mixfield
139 integer :: nauxmixfield
140 type(mixfield_ptr_t) :: auxmixfield(MAX_AUXMIXFIELD)
146 real(real64) :: kerker_factor
147 logical :: precondition
148 type(nl_operator_t) :: preconditioner
151 logical :: mix_spin_density_matrix
153 procedure :: compute_residuals_aux_field
172 subroutine mix_init(smix, namespace, space, der, d1, d2, def_, func_type_, prefix_)
173 type(mix_t),
intent(out) :: smix
177 integer,
intent(in) :: d1
178 integer,
intent(in) :: d2
179 integer,
optional,
intent(in) :: def_
180 type(
type_t),
optional,
intent(in) :: func_type_
181 character(len=*),
optional,
intent(in) :: prefix_
184 character(len=32) :: prefix
186 real(real64) :: coeff
192 def = option__mixingscheme__broyden
193 if (
present(def_)) def = def_
194 if (
present(func_type_))
then
195 func_type = func_type_
200 if (
present(prefix_)) prefix = prefix_
226 call parse_variable(namespace, trim(prefix)//
'MixingScheme', def, smix%scheme)
241 call parse_variable(namespace, trim(prefix)+
'MixingPreconditioner', .false., smix%precondition)
242 if (der%dim /= 3) smix%precondition = .false.
253 call parse_variable(namespace, trim(prefix)+
'Mixing', 0.3_real64, coeff)
257 safe_allocate(smix%coeff(1:d2))
271 call parse_variable(namespace, trim(prefix)+
'MixingSpinDensityMatrix', .false., smix%mix_spin_density_matrix)
281 call parse_variable(namespace, trim(prefix)+
'MixingMagnetization', 1.5_real64, coeff)
283 if (.not. smix%mix_spin_density_matrix) smix%coeff(2:d2) = coeff
285 smix%mix_spin_density_matrix = .
true.
296 call parse_variable(namespace, trim(prefix)+
'MixingResidual', 0.05_real64, smix%residual_coeff)
297 if (smix%residual_coeff <=
m_zero .or. smix%residual_coeff >
m_one)
then
298 call messages_input_error(namespace,
'MixingResidual',
'Value should be positive and smaller than one.')
310 if (smix%scheme /= option__mixingscheme__linear)
then
311 call parse_variable(namespace, trim(prefix)//
'MixNumberSteps', 4, smix%ns)
326 if (smix%scheme /= option__mixingscheme__linear)
then
327 call parse_variable(namespace, trim(prefix)//
'MixingRestart', 20, smix%ns_restart)
333 write(
message(1),
'(A,I4,A,I4,A)')
"Info: Mixing uses ", smix%ns,
" steps and restarts after ", &
334 smix%ns_restart,
" steps."
347 call parse_variable(namespace, trim(prefix)//
'MixInterval', 1, smix%interval)
348 if (smix%interval < 1)
call messages_input_error(namespace,
'MixInterval',
'MixInterval must be larger or equal than 1')
363 call parse_variable(namespace, trim(prefix)+
'MixingKerker', .false., smix%kerker)
376 call parse_variable(namespace, trim(prefix)+
'MixingKerkerFactor', 1._real64, smix%kerker_factor)
378 smix%nauxmixfield = 0
379 do ii = 1,max_auxmixfield
380 nullify(smix%auxmixfield(ii)%p)
383 call mixfield_init(smix, smix%mixfield, d1, d2, smix%ns, func_type)
393 integer :: ns, maxp, ip, is
394 real(real64),
parameter :: weight = 50.0_real64
401 assert(.not. der%mesh%use_curvilinear)
406 call nl_operator_build(space, der%mesh, smix%preconditioner, der%mesh%np, const_w = .not. der%mesh%use_curvilinear)
408 ns = smix%preconditioner%stencil%size
410 if (smix%preconditioner%const_w)
then
419 select case (sum(abs(smix%preconditioner%stencil%points(1:der%dim, is))))
421 smix%preconditioner%w(is, ip) =
m_one + weight/8.0_real64
423 smix%preconditioner%w(is, ip) = weight/16.0_real64
425 smix%preconditioner%w(is, ip) = weight/32.0_real64
427 smix%preconditioner%w(is, ip) = weight/64.0_real64
446 type(
mix_t),
intent(inout) :: smix
461 type(
mix_t),
intent(inout) :: smix
471 smix%nauxmixfield = 0
472 do ii = 1,max_auxmixfield
473 nullify(smix%auxmixfield(ii)%p)
476 safe_deallocate_a(smix%coeff)
483 subroutine mix_dump(namespace, restart, smix, space, mesh, ierr)
486 type(
mix_t),
intent(in) :: smix
487 class(
space_t),
intent(in) :: space
488 class(
mesh_t),
intent(in) :: mesh
489 integer,
intent(out) :: ierr
491 integer :: iunit, id2, id3, err, err2(4)
492 character(len=40) :: lines(7)
493 character(len=80) :: filename
504 message(1) =
"Debug: Writing mixing restart."
508 assert(mesh%np == smix%mixfield%d1)
512 write(lines(1),
'(a11,i1)')
'scheme= ', smix%scheme
514 write(lines(2),
'(a11,i10)')
'd1= ', mesh%np_global
515 write(lines(3),
'(a11,i10)')
'd2= ', smix%mixfield%d2
516 write(lines(4),
'(a11,i10)')
'd3= ', smix%mixfield%d3
517 write(lines(5),
'(a11,i10)')
'iter= ', smix%iter
518 write(lines(6),
'(a11,i10)')
'ns= ', smix%ns
519 write(lines(7),
'(a11,i10)')
'last_ipos= ', smix%last_ipos
527 if (smix%scheme /= option__mixingscheme__linear)
then
528 do id2 = 1, smix%mixfield%d2
529 do id3 = 1, smix%mixfield%d3
531 write(filename,
'(a3,i2.2,i2.2)')
'df_', id2, id3
532 if (smix%mixfield%func_type ==
type_float)
then
537 err2(1) = err2(1) + err
539 write(filename,
'(a3,i2.2,i2.2)')
'dv_', id2, id3
540 if (smix%mixfield%func_type ==
type_float)
then
545 err2(2) = err2(2) + err
549 write(filename,
'(a6,i2.2)')
'f_old_', id2
550 if (smix%mixfield%func_type ==
type_float)
then
555 err2(3) = err2(3) + err
557 write(filename,
'(a8,i2.2)')
'vin_old_', id2
558 if (smix%mixfield%func_type ==
type_float)
then
563 err2(4) = err2(4) + err
567 if (err2(1) /= 0) ierr = ierr + 2
568 if (err2(2) /= 0) ierr = ierr + 4
569 if (err2(3) /= 0) ierr = ierr + 8
570 if (err2(4) /= 0) ierr = ierr + 16
573 message(1) =
"Debug: Writing mixing restart done."
581 subroutine mix_load(namespace, restart, smix, space, mesh, ierr)
584 type(
mix_t),
intent(inout) :: smix
585 class(
space_t),
intent(in) :: space
586 class(
mesh_t),
intent(in) :: mesh
587 integer,
intent(out) :: ierr
589 integer :: iunit, err, err2(4)
590 integer :: scheme, d1, d2, d3, ns
592 character(len=11) :: str
593 character(len=80) :: filename
594 character(len=256) :: lines(7)
606 message(1) =
"Debug: Reading mixing restart."
615 read(lines(1), *) str, scheme
616 read(lines(2), *) str, d1
617 read(lines(3), *) str, d2
618 read(lines(4), *) str, d3
619 read(lines(5), *) str, smix%iter
620 read(lines(6), *) str, ns
621 read(lines(7), *) str, smix%last_ipos
628 if (scheme /= smix%scheme .or. ns /= smix%ns)
then
629 message(1) =
"The mixing scheme from the restart data is not the same as the one used in the current calculation."
635 if (mesh%np_global /= d1 .or. mesh%np /= smix%mixfield%d1 .or. d2 /= smix%mixfield%d2)
then
636 message(1) =
"The dimensions of the arrays from the mixing restart data"
637 message(2) =
"are not the same as the ones used in this calculation."
647 if (smix%scheme /= option__mixingscheme__linear)
then
649 do id2 = 1, smix%mixfield%d2
650 do id3 = 1, smix%mixfield%d3
652 write(filename,
'(a3,i2.2,i2.2)')
'df_', id2, id3
653 if (smix%mixfield%func_type ==
type_float)
then
658 if (err /= 0) err2(1) = err2(1) + 1
660 write(filename,
'(a3,i2.2,i2.2)')
'dv_', id2, id3
661 if (smix%mixfield%func_type ==
type_float)
then
666 if (err /= 0) err2(2) = err2(2) + 1
670 write(filename,
'(a6,i2.2)')
'f_old_', id2
671 if (smix%mixfield%func_type ==
type_float)
then
676 if (err /= 0) err2(3) = err2(3) + 1
678 write(filename,
'(a8,i2.2)')
'vin_old_', id2
679 if (smix%mixfield%func_type ==
type_float)
then
684 if (err /= 0) err2(4) = err2(4) + 1
688 if (err2(1) /= 0) ierr = ierr + 8
689 if (err2(2) /= 0) ierr = ierr + 16
690 if (err2(3) /= 0) ierr = ierr + 32
691 if (err2(4) /= 0) ierr = ierr + 64
700 message(1) =
"Debug: Reading mixing restart done."
707 type(
mix_t),
intent(in) :: this
709 coefficient = this%coeff(1)
712 integer pure function
mix_scheme(this) result(scheme)
713 type(
mix_t),
intent(in) :: this
718 integer pure function
mix_d3(this)
719 type(
mix_t),
intent(in) :: this
725 type(
mix_t),
target,
intent(in) :: this
726 type(
mixfield_t),
pointer,
intent(out) :: mixfield
728 mixfield => this%mixfield
732 subroutine mixing(namespace, smix)
733 type(namespace_t),
intent(in) :: namespace
734 type(
mix_t),
intent(inout) :: smix
738 if (smix%mixfield%func_type == type_float)
then
739 call dmixing(namespace, smix, smix%mixfield%dvin, smix%mixfield%dvout, smix%mixfield%dvnew)
741 call zmixing(namespace, smix, smix%mixfield%zvin, smix%mixfield%zvout, smix%mixfield%zvnew)
748 type(namespace_t),
intent(in) :: namespace
749 type(
mix_t),
intent(inout) :: smix
750 type(
mixfield_t),
target,
intent(in) :: mixfield
754 smix%nauxmixfield = smix%nauxmixfield + 1
755 smix%auxmixfield(smix%nauxmixfield)%p => mixfield
757 if (smix%scheme == option__mixingscheme__diis)
then
758 message(1) =
'Mixing scheme DIIS is not implemented for auxiliary mixing fields'
759 call messages_fatal(1, namespace=namespace)
766 subroutine mixfield_init(smix, mixfield, d1, d2, d3, func_type)
767 type(
mix_t),
intent(in) :: smix
769 integer,
intent(in) :: d1, d2, d3
770 type(type_t),
intent(in) :: func_type
778 mixfield%func_type = func_type
780 mixfield%mix_spin_density_matrix = smix%mix_spin_density_matrix
782 if (smix%scheme /= option__mixingscheme__linear)
then
783 if (mixfield%func_type == type_float)
then
784 safe_allocate( mixfield%ddf(1:d1, 1:d2, 1:d3))
785 safe_allocate( mixfield%ddv(1:d1, 1:d2, 1:d3))
786 safe_allocate(mixfield%dvin_old(1:d1, 1:d2))
787 safe_allocate( mixfield%df_old(1:d1, 1:d2))
789 safe_allocate( mixfield%zdf(1:d1, 1:d2, 1:d3))
790 safe_allocate( mixfield%zdv(1:d1, 1:d2, 1:d3))
791 safe_allocate(mixfield%zvin_old(1:d1, 1:d2))
792 safe_allocate( mixfield%zf_old(1:d1, 1:d2))
796 if (mixfield%func_type == type_float)
then
797 safe_allocate(mixfield%dvin(1:d1, 1:d2))
798 safe_allocate(mixfield%dvout(1:d1, 1:d2))
799 safe_allocate(mixfield%dvnew(1:d1, 1:d2))
800 safe_allocate(mixfield%dresidual(1:d1, 1:d2))
802 safe_allocate(mixfield%zvin(1:d1, 1:d2))
803 safe_allocate(mixfield%zvout(1:d1, 1:d2))
804 safe_allocate(mixfield%zvnew(1:d1, 1:d2))
805 safe_allocate(mixfield%zresidual(1:d1, 1:d2))
813 type(
mix_t),
intent(inout) :: smix
819 if (smix%scheme /= option__mixingscheme__linear)
then
820 if (mixfield%func_type == type_float)
then
821 safe_deallocate_a(mixfield%ddf)
822 safe_deallocate_a(mixfield%ddv)
823 safe_deallocate_a(mixfield%dvin_old)
824 safe_deallocate_a(mixfield%df_old)
826 safe_deallocate_a(mixfield%zdf)
827 safe_deallocate_a(mixfield%zdv)
828 safe_deallocate_a(mixfield%zvin_old)
829 safe_deallocate_a(mixfield%zf_old)
833 if (mixfield%func_type == type_float)
then
834 safe_deallocate_a(mixfield%dvin)
835 safe_deallocate_a(mixfield%dvout)
836 safe_deallocate_a(mixfield%dvnew)
837 safe_deallocate_a(mixfield%dresidual)
839 safe_deallocate_a(mixfield%zvin)
840 safe_deallocate_a(mixfield%zvout)
841 safe_deallocate_a(mixfield%zvnew)
842 safe_deallocate_a(mixfield%zresidual)
850 integer,
intent(in) :: scheme
852 integer :: d1, d2, d3
860 if (scheme /= option__mixingscheme__linear)
then
861 if (mixfield%func_type == type_float)
then
862 assert(
allocated(mixfield%ddf))
863 mixfield%ddf(1:d1, 1:d2, 1:d3) = m_zero
864 mixfield%ddv(1:d1, 1:d2, 1:d3) = m_zero
865 mixfield%dvin_old(1:d1, 1:d2) = m_zero
866 mixfield%df_old(1:d1, 1:d2) = m_zero
868 assert(
allocated(mixfield%zdf))
869 mixfield%zdf(1:d1, 1:d2, 1:d3) = m_z0
870 mixfield%zdv(1:d1, 1:d2, 1:d3) = m_z0
871 mixfield%zvin_old(1:d1, 1:d2) = m_z0
872 mixfield%zf_old(1:d1, 1:d2) = m_z0
876 if (mixfield%func_type == type_float)
then
877 mixfield%dvin(1:d1, 1:d2) = m_zero
878 mixfield%dvout(1:d1, 1:d2) = m_zero
879 mixfield%dvnew(1:d1, 1:d2) = m_zero
880 mixfield%dresidual(1:d1, 1:d2) = m_zero
882 mixfield%zvin(1:d1, 1:d2) = m_z0
883 mixfield%zvout(1:d1, 1:d2) = m_z0
884 mixfield%zvnew(1:d1, 1:d2) = m_z0
885 mixfield%zresidual(1:d1, 1:d2) = m_z0
900 class(
mix_t),
intent(inout) :: this
908 do i = 1, this%nauxmixfield
909 aux_field => this%auxmixfield(i)%p
910 dims = [aux_field%d1, aux_field%d2]
912 if (aux_field%func_type == type_float)
then
913 call dcompute_residual(this, dims, aux_field%dvin, aux_field%dvout, aux_field%dresidual)
915 call zcompute_residual(this, dims, aux_field%zvin, aux_field%zvout, aux_field%zresidual)
937 type(
mix_t),
intent(inout) :: smix
944 call smix%compute_residuals_aux_field()
946 do i = 1, smix%nauxmixfield
947 field => smix%auxmixfield(i)%p
949 if (field%func_type == type_float)
then
950 call dmixing_linear(field%d1, field%d2, smix%coeff, field%dvin, field%dresidual, field%dvnew)
952 call zmixing_linear(field%d1, field%d2, smix%coeff, field%zvin, field%zresidual, field%zvnew)
965#include "mix_inc.F90"
968#include "complex.F90"
970#include "mix_inc.F90"
subroutine init_preconditioner()
This module calculates the derivatives (gradients, Laplacians, etc.) of a function.
real(real64), parameter, public m_zero
real(real64), parameter, public m_one
This module is intended to contain "only mathematical" functions and procedures.
This module defines various routines, operating on mesh functions.
This module defines the meshes, which are used in Octopus.
subroutine, public messages_warning(no_lines, all_nodes, namespace)
subroutine, public messages_obsolete_variable(namespace, name, rep)
character(len=256), dimension(max_lines), public message
to be output by fatal, warning
subroutine, public messages_input_error(namespace, var, details, row, column)
subroutine, public messages_experimental(name, namespace)
subroutine, public messages_info(no_lines, iunit, debug_only, stress, all_nodes, namespace)
subroutine, public mixfield_end(smix, mixfield)
Deallocate all arrays of a mixfield instance.
integer pure function, public mix_scheme(this)
subroutine dmixfield_set_vin(mixfield, vin)
real(real64) pure function, public mix_coefficient(this)
subroutine, public mixing(namespace, smix)
Main entry-point to SCF mixer.
subroutine, public mixfield_init(smix, mixfield, d1, d2, d3, func_type)
Initialise all attributes of a mixfield instance.
subroutine zmixfield_get_vnew(mixfield, vnew)
subroutine dcompute_residual(smix, dims, vin, vout, residual)
Compute the residual of the potential (or density) for SCF mixing.
subroutine, public mix_get_field(this, mixfield)
subroutine compute_residuals_aux_field(this)
Compute the residuals of the auxilliary fields.
subroutine zmixfield_set_vout(mixfield, vout)
subroutine, public mix_add_auxmixfield(namespace, smix, mixfield)
subroutine dmixfield_get_vnew(mixfield, vnew)
subroutine dmixing_linear(d1, d2, coeff, vin, residual, vnew)
Linear mixing of the input and output potentials.
subroutine, public mix_dump(namespace, restart, smix, space, mesh, ierr)
subroutine, public mixfield_clear(scheme, mixfield)
Zero all potential and field attributes of a mixfield instance.
subroutine, public mix_load(namespace, restart, smix, space, mesh, ierr)
subroutine, public mix_init(smix, namespace, space, der, d1, d2, def_, func_type_, prefix_)
Initialise mix_t instance.
subroutine zmixfield_set_vin(mixfield, vin)
subroutine, public zmixing(namespace, smix, vin, vout, vnew)
Mix the input and output potentials (or densities) according to some scheme.
integer pure function, public mix_d3(this)
subroutine dmixfield_set_vout(mixfield, vout)
subroutine zcompute_residual(smix, dims, vin, vout, residual)
Compute the residual of the potential (or density) for SCF mixing.
subroutine, public dmixing(namespace, smix, vin, vout, vnew)
Mix the input and output potentials (or densities) according to some scheme.
subroutine linear_mixing_aux_field(smix)
Linear mixing of the auxilliary fields.
subroutine zmixing_linear(d1, d2, coeff, vin, residual, vnew)
Linear mixing of the input and output potentials.
subroutine, public mix_end(smix)
subroutine, public mix_clear(smix)
This module defines non-local operators.
subroutine, public nl_operator_init(op, label)
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)
subroutine, public nl_operator_allocate_gpu_buffers(op)
subroutine, public restart_read(restart, iunit, lines, nlines, ierr)
subroutine, public restart_close(restart, iunit)
Close a file previously opened with restart_open.
subroutine, public restart_write(restart, iunit, lines, nlines, ierr)
logical pure function, public restart_skip(restart)
Returns true if the restart information should neither be read nor written. This might happen because...
integer function, public restart_open(restart, filename, status, position, silent)
Open file "filename" found inside the current restart directory. Depending on the type of restart,...
This module is intended to contain "only mathematical" functions and procedures.
This module defines routines, generating operators for a cubic stencil.
subroutine, public stencil_cube_get_lapl(this, dim, order)
type(type_t), public type_float
class representing derivatives
Describes mesh distribution to nodes.
Quantities used in mixing: Input, output and new potentials, and the residuals.