spinactive.f Source File


Contents

Source Code


Source Code

!> Author:   Jabir Ali Ouassou
!> Category: Materials
!>
!> This submodule is included by conductor.f, and contains the equations which model spin-active interfaces.
!> 
!> @TODO 
!>   Reimplement shortcut-evaluation of the current for nonmagnetic interfaces.

module spinactive_m
  use :: propagator_m
  use :: material_m
  use :: condmat_m
  private

  ! Public interface
  public spinactive

  ! Type declarations
  type :: spinactive
    ! Physical parameters of the interface
    real(wp)                 :: conductance   = 1.0      !! Interfacial conductance
    real(wp)                 :: polarization  = 0.0      !! Interfacial spin-polarization
    real(wp)                 :: spinmixing    = 0.0      !! Interfacial 1st-order spin-mixing
    real(wp)                 :: secondorder   = 0.0      !! Interfacial 2nd-order spin-mixing
    real(wp), dimension(1:3) :: magnetization = [0,0,1]  !! Interfacial magnetization direction
    real(wp), dimension(1:3) :: misalignment0 = [0,0,0]  !! Interfacial magnetization misalignment (this  side)
    real(wp), dimension(1:3) :: misalignment1 = [0,0,0]  !! Interfacial magnetization misalignment (other side)
  
    ! Fields used internally by the object
    type(nambu), private     :: M                        !! Magnetization matrix (transmission)
    type(nambu), private     :: M0                       !! Magnetization matrix (reflection, this  side)
    type(nambu), private     :: M1                       !! Magnetization matrix (reflection, other side)
  contains
    procedure :: diffusion_current    => spinactive_diffusion_current
    procedure :: kinetic_current      => spinactive_kinetic_current
    procedure :: update_prehook       => spinactive_update_prehook
  end type
