mix.F90 6.96 KB
Newer Older
1 2 3 4 5
!--------------------------------------------------------------------------------
! Copyright (c) 2016 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.
!--------------------------------------------------------------------------------
Daniel Wortmann's avatar
Daniel Wortmann committed
6
MODULE m_mix
7

8
  !------------------------------------------------------------------------
9
  !  mixing of charge densities or potentials:
10
  !    IMIX = 0 : linear mixing                                     
11 12 13 14
  !    IMIX = 3 : Broyden's First method                            
  !    IMIX = 5 : Broyden's Second method                           
  !    IMIX = 7 : Generalized Anderson method                       
  !------------------------------------------------------------------------
15

16
contains
17

18 19 20
  SUBROUTINE mix_charge( field, DIMENSION,  mpi, l_writehistory,&
       stars, atoms, sphhar, vacuum, input, sym, cell, noco, &
       oneD, archiveType, inDen, outDen, results )
21

22 23 24 25 26 27 28 29
    use m_juDFT
    use m_constants
    use m_cdn_io
    use m_stmix
    use m_broyden
    use m_qfix
    use m_types
    use m_umix
Daniel Wortmann's avatar
Daniel Wortmann committed
30
    USE m_kerker
31
    use m_pulay
32
    use m_a_pulay
Daniel Wortmann's avatar
Daniel Wortmann committed
33
    use m_types_mixvector
Daniel Wortmann's avatar
Daniel Wortmann committed
34 35
    USE m_distance
    use m_mixing_history
36 37 38 39 40 41 42
    implicit none

    type(t_oneD),      intent(in)    :: oneD
    type(t_input),     intent(in)    :: input
    type(t_vacuum),    intent(in)    :: vacuum
    type(t_noco),      intent(in)    :: noco
    type(t_sym),       intent(in)    :: sym
43 44 45
    TYPE(t_stars),TARGET,INTENT(in)  :: stars
    TYPE(t_cell),TARGET,INTENT(in)   :: cell
    TYPE(t_sphhar),TARGET,INTENT(in) :: sphhar
46 47 48
    type(t_field),     intent(inout) :: field
    type(t_dimension), intent(in)    :: dimension
    type(t_mpi),       intent(in)    :: mpi
49
    TYPE(t_atoms),TARGET,INTENT(in)  :: atoms 
50 51 52 53
    type(t_potden),    intent(inout) :: outDen
    type(t_results),   intent(inout) :: results
    type(t_potden),    intent(inout) :: inDen
    integer,           intent(in)    :: archiveType
54
    LOGICAL,           INTENT(IN)    :: l_writehistory
55

Daniel Wortmann's avatar
Daniel Wortmann committed
56
    real                             :: fix
57
    type(t_potden)                   :: resDen, vYukawa
Daniel Wortmann's avatar
Daniel Wortmann committed
58 59
    TYPE(t_mixvector),ALLOCATABLE    :: sm(:), fsm(:)
    TYPE(t_mixvector)                :: fsm_mag
Daniel Wortmann's avatar
Daniel Wortmann committed
60
    LOGICAL                          :: l_densitymatrix
Daniel Wortmann's avatar
Daniel Wortmann committed
61
    INTEGER                          :: it,maxiter
62

63

64
    CALL timestart("Charge Density Mixing")
65 66 67 68 69 70 71 72 73 74
    l_densitymatrix=.FALSE.
    IF (atoms%n_u>0) THEN
       l_densitymatrix=.NOT.input%ldaulinmix
       IF (mpi%irank==0) CALL u_mix(input,atoms,inDen%mmpMat,outDen%mmpMat)
       IF (ALL(inDen%mmpMat==0.0)) THEN
          l_densitymatrix=.FALSE.
          inDen%mmpMat=outDen%mmpMat
          if (mpi%irank.ne.0) inden%mmpmat=0.0 
       ENDIF
    ENDIF
75 76

    CALL timestart("Reading of distances")
77 78 79 80 81 82 83 84
    CALL mixvector_init(mpi%mpi_comm,l_densitymatrix,oneD,input,vacuum,noco,sym,stars,cell,sphhar,atoms)

    CALL mixing_history_open(mpi,input%maxiter)

    maxiter=MERGE(1,input%maxiter,input%imix==0)
    CALL mixing_history(input%imix,maxiter,inden,outden,sm,fsm,it)

    CALL distance(mpi%irank,cell%vol,input%jspins,fsm(it),inDen,outDen,results,fsm_Mag)
85 86
    CALL timestop("Reading of distances")
 
87
    ! KERKER PRECONDITIONER
88
    IF( input%preconditioning_param /= 0 )  THEN 
89
       CALL timestart("Preconditioner")
90 91 92
       CALL kerker( field, DIMENSION, mpi, &
                    stars, atoms, sphhar, vacuum, input, sym, cell, noco, &
                    oneD, inDen, outDen, fsm(it) )
93 94
       !Store modified density in history
       CALL mixing_history_store(fsm(it))
95
       CALL timestop("Preconditioner")
96
    END IF
97 98
  
    CALL timestart("Mixing")
