10
0
mirror of https://github.com/LCPQ/quantum_package synced 2024-11-18 12:03:57 +01:00
quantum_package/src/Davidson/parameters.irp.f

50 lines
1.6 KiB
Fortran

BEGIN_PROVIDER [ character(64), davidson_criterion ]
implicit none
BEGIN_DOC
! Can be : [ energy | residual | both | wall_time | cpu_time | iterations ]
END_DOC
davidson_criterion = 'residual'
END_PROVIDER
subroutine davidson_converged(energy,residual,wall,iterations,cpu,N_st,converged)
implicit none
BEGIN_DOC
! True if the Davidson algorithm is converged
END_DOC
integer, intent(in) :: N_st, iterations
logical, intent(out) :: converged
double precision, intent(in) :: energy(N_st), residual(N_st)
double precision, intent(in) :: wall, cpu
double precision :: E(N_st), time
double precision, allocatable, save :: energy_old(:)
if (iterations < 2) then
converged = .False.
return
endif
if (.not.allocated(energy_old)) then
allocate(energy_old(N_st))
energy_old = 0.d0
endif
E = energy - energy_old
energy_old = energy
if (davidson_criterion == 'energy') then
converged = dabs(maxval(E(1:N_st))) < threshold_davidson
else if (davidson_criterion == 'residual') then
converged = dabs(maxval(residual(1:N_st))) < threshold_davidson
else if (davidson_criterion == 'both') then
converged = dabs(maxval(residual(1:N_st))) + dabs(maxval(E(1:N_st)) ) &
< threshold_davidson
else if (davidson_criterion == 'wall_time') then
call wall_time(time)
converged = time - wall > threshold_davidson
else if (davidson_criterion == 'cpu_time') then
call cpu_time(time)
converged = time - cpu > threshold_davidson
else if (davidson_criterion == 'iterations') then
converged = iterations >= int(threshold_davidson)
endif
end