contains
  impure subroutine spinactive_update_prehook(this)
    !! Updates the internal variables associated with spin-active interfaces.
    class(spinactive), intent(inout) :: this 
  
    ! Transmission magnetization
    this % M = nambuv(this % magnetization)

    ! Reflection magnetization (this side)
    this % M0 = this % M
    if (nonzero(this % misalignment0)) then
      this % M0 = nambuv(this % misalignment0)
    end if

    ! Reflection magnetization (other side)
    this % M1 = this % M
    if (nonzero(this % misalignment1)) then
      this % M1 = nambuv(this % misalignment1)
    end if
  end subroutine
  
  pure function spinactive_diffusion_current(this, G0, G1) result(I)
    !! Calculate the matrix current at an interface with spin-active properties. The equations
    !! implemented here should be valid for an arbitrary interface polarization, and up to 2nd
    !! order in the transmission probabilities and spin-mixing angles of the interface. 
    class(spinactive), intent(in) :: this
    type(nambu),       intent(in) :: G0, G1      !! Propagator matrices
    type(nambu)                   :: S0, S1      !! Matrix expressions
    type(nambu)                   :: I           !! Matrix current
  
    ! Evaluate the 1st-order matrix functions
    S0 = spinactive_current1_transmission(G1)
    S1 = spinactive_current1_reflection()
  
    ! Evaluate the 1st-order matrix current
    associate(S => S0 + S1)
      I  = (S*G0 - G0*S)
    end associate
  
    ! Calculate the 2nd-order contributions to the matrix current. Note that we make a
    ! number of simplifications in this implementation. In particular, we assume that 
    ! all interface parameters except the magnetization directions are equal on both
    ! sides of the interface. We also assume that the spin-mixing angles and tunneling
    ! probabilities of different channels have standard deviations that are much smaller
    ! than their mean values, which reduces the number of new fitting parameters to one.
  
    if (abs(this % secondorder) > 0) then
      ! Evaluate the 1st-order matrix functions
      associate(M1 => this % M1)
        S1 = spinactive_current1_transmission(G1*M1*G1 - M1) 
      end associate
  
      ! Evaluate the 2nd-order matrix current
      I = I                                     &
        + spinactive_current2_transmission()    &
        + spinactive_current2_crossterms()      &
        + spinactive_current2_reflection()
    end if

    ! Scale the final result based on conductance
    I = (this % conductance/2) * I
  contains
    pure function spinactive_current1_transmission(G) result(F)
      !! Calculate the 1st-order transmission terms in the matrix current commutator.
      type(nambu), intent(in) :: G
      type(nambu)             :: F
      real(wp) :: Pr, Pp, Pm
  
      associate(P => this % polarization, M => this % M)
        Pr = sqrt(1 - P**2)
        Pp = 1 + Pr
        Pm = 1 - Pr
  
        F = G + (P/Pp)*(M*G+G*M) + (Pm/Pp)*(M*G*M)
      end associate
    end function
  
    pure function spinactive_current1_reflection() result(F)
      !! Calculate the 1st-order spin-mixing terms in the matrix current commutator.
      type(nambu) :: F
  
      associate(Q => this % spinmixing, M0 => this % M0)
        F = ((0,-1)*Q) * M0
      end associate
    end function
  
    pure function spinactive_current2_transmission() result(I)
      !! Calculate the 2nd-order transmission terms in the matrix current.
      type(nambu) :: I
  
      associate(R => this % secondorder, Q => this % spinmixing)
        I = (-0.50*R/Q) * (S0*G0*S0)
      end associate
    end function
  
    pure function spinactive_current2_reflection() result(I)
      !! Calculate the 2nd-order spin-mixing terms in the matrix current.
      type(nambu) :: I, U
  
      associate(R => this % secondorder, Q => this % spinmixing, M0 => this % M0)
        U = M0*G0*M0
        I = (0.25*R*Q) * (U*G0 - G0*U)
      end associate
    end function
  
    pure function spinactive_current2_crossterms() result(I)
      !! Calculate the 2nd-order cross-terms in the matrix current.
      type(nambu) :: I, U
  
      associate(R => this % secondorder, M0 => this % M0)
        U = S0*G0*M0 + M0*G0*S0 + S1
        I = ((0.00,0.25)*R) * (U*G0 - G0*U)
      end associate
    end function
  end function

  pure subroutine spinactive_kinetic_current(this, G0, G1, C0, C1)
    !! Calculate the kinetic boundary coefficients at an interface with spin-active properties.
    !! These can be used to calculate the generalized current according to J = C₀H₀ - C₁H₁.
    class(spinactive),               intent(in)  :: this
    type(propagator),                intent(in)  :: G0   !! Propagator (this  side)
    type(propagator),                intent(in)  :: G1   !! Propagator (other side)
    complex(wp), dimension(0:7,0:7), intent(out) :: C0   !! Boundary coefficient (this  side)
    complex(wp), dimension(0:7,0:7), intent(out) :: C1   !! Boundary coefficient (other side)

    type(nambu), dimension(0:7) :: N
    type(nambu)                 :: GR0, GA0
    type(nambu)                 :: GR1, GA1
    integer                     :: i, j

    ! Construct the basis matrices
    do i=0,7
      N(i) = nambuv(i)
    end do
 
    ! Construct the propagator matrices (this side)
    GR0 = G0 % retarded()
    GA0 = G0 % advanced()
 
    ! Construct the propagator matrices (other side)
    GR1 = G1 % retarded()
    GA1 = G1 % advanced()

    ! Construct the boundary coefficients
    do j=0,7
      do i=0,7
        ! Calculate the boundary matrix coefficients
        C0(i,j) = (this % conductance/8) * trace( ( R(GA1)*N(i) - N(i)*R(GR1) ) * (  (GR0*N(j) - N(j)*GA0) ) )
        C1(i,j) = (this % conductance/8) * trace( (   GA0 *N(i) - N(i)*  GR0  ) * ( T(GR1*N(j) - N(j)*GA1) ) )
      end do
    end do
  contains
    pure function T(U)
      ! Calculates the contents of the spin-active boundary condition commutators:
      !   I ~ [F(G₁), G₀]
      ! This is used for the calculation of the boundary coefficient matrices.
      ! Note that this version of the function only includes transmission terms,
      ! and used to evaluate contributions from the other side of the interface.

      type(nambu), intent(in) :: U
      type(nambu)             :: T
      real(wp)                :: GMR
      real(wp)                :: GT1

      associate(M => this % M, P => this % polarization)
        ! Calculate the normalized interface conductances
        GMR  = P/(1 + sqrt(1-P**2))
        GT1  = (1 - sqrt(1-P**2))/(1 + sqrt(1-P**2))

        ! Calculate the transmission function
        T = U + GMR * (M*U+U*M) + GT1 * M*U*M
      end associate
    end function

    pure function R(U)
      ! Calculates the contents of the spin-active boundary condition commutators:
      !   I ~ [F(G₁), G₀]
      ! This is used for the calculation of the boundary coefficient matrices.
      ! Note that this version of the function also includes reflection terms,
      ! and is used to evaluate contributions from this side of the interface.

      type(nambu), intent(in) :: U
      type(nambu)             :: R
      complex(wp)             :: Gphi

      associate(M => this % M0, Q => this % spinmixing)
        ! Calculate the normalized interface conductance
        Gphi = (0,-1) * Q

        ! Calculate the reflection function
        R = T(U) + Gphi * M
      end associate
    end function
  end subroutine
end module