Commit 462d16e8 authored by Gregor Michalicek's avatar Gregor Michalicek

Added alternativ implementation of the broyden subroutine for continuous restarting

This is not yet fully functional and not yet activated in the code. To activate it
the broyden call in "mix" has to be replaced by a broyden2 call.
parent 271de2a3
......@@ -135,6 +135,7 @@ CONTAINS
ENDIF
DO nn = 1,atoms%neq(n)
na = na + 1
i_u_save = i_u
IF (atoms%lnonsph(n).LT.0) CYCLE ntype_loop
IF ((atoms%invsat(na).EQ.0) .OR. (atoms%invsat(na).EQ.1)) THEN
IF (atoms%invsat(na).EQ.0) invsfct = 1
......@@ -270,12 +271,10 @@ CONTAINS
ENDIF
END IF
IF (atoms%n_u.GT.0) THEN
nkvecprevatuTemp = nkvecprevatu
iilouTemp = iilou
locoluTemp = locolu
i_u_save = i_u
DO WHILE (i_u.LE.atoms%n_u)
IF (atoms%lda_u(i_u)%atomType.GT.n) EXIT
nkvecprevatuTemp = nkvecprevatu
......
!--------------------------------------------------------------------------------
! Copyright (c) 2018 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
! This file is part of FLEUR and available as free software under the conditions
! of the MIT license as expressed in the LICENSE file in more detail.
!--------------------------------------------------------------------------------
MODULE m_broyd_io
USE m_types
......@@ -192,6 +198,247 @@ SUBROUTINE writeVVec(input,hybrid,vecLen,currentIter,dfivi,vVec)
END SUBROUTINE writeVVec
SUBROUTINE readDeltaNVec(input,hybrid,vecLen,relIter,currentIter,deltaNVec)
TYPE(t_input), INTENT(IN) :: input
TYPE(t_hybrid), INTENT(IN) :: hybrid
INTEGER, INTENT(IN) :: vecLen, relIter, currentIter
REAL, INTENT(OUT) :: deltaNVec(vecLen)
INTEGER :: mode, npos
INTEGER*8 :: recLen
CALL getIOMode(mode)
! At the moment broyden IO is mode independent
recLen=(vecLen+1)*8
IF (hybrid%l_calhf) THEN
OPEN (59,file='hf_broyd_DN',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ELSE
OPEN (59,file='broyd_DN',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ENDIF
npos=currentIter+relIter-1
IF (currentIter.GT.input%maxiter+1) npos = MOD(currentIter-2,input%maxiter)+1
READ(59,rec=npos) deltaNVec(:vecLen)
CLOSE(59)
END SUBROUTINE readDeltaNVec
SUBROUTINE writeDeltaNVec(input,hybrid,vecLen,currentIter,deltaNVec)
TYPE(t_input), INTENT(IN) :: input
TYPE(t_hybrid), INTENT(IN) :: hybrid
INTEGER, INTENT(IN) :: vecLen, currentIter
REAL, INTENT(IN) :: deltaNVec(vecLen)
INTEGER :: mode, npos
INTEGER*8 :: recLen
CALL getIOMode(mode)
! At the moment broyden IO is mode independent
recLen=(vecLen+1)*8
IF (hybrid%l_calhf) THEN
OPEN (59,file='hf_broyd_DN',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ELSE
OPEN (59,file='broyd_DN',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ENDIF
npos=currentIter-1
IF (currentIter.GT.input%maxiter+1) npos = MOD(currentIter-2,input%maxiter)+1
WRITE(59,rec=npos) deltaNVec(:vecLen)
CLOSE(59)
END SUBROUTINE writeDeltaNVec
SUBROUTINE readDeltaFVec(input,hybrid,vecLen,relIter,currentIter,deltaFVec)
TYPE(t_input), INTENT(IN) :: input
TYPE(t_hybrid), INTENT(IN) :: hybrid
INTEGER, INTENT(IN) :: vecLen, relIter, currentIter
REAL, INTENT(OUT) :: deltaFVec(vecLen)
INTEGER :: mode, npos
INTEGER*8 :: recLen
CALL getIOMode(mode)
! At the moment broyden IO is mode independent
recLen=(vecLen+1)*8
IF (hybrid%l_calhf) THEN
OPEN (59,file='hf_broyd_DF',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ELSE
OPEN (59,file='broyd_DF',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ENDIF
npos=currentIter+relIter-1
IF (currentIter.GT.input%maxiter+1) npos = MOD(currentIter-2,input%maxiter)+1
READ(59,rec=npos) deltaFVec(:vecLen)
CLOSE(59)
END SUBROUTINE readDeltaFVec
SUBROUTINE writeDeltaFVec(input,hybrid,vecLen,currentIter,deltaFVec)
TYPE(t_input), INTENT(IN) :: input
TYPE(t_hybrid), INTENT(IN) :: hybrid
INTEGER, INTENT(IN) :: vecLen, currentIter
REAL, INTENT(IN) :: deltaFVec(vecLen)
INTEGER :: mode, npos
INTEGER*8 :: recLen
CALL getIOMode(mode)
! At the moment broyden IO is mode independent
recLen=(vecLen+1)*8
IF (hybrid%l_calhf) THEN
OPEN (59,file='hf_broyd_DF',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ELSE
OPEN (59,file='broyd_DF',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ENDIF
npos=currentIter-1
IF (currentIter.GT.input%maxiter+1) npos = MOD(currentIter-2,input%maxiter)+1
WRITE(59,rec=npos) deltaFVec(:vecLen)
CLOSE(59)
END SUBROUTINE writeDeltaFVec
SUBROUTINE writeBroydenOverlapExt(input,hybrid,currentIter,historyLength,&
dNdNLast,dFdFLast,dNdFLast,dFdNLast)
TYPE(t_input), INTENT(IN) :: input
TYPE(t_hybrid), INTENT(IN) :: hybrid
INTEGER, INTENT(IN) :: currentIter, historyLength
REAL, INTENT(IN) :: dNdNLast(input%maxIter)
REAL, INTENT(IN) :: dFdFLast(input%maxIter)
REAL, INTENT(IN) :: dNdFLast(input%maxIter)
REAL, INTENT(IN) :: dFdNLast(input%maxIter)
INTEGER :: recLen, npos
recLen = 8*4*input%maxIter ! sizeOfReal*numberOfVectors*vectorLength
recLen = recLen + 2*8 ! storage for currentIter, historyLength
IF (hybrid%l_calhf) THEN
OPEN (59,file='hf_broydOvlp',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ELSE
OPEN (59,file='broydOvlp',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ENDIF
npos=currentIter-1
IF (currentIter.GT.input%maxiter+1) npos = MOD(currentIter-2,input%maxiter)+1
WRITE(59,rec=npos) currentIter, historyLength,&
dNdNLast(:input%maxIter), dFdFLast(:input%maxIter), &
dNdFLast(:input%maxIter), dFdNLast(:input%maxIter)
CLOSE(59)
END SUBROUTINE writeBroydenOverlapExt
SUBROUTINE readBroydenOverlaps(input,hybrid,currentIter,historyLength,&
dNdNMat,dFdFMat,dNdFMat,dFdNMat)
TYPE(t_input), INTENT(IN) :: input
TYPE(t_hybrid), INTENT(IN) :: hybrid
INTEGER, INTENT(IN) :: currentIter, historyLength
REAL, INTENT(INOUT) :: dNdNMat(historyLength,historyLength)
REAL, INTENT(INOUT) :: dFdFMat(historyLength,historyLength)
REAL, INTENT(INOUT) :: dNdFMat(historyLength,historyLength)
REAL, INTENT(INOUT) :: dFdNMat(historyLength,historyLength)
INTEGER :: i, j
INTEGER :: recLen, npos, iter
INTEGER :: recIter, recHistLen
REAL :: dNdNLast(input%maxIter)
REAL :: dFdFLast(input%maxIter)
REAL :: dNdFLast(input%maxIter)
REAL :: dFdNLast(input%maxIter)
recLen = 8*4*input%maxIter ! sizeOfReal*numberOfVectors*vectorLength
recLen = recLen + 2*8 ! storage for currentIter, historyLength
IF (hybrid%l_calhf) THEN
OPEN (59,file='hf_broydOvlp',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ELSE
OPEN (59,file='broydOvlp',access='direct',&
recl=recLen,form='unformatted',status='unknown')
ENDIF
dNdNMat = 0.0
dFdFMat = 0.0
dNdFMat = 0.0
dFdNMat = 0.0
DO i = 1, historyLength
iter = currentIter - historyLength + i
npos=iter-1
IF (iter.GT.input%maxiter+1) npos = MOD(iter-2,input%maxiter)+1
READ(59,rec=npos) recIter, recHistLen,&
dNdNLast(:input%maxIter), dFdFLast(:input%maxIter), &
dNdFLast(:input%maxIter), dFdNLast(:input%maxIter)
DO j = 1, recHistLen
IF ((j-recHistLen+i).LE.0) CYCLE
dNdNMat(j-recHistLen+i,i) = dNdNLast(j)
dFdFMat(j-recHistLen+i,i) = dFdFLast(j)
dNdFMat(j-recHistLen+i,i) = dNdFLast(j)
dFdNMat(j-recHistLen+i,i) = dFdNLast(j)
END DO
END DO
CLOSE(59)
END SUBROUTINE readBroydenOverlaps
SUBROUTINE resetBroydenHistory()
INTEGER :: i
......
......@@ -27,6 +27,7 @@ SUBROUTINE mix(stars,atoms,sphhar,vacuum,input,sym,cell,noco,oneD,&
USE m_brysh1
USE m_stmix
USE m_broyden
USE m_broyden2
USE m_brysh2
USE m_metric
USE m_qfix
......@@ -155,6 +156,8 @@ SUBROUTINE mix(stars,atoms,sphhar,vacuum,input,sym,cell,noco,oneD,&
ELSE
CALL broyden(cell,stars,atoms,vacuum,sphhar,input,noco,oneD,sym,&
hybrid,mmap,nmaph,mapmt,mapvac2,nmap,fsm,sm)
! CALL broyden2(cell,stars,atoms,vacuum,sphhar,input,noco,oneD,sym,&
! hybrid,mmap,nmaph,mapmt,mapvac2,nmap,fsm,sm)
END IF
!initiatlize mixed density and extract it with brysh2 call
......
......@@ -3,6 +3,7 @@ mix/metr_z0.f
)
set(fleur_F90 ${fleur_F90}
mix/broyden.F90
mix/broyden2.F90
mix/brysh1.f90
mix/brysh2.f90
mix/metric.f90
......
......@@ -43,7 +43,7 @@ CONTAINS
REAL, INTENT (INOUT) :: sm(nmap)
! Local Scalars
INTEGER :: i,it,k,nit,npos,iread,nmaph, mit
INTEGER :: i,it,k,nit,iread,nmaph, mit
REAL :: bm,dfivi,fmvm,smnorm,vmnorm,alphan
LOGICAL :: l_pot, l_exist
REAL, PARAMETER :: one=1.0, zero=0.0
......@@ -109,13 +109,14 @@ CONTAINS
! |vi> = w|vi>
! loop to generate um : um = sm1 + alpha*fm1 - \sum <fm1|w|vi> ui
um(:nmap) = input%alpha * fm1(:nmap) + sm1(:nmap)
iread = MIN(mit-1,input%maxiter+1)
DO it = 2, iread
CALL readUVec(input,hybrid,nmap,it-mit,mit,ui)
CALL readVVec(input,hybrid,nmap,it-mit,mit,dfivi,vi)
am(it) = CPP_BLAS_sdot(nmap,vi,1,fm1,1)
! calculate um(:) = -am(it)*ui(:) + um
! calculate um(:) = -am(it)*ui(:) + um(:)
CALL CPP_BLAS_saxpy(nmap,-am(it),ui,1,um,1)
WRITE(6,FMT='(5x,"<vi|w|Fm> for it",i2,5x,f10.6)')it,am(it)
END DO
......@@ -134,6 +135,7 @@ CONTAINS
! generate vm = alpha*sm1 - \sum <ui|w|sm1> vi
vm(:) = input%alpha * fm1(:)
DO it = 2,iread
CALL readUVec(input,hybrid,nmap,it-mit,mit,ui)
CALL readVVec(input,hybrid,nmap,it-mit,mit,dfivi,vi)
......@@ -155,7 +157,7 @@ CONTAINS
! broyden's second method
!****************************************
! multiply fm1 with metric matrix and store in vm: w |fm1>
! multiply fm1 with metric matrix and store in vm: w |fm1>
CALL metric(cell,atoms,vacuum,sphhar,input,noco,stars,sym,oneD,&
mmap,nmaph,mapmt,mapvac2,fm1,vm,l_pot)
......@@ -192,16 +194,13 @@ CONTAINS
! write um,vm and dfivi on file broyd.?
npos=mit-1
IF (mit.GT.input%maxiter+1) npos = MOD(mit-2,input%maxiter)+1
CALL writeUVec(input,hybrid,nmap,mit,um)
CALL writeVVec(input,hybrid,nmap,mit,dfivi,vm)
! update rho(m+1)
! calculate <fm|w|vm>
fmvm = CPP_BLAS_sdot(nmap,vm,1,fm,1)
! calculate sm(:) = (1.0-fmvm)*ui(:) + sm
! calculate sm(:) = (1.0-fmvm)*um(:) + sm
CALL CPP_BLAS_saxpy(nmap,one-fmvm,um,1,sm,1)
END IF
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment