vmatgen.f90 8.69 KB
Newer Older
1 2 3 4 5 6
!--------------------------------------------------------------------------------
! 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.
!--------------------------------------------------------------------------------

7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
MODULE m_vmatgen
  USE m_juDFT
  !**********************************************************************
  !     This subroutine prepares the spin dependent 2x2 matrix potential
  !     for the Hamiltonian setup. This is done in 4 steps.
  !
  !    i) The spin up and down potential and the direction of the
  !     magentic field, theta and phi, are reloaded from files nrp,
  !     dirofmag.
  !    ii) The spin up and down potential is Fouriertransformed to real
  !     space (theta and phi are stored in real space).
  !    iii) The four components of the matrix potential are calculated on
  !     the real space mesh.
  !    iv) The matrix potential is Fouriertransformed, stored in terms of
  !     stars and written to file potmat.
  !
  !     Philipp Kurz 99/11/01
  !**********************************************************************
CONTAINS
26
  SUBROUTINE vmatgen(stars,atoms,vacuum,sym,input,den,vTot)
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43

    !******** ABBREVIATIONS ***********************************************
    !     ifft3    : size of the 3d real space mesh
    !     ifft2    : size of the 2d real space mesh
    !     vpw      : first interstitial spin up and down potential
    !                later four components of matrix potential
    !                all stored in terms of 3d-stars
    !     vis      : first interstitial spin up and down potential and
    !                direction of magnetic field (theta and phi)
    !                later four components of matrix potential
    !                all stored on real space mesh
    !**********************************************************************

    USE m_fft2d
    USE m_fft3d
    USE m_types
    IMPLICIT NONE
44
!    TYPE(t_oneD),INTENT(IN)   :: oneD
45 46 47 48 49
    TYPE(t_input),INTENT(IN)  :: input
    TYPE(t_vacuum),INTENT(IN) :: vacuum
    TYPE(t_sym),INTENT(IN)    :: sym
    TYPE(t_stars),INTENT(IN)  :: stars
    TYPE(t_atoms),INTENT(IN)  :: atoms
50
    TYPE(t_potden),INTENT(IN) :: den
51
    TYPE(t_potden),INTENT(INOUT):: vTot
52

53
 
54 55 56
    !     ..
    !     .. Local Scalars ..
    INTEGER imeshpt,ipot,jspin,ig2 ,ig3,ivac,ifft2,ifft3,imz,iter
57
    REAL    vup,vdown,veff,beff,vziw,theta,phi
58 59 60 61
    !     ..
    !     .. Local Arrays ..
    REAL,    ALLOCATABLE :: vvacxy(:,:,:,:),vis(:,:),fftwork(:)

62
    ifft3 = 27*stars%mx1*stars%mx2*stars%mx3
63 64 65 66 67 68 69
    IF (ifft3.NE.SIZE(den%theta_pw)) CALL judft_error("Wrong size of angles")
    ifft2 = SIZE(den%phi_vacxy,1) 
    
    
    ALLOCATE ( vis(ifft3,4),fftwork(ifft3))
      
    
70 71 72
    !---> fouriertransform the spin up and down potential
    !---> in the interstitial, vpw, to real space (vis)
    DO jspin = 1,input%jspins
73
       CALL fft3d(vis(:,jspin),fftwork, vTot%pw(:,jspin), stars,+1)
74 75 76 77
    ENDDO

    !---> calculate the four components of the matrix potential on
    !---> real space mesh
78
    DO imeshpt = 1,ifft3
79 80
       vup   = vis(imeshpt,1)
       vdown = vis(imeshpt,2)
81 82
       theta = den%theta_pw(imeshpt)
       phi   = den%phi_pw(imeshpt)
83 84 85 86 87 88 89 90 91 92 93 94 95
       !--->    at first determine the effective potential and magnetic field
       veff  = (vup + vdown)/2.0
       beff  = (vup - vdown)/2.0
       !--->    now calculate the matrix potential, which is hermitian.
       !--->    thus calculate the diagonal elements:
       !--->    V_11
       vis(imeshpt,1) = veff + beff*COS(theta)
       !--->    V_22
       vis(imeshpt,2) = veff - beff*COS(theta)
       !--->    the real part of V_21
       vis(imeshpt,3) = beff*SIN(theta)*COS(phi)
       !--->    and the imaginary part of V_21
       vis(imeshpt,4) = beff*SIN(theta)*SIN(phi)
96 97 98 99

       DO ipot = 1,4
          vis(imeshpt,ipot) =  vis(imeshpt,ipot) * stars%ufft(imeshpt-1)
       ENDDO
100 101 102 103 104
    ENDDO

    !---> Fouriertransform the matrix potential back to reciprocal space
    DO ipot = 1,2
       fftwork=0.0
105
       CALL fft3d(vis(:,ipot),fftwork, vTot%pw_w(1,ipot), stars,-1)
106
    ENDDO
107
    CALL fft3d(vis(:,3),vis(:,4), vTot%pw_w(1,3), stars,-1)
108 109 110 111

    IF (.NOT. input%film) RETURN

    !Now the vacuum part starts
112

113
 
114
    ALLOCATE(vvacxy(ifft2,vacuum%nmzxyd,2,4))
115 116

    
117 118 119 120 121 122
       !--->    fouriertransform the spin up and down potential
       !--->    in the vacuum, vz & vxy, to real space (vvacxy)
       DO jspin = 1,input%jspins
          DO ivac = 1,vacuum%nvac
             DO imz = 1,vacuum%nmzxyd
                vziw = 0.0
