rot_den_mat.f 3.47 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
      MODULE m_rotdenmat
      use m_juDFT
      CONTAINS
10
      SUBROUTINE rot_den_mat(alph,beta,rho11,rho22,rho21)
11 12 13 14 15
c***********************************************************************
c This subroutine rotates the direction of the magnetization of the 
c density matrix by multiplying with the unitary 2x2 spin rotation
c matrix. --> U*rho*U^dagger
c Philipp Kurz 2000-02-03
16
c new method for improved stability (l_new=t) gb'19
17 18
c***********************************************************************

19
      use m_constants
20 21 22 23 24 25 26 27 28 29
      IMPLICIT NONE

C     .. Scalar Arguments ..
      REAL, INTENT    (IN) :: alph,beta
      REAL, INTENT    (INOUT) :: rho11
      REAL, INTENT    (INOUT) :: rho22
      COMPLEX, INTENT (INOUT) :: rho21
C     ..
C     .. Local Scalars ..
      INTEGER ispin
30 31 32
      REAL eps,r11n,r22n
      COMPLEX r21n
      LOGICAL l_new
33 34 35 36
C     ..
C     .. Local Arrays ..
      COMPLEX u2(2,2),rho(2,2),rhoh(2,2)
C     ..
37 38 39 40 41 42 43 44
      l_new = .true.

      IF (l_new) THEN

      r11n = 0.5*(1.0+cos(beta))*rho11 - sin(beta)*real(rho21) +
     +       0.5*(1.0-cos(beta))*rho22
      r22n = 0.5*(1.0-cos(beta))*rho11 + sin(beta)*real(rho21) +
     +       0.5*(1.0+cos(beta))*rho22
Robin Hilgers's avatar
Robin Hilgers committed
45
      r21n = CMPLX(cos(alph),+sin(alph))*(sin(beta)*(rho11-rho22) +
46
     +       2.0*(cos(beta)*real(rho21)+cmplx(0.0,aimag(rho21))))*0.5
47 48 49 50 51 52

      rho11 = r11n
      rho22 = r22n
      rho21 = r21n

      ELSE
53 54 55 56
      
      eps = 1.0e-10

c---> set up the unitary 2x2 spin rotation matrix U^(2)
57 58 59 60
      u2(1,1) =  exp(-ImagUnit*alph/2)*cos(beta/2)
      u2(1,2) = -exp(-ImagUnit*alph/2)*sin(beta/2)
      u2(2,1) =  exp( ImagUnit*alph/2)*sin(beta/2)
      u2(2,2) =  exp( ImagUnit*alph/2)*cos(beta/2)
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
      
      rho(1,1) = cmplx(rho11,0.0)
      rho(2,2) = cmplx(rho22,0.0)
      rho(2,1) =       rho21
      rho(1,2) = conjg(rho21)

c---> first calculate U*rho
      rhoh(1,1) = u2(1,1)*rho(1,1) + u2(1,2)*rho(2,1)
      rhoh(1,2) = u2(1,1)*rho(1,2) + u2(1,2)*rho(2,2)
      rhoh(2,1) = u2(2,1)*rho(1,1) + u2(2,2)*rho(2,1)
      rhoh(2,2) = u2(2,1)*rho(1,2) + u2(2,2)*rho(2,2)
c---> now calculate (U*rho)*U^dagger
      rho(1,1) = rhoh(1,1)*conjg(u2(1,1))
     +         + rhoh(1,2)*conjg(u2(1,2))
      rho(1,2) = rhoh(1,1)*conjg(u2(2,1))
     +         + rhoh(1,2)*conjg(u2(2,2))
      rho(2,1) = rhoh(2,1)*conjg(u2(1,1))
     +         + rhoh(2,2)*conjg(u2(1,2))
      rho(2,2) = rhoh(2,1)*conjg(u2(2,1))
     +         + rhoh(2,2)*conjg(u2(2,2))

c---> check wether the diagonal elements of the rotated density
c---> are real.
      DO ispin = 1,2
         IF (aimag(rho(ispin,ispin)).GT.eps) THEN
            CALL juDFT_error("rotation of mag. failed",calledby
Daniel Wortmann's avatar
Daniel Wortmann committed
87
     +           ="rot_den_mat",hint=
88 89
     +        'After the rotation of the density matrix in the '//
     +       'muffin-tin sphere one diagonal element of the '//
90
     +       '(hermitian) density matrix is not real. That means '//
91
     +       'that the density matrix was probably damaged.')
92 93 94
         ENDIF
      ENDDO
 
95 96 97 98
      rho11 = real(rho(1,1))
      rho22 = real(rho(2,2))
      rho21 =      rho(2,1)

99 100
      ENDIF
      
101 102 103
      END SUBROUTINE rot_den_mat
      END MODULE m_rotdenmat