LCOV - code coverage report
Current view: top level - src/67_common - m_spin_current.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 94.3 % 265 250
Test Date: 2026-09-20 15:27:41 Functions: 100.0 % 2 2

            Line data    Source code
       1              : !!****m* ABINIT/m_spin_current
       2              : !! NAME
       3              : !!  m_spin_current
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !! Copyright (C) 2005-2026 ABINIT group (Mver)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_spin_current
      23              : 
      24              :  use m_errors
      25              :  use m_abicore
      26              :  use m_splines
      27              :  use m_hdr
      28              :  use m_dtset
      29              :  use m_dtfil
      30              : 
      31              :  use defs_datatypes, only : pseudopotential_type
      32              :  use defs_abitypes, only : MPI_type
      33              :  use m_io_tools,   only : open_file
      34              :  use m_pptools,    only : printxsf
      35              :  use m_geometry,   only : xred2xcart
      36              :  use m_fftcore,    only : sphereboundary
      37              :  use m_special_funcs,   only : gamma_function
      38              :  use m_fft,            only : fourwf
      39              : 
      40              :  implicit none
      41              : 
      42              :  private
      43              : !!***
      44              : 
      45              :  public :: spin_current
      46              : !!***
      47              : 
      48              : contains
      49              : !!***
      50              : 
      51              : !!****f* m_spin_current/spin_current
      52              : !! NAME
      53              : !! spin_current
      54              : !!
      55              : !! FUNCTION
      56              : !!
      57              : !! INPUTS
      58              : !!  atindx(natom)=index table for atoms (see gstate.f)
      59              : !!  atindx1(natom)=inverse of atindx
      60              : !!  cg(2,mcg)=wavefunctions (may be read from disk instead of input)
      61              : !!  dtfil <type(datafiles_type)>=variables related to files
      62              : !!  dtset <type(dataset_type)>=all input variables in this dataset
      63              : !!  eigen(mband*nkpt*nsppol)=array for holding eigenvalues (hartree)
      64              : !!  gmet = reciprocal space metric
      65              : !!  gprimd = dimensionful reciprocal space vectors
      66              : !!  hdr <type(hdr_type)>=the header of wf, den and pot files
      67              : !!  kg(3,mpw*mkmem)=reduced (integer) coordinates of G vecs in basis sphere
      68              : !!  mcg=size of wave-functions array (cg) =mpw*nspinor*mband*mkmem*nsppol
      69              : !!  mpi_enreg=information about MPI parallelization
      70              : !!  nattyp(dtset%ntypat)=number of atoms of each type
      71              : !!  nfftf = fft grid dimensions for fine grid
      72              : !!  ph1d = phase factors in 1 radial dimension
      73              : !!  psps <type(pseudopotential_type)>=variables related to pseudopotentials
      74              : !!   | mpsang= 1+maximum angular momentum
      75              : !!  rhog(2,nfftf)=Fourier transform of total electron density (including compensation density in PAW)
      76              : !!  rhor(nfftf,nspden)=total electron density (including compensation density in PAW)
      77              : !!  rmet = real space metric tensor
      78              : !!  symrec(3,3,nsym)=symmetries in reciprocal space, reduced coordinates
      79              : !!  ucvol = unit cell volume
      80              : !!  wffnow=unit number for current wf disk file
      81              : !!  ylm(mpw*mkmem,mpsang*mpsang*useylm)= real spherical harmonics for each G and k point
      82              : !!  ylmgr(mpw*mkmem,3,mpsang*mpsang*useylm)= gradients of real spherical harmonics
      83              : !!
      84              : !! OUTPUT
      85              : !!   only output to file
      86              : !!
      87              : !! SOURCE
      88              : 
      89            1 : subroutine spin_current(cg,dtfil,dtset,gprimd,hdr,kg,mcg,mpi_enreg,psps)
      90              : 
      91              : !Arguments ------------------------------------
      92              : !scalars
      93              : !integer,intent(in) :: nfftf
      94              : !real(dp),intent(in) :: ucvol
      95              :  integer,intent(in) :: mcg
      96              :  type(MPI_type),intent(in) :: mpi_enreg
      97              :  type(datafiles_type),intent(in) :: dtfil
      98              :  type(dataset_type),intent(in) :: dtset
      99              :  type(hdr_type),intent(inout) :: hdr
     100              :  type(pseudopotential_type),intent(in) :: psps
     101              : !type(wffile_type),intent(in) :: wffnow
     102              : !arrays
     103              : !integer,intent(in) :: atindx(dtset%natom),atindx1(dtset%natom)
     104              :  integer,intent(in) :: kg(3,dtset%mpw*dtset%mkmem)
     105              : !integer,intent(in) :: nattyp(dtset%ntypat)
     106              : !integer,intent(in) :: symrec(3,3,dtset%nsym)
     107              :  real(dp),intent(in) :: cg(2,mcg)
     108              : !real(dp),intent(in) :: eigen(dtset%mband*dtset%nkpt*dtset%nsppol),gmet(3,3)
     109              :  real(dp),intent(in) :: gprimd(3,3)
     110              : !real(dp),intent(in) :: rhog(2,nfftf),rhor(nfftf,dtset%nspden)
     111              : !real(dp),intent(in) :: rmet(3,3)
     112              : !real(dp),intent(in) :: ylm(dtset%mpw*dtset%mkmem,psps%mpsang*psps%mpsang*psps%useylm)
     113              : !real(dp),intent(in) :: ylmgr(dtset%mpw*dtset%mkmem,3,psps%mpsang*psps%mpsang*psps%useylm)
     114              : !real(dp),intent(inout) :: ph1d(2,3*(2*dtset%mgfft+1)*dtset%natom)
     115              : 
     116              : !Local variables-------------------------------
     117              : !scalars
     118              :  integer :: cplex,fft_option,i1
     119              :  integer :: i2,i3,iband,icartdir,icg,ig
     120              :  integer :: ikg,ikpt,iocc,irealsp,ispindir,ispinor,ispinorp
     121              :  integer :: npw
     122              :  integer :: icplex
     123              :  integer :: realrecip
     124              :  integer :: iatom,spcur_unit
     125              :  real(dp) :: prefact_nk
     126              :  real(dp) :: rescale_current
     127              :  character(len=500) :: message
     128              :  character(len=fnlen) :: filnam
     129              : !arrays
     130            1 :  integer,allocatable :: gbound(:,:),kg_k(:,:)
     131            1 :  real(dp),allocatable :: dpsidr(:,:,:,:,:,:)
     132            1 :  real(dp),allocatable :: density(:,:,:,:)
     133            1 :  real(dp),allocatable :: dummy_denpot(:,:,:)
     134            1 :  real(dp),allocatable :: gpsi(:,:,:,:),kgcart(:,:)
     135            1 :  real(dp),allocatable :: position_op(:,:,:,:)
     136            1 :  real(dp),allocatable :: psi(:,:,:),psi_r(:,:,:,:,:)
     137            1 :  real(dp),allocatable :: spincurrent(:,:,:,:,:)
     138            1 :  real(dp),allocatable :: vso_realspace(:,:,:,:,:),datagrid(:)
     139              :  real(dp) :: dummy_fofgout(0,0)
     140            1 :  real(dp),allocatable :: xcart(:,:)
     141              :  character :: spin_symbol(3)
     142              :  character :: spinor_sym(2)
     143              :  character(len=2) :: realimag(2)
     144              : !no_abirules
     145              : !real(dp),allocatable :: density_matrix(:,:,:,:,:)
     146              : !real(dp),allocatable :: vso_realspace_nl(:,:,:,:,:)
     147              : 
     148              : ! *************************************************************************
     149              : 
     150              : !write(std_out,*) ' Entering subroutine spin_current '
     151              : !write(std_out,*) ' dtset%ngfft = ', dtset%ngfft
     152              : !write(std_out,*) ' hdr%istwfk = ', hdr%istwfk
     153              : 
     154              : !===================== init and checks ============================
     155              : !check if nspinor is 2
     156            1 :  if (dtset%nspinor /= 2) then
     157            0 :    write(message, '(a,i0)' )' nspinor must be 2, but it is ',dtset%nspinor
     158            0 :    ABI_ERROR(message)
     159              :  end if
     160              : 
     161            1 :  if (dtset%nsppol /= 1) then
     162            0 :    write(message, '(a,i0)' )' spin_current:  nsppol must be 1 but it is ',dtset%nsppol
     163            0 :    ABI_ERROR(message)
     164              :  end if
     165              : 
     166            1 :  if (dtset%mkmem /= dtset%nkpt) then
     167              :    write(message, '(a,i6,a,i6,a,a)' )&
     168            0 : &   ' mkmem =  ',dtset%mkmem,' must be equal to nkpt ',dtset%nkpt,ch10,&
     169            0 : &   ' keep all kpt in memory'
     170            0 :    ABI_ERROR(message)
     171              :  end if
     172              : 
     173            1 :  if (dtset%usepaw /= 0) then
     174              :    write(message, '(a,i0,a,a,a)' )&
     175            0 : &   'usepaw =  ',dtset%usepaw,' must be equal to 0 ',ch10,&
     176            0 : &   'Not functional for PAW case yet.'
     177            0 :    ABI_ERROR(message)
     178              :  end if
     179              : 
     180            1 :  cplex=2
     181            1 :  fft_option = 0 ! just do direct fft
     182            4 :  spin_symbol = (/'x','y','z'/)
     183            3 :  spinor_sym = (/'u','d'/)
     184            3 :  realimag = (/'Re','Im'/)
     185              : 
     186            1 :  write(std_out,*) ' psps%mpsang,psps%mpssoang ', psps%mpsang,psps%mpssoang
     187              : 
     188              : !======================= main code ================================
     189              : !-----------------------------------------------------------------------------------------
     190              : !-----------------------------------------------------------------------------------------
     191              : !first get normal contribution to current, as psi tau dpsidr + dpsidr tau psi
     192              : !where tau are 1/2 the pauli matrices
     193              : !-----------------------------------------------------------------------------------------
     194              : !-----------------------------------------------------------------------------------------
     195              : 
     196              : !init plane wave coeff counter
     197            1 :  icg = 0
     198              : !init plane wave counter
     199            1 :  ikg = 0
     200              : !init occupation/band counter
     201            1 :  iocc = 1
     202              : 
     203              : !rspace point, cartesian direction, spin pol=x,y,z
     204            7 :  ABI_MALLOC(spincurrent,(dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),3,3))
     205        32548 :  spincurrent = zero
     206              : 
     207            5 :  ABI_MALLOC(dummy_denpot,(cplex*dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6)))
     208              : 
     209            4 :  ABI_MALLOC(gbound,(2*dtset%mgfft+8,2))
     210              : 
     211              : !allocate (density_matrix(2,dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),dtset%nspinor,&
     212              : !&                           dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),dtset%nspinor))
     213              : !density_matrix= zero
     214            5 :  ABI_MALLOC(density,(2,dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),dtset%nspinor,dtset%nspinor))
     215        40507 :  density= zero
     216              : 
     217            7 :  ABI_MALLOC(dpsidr,(2,dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),dtset%nspinor,3))
     218            6 :  ABI_MALLOC(psi_r,(2,dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),dtset%nspinor))
     219              : 
     220              : !loop over kpoints
     221            2 :  do ikpt=1,dtset%nkpt
     222              : 
     223              : !  number of plane waves for this kpt
     224            1 :    npw = hdr%npwarr(ikpt)
     225              : 
     226              : !  allocate arrays dep on number of pw
     227            3 :    ABI_MALLOC(kg_k,(3,npw))
     228            5 :    ABI_MALLOC(gpsi,(2,npw,dtset%nspinor,3))
     229            4 :    ABI_MALLOC(psi,(2,npw,dtset%nspinor))
     230            3 :    ABI_MALLOC(kgcart,(3,npw))
     231              : 
     232              : !  get cartesian coordinates of k+G vectors around this kpoint
     233          172 :    do ig=1,npw
     234         3249 :      kgcart(:,ig) = matmul(gprimd(:,:),dtset%kpt(:,ikpt)+kg(:,ikg+ig))
     235          685 :      kg_k (:,ig) = kg(:,ikg+ig)
     236              :    end do
     237              : 
     238              : !  get gbound
     239            1 :    call sphereboundary(gbound,dtset%istwfk(ikpt),kg_k,dtset%mgfft,npw)
     240              : 
     241              : !  loop over bands
     242           11 :    do iband=1,dtset%nband(ikpt)
     243              : 
     244              : !    prefactor for sum over bands and kpoints
     245           10 :      prefact_nk = hdr%occ(iocc) * dtset%wtk(ikpt)
     246              : 
     247              : !    initialize this wf
     248        30880 :      gpsi=zero
     249        10290 :      psi=zero
     250         5140 :      psi(:,1:npw,1) = cg(:,icg+1:icg+npw)
     251              : 
     252              : !    multiply psi by - i 2 pi G
     253         1720 :      do ig=1,npw
     254         5130 :        gpsi(1,ig,:,1) =  two_pi * kgcart(1,ig)*psi(2,ig,:)
     255         5130 :        gpsi(2,ig,:,1) = -two_pi * kgcart(1,ig)*psi(1,ig,:)
     256         5130 :        gpsi(1,ig,:,2) =  two_pi * kgcart(2,ig)*psi(2,ig,:)
     257         5130 :        gpsi(2,ig,:,2) = -two_pi * kgcart(2,ig)*psi(1,ig,:)
     258         5130 :        gpsi(1,ig,:,3) =  two_pi * kgcart(3,ig)*psi(2,ig,:)
     259         5140 :        gpsi(2,ig,:,3) = -two_pi * kgcart(3,ig)*psi(1,ig,:)
     260              :      end do
     261              : 
     262              : !    loop over spinorial components
     263           30 :      do ispinor=1,dtset%nspinor
     264              : !      FT Gpsi_x to real space
     265              :        call fourwf(cplex,dummy_denpot,gpsi(:,:,ispinor,1),dummy_fofgout,&
     266              : &       dpsidr(:,:,:,:,ispinor,1),gbound,gbound,&
     267              : &       hdr%istwfk(ikpt),kg_k,kg_k,dtset%mgfft,mpi_enreg,1,dtset%ngfft,npw,&
     268              : &       npw,dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),&
     269           20 : &       fft_option,0,one,one,gpu_option=dtset%gpu_option)
     270              : 
     271              : !      FT Gpsi_y to real space
     272              :        call fourwf(cplex,dummy_denpot,gpsi(:,:,ispinor,2),dummy_fofgout,&
     273              : &       dpsidr(:,:,:,:,ispinor,2),gbound,gbound,&
     274              : &       hdr%istwfk(ikpt),kg_k,kg_k,dtset%mgfft,mpi_enreg,1,dtset%ngfft,npw,&
     275              : &       npw,dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),&
     276           20 : &       fft_option,0,one,one,gpu_option=dtset%gpu_option)
     277              : 
     278              : !      FT Gpsi_z to real space
     279              :        call fourwf(cplex,dummy_denpot,gpsi(:,:,ispinor,3),dummy_fofgout,&
     280              : &       dpsidr(:,:,:,:,ispinor,3),gbound,gbound,&
     281              : &       hdr%istwfk(ikpt),kg_k,kg_k,dtset%mgfft,mpi_enreg,1,dtset%ngfft,npw,&
     282              : &       npw,dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),&
     283           20 : &       fft_option,0,one,one,gpu_option=dtset%gpu_option)
     284              : 
     285              : !      FT psi to real space
     286              :        call fourwf(cplex,dummy_denpot,psi(:,:,ispinor),dummy_fofgout,&
     287              : &       psi_r(:,:,:,:,ispinor),gbound,gbound,&
     288              : &       hdr%istwfk(ikpt),kg_k,kg_k,dtset%mgfft,mpi_enreg,1,dtset%ngfft,npw,&
     289              : &       npw,dtset%ngfft(4),dtset%ngfft(5),dtset%ngfft(6),&
     290           30 : &       fft_option,0,one,one,gpu_option=dtset%gpu_option)
     291              : 
     292              :      end do ! ispinor
     293              : 
     294              : !    dpsidr now contains the full derivative of psi wrt space (gradient) in cartesian coordinates
     295              : 
     296              : !    get 3 pauli matrix contributions to the current: x,y,z, cart dir, spin dir
     297           40 :      do icartdir=1,3
     298              : 
     299              : !      x pauli spin matrix
     300              : !      sigma_x =  | 0   1 |
     301              : !      | 1   0 |
     302              :        spincurrent(:,:,:,icartdir,1) =  spincurrent(:,:,:,icartdir,1) + prefact_nk * &
     303              : !      Re(psi_r(up)^* dpsidr(down))
     304              : &       real(psi_r(1,:,:,:,1)*dpsidr(1,:,:,:,2,icartdir)  &
     305              : &       + psi_r(2,:,:,:,1)*dpsidr(2,:,:,:,2,icartdir)  &
     306              : !      Re(psi_r(down)^* dpsidr(up))
     307              : &       + psi_r(1,:,:,:,2)*dpsidr(1,:,:,:,1,icartdir)  &
     308       108480 : &       + psi_r(2,:,:,:,2)*dpsidr(2,:,:,:,1,icartdir))
     309              : 
     310              : !      y pauli spin matrix
     311              : !      sigma_y =  | 0  -i |
     312              : !      | i   0 |
     313              :        spincurrent(:,:,:,icartdir,2) =  spincurrent(:,:,:,icartdir,2) + prefact_nk * &
     314              : !      Re(-i psi_r(up)^* dpsidr(down))
     315              : &       real(psi_r(1,:,:,:,1)*dpsidr(2,:,:,:,2,icartdir)  &
     316              : &       - psi_r(2,:,:,:,1)*dpsidr(1,:,:,:,2,icartdir)  &
     317              : !      Re(i psi_r(down)^* dpsidr(up))
     318              : &       - psi_r(1,:,:,:,2)*dpsidr(2,:,:,:,1,icartdir)  &
     319       108480 : &       + psi_r(2,:,:,:,2)*dpsidr(1,:,:,:,1,icartdir))
     320              : 
     321              : !      z pauli spin matrix
     322              : !      sigma_z =  | 1   0 |
     323              : !      | 0  -1 |
     324              :        spincurrent(:,:,:,icartdir,3) =  spincurrent(:,:,:,icartdir,3) + prefact_nk * &
     325              : !      Re(psi_r(up)^* dpsidr(up))
     326              : &       real(psi_r(1,:,:,:,1)*dpsidr(1,:,:,:,1,icartdir)  &
     327              : &       - psi_r(2,:,:,:,1)*dpsidr(2,:,:,:,1,icartdir)  &
     328              : !      Re(-psi_r(down)^* dpsidr(down))
     329              : &       - psi_r(1,:,:,:,2)*dpsidr(1,:,:,:,2,icartdir)  &
     330       108490 : &       + psi_r(2,:,:,:,2)*dpsidr(2,:,:,:,2,icartdir))
     331              :      end do ! end icartdir
     332              : 
     333              : !
     334              : !    accumulate non local density matrix in real space
     335              : !    NOTE: if we are only using the local part of the current, this becomes the
     336              : !    density spinor matrix! (much lighter to calculate) rho(r, sigma, sigmaprime)
     337              : !
     338           30 :      do ispinor=1,dtset%nspinor
     339          330 :        do i3=1,dtset%ngfft(3)
     340         4820 :          do i2=1,dtset%ngfft(2)
     341        72300 :            do i1=1,dtset%ngfft(1)
     342        67500 :              irealsp = i1 + (i2-1)*dtset%ngfft(1) + (i3-1)*dtset%ngfft(2)*dtset%ngfft(1)
     343              : 
     344       207000 :              do ispinorp=1,dtset%nspinor
     345              :                density(1,irealsp,ispinor,ispinorp) = &
     346              : &               density(1,irealsp,ispinor,ispinorp) + &
     347              : &               prefact_nk * (psi_r(1,i1,i2,i3,ispinor)*psi_r(1,i1,i2,i3,ispinorp)&
     348       135000 : &               +  psi_r(2,i1,i2,i3,ispinor)*psi_r(2,i1,i2,i3,ispinorp))
     349              :                density(2,irealsp,ispinor,ispinorp) = &
     350              : &               density(2,irealsp,ispinor,ispinorp) + &
     351              : &               prefact_nk * (psi_r(1,i1,i2,i3,ispinor)*psi_r(2,i1,i2,i3,ispinorp)&
     352       202500 : &               -  psi_r(2,i1,i2,i3,ispinor)*psi_r(1,i1,i2,i3,ispinorp))
     353              : 
     354              : !              do i3p=1,dtset%ngfft(3)
     355              : !              do i2p=1,dtset%ngfft(2)
     356              : !              do i1p=1,dtset%ngfft(1)
     357              : !              irealsp_p = i1p + (i2p-1)*dtset%ngfft(1) + (i3p-1)*dtset%ngfft(2)*dtset%ngfft(1)
     358              : !
     359              : !              NOTE : sign changes in second terms below because rho = psi*(r) psi(rprime)
     360              : !
     361              : !              density_matrix(1,irealsp,ispinor,irealsp_p,ispinorp) = &
     362              : !              &           density_matrix(1,irealsp,ispinor,irealsp_p,ispinorp) + &
     363              : !              &           prefact_nk * (psi_r(1,i1,i2,i3,ispinor)*psi_r(1,i1p,i2p,i3p,ispinorp)&
     364              : !              &           +  psi_r(2,i1,i2,i3,ispinor)*psi_r(2,i1p,i2p,i3p,ispinorp))
     365              : !              density_matrix(2,irealsp,ispinor,irealsp_p,ispinorp) = &
     366              : !              &           density_matrix(2,irealsp,ispinor,irealsp_p,ispinorp) + &
     367              : !              &           prefact_nk * (psi_r(1,i1,i2,i3,ispinor)*psi_r(2,i1p,i2p,i3p,ispinorp)&
     368              : !              &           -  psi_r(2,i1,i2,i3,ispinor)*psi_r(1,i1p,i2p,i3p,ispinorp))
     369              : !              end do
     370              : !              end do
     371              : !              end do ! end irealspprime
     372              : 
     373              :              end do !end ispinorp do
     374              : 
     375              :            end do
     376              :          end do
     377              :        end do ! end irealsp
     378              :      end do !end ispinor do
     379              : 
     380              : !    update pw counter
     381           10 :      icg=icg+npw
     382           11 :      iocc=iocc+1
     383              :    end do ! iband
     384              : 
     385            1 :    ikg=ikg+npw
     386              : 
     387              : !  deallocate arrays dep on npw for this kpoint
     388            1 :    ABI_FREE(kg_k)
     389            1 :    ABI_FREE(gpsi)
     390            1 :    ABI_FREE(psi)
     391            2 :    ABI_FREE(kgcart)
     392              : 
     393              :  end do ! ikpt
     394              : 
     395            1 :  ABI_FREE(dpsidr)
     396            1 :  ABI_FREE(psi_r)
     397            1 :  ABI_FREE(dummy_denpot)
     398            1 :  ABI_FREE(gbound)
     399              : 
     400              : !prefactor for contribution to spin current
     401              : !prefactor is 1/2 * 1/2 * 2 Re(.):
     402              : !1/2 from the formula for the current
     403              : !1/2 from the use of the normalized Pauli matrices
     404              : !2 from the complex conjugate part
     405              : !total = 1/2
     406        32548 :  spincurrent = half * spincurrent
     407              : 
     408              : !make array of positions for all points on grid
     409            5 :  ABI_MALLOC(position_op,(3,dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3)))
     410           16 :  do i3=1,dtset%ngfft(3)
     411          241 :    do i2=1,dtset%ngfft(2)
     412         3615 :      do i1=1,dtset%ngfft(1)
     413              :        position_op(:,i1,i2,i3) = matmul(hdr%rprimd,(/i1-one,i2-one,i3-one/))&
     414        74475 : &       /(/dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3)/)
     415              :      end do
     416              :    end do
     417              :  end do
     418              : 
     419              : !-----------------------------------------------------------------------------------------
     420              : !-----------------------------------------------------------------------------------------
     421              : !add electric field term to current. Non local term in case of pseudopotential SO
     422              : !present theory is that it is equal to A(r,r') = (W_SO(r,r') + W_SO(r',r))
     423              : !For the strictly local part of the current, this becomes 2 W_SO(r,r)
     424              : !
     425              : !W_SO is the prefactor in the spinorbit part of the potential, such that it
     426              : !can be written V_SO = W_SO . p (momentum operator)
     427              : !decomposed from V_SO = v_SO(r,r') L.S = v_SO(r,r') (rxp).S = v_SO(r,r') (Sxr).p
     428              : !and ensuring symmetrization for the r operator wrt the two arguments of v_SO(r,r')
     429              : !Hence:
     430              : !W_SO(r,r) = v_SO(r,r) (Sxr)
     431              : !-----------------------------------------------------------------------------------------
     432              : !-----------------------------------------------------------------------------------------
     433              : 
     434              : !allocate (vso_realspace_nl(2,dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),dtset%nspinor,&
     435              : !& dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),dtset%nspinor))
     436              : 
     437              : !call vso_realspace_nonlop(atindx,atindx1,dtfil,dtset,gmet,gprimd,hdr,kg,&
     438              : !& mpi_enreg,nattyp,ph1d,position_op,psps,rmet,ucvol,vso_realspace_nl,ylm,ylmgr)
     439              : !anticommutator of VSO with position operator
     440              : !--- not needed in local spin current case ---
     441              : 
     442            6 :  ABI_MALLOC(vso_realspace,(2,dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),dtset%nspinor,dtset%nspinor,3))
     443              : 
     444            1 :  call vso_realspace_local(dtset,hdr,position_op,psps,vso_realspace)
     445              : 
     446              : 
     447              : !multiply by density (or density matrix for nonlocal case)
     448              : !and add to spin current
     449              : 
     450              : 
     451              : 
     452            1 :  ABI_FREE(density)
     453              : 
     454            1 :  realrecip = 0 ! real space for xsf output
     455            3 :  ABI_MALLOC(xcart,(3,dtset%natom))
     456            1 :  call xred2xcart(dtset%natom,hdr%rprimd,xcart,hdr%xred)
     457              : 
     458              : !-----------------------------------------------------------------------------------------
     459              : !-----------------------------------------------------------------------------------------
     460              : !output 3 components of current for each real space point
     461              : !-----------------------------------------------------------------------------------------
     462              : !-----------------------------------------------------------------------------------------
     463            4 :  do ispindir=1, 3
     464              : !  choose rescale_current such that the maximum current component printed out
     465              : !  is 1 percent of lattice distance
     466              : !  By default XCrysDen multiplies by 200 to get something comparable to a distance in real space.
     467        32547 :    rescale_current = maxval(abs(spincurrent(:, :, :, :, ispindir)))
     468            3 :    if (abs(rescale_current) < tol8) then
     469              :      rescale_current = one
     470              :    else
     471              :      rescale_current = 0.001_dp * sqrt(max(sum(hdr%rprimd(:,1)**2), &
     472           10 : &     sum(hdr%rprimd(:,2)**2), sum(hdr%rprimd(:,3)**2)))
     473              :    end if
     474              : 
     475            3 :    filnam=trim(dtfil%fnameabo_spcur)//spin_symbol(ispindir)//".xsf"
     476            3 :    if (open_file(filnam,message,newunit=spcur_unit,status='unknown') /= 0) then
     477            0 :      ABI_ERROR(message)
     478              :    end if
     479              : 
     480              : !  print header
     481            3 :    write (spcur_unit,'(a)')          '#'
     482            3 :    write (spcur_unit,'(a)')          '#  Xcrysden format file'
     483            3 :    write (spcur_unit,'(a)')          '#  spin current density, for all real space points'
     484            3 :    write (spcur_unit,'(a,3(I5,1x))') '#  fft grid is ', dtset%ngfft(1), dtset%ngfft(2), dtset%ngfft(3)
     485            3 :    write (spcur_unit,'(a,a,a)')  '# ', spin_symbol(ispindir), '-spin current, full vector '
     486              : 
     487            3 :    write (spcur_unit,'(a)')  'ATOMS'
     488            6 :    do iatom = 1, dtset%natom
     489            6 :      write (spcur_unit,'(I4, 2x, 3(E16.6, 1x))') int(dtset%znucl(dtset%typat(iatom))), xcart(:,iatom)
     490              :    end do
     491              : 
     492           48 :    do i3=1,dtset%ngfft(3)
     493          723 :      do i2=1,dtset%ngfft(2)
     494        10845 :        do i1=1,dtset%ngfft(1)
     495        10125 :          write (spcur_unit,'(a, 3(E10.3),2x, 3(E20.10))') 'X ', &
     496        51300 : &         position_op(:, i1, i2, i3), spincurrent(i1, i2, i3, :, ispindir)*rescale_current
     497              :        end do
     498              :      end do
     499              :    end do
     500            4 :    close (spcur_unit)
     501              : 
     502              :  end do ! end ispindir
     503              : 
     504              : !-----------------------------------------------------------------------------------------
     505              : !-----------------------------------------------------------------------------------------
     506              : !output 3 spin components of V_SO matrices, for each real space point
     507              : !-----------------------------------------------------------------------------------------
     508              : !-----------------------------------------------------------------------------------------
     509            3 :  ABI_MALLOC(datagrid, (dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3)))
     510              : 
     511            4 :  do ispindir=1,3
     512           10 :    do icplex=1,2
     513           21 :      do ispinor=1,dtset%nspinor
     514           42 :        do ispinorp=1,dtset%nspinor
     515              : 
     516              : !        for the moment only print out if non zero
     517        81024 :          if (abs(sum(vso_realspace(icplex, :, ispinor, ispinorp, ispindir))) < tol8) cycle
     518              : 
     519              :          filnam=trim(dtfil%fnameabo_vso)//"_spin_"//spin_symbol(ispindir)//"_"//&
     520           12 : &         spinor_sym(ispinor)//spinor_sym(ispinorp)//"_"//realimag(icplex)//".xsf"
     521              : 
     522           12 :          if (open_file(filnam,message,newunit=spcur_unit,status='unknown') /= 0) then
     523            0 :            ABI_ERROR(message)
     524              :          end if
     525              : 
     526              :          ! print header
     527           12 :          write (spcur_unit,'(a)')        '#'
     528           12 :          write (spcur_unit,'(a)')        '#  Xcrysden format file'
     529           12 :          write (spcur_unit,'(a)')        '#  spin-orbit potential (space diagonal), for all real space points'
     530           12 :          write (spcur_unit,'(a)')        '#    Real part first, then imaginary part'
     531           12 :          write (spcur_unit,'(a,3(I5,1x))') '#  fft grid is ', dtset%ngfft(1), dtset%ngfft(2),   dtset%ngfft(3)
     532           12 :          write (spcur_unit,'(a,a,a)')    '# ', spin_symbol(ispindir), '-spin contribution '
     533           12 :          write (spcur_unit,'(a,a,a)')    '# ', spinor_sym(ispinor)//spinor_sym(ispinorp), &
     534           24 :              '-spin element of the spinor 2x2 matrix '
     535           12 :          write (spcur_unit,'(a,a)')      '#  cart x     *  cart y    *  cart z    ***',&
     536           24 : &         ' up-up component    *  up-down           * down-up          * down-down          '
     537              : 
     538              :          ! Build contiguous array
     539        40524 :          datagrid = vso_realspace(icplex,:,ispinor, ispinorp, ispindir)
     540              : 
     541              :          call printxsf(dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3),&
     542              : &         datagrid,hdr%rprimd,(/zero,zero,zero/), dtset%natom, dtset%ntypat, &
     543           12 : &         dtset%typat, xcart, dtset%znucl, spcur_unit,realrecip)
     544              : 
     545              : !
     546              : !        NOTE: have chosen actual dims of grid (n123) instead of fft box, for which n45
     547              : !        may be different
     548              : !
     549              : !        do i3_dum=1,dtset%ngfft(3)+1
     550              : !        i3 = mod(i3_dum-1,dtset%ngfft(3)) + 1
     551              : !        do i2_dum=1,dtset%ngfft(2)+1
     552              : !        i2 = mod(i2_dum-1,dtset%ngfft(2)) + 1
     553              : !        do i1_dum=1,dtset%ngfft(1)+1
     554              : !        i1 = mod(i1_dum-1,dtset%ngfft(1)) + 1
     555              : !
     556              : !        irealsp = i1 + (i2-1)*dtset%ngfft(1) + (i3-1)*dtset%ngfft(2)*dtset%ngfft(1)
     557              : !        write (spcur_unit,'(E20.10,1x)')&
     558              : !        &      vso_realspace(icplex,irealsp,  ispinor, ispinorp, ispindir)
     559              : !        end do
     560              : !        end do
     561              : !        end do
     562              : 
     563           36 :          close (spcur_unit)
     564              : 
     565              :        end do ! ispinorp
     566              :      end do ! ispinor
     567              :    end do ! icplex
     568              :  end do ! end ispindir
     569              : 
     570            1 :  ABI_FREE(datagrid)
     571            1 :  ABI_FREE(vso_realspace)
     572              : !deallocate (vso_realspace_nl)
     573            1 :  ABI_FREE(position_op)
     574            1 :  ABI_FREE(spincurrent)
     575            1 :  ABI_FREE(xcart)
     576              : 
     577            1 :  write(std_out,*) ' Exiting subroutine spin_current '
     578              : 
     579            1 : end subroutine spin_current
     580              : !!***
     581              : 
     582              : !!****f* m_spin_current/vso_realspace_local
     583              : !! NAME
     584              : !!   vso_realspace_local
     585              : !!
     586              : !! FUNCTION
     587              : !!  Calculate real space (local - (r,r)) values of the SO part of the
     588              : !!  pseudopotential. Reconstructed explicitly in the HGH/GTH case.
     589              : !!
     590              : !! INPUTS
     591              : !!
     592              : !! OUTPUT
     593              : !!
     594              : !! SIDE EFFECTS
     595              : !!
     596              : !! NOTES
     597              : !!
     598              : !! SOURCE
     599              : 
     600            1 : subroutine vso_realspace_local(dtset,hdr,position_op,psps,vso_realspace)
     601              : 
     602              : !Arguments -------------------------------
     603              :  type(hdr_type),intent(inout) :: hdr
     604              :  type(dataset_type),intent(in) :: dtset
     605              :  type(pseudopotential_type),intent(in) :: psps
     606              :  real(dp),intent(in) :: position_op(3,dtset%ngfft(1),dtset%ngfft(2),dtset%ngfft(3))
     607              :  real(dp),intent(out) :: vso_realspace(2,dtset%ngfft(1)*dtset%ngfft(2)*dtset%ngfft(3),&
     608              : & dtset%nspinor,dtset%nspinor,3)
     609              : 
     610              : !Local variables -------------------------
     611              : !scalars
     612              :  integer :: i,j,l, lmax,ipsp,iatom, ir1,ir2,ir3
     613              :  integer :: rcexponent,irealsp
     614              :  integer :: nradgrid,iradgrid
     615              :  real(dp) :: gammai, gammaj, relative_position(3), radial_cutoff, norm_rel_pos
     616              :  real(dp) :: expfact,lfact, vso_interpol, x,y,z
     617              : !arrays
     618            2 :  real(dp) :: xcart(3,dtset%natom),splint_x(1),splint_y(1)
     619            1 :  real(dp), allocatable :: radial_grid(:)
     620            1 :  real(dp), allocatable :: prefact_ijl(:,:,:,:),tmpvso(:),tmpvso_pp(:)
     621            1 :  real(dp), allocatable :: vso_radial(:,:),vso_radial_pp(:,:),tmp_spline(:)
     622            1 :  real(dp), allocatable :: offdiag_l_fact(:,:,:),kpar_matrix(:,:)
     623              : 
     624              : ! *********************************************************************
     625              : 
     626              : !recalculate xcart (option = 1)
     627            1 :  call xred2xcart(dtset%natom,hdr%rprimd,xcart,hdr%xred)
     628              : 
     629            1 :  lmax = psps%mpsang-1
     630              : 
     631              : !content of gth pseudo type:
     632              : !These are {rloc, C(1...4)} coefficients for psppar(0, :, :) indices,
     633              : !Followed by the h coefficients for psppar(1:2, 1:, :) indices.
     634              : !size (0:2, 0:4, npsp)
     635              : !potential radius r_l is in psppar(l+1,0,ipsp)
     636              : !real(dp), pointer :: psppar(:, :, :)
     637              : !The covalence radii for each pseudo (?) size (npsp)
     638              : !real(dp), pointer :: radii_cov(:)
     639              : !Cut-off radii for core part and long-range part.
     640              : !radii_cf(:, 1) is for the long-range cut-off and
     641              : !radii_cf(:, 2) is for the core cut-off.
     642              : !size (npsp, 2)
     643              : !real(dp), pointer :: radii_cf(:, :)
     644              : !Spin orbit coefficients in HGH/GTH formats: k11p
     645              : !etc... see psp3ini.F90
     646              : !dimension = num l channels, 3 coeffs, num psp =
     647              : !(1:lmax+1,1:3,npsp)
     648              : !real(dp), pointer :: psp_k_par(:, :, :)
     649              : 
     650              : !v_SO^l (r,r') = sum_i sum_j sum_m Y_{lm} (\hat{r}) p_i^l (r) k_{ij}^l p_j^l(r') Y^{*}_lm (\hat{r'})
     651              : !
     652              : !v_SO^l (r,r)  = sum_ij  p_i^l (r) k_{ij}^l p_j^l(r) sum_m Y_{lm} (\hat{r}) Y^{*}_lm (\hat{r})
     653              : != (2l+1)/4\pi sum_ij  p_i^l (r) k_{ij}^l p_j^l(r) (eq B.17 Patrick Rinke thesis)
     654              : !p are gaussian projectors (from HGH paper prb 58 3641) [[cite:Hartwigsen1998]]
     655              : !sum_l v_SO^l (r,r) is a purely radial quantity (function of |r|), so spline it
     656              : 
     657              : !maximum distance needed in unit cell
     658            7 :  radial_cutoff = four * maxval(psps%gth_params%psppar(:, 0, :))
     659              : 
     660              : !setup radial grid; Should we use a logarithmic grid? The spline functions can
     661              : !take it...
     662            1 :  nradgrid = 201 ! this is heuristic
     663            1 :  ABI_MALLOC(radial_grid,(nradgrid))
     664          202 :  do iradgrid=1,nradgrid
     665          202 :    radial_grid(iradgrid) = (iradgrid-1)*radial_cutoff/(nradgrid-1)
     666              :  end do
     667              : 
     668              : !calculate prefactors independent of r
     669            4 :  ABI_MALLOC(prefact_ijl,(3,3,0:lmax,psps%npsp))
     670            3 :  ABI_MALLOC(offdiag_l_fact,(3,3,0:lmax))
     671            1 :  ABI_MALLOC(kpar_matrix,(3,3))
     672              : 
     673              : !these factors complete the full 3x3 matrix of k (or h) parameters for the
     674              : !HGH pseudos
     675           40 :  offdiag_l_fact = zero
     676              : !l=0
     677            1 :  offdiag_l_fact(1,2,0) = -half*sqrt(three/five)
     678            1 :  offdiag_l_fact(1,3,0) = half*sqrt(five/21._dp)
     679            1 :  offdiag_l_fact(2,3,0) = -half*sqrt(100._dp/63._dp)
     680              : !l=1
     681            1 :  offdiag_l_fact(1,2,1) = -half*sqrt(five/seven)
     682            1 :  offdiag_l_fact(1,3,1) = sixth*sqrt(35._dp/11._dp)
     683            1 :  offdiag_l_fact(2,3,1) = -sixth*14._dp/sqrt(11._dp)
     684              : !l=2
     685            1 :  if (lmax >= 2) then
     686            1 :    offdiag_l_fact(1,2,2) = -half*sqrt(seven/nine)
     687            1 :    offdiag_l_fact(1,3,2) = half*sqrt(63._dp/143._dp)
     688            1 :    offdiag_l_fact(2,3,2) = -half*18._dp /sqrt(143._dp)
     689              :  end if
     690              : !l=3
     691            1 :  if (lmax >= 3) then
     692            0 :    offdiag_l_fact(1,2,3) = zero
     693            0 :    offdiag_l_fact(1,3,3) = zero
     694            0 :    offdiag_l_fact(2,3,3) = zero
     695              :  end if
     696              : !get prefactors for evaluation of V_SO: terms that do not depend on r
     697           41 :  prefact_ijl = zero
     698            4 :  do l=0,lmax
     699              : !  first the diagonal i=j term
     700           12 :    do i=1,3
     701            9 :      call gamma_function(l+(4._dp*i-1._dp)*0.5_dp, gammai)
     702            9 :      gammai = sqrt(gammai)
     703            9 :      rcexponent = 2*l+2*i+2*i-1
     704           21 :      do ipsp=1,psps%npsp
     705              :        prefact_ijl(i,i,l,ipsp) = psps%gth_params%psp_k_par(l+1,i,ipsp) &
     706              : &       / ( (psps%gth_params%psppar(l+1,0,ipsp))**(rcexponent) &
     707           18 : &       * gammai * gammai)
     708              :      end do
     709              :    end do
     710              : !  now the off diagonal elements
     711            6 :    do ipsp=1,psps%npsp
     712            3 :      kpar_matrix(1,2) = offdiag_l_fact (1,2,l)* psps%gth_params%psp_k_par(l+1,2,ipsp)
     713            3 :      kpar_matrix(2,1) = kpar_matrix(1,2)
     714            3 :      kpar_matrix(1,3) = offdiag_l_fact (1,3,l)* psps%gth_params%psp_k_par(l+1,3,ipsp)
     715            3 :      kpar_matrix(3,1) = kpar_matrix(1,3)
     716            3 :      kpar_matrix(2,3) = offdiag_l_fact (2,3,l)* psps%gth_params%psp_k_par(l+1,3,ipsp)
     717            6 :      kpar_matrix(3,2) = kpar_matrix(2,3)
     718              :    end do
     719              : 
     720              : !  for the f case only the 1,1 matrix element is non 0 - it is done above and
     721              : !  all these terms are actually 0
     722            3 :    if (l > 2) cycle
     723              : 
     724           13 :    do i=1,3
     725            9 :      call gamma_function(l+(4._dp*i-1._dp)*0.5_dp, gammai)
     726            9 :      gammai = sqrt(gammai)
     727           39 :      do j=1,3
     728           27 :        if (j==i) cycle
     729           18 :        rcexponent = 2*l+2*i+2*j-1
     730           18 :        call gamma_function(l+(4._dp*j-1._dp)*0.5_dp,gammaj)
     731           18 :        gammaj = sqrt(gammaj)
     732           45 :        do ipsp=1,psps%npsp
     733              :          prefact_ijl(i,j,l,ipsp) = kpar_matrix(i,j) &
     734              : &         / ( (psps%gth_params%psppar(l+1,0,ipsp))**rcexponent &
     735           45 : &         * gammai * gammaj )
     736              :        end do
     737              :      end do
     738              :    end do
     739              :  end do
     740              : 
     741            1 :  ABI_FREE(kpar_matrix)
     742            1 :  ABI_FREE(offdiag_l_fact)
     743              : 
     744           41 :  prefact_ijl = prefact_ijl * two
     745              : 
     746              : !calculate v_SO on radial grid
     747              : ! MGNAG Runtime Error: *** Arithmetic exception: Floating invalid operation - aborting
     748            3 :  ABI_MALLOC(vso_radial,(nradgrid,psps%npsp))
     749          203 :  vso_radial = zero
     750            4 :  do l=0,lmax
     751          606 :    lfact=(2._dp*l+1._dp)/four/pi
     752          607 :    do iradgrid=1,nradgrid
     753          603 :      norm_rel_pos = radial_grid(iradgrid)
     754         1209 :      do ipsp=1,psps%npsp
     755          603 :        expfact = exp(-norm_rel_pos**2 / (psps%gth_params%psppar(l+1,0,ipsp))**2)
     756              : 
     757         3015 :        do i=1,3
     758         7839 :          do j=1,3
     759         5427 :            rcexponent = 2*l +2*i+2*j-4
     760         7236 :            if(prefact_ijl(i,j,l,ipsp)/=0) then !vz_d 0**0
     761              :              vso_radial(iradgrid,ipsp) = vso_radial(iradgrid,ipsp) + &
     762         1005 : &             prefact_ijl(i,j,l,ipsp)*(norm_rel_pos**rcexponent) * expfact
     763              :            end if  !vz_d
     764              :          end do ! j
     765              :        end do ! i
     766              :      end do ! ipsp
     767              :    end do ! iradgrid
     768              :  end do ! lmax
     769              : 
     770              : !spline v_SO(radial coord): get second derivative coefficients
     771            2 :  ABI_MALLOC(vso_radial_pp,(nradgrid,psps%npsp))
     772              : 
     773            1 :  ABI_MALLOC(tmp_spline,(nradgrid))
     774            1 :  ABI_MALLOC(tmpvso,(nradgrid))
     775            1 :  ABI_MALLOC(tmpvso_pp,(nradgrid))
     776            2 :  do ipsp=1,psps%npsp
     777          203 :    tmpvso = vso_radial(:,ipsp)
     778            1 :    call spline( radial_grid, tmpvso, nradgrid, zero, radial_grid(nradgrid), tmpvso_pp )
     779          203 :    vso_radial_pp(:,ipsp) = tmpvso_pp
     780              :  end do
     781            1 :  ABI_FREE(tmp_spline)
     782            1 :  ABI_FREE(tmpvso)
     783            1 :  ABI_FREE(tmpvso_pp)
     784              : 
     785              : !to optimize this I should precalculate the distances which are actually needed by
     786              : !symmetry, or only sum over irreducible points in space and use weights
     787              : 
     788              : !for each physical atom present in unit cell
     789       121522 :  vso_realspace = zero
     790            2 :  do iatom=1,dtset%natom
     791              : !  atom type will be dtset%typat(iatom)
     792              : 
     793              : !  for each point on grid
     794           17 :    do ir3=1,dtset%ngfft(3)
     795          241 :      do ir2=1,dtset%ngfft(2)
     796         3615 :        do ir1=1,dtset%ngfft(1)
     797         3375 :          irealsp = ir1 + (ir2-1)*dtset%ngfft(1) + (ir3-1)*dtset%ngfft(2)*dtset%ngfft(1)
     798              : 
     799              : !        relative position from atom to point
     800        13500 :          relative_position = position_op(:,ir1,ir2,ir3) - xcart(:,iatom)
     801         3375 :          x=relative_position(1)
     802         3375 :          y=relative_position(2)
     803         3375 :          z=relative_position(3)
     804              : 
     805              : !        calculate norm^2
     806         3375 :          norm_rel_pos = relative_position(1)**2+relative_position(2)**2+relative_position(3)**2
     807              : 
     808              : !        if norm^2 is too large, skip this point
     809         3375 :          if (norm_rel_pos > radial_cutoff*radial_cutoff) cycle
     810              : 
     811              : !        calculate norm
     812          459 :          splint_x(1) = sqrt(norm_rel_pos)
     813              : 
     814              : !        spline interpolate vso only depends on position (through pos - atomic position)
     815              :          call splint (nradgrid,radial_grid,vso_radial(:,dtset%typat(iatom)),&
     816          459 : &         vso_radial_pp(:,dtset%typat(iatom)),1,splint_x,splint_y)
     817          459 :          vso_interpol=splint_y(1)
     818              : 
     819              : !        multiply by vectorial spin factor (S x r)
     820              : !        NOTE: this r is taken relative to atom center. It could be that the r operator should
     821              : !        applied in an absolute way wrt the origin...
     822              : !
     823              : !        Is this correct: accumulated sum over atoms ?
     824              :          vso_realspace(1,irealsp,:,:,1) = vso_realspace(1,irealsp,:,:,1) + &
     825         5049 : &         vso_interpol * reshape((/y,   zero,zero,-y/),(/2,2/))
     826              :          vso_realspace(2,irealsp,:,:,1) = vso_realspace(2,irealsp,:,:,1) + &
     827         5049 : &         vso_interpol * reshape((/zero,z,  -z,    zero/),(/2,2/))
     828              : 
     829              :          vso_realspace(1,irealsp,:,:,2) = vso_realspace(1,irealsp,:,:,2) + &
     830         5049 : &         vso_interpol * reshape((/-x,  z,   z,   x/),(/2,2/))
     831              :          vso_realspace(2,irealsp,:,:,2) = vso_realspace(2,irealsp,:,:,2) + &
     832         3213 : &         vso_interpol * reshape((/zero,zero,zero,zero/),(/2,2/))
     833              : 
     834              :          vso_realspace(1,irealsp,:,:,3) = vso_realspace(1,irealsp,:,:,3) + &
     835         5049 : &         vso_interpol * reshape((/zero,-y, -y,   zero/),(/2,2/))
     836              :          vso_realspace(2,irealsp,:,:,3) = vso_realspace(2,irealsp,:,:,3) + &
     837         8190 : &         vso_interpol * reshape((/zero,-x, -x,    zero/),(/2,2/))
     838              : 
     839              :        end do  ! ir3
     840              :      end do  ! ir2
     841              :    end do  ! ir1
     842              :  end do ! iatom
     843              : 
     844            1 :  ABI_FREE(prefact_ijl)
     845            1 :  ABI_FREE(vso_radial)
     846            1 :  ABI_FREE(vso_radial_pp)
     847            1 :  ABI_FREE(radial_grid)
     848              : 
     849            1 : end subroutine vso_realspace_local
     850              : !!***
     851              : 
     852          171 : end module m_spin_current
     853              : !!***
        

Generated by: LCOV version 2.3-1