mix.F90 7.2 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
Gregor Michalicek's avatar
Gregor Michalicek committed
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                       
  !------------------------------------------------------------------------
Gregor Michalicek's avatar
Gregor Michalicek committed
15

16
contains
Gregor Michalicek's avatar
Gregor Michalicek committed
17

Daniel Wortmann's avatar
Daniel Wortmann committed
18
  SUBROUTINE mix( field, xcpot, DIMENSION, obsolete, sliceplot, mpi, &
19 20
                stars, atoms, sphhar, vacuum, input, sym, cell, noco, &
                oneD, hybrid, archiveType, inDen, outDen, results )
Gregor Michalicek's avatar
Gregor Michalicek committed
21

22 23 24 25 26 27 28 29 30 31 32 33 34 35
    use m_juDFT
    use m_constants
    use m_cdn_io
    use m_broyd_io
    use m_brysh1
    use m_stmix
    use m_broyden
    use m_broyden2
    use m_brysh2
    use m_metric
    use m_qfix
    use m_types
    use m_xmlOutput
    use m_umix
Daniel Wortmann's avatar
Daniel Wortmann committed
36 37
    USE m_kerker
    use m_types_mixvector
38 39 40
#ifdef CPP_MPI
    use m_mpi_bc_potden
#endif
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
    implicit none

    type(t_oneD),      intent(in)    :: oneD
    type(t_hybrid),    intent(in)    :: hybrid 
    type(t_input),     intent(in)    :: input
    type(t_vacuum),    intent(in)    :: vacuum
    type(t_noco),      intent(in)    :: noco
    type(t_sym),       intent(in)    :: sym
    type(t_stars),     intent(in)    :: stars
    type(t_cell),      intent(in)    :: cell
    type(t_sphhar),    intent(in)    :: sphhar
    type(t_field),     intent(inout) :: field
    class(t_xcpot),    intent(in)    :: xcpot
    type(t_dimension), intent(in)    :: dimension
    type(t_obsolete),  intent(in)    :: obsolete
    type(t_sliceplot), intent(in)    :: sliceplot
    type(t_mpi),       intent(in)    :: mpi
    type(t_atoms),     intent(inout) :: atoms !n_u is modified temporarily
    type(t_potden),    intent(inout) :: outDen
    type(t_results),   intent(inout) :: results
    type(t_potden),    intent(inout) :: inDen
    integer,           intent(in)    :: archiveType

Daniel Wortmann's avatar
Daniel Wortmann committed
64
    real                             :: fix
65
    type(t_potden)                   :: resDen, vYukawa
Daniel Wortmann's avatar
Daniel Wortmann committed
66 67
    TYPE(t_mixvector)                :: sm, fsm, fmMet, smMet,fsm_mag
    LOGICAL                          :: l_densitymatrix
68

Daniel Wortmann's avatar
Daniel Wortmann committed
69 70
    
    MPI0_a: IF( mpi%irank == 0 ) THEN
71 72 73 74 75
      !determine type of mixing:
      !imix=0:straight, imix=o broyden first, imix=5:broyden second
      !imix=:generalozed anderson mixing
      select case( input%imix )
        case( 0 )
Daniel Wortmann's avatar
Daniel Wortmann committed
76 77 78 79 80 81
           WRITE( 6, fmt='(a,2f10.5)' ) 'STRAIGHT MIXING',input%alpha
           IF (input%jspins.EQ.1) WRITE (6,FMT='(a,2f10.5)')&
                &    'charge density mixing parameter:',input%alpha
           IF (input%jspins.EQ.2) WRITE (6,FMT='(a,2f10.5)')&
                &    'spin density mixing parameter:',input%alpha*input%spinf

82
        case( 3 )
83
          write( 6, fmt='(a,f10.5)' ) 'BROYDEN FIRST MIXING',input%alpha
84
        case( 5 )
85
          write( 6, fmt='(a,f10.5)' ) 'BROYDEN SECOND MIXING',input%alpha
86
        case( 7 )
87
          write( 6, fmt='(a,f10.5)' ) 'ANDERSON GENERALIZED',input%alpha
88 89 90 91 92 93
        case default
          call juDFT_error( "mix: input%imix =/= 0,3,5,7 ", calledby ="mix" )
      end select

      if ( input%jspins == 2 .and. input%imix /= 0 ) then
        write( 6, '(''WARNING : for QUASI-NEWTON METHODS SPINF=1'')' )
94
      end if