123 124
                !IF (oneD%odi%d1) THEN
                IF (.FALSE.) THEN
125 126 127 128 129 130 131 132
                   CALL judft_error("oneD not implemented",calledby="vmatgen")
                   !                  CALL fft2d(&
                   !     &                 oneD%k3,odi%M,odi%n2d,&
                   !     &                 vvacxy(0,imz,ivac,jspin),fftwork,&
                   !     &                 vz(imz,ivac,jspin),vziw,vxy(imz,1,ivac,jspin),&
                   !     &                 vacuum,odi%nq2,odi%kimax2,1,&
                   !     &                  %igf,odl%pgf,odi%nst2)
                ELSE
133
                   CALL fft2d(stars, vvacxy(:,imz,ivac,jspin),fftwork,&
134
                        vTot%vacz(imz,ivac,jspin),vziw,vTot%vacxy(imz,1,ivac,jspin), vacuum%nmzxyd,1)
135 136 137 138 139 140 141 142 143
                ENDIF
             ENDDO
          ENDDO
       ENDDO

       !--->    calculate the four components of the matrix potential on
       !--->    real space mesh
       DO ivac = 1,vacuum%nvac
          DO imz = 1,vacuum%nmzxyd
144
             DO imeshpt = 1,ifft2
145 146
                vup   = vvacxy(imeshpt,imz,ivac,1)
                vdown = vvacxy(imeshpt,imz,ivac,2)
147 148
                theta = den%theta_vacxy(imeshpt,imz,ivac)
                phi   = den%phi_vacxy(imeshpt,imz,ivac)
149 150 151 152 153 154 155 156 157
                veff  = (vup + vdown)/2.0
                beff  = (vup - vdown)/2.0
                vvacxy(imeshpt,imz,ivac,1) = veff + beff*COS(theta)
                vvacxy(imeshpt,imz,ivac,2) = veff - beff*COS(theta)
                vvacxy(imeshpt,imz,ivac,3) = beff*SIN(theta)*COS(phi)
                vvacxy(imeshpt,imz,ivac,4) = beff*SIN(theta)*SIN(phi)
             ENDDO
          ENDDO
          DO imz = vacuum%nmzxyd+1,vacuum%nmzd
158 159
             vup   = vTot%vacz(imz,ivac,1)
             vdown = vTot%vacz(imz,ivac,2)
160 161
             theta = den%theta_vacz(imz,ivac)
             phi   = den%phi_vacz(imz,ivac)
162 163
             veff  = (vup + vdown)/2.0
             beff  = (vup - vdown)/2.0
164 165 166 167
             vTot%vacz(imz,ivac,1) = veff + beff*COS(theta)
             vTot%vacz(imz,ivac,2) = veff - beff*COS(theta)
             vTot%vacz(imz,ivac,3) = beff*SIN(theta)*COS(phi)
             vTot%vacz(imz,ivac,4) = beff*SIN(theta)*SIN(phi)
168 169 170 171 172 173 174 175
          ENDDO
       ENDDO

       !--->    Fouriertransform the matrix potential back to reciprocal space
       DO ipot = 1,2
          DO ivac = 1,vacuum%nvac
             DO imz = 1,vacuum%nmzxyd
                fftwork=0.0
176 177
                !IF (oneD%odi%d1) THEN
                IF (.FALSE.) THEN
178 179 180 181 182 183 184 185
                   CALL judft_error("oneD not implemented",calledby="vmatgen")
                   !                CALL fft2d(&
                   !     &                 oneD%k3,odi%M,odi%n2d,&
                   !     &                 vvacxy(0,imz,ivac,ipot),fftwork,&
                   !     &                 vz(imz,ivac,ipot),vziw,vxy(imz,1,ivac,ipot),&
                   !     &                 vacuum,odi%nq2,odi%kimax2,-1,&
                   !     &                  %igf,odl%pgf,odi%nst2)
                ELSE
186
                   CALL fft2d(stars, vvacxy(:,imz,ivac,ipot),fftwork,&
187
                        vTot%vacz(imz,ivac,ipot),vziw,vTot%vacxy(imz,1,ivac,ipot), vacuum%nmzxyd,-1)
188 189 190 191 192 193 194 195
                END IF
             ENDDO
          ENDDO
       ENDDO

       DO ivac = 1,vacuum%nvac
          DO imz = 1,vacuum%nmzxyd
             fftwork=0.0
196 197 198
             !IF (oneD%odi%d1) THEN
             IF (.FALSE.) THEN
             CALL judft_error("oneD not implemented",calledby="vmatgen")
199 200 201 202 203 204 205
                !              CALL fft2d(&
                !   &              oneD%k3,odi%M,odi%n2d,&
                !   &              vvacxy(0,imz,ivac,3),vvacxy(0,imz,ivac,4),&
                !   &              vz(imz,ivac,3),vz(imz,ivac,4),vxy(imz,1,ivac,3),&
                !   &              vacuum,odi%nq2,odi%kimax2,-1,&
                !   &               %igf,odl%pgf,odi%nst2)
             ELSE
206
                CALL fft2d(stars, vvacxy(:,imz,ivac,3),vvacxy(:,imz,ivac,4),&
207
                     vTot%vacz(imz,ivac,3),vTot%vacz(imz,ivac,4),vTot%vacxy(imz,1,ivac,3), vacuum%nmzxyd,-1)
208 209 210 211 212 213 214
             END IF
          ENDDO
       ENDDO

    RETURN
  END SUBROUTINE vmatgen
END MODULE m_vmatgen