Daniel Wortmann's avatar
Daniel Wortmann committed
99
    !mixing of the densities
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
    SELECT CASE(input%imix)
    CASE(0)
       IF (mpi%irank==0) WRITE( 6, fmt='(a,f10.5,a,f10.5)' ) &
            'STRAIGHT MIXING: alpha=',input%alpha," spin-mixing=",MERGE(input%alpha*input%spinf,0.,input%jspins>1)
       CALL stmix(atoms,input,noco,fsm(it),fsm_mag,sm(it))
    CASE(3,5)
       CALL judft_error("Broyden 1/2 method not implemented")
    CASE(7)
       IF (mpi%irank==0) WRITE( 6, fmt='(a,f10.5,a,i0)' ) &
            'GENERALIZED ANDERSON MIXING: alpha=',input%alpha," History-length=",it-1
       Call broyden(input%alpha,fsm,sm)
    CASE(9)
       IF (mpi%irank==0) WRITE( 6, fmt='(a,f10.5,a,i0,a,i0)' ) &
            'PULAY MIXING: alpha=',input%alpha," History-length=",it-1,"/",input%maxiter
       CALL pulay(input%alpha,fsm,sm,0)
    CASE(11)
       IF (mpi%irank==0) WRITE( 6, fmt='(a,f10.5,a,i0,a,i0)' ) &
            'PERIODIC PULAY MIXING: alpha=',input%alpha," History-length=",it-1,"/",input%maxiter
       CALL pulay(input%alpha,fsm,sm,input%maxiter)
    CASE(13)
       IF (mpi%irank==0) WRITE( 6, fmt='(a,f10.5,a,i0,a,i0)' ) &
            'RESTARTED PULAY MIXING: alpha=',input%alpha," History-length=",it-1,"/",input%maxiter
       CALL pulay(input%alpha,fsm,sm,0)
       IF (it==input%maxiter) CALL mixing_history_limit(0) !Restarting Pulay 
    CASE(15)
       IF (mpi%irank==0) WRITE( 6, fmt='(a,f10.5,a,i0,a,i0)' ) &
            'ADAPTED PULAY MIXING: alpha=',input%alpha," History-length=",it-1,"/",input%maxiter
       CALL a_pulay(input%alpha,fsm,sm)
    CASE DEFAULT
       CALL judft_error("Unknown Mixing schema")
    END SELECT
    CALL timestop("Mixing")


    CALL timestart("Postprocessing")
135 136 137 138 139
    !extracte mixed density 
    inDen%pw=0.0;inDen%mt=0.0
    IF (ALLOCATED(inDen%vacz)) inden%vacz=0.0
    IF (ALLOCATED(inDen%vacxy)) inden%vacxy=0.0
    IF (ALLOCATED(inDen%mmpMat).AND.l_densitymatrix) inden%mmpMat=0.0
140
    CALL sm(it)%to_density(inDen)
141 142 143 144 145 146 147 148
    IF (atoms%n_u>0.AND..NOT.l_densitymatrix.AND..NOT.input%ldaulinmix) THEN
       !No density matrix was present 
       !but is now created...
       inden%mmpMAT=outden%mmpMat
       CALL mixing_history_reset(mpi)
       CALL mixvector_reset()
    ENDIF

Daniel Wortmann's avatar
Daniel Wortmann committed
149
    !fix charge of the new density
150 151
    IF (mpi%irank==0) CALL qfix(mpi,stars,atoms,sym,vacuum, sphhar,input,cell,oneD,inDen,noco%l_noco,.FALSE.,.FALSE., fix)

Daniel Wortmann's avatar
Daniel Wortmann committed
152 153 154 155 156 157 158 159 160 161


    IF(vacuum%nvac.EQ.1) THEN
       inDen%vacz(:,2,:) = inDen%vacz(:,1,:)
       IF (sym%invs) THEN
          inDen%vacxy(:,:,2,:) = CONJG(inDen%vacxy(:,:,1,:))
       ELSE
          inDen%vacxy(:,:,2,:) = inDen%vacxy(:,:,1,:)
       END IF
    END IF
162 163


Daniel Wortmann's avatar
Daniel Wortmann committed
164
    !write out mixed density
165
    IF (mpi%irank==0) CALL writeDensity(stars,vacuum,atoms,cell,sphhar,input,sym,oneD,archiveType,CDN_INPUT_DEN_const,&
Daniel Wortmann's avatar
Daniel Wortmann committed
166
         1,results%last_distance,results%ef,.TRUE.,inDen)
167

168
#ifdef CPP_HDF
169
    IF (mpi%irank==0.and.judft_was_argument("-last_extra")) THEN
Daniel Wortmann's avatar
Daniel Wortmann committed
170 171 172
       CALL system("rm cdn_last.hdf")
       CALL writeDensity(stars,vacuum,atoms,cell,sphhar,input,sym,oneD,archiveType,CDN_INPUT_DEN_const,&
            1,results%last_distance,results%ef,.TRUE.,inDen,'cdn_last')
173

Daniel Wortmann's avatar
Daniel Wortmann committed
174
    END IF
175 176
#endif

Daniel Wortmann's avatar
Daniel Wortmann committed
177
    inDen%iter = inDen%iter + 1
178

179
    IF (l_writehistory.AND.input%imix.NE.0) CALL mixing_history_close(mpi)
Daniel Wortmann's avatar
Daniel Wortmann committed
180

181 182 183
    CALL timestop("Postprocessing")

    CALL timestop("Charge Density Mixing")
184
  END SUBROUTINE mix_charge
Daniel Wortmann's avatar
Daniel Wortmann committed
185 186
  
END MODULE m_mix