Daniel Wortmann's avatar
Daniel Wortmann committed
95 96 97 98 99 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
   ENDIF MPI0_a

   l_densitymatrix=.FALSE.
   IF (atoms%n_u>0) THEN
      l_densitymatrix=.NOT.input%ldaulinmix
      CALL u_mix(input,atoms,inDen%mmpMat,outDen%mmpMat)
      IF (ALL(inDen%mmpMat==0.0)) THEN
         l_densitymatrix=.FALSE.
         inDen%mmpMat=outDen%mmpMat
      ENDIF
   ENDIF
   CALL mixvector_init(mpi%mpi_comm,l_densitymatrix,oneD,input,vacuum,noco,sym,stars,cell,sphhar,atoms)
    
   CALL sm%alloc()
   CALL fsm%alloc()
   CALL fmMet%alloc()
   CALL fsm_mag%alloc()
   !put input charge density into array sm
   !(in the spin polarized case the arrays sm and fsm consist of spin up and spin down densities)
   
   CALL sm%from_density(inDen)
   CALL fsm%from_density(outDen)
   
   !store the difference fsm - sm in fsm
   fsm = fsm - sm
   ! calculate Magnetisation-difference
   CALL fsm_mag%from_density(outden,swapspin=.true.)
   fsm_mag=fsm_mag-sm

   ! Apply metric w to fsm and store in fmMet:  w |fsm>
   fmMet=fsm%apply_metric()
   
   !CALL distance(fsm,fmMet)
   
129
    ! KERKER PRECONDITIONER
Daniel Wortmann's avatar
Daniel Wortmann committed
130 131 132
    IF( input%preconditioning_param /= 0 ) THEN
       call kerker(field, DIMENSION, mpi, &
                stars, atoms, sphhar, vacuum, input, sym, cell, noco, &
133
                oneD, inDen, outDen, fsm )
Daniel Wortmann's avatar
Daniel Wortmann committed
134
    ENDIF
135

Daniel Wortmann's avatar
Daniel Wortmann committed
136 137 138 139 140 141 142 143 144 145 146 147 148
    
    !mixing of the densities
    SELECT CASE(input%imix)
    CASE(0)
       CALL stmix(atoms,input,noco,fsm,fsm_mag,sm)
    CASE(9)
       CALL pulay()
    CASE default
       PRINT *,"New Broyden"
       
       !CALL broyden(cell,stars,atoms,vacuum,sphhar,input,noco,oneD,sym,&
       !     hybrid,mmap,nmaph,mapmt,mapvac2,nmap,fsm,sm)
    END SELECT
149

Daniel Wortmann's avatar
Daniel Wortmann committed
150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
    !initiatlize mixed density and extract it 
    CALL sm%to_density(inDen)
      
    !fix charge of the new density
    CALL qfix(mpi,stars,atoms,sym,vacuum, sphhar,input,cell,oneD,inDen,noco%l_noco,.FALSE.,.FALSE., fix)

    IF(atoms%n_u.NE.n_u_keep) THEN
       inDen%mmpMat = outden%mmpMat
    END IF

    atoms%n_u=n_u_keep

    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
    
    IF (atoms%n_u > 0) THEN
       IF (.NOT.l_densityMatrixPresent) THEN
          inDen%mmpMat(:,:,:,:) = outDen%mmpMat(:,:,:,:)
          CALL resetBroydenHistory()
       END IF
    ENDIF
    
    !write out mixed density
    CALL writeDensity(stars,vacuum,atoms,cell,sphhar,input,sym,oneD,archiveType,CDN_INPUT_DEN_const,&
         1,results%last_distance,results%ef,.TRUE.,inDen)
    
182
#ifdef CPP_HDF
Daniel Wortmann's avatar
Daniel Wortmann committed
183 184 185 186 187 188
    IF (judft_was_argument("-last_extra")) THEN
       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')
       
    END IF
189 190
#endif

Daniel Wortmann's avatar
Daniel Wortmann committed
191 192 193 194 195 196 197 198 199 200 201 202 203 204
    inDen%iter = inDen%iter + 1
    
7900 FORMAT (/,'---->    distance of charge densities for spin ',i2,'                 it=',i5,':',f13.6,' me/bohr**3')
7901 FORMAT (/,'----> HF distance of charge densities for spin ',i2,'                 it=',i5,':',f13.6,' me/bohr**3')
8000 FORMAT (/,'---->    distance of charge densities for it=',i5,':', f13.6,' me/bohr**3')
8001 FORMAT (/,'----> HF distance of charge densities for it=',i5,':', f13.6,' me/bohr**3')
8010 FORMAT (/,'---->    distance of spin densities for it=',i5,':', f13.6,' me/bohr**3')
8011 FORMAT (/,'----> HF distance of spin densities for it=',i5,':', f13.6,' me/bohr**3')
8020 FORMAT (4d25.14)
8030 FORMAT (10i10)

  END SUBROUTINE mix
  
END MODULE m_mix