mix.F90 5.83 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

18
  SUBROUTINE mix( field, DIMENSION,  mpi, &
19
                stars, atoms, sphhar, vacuum, input, sym, cell, noco, &
20
                oneD, archiveType, inDen, outDen, results )
Gregor Michalicek's avatar
Gregor Michalicek committed
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 31
    USE m_kerker
    use m_types_mixvector
32
    use m_distance
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
    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
    type(t_stars),     intent(in)    :: stars
    type(t_cell),      intent(in)    :: cell
    type(t_sphhar),    intent(in)    :: sphhar
    type(t_field),     intent(inout) :: field
    type(t_dimension), intent(in)    :: dimension
    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
52
    real                             :: fix
53
    type(t_potden)                   :: resDen, vYukawa
54 55
    TYPE(t_mixvector),allocatable    :: sm(:), fsm(:)
    TYPE(t_mixvector)                :: fmMet, smMet,fsm_mag
Daniel Wortmann's avatar
Daniel Wortmann committed
56
    LOGICAL                          :: l_densitymatrix
57
    integer                          :: it
58

Daniel Wortmann's avatar
Daniel Wortmann committed
59 60
    
    MPI0_a: IF( mpi%irank == 0 ) THEN
61 62 63 64 65
      !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
66 67 68 69 70 71
           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

72
        case( 3 )
73
          write( 6, fmt='(a,f10.5)' ) 'BROYDEN FIRST MIXING',input%alpha
74
        case( 5 )
75
          write( 6, fmt='(a,f10.5)' ) 'BROYDEN SECOND MIXING',input%alpha
76
        case( 7 )
77
          write( 6, fmt='(a,f10.5)' ) 'ANDERSON GENERALIZED',input%alpha
78 79 80 81 82 83
        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'')' )
84
      end if
Daniel Wortmann's avatar
Daniel Wortmann committed
85 86 87 88 89 90 91 92 93 94 95 96
   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)
97 98 99 100
   maxiter=merge(1,input%maxiter,input%imix==0)
   CALL mixing_history(maxiter,inden,outden,sm,fsm,it)
  
   CALL distance(mpi%irank,cell%vol,input%jspins,fsm,sm,inDen%iter,outDen,results)
Daniel Wortmann's avatar
Daniel Wortmann committed
101
   
102
    ! KERKER PRECONDITIONER
103
    IF( input%preconditioning_param /= 0 )  call kerker(field, DIMENSION, mpi, &
Daniel Wortmann's avatar
Daniel Wortmann committed
104
                stars, atoms, sphhar, vacuum, input, sym, cell, noco, &
105 106
                oneD, inDen, outDen, fsm(it) )
    
Daniel Wortmann's avatar
Daniel Wortmann committed
107 108
    
    !mixing of the densities
109 110 111
    if(input%imix==0.or.it==1) CALL stmix(atoms,input,noco,fsm(it),fsm_mag,sm(it))
    !if(it>1.and.input%imix==9) CALL pulay(input%alpha,fsm,sm)
    if(it>1.and.(input%imax==3.or.input%imix==5.or.input%imix==7)) Call broyden(input%alpha,fsm,sm)
112

Daniel Wortmann's avatar
Daniel Wortmann committed
113
    !initiatlize mixed density and extract it 
114
    CALL sm(it)%to_density(inDen)
Daniel Wortmann's avatar
Daniel Wortmann committed
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144
      
    !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)
    
145
#ifdef CPP_HDF
Daniel Wortmann's avatar
Daniel Wortmann committed
146 147 148 149 150 151
    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
152 153
#endif

Daniel Wortmann's avatar
Daniel Wortmann committed
154 155
    inDen%iter = inDen%iter + 1
    
156

Daniel Wortmann's avatar
Daniel Wortmann committed
157 158 159 160

  END SUBROUTINE mix
  
END MODULE m_mix