Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=8), | intent(inout), | dimension(:) | :: | x | ||
real(kind=8), | intent(in), | dimension(size(x)) | :: | Fx | ||
real(kind=8), | intent(in) | :: | alpha | |||
integer, | intent(in) | :: | iter |
subroutine d_adaptive_mix(x,Fx,alpha,iter) real(8),intent(inout),dimension(:) :: x !x_in real(8),intent(in),dimension(size(x)) :: Fx !x_out-x_in real(8),intent(in) :: alpha !mixing α integer,intent(in) :: iter integer :: N real(8),parameter :: alpha_max = 1d0 real(8),allocatable,dimension(:),save :: Fx_prev !prev iter real(8),allocatable,dimension(:),save :: beta !mixing β integer :: j logical :: not_oscillating ! N = size(x) ! if(iter==1)then !reset persistent variables if(allocated(Fx_prev))deallocate(Fx_prev) allocate(Fx_prev(N)) Fx_prev = 0d0 ! if(allocated(beta))deallocate(beta) allocate(beta(N)) beta = alpha endif ! X = X + beta*Fx ! = (1-β)x_in + βx_out (β: effective speed) ! if (iter > 1) then !update effective elemental mixing do j=1,N not_oscillating = Fx_prev(j)*Fx(j)>0 !same sign if(not_oscillating) then !increase mixing speed beta(j) = beta(j) + alpha !but with a cutoff if (beta(j) > alpha_max) beta(j) = alpha_max else beta(j) = alpha ! reset to input mixing α end if end do end if ! Fx_prev = Fx !store Fx_prev for future calls ! end subroutine d_adaptive_mix