!-----------------------------------------------------------------------------------------! ! Copyright (c) 2018 Peter Grünberg Institut, Forschungszentrum Jülich, Germany ! ! This file is part of Jülich KKR code and available as free software under the conditions! ! of the MIT license as expressed in the LICENSE.md file in more detail. ! !-----------------------------------------------------------------------------------------! !------------------------------------------------------------------------------------ !> Summary: Module storing the run options and the paramters for bfields and constraining fields !> Author: Sascha Brinker !> !> !> !> !> !------------------------------------------------------------------------------------ module mod_bfield use :: mod_profiling use :: mod_datatypes use :: global_variables, only: lmmaxd, ncleb, ntotd, nfund use :: mod_types, only: t_inc use :: mod_rotatespinframe, only: rotatematrix use :: mod_mympi, only: myrank, master implicit none !------------------------------------------------------------------------------- !> Summary: Type used in t_params to store all relevant information for bfields and constraining fields !> Author: Sascha Brinker !> Category: communication, KKRhost, bfield !> Deprecated: False !> !------------------------------------------------------------------------------- type :: type_bfield logical :: lbfield = .False. ! external magnetic field (turned on via runoption <noncobfield>) non-collinear magnetic field logical :: lbfield_constr = .False. ! constraining fields (turned on via runoption <noncobfield>) non-collinear magnetic field logical :: lbfield_all = .False. ! apply same field to all atoms (True) or individual fields to each atom logical :: lbfield_trans = .False. ! apply only transversal field logical :: lbfield_mt = .False. ! apply only field in muffin-tin logical :: ltorque = .False. ! calculate magnetic torque integer :: ibfield = 0 ! spin (0), orbital (1), spin+orbial (2) fields integer :: ibfield_constr = 0 ! type of contraint (0 = torque, 1 = magnetic moment) integer :: itscf0 = 0 ! start magnetic field at iteration itscf0 integer :: itscf1 = 10000 ! stop applying magnetic field after iteration itscf1 real (kind=dp), dimension (:,:), allocatable :: bfield ! external magnetic field in cartesian coordinates, dimensions (natom,3) real (kind=dp), dimension (:), allocatable :: bfield_strength ! absolute value of the external magnetic field, dimensions (natom) real (kind=dp), dimension (:,:), allocatable :: bfield_constr ! constraining field in cartesian coordinates, dimensions (natom,3) real (kind=dp), dimension (:), allocatable :: theta ! polar angle of the magnetic field real (kind=dp), dimension (:), allocatable :: phi ! azimuthal angle of the magnetic field real (kind=dp), dimension (:,:,:,:), allocatable :: thetallmat ! shapefun in the ll' expansion !------------------------------------------------------------------------------------ ! Magnetic torque !------------------------------------------------------------------------------------ real(kind=dp),dimension(:,:), allocatable :: mag_torque end type type_bfield type (type_bfield), save :: bfield contains !------------------------------------------------------------------------------- !> Summary: Allocate initial magnetic field parameters to be broadcasted via mpi !> Author: Sascha Brinker !> Category: memory-management, profiling, KKRhost, bfield !> Deprecated: False !------------------------------------------------------------------------------- subroutine init_bfield(bfield,natyp,lbfield,lbfield_constr,lbfield_all,lbfield_trans,lbfield_mt,ltorque,ibfield,ibfield_constr,itscf0, & itscf1,npan_log,npan_eq,ncheb,ntotd,nfund,ncelld,lmax,iend,ntcell,ipan_intervall,ifunm,icleb,cleb,thetasnew) implicit none type(type_bfield), intent(inout) :: bfield integer, intent(in) :: natyp integer :: i_stat logical, intent(in) :: lbfield logical, intent(in) :: lbfield_constr logical, intent(in) :: lbfield_all logical, intent(in) :: lbfield_trans logical, intent(in) :: lbfield_mt logical, intent(in) :: ltorque integer, intent(in) :: ibfield integer, intent(in) :: ibfield_constr integer, intent(in) :: itscf0 integer, intent(in) :: itscf1 integer, intent(in) :: npan_log integer, intent(in) :: npan_eq integer, intent(in) :: ncheb integer, intent(in) :: ntotd integer, intent(in) :: nfund integer, intent(in) :: ncelld integer, intent(in) :: lmax integer, intent (in):: iend ! Number of nonzero gaunt coefficients integer, dimension (natyp), intent (in) :: ntcell ! pointer from natyp to ndcell integer, dimension (0:ntotd, natyp), intent (in) :: ipan_intervall integer, dimension (1:(2*lmax+1)**2,natyp), intent (in) :: ifunm ! pointer array for shapefun ! Check index and dimensions!!!!! integer, dimension (ncleb, 4), intent (in) :: icleb !! Pointer array real (kind=dp), dimension (ncleb), intent (in) :: cleb !! GAUNT coefficients (GAUNT) real (kind=dp), dimension (ntotd*(ncheb+1), nfund, ncelld), intent (in) :: thetasnew !! interpolated shape function in Chebychev radial mesh integer :: icell integer :: i1 logical, dimension(ncelld) :: celldone !write(*,'("Init bfield")') ! init basic parameters bfield%lbfield = lbfield bfield%lbfield_constr = lbfield_constr bfield%lbfield_all = lbfield_all bfield%lbfield_trans = lbfield_trans bfield%lbfield_mt = lbfield_mt bfield%ltorque = ltorque bfield%ibfield = ibfield bfield%ibfield_constr = ibfield_constr bfield%itscf0 = itscf0 bfield%itscf1 = itscf1 ! allocate arrays and add to memory screening routine allocate (bfield%theta(natyp), stat=i_stat) call memocc(i_stat, product(shape(bfield%theta))*kind(bfield%theta), 'bfield%theta', 'init_bfield') allocate (bfield%phi(natyp), stat=i_stat) call memocc(i_stat, product(shape(bfield%phi))*kind(bfield%phi), 'bfield%phi', 'init_bfield') allocate (bfield%bfield(natyp,3), stat=i_stat) call memocc(i_stat, product(shape(bfield%bfield))*kind(bfield%bfield), 'bfield%bfield', 'init_bfield') allocate (bfield%bfield_strength(natyp), stat=i_stat) call memocc(i_stat, product(shape(bfield%bfield_strength))*kind(bfield%bfield_strength), 'bfield%bfield_strength', 'init_bfield') allocate (bfield%bfield_constr(natyp,3), stat=i_stat) call memocc(i_stat, product(shape(bfield%bfield_constr))*kind(bfield%bfield_constr), 'bfield%bfield_constr', 'init_bfield') ! init allocated arrays ! bfield%bfield_constr(:,:) = 0.d0 if(lbfield) call read_bfield(bfield,natyp) ! MdSD: constraining fields if(lbfield_constr) call read_bconstr(natyp,bfield%bfield_constr) allocate (bfield%mag_torque(natyp,3), stat=i_stat) call memocc(i_stat, product(shape(bfield%mag_torque ))*kind(bfield%mag_torque ), 'bfield%mag_torque', 'init_bfield') ! Calculate the LL' expansion of hte shape function in the new mesh which ! is needed to convolute the magnetic field (only done once and stored to ! safe computing time) if(lbfield) then allocate (bfield%thetallmat((lmax+1)**2,(lmax+1)**2,ntotd*(ncheb+1),ncelld), stat=i_stat) call memocc(i_stat, product(shape(bfield%thetallmat ))*kind(bfield%thetallmat ), 'bfield%thetallmat', 'init_bfield') celldone(:) = .False. do i1=1,natyp icell = ntcell(i1) if(.not. celldone(icell)) then call calc_thetallmat(bfield%thetallmat(:,:,:,icell), lmax, ipan_intervall(npan_log+npan_eq,i1) + 1, iend, ntotd*(ncheb+1), thetasnew(:,:,icell), ifunm(:,i1), icleb, cleb) end if celldone(icell) = .True. end do end if !write(*,'("Init bfield done")') end subroutine init_bfield !------------------------------------------------------------------------------- !> Summary: Writes the atom-wise constraining field to bconstr_out.dat !> Author: MdSD !> Category: KKRhost, bfield !> Deprecated: False !> the file has the format: !> bz by bz (in Ry), mspin (in muB) !------------------------------------------------------------------------------- subroutine save_bconstr(natyp,bconstr_in,bconstr_out) implicit none integer , intent(in) :: natyp real(kind=dp), dimension(4,natyp), intent(in) :: bconstr_in !! bx, by, bz, mspin real(kind=dp), dimension(natyp,3), intent(inout) :: bconstr_out !! bx, by, bz ! local integer :: iatom, nrms real(kind=dp) :: rms open(unit=57493215, file='bconstr_out.dat', status='replace') write(57493215,'("# bconstr_x [Ry], bconstr_y [Ry], bconstr_z [Ry], m_spin [mu_B]")') rms = 0.d0; nrms = 0 do iatom=1,natyp ! check if this atom is actually being constrained if (dot_product(bconstr_in(1:3,iatom), bconstr_in(1:3,iatom)) > 1.d-16) then rms = rms + dot_product(bconstr_out(iatom,:)-bconstr_in(1:3,iatom), bconstr_out(iatom,:)-bconstr_in(1:3,iatom)) nrms = nrms + 1 end if write(57493215,'(4es16.8)') bconstr_in(:,iatom) bconstr_out(iatom,:) = bconstr_in(1:3,iatom) end do close(57493215) write(1337,'("Number of constrained atoms=",i8," rms for constraining fields=",es16.8)') nrms, sqrt(rms)/max(nrms,1) end subroutine save_bconstr !------------------------------------------------------------------------------- !> Summary: Reads the atom-wise constraining field from bconstr.dat !> Author: MdSD !> Category: KKRhost, bfield !> Deprecated: False !> the file has the format: !> bz by bz (in Ry), mspin (in muB) !------------------------------------------------------------------------------- subroutine read_bconstr(natyp,bconstr_out) implicit none integer , intent(in) :: natyp real(kind=dp), dimension(natyp,3), intent(out) :: bconstr_out !! bx, by, bz ! local integer :: iatom logical :: file_exists inquire(file='bconstr_in.dat',exist=file_exists) if (file_exists) then open(unit=57493215, file='bconstr_in.dat') read(57493215,*) ! skip header do iatom=1,natyp read(57493215,*) bconstr_out(iatom,:) end do close(57493215) else bconstr_out(:,:) = 0.0_dp end if write(1337,*) ' ############################################################' write(1337,*) ' input constraining fields' write(1337,*) ' ############################################################' write(1337,*) ' iatom Bx By Bz (in Ry)' do iatom=1,natyp write(1337,'(" ",i4,3es16.8)') iatom, bconstr_out(iatom,:) end do end subroutine read_bconstr !------------------------------------------------------------------------------- !> Summary: Reads the atom-wise magnetic field from bfield.dat !> Author: Sascha Brinker !> Category: KKRhost, bfield !> Deprecated: False !> the file has the format: !> theta phi bfield_strength (in Tesla) !------------------------------------------------------------------------------- subroutine read_bfield(bfield,natyp) implicit none integer , intent(in) :: natyp type(type_bfield) , intent(inout) :: bfield !local integer :: iatom,ios,ierror character(len=200) :: string1 integer,save :: first=1 if (first==1) then open(unit=57493215, file='bfield.dat', status='old', iostat=ierror) if (ierror/=0) then write(*,*) '[read_bfield] bfield file does not exist' write(*,*) ' setting all bfields to zero' if (.not.bfield%lbfield_constr) then write(*,*) ' disabling magnetic field lbfield = F' bfield%lbfield = .false. end if do iatom=1,natyp bfield%theta(iatom) = 0.0D0 bfield%phi(iatom) = 0.0D0 bfield%bfield_strength(iatom) = 0.0D0 bfield%bfield(iatom,:) = 0.0D0 end do return end if call read_numbofbfields(natyp) end if write(1337,*) ' ###############################################' write(1337,*) ' non-collinear magnetic fields' write(1337,*) ' ###############################################' write(1337,*) ' iatom theta phi bfield (in Ry )' do iatom=1,natyp string1=this_readline(57493215,ios) if (ios/=0) stop '[read_bfield] Error reading atom info2' if (ios==-1) stop '[read_bfield] EOF' read(string1,*) bfield%theta(iatom),bfield%phi(iatom),bfield%bfield_strength(iatom) write(1337,'(" ",i4,3es16.8)') iatom,bfield%theta(iatom),bfield%phi(iatom),bfield%bfield_strength(iatom) bfield%theta(iatom) = bfield%theta(iatom)/360.0D0*8.0D0*datan(1.0D0) bfield%phi(iatom) = bfield%phi(iatom) /360.0D0*8.0D0*datan(1.0D0) bfield%bfield_strength(iatom) = bfield%bfield_strength(iatom)!/235051.787_dp !conversion from Tesla to Ry bfield%bfield(iatom,1) = bfield%bfield_strength(iatom)*cos(bfield%phi(iatom))*sin(bfield%theta(iatom)) bfield%bfield(iatom,2) = bfield%bfield_strength(iatom)*sin(bfield%phi(iatom))*sin(bfield%theta(iatom)) bfield%bfield(iatom,3) = bfield%bfield_strength(iatom)*cos(bfield%theta(iatom)) !write(*,*) iatom,bfield%theta(iatom),bfield%phi(iatom),bfield%bfield_strength(iatom),bfield%bfield(iatom,1),bfield%bfield(iatom,2),bfield%bfield(iatom,3) end do ! close(33952084) first=0 end subroutine read_bfield subroutine read_numbofbfields(natom) implicit none integer,intent(in) :: natom integer :: ios,linecount,ierror character(len=200) :: string1 open(unit=55493215, file='bfield.dat', status='old', iostat=ierror) ios=0 linecount = -1 do while (ios/=-1) string1=this_readline(55493215,ios) linecount=linecount+1 end do if (natom/=linecount) then print *,'[read_bfield] number of angles given in file bfield.dat' print *,' is not correct' print *,'linecount',linecount print *,'natyp',natom stop end if close(55493215) end subroutine read_numbofbfields function this_readline(ifile,ios) !-------------------------------------------------------- !-- reads the next line in file unit ifile -- !-------------------------------------------------------- !-- files starting with a dash (#) are treated as -- !-- a comment !!! -- !-- OUTPUT: next line which is not commented out -- !-- error variable IOS (should be zero) -- !-------------------------------------------------------- ! input variables implicit none integer,intent(in) :: ifile integer,intent(out) :: ios ! local variables character(len=200) ::this_readline do read(unit=ifile,fmt='(A)', iostat=ios) this_readline if (ios/=0 .or. this_readline(1:1)/='#') exit end do end function this_readline !------------------------------------------------------------------------------------ !> Summary: Adds magnetic field to the LL' expansion of the potential !> Author: Sascha Brinker !> Category: KKRhost, bfield !> Deprecated: False !> Calculates the LL' expansion of a magnetic field. !> There are two magnetic field, which can be added: a homogeneous magnetic !> field read in from bfield.dat and a constraining field, which compensates !> the magnetic torque. !> @note The magnetic field is added in the following form: !> $ H = H_0 - \sigma \cdot \vec{B} $ !> The input magnetic field is read in from bfield.dat. !> It is homogeneous within each cell. !> @endnote !> @note Runs only with the new solver and either spin-orbit coupling or !> noncollinear magnetism. !> @endnote !------------------------------------------------------------------------------------ subroutine add_bfield(bfield,iatom,lmax,nspin,irmdnew,imt1,iend,ncheb,theta,phi,ifunm,icleb,cleb,thetasnew,mode,vnspll0,vnspll1,thetansll) implicit none type(type_bfield) , intent (in) :: bfield ! contains all relevant information about the magnetic fields integer , intent (in) :: iatom ! atom index integer , intent (in) :: lmax ! angular momentum cut-off integer , intent (in) :: nspin ! number of spins integer , intent (in) :: irmdnew ! number of radials point on the Cheby mesh integer , intent (in) :: imt1 ! index muffin-tin radius integer , intent (in) :: iend ! Number of nonzero gaunt coefficients integer , intent (in) :: ncheb ! Number of Chebychev pannels for the new solver real (kind=dp) , intent (in) :: theta ! polar angle of the magnetic moment real (kind=dp) , intent (in) :: phi ! azimuthal angle of the magnetic moment integer , dimension (1:(2*lmax+1)**2) , intent (in) :: ifunm ! pointer array for shapefun ! Check index and dimensions!!!!! integer, dimension (ncleb, 4), intent (in) :: icleb !! Pointer array real (kind=dp), dimension (ncleb), intent (in) :: cleb !! GAUNT coefficients (GAUNT) ! CHECK THE DIMENSION AND HOW IT IS USED!!! real (kind=dp) , dimension (irmdnew, nfund) , intent (in) :: thetasnew ! shapefun on the Cheby mesh character (len=*) , intent (in) :: mode !! either '1' or 'transpose', depending whether SOC potential is constructed for right or left solution complex (kind=dp) , dimension(lmmaxd, lmmaxd, irmdnew) , intent (in) :: vnspll0 !! input potential in (l,m,s) basis complex (kind=dp) , dimension(lmmaxd, lmmaxd, irmdnew) , intent (out) :: vnspll1 !! input potential in (l,m,s) basis real(kind=dp) , dimension(1:(lmax+1)**2,1:(lmax+1)**2,1:irmdnew), intent(in) :: thetansll !------------------------------------------------------------------------------------ ! local variables !------------------------------------------------------------------------------------ integer :: lmmax integer :: i integer :: j integer :: ilm1 integer :: ilm2 integer :: ir integer :: irend integer , dimension(2) :: lmstart integer , dimension(2) :: lmend real(kind=dp) , dimension(3) :: bin(3) real(kind=dp),dimension(3) :: magdir ! direction of the magnetic moment double complex , dimension(2,2) :: bs ! sigma*b_0 character(len=1024) :: filename double complex , dimension(1:irmdnew) :: temp double complex :: icompl double complex :: temp2 logical :: debug=.False. !------------------------------------------------------------------------------------ ! old variables !------------------------------------------------------------------------------------ !double complex :: bxcll(2*(lmax+1)**2,2*(lmax+1)**2,nrmaxnew) !double complex :: templl(2*(lmax+1)**2,2*(lmax+1)**2,nrmaxnew) !------------------------------------------------------------------------------------ !------------------------------------------------------------------------------------ !!write(*,*) bfield ! contains all relevant information about the magnetic fields !write(*,*) iatom ! atom index !write(*,*) lmax ! angular momentum cut-off !write(*,*) nspin ! number of spins !write(*,*) irmdnew ! number of radials point on the Cheby mesh !write(*,*) imt1 ! index muffin-tin radius !write(*,*) iend ! Number of nonzero gaunt coefficients !write(*,*) ncheb ! Number of Chebychev pannels for the new solver !write(*,*) theta ! polar angle of the magnetic moment !write(*,*) phi ! azimuthal angle of the magnetic moment !write(*,*) ifunm ! pointer array for shapefun !write(*,*) icleb !! Pointer array !write(*,*) cleb !! GAUNT coefficients (GAUNT) !------------------------------------------------------------------------------------ !------------------------------------------------------------------------------------ if (t_inc%i_write>1 .and. mode=='1') then write(1337,'("===============================================================================")') write(1337,'(" Magnetic fields for atom ",i4)') iatom write(1337,'("===============================================================================")') end if !lmmax=lmmaxd ! could be replace it is still here due to copy/paste lmmax=(lmax+1)**2 icompl=(0d0,1d0) lmstart(1)= 1 lmstart(2)= lmmax+1 lmend(1)=lmmax lmend(2)=2*lmmax !if(myrank==master .and. debug) then ! write(filename,'("debug_bfield_",i3.3)') iatom ! open(unit=17*iatom**2,file=filename) ! write(17*iatom**2,'(" mode =")') ! write(17*iatom**2,*) mode ! write(17*iatom**2,'(" lmax= ",i4," lmmax= ",i4," irmdnew= ",i4," imt1= ",i4," ncheb= ",i4," iend= ",i4," iatom= ",i4," nspin= ",i4," theta= ",f16.8," phi= ",f16.8)') lmax,lmmax,irmdnew,imt1,ncheb,iend,iatom,nspin,theta,phi ! write(17*iatom**2,'(" bfield is =",3f16.8," theta, phi= ",2f16.8)') bfield%bfield(iatom,:),bfield%theta(iatom),bfield%phi(iatom) !end if !!!! calc LL' expansion of the shapefunction !!!call calc_thetallmat(thetansll, lmax, imt1, iend, irmdnew, thetasnew, ifunm, icleb, cleb) !!! !!!if(myrank==master) then !!! write(*,'(" thetansll = ")') !!! do ilm1=1,lmmax !!! do ilm2=1,lmmax !!! if(sum(abs(thetansll(ilm1,ilm2,:)))>1e-8 .or. sum(abs(thetansll_new(ilm1,ilm2,:)))>1e-8) then !!! write(*,'(2i4,1000es16.8)') ilm1, ilm2, thetansll(ilm1,ilm2,:) !!! write(*,'(2i4,1000es16.8)') ilm1, ilm2, thetansll_new(ilm1,ilm2,:) !!! end if !!! end do !!! end do !!!end if ! First add inhomogeneous bfield here (constraining field from xc potential) !if( density%magmomentfixed == 6 ) then ! add xc field as constraining field here ! write(17*iatom**2,'(" Adding xc constraining field")') ! write(17*iatom**2,'(" c_xc= ",10es16.8)') bfield%c_xc(:) ! !bxcll(1:lmmax,1:lmmax,:) = (vpotll(1:lmmax,1:lmmax,:)-vpotll(lmmax+1:2*lmmax,lmmax+1:2*lmmax,:))/2.d0 ! call vllmat(templl,cellnew%vpotnew(:,:,:),lmax,(lmax+1)**2,lmax,1, & ! cellnew%nrmaxnew,gauntcoeff,zatom,cellnew%rmeshnew,2*lmmax,1,nspin,ispin,'NS') ! bxcll(1:lmmax,1:lmmax,:) = (templl(1:lmmax,1:lmmax,:)-templl(lmmax+1:2*lmmax,lmmax+1:2*lmmax,:))/2.d0 ! write(17*iatom**2,'(" bxcll = ")') ! do ilm1=1,lmmax ! do ilm2=1,lmmax ! if(sum(abs(bxcll(ilm1,ilm2,:)))>1e-8) then ! write(17*iatom**2,'(2i4,1000es16.8)') ilm1, ilm2, bxcll(ilm1,ilm2,:) ! end if ! end do ! end do ! bs(:,:)=0.d0 ! ! down/down block ! bs(1,1)=-bfield%c_xc(3) ! ! up/up block ! bs(2,2)= bfield%c_xc(3) ! ! down/up block ! bs(1,2)=(bfield%c_xc(1)+icompl*bfield%c_xc(2)) ! ! up/down block ! bs(2,1)=(bfield%c_xc(1)-icompl*bfield%c_xc(2)) ! if (ncoll==1) then ! call rotatematrix(bs,theta, phi,1,'glob->loc') ! end if ! if (mode=='transpose') then ! used for the left solution / Bxc is symmetric in LL' by construction ! temp2 = bs(1,2) ! bs(1,2) = bs(2,1) ! bs(2,1) = temp2 ! elseif (mode=='1') then ! else ! stop'[bfield] mode not known' ! end if ! do i = 1,2 ! do j = 1,2 ! vpotll(lmstart(i):lmend(i),lmstart(j):lmend(j),:)=vpotll(lmstart(i):lmend(i),lmstart(j):lmend(j),:)-bs(i,j)*bxcll(:,:,:) ! end do ! end do !end if ! Add different contributions to the magnetic field bin(:) = 0.d0 if ( t_inc%i_iteration>=bfield%itscf0 .and. t_inc%i_iteration<=bfield%itscf1 ) then ! preconvergence without adding the constraining field !if(myrank==master .and. debug) write(*,'("Adding bfield for iatom="i4)') iatom if(bfield%lbfield) then bin(:) = bfield%bfield(iatom,:) end if if( bfield%lbfield_constr ) then if( bfield%ibfield_constr == 0 .or. bfield%ibfield_constr == 1 ) then ! add homogenous constraining field here bin(:) = bin(:) + bfield%bfield_constr(iatom,:) end if end if end if if(bfield%lbfield_trans) then magdir(1) = sin(theta)*cos(phi) magdir(2) = sin(theta)*sin(phi) magdir(3) = cos(theta) bin(:) = bin(:) - magdir*dot_product(magdir(:),bin(:)) end if if (t_inc%i_write>1 .and. mode=='1') write(1337,'("iatom, bin=",i4,3es16.8)') iatom, bin bs(:,:)=0.d0 ! down/down block bs(1,1)=-bin(3) ! up/up block bs(2,2)= bin(3) ! down/up block bs(1,2)=(bin(1)+icompl*bin(2)) ! up/down block bs(2,1)=(bin(1)-icompl*bin(2)) if(myrank==master .and. debug) write(17*iatom**2,'(" bs(glob) =",8es16.8)') bs(1,1),bs(1,2),bs(2,1),bs(2,2) ! Just always rotate it even for collinear calculations call rotatematrix(bs,theta, phi,1,1)!'glob->loc') if(myrank==master .and. debug) write(17*iatom**2,'(" bs(loc) =",8es16.8)') bs(1,1),bs(1,2),bs(2,1),bs(2,2) if (mode=='transpose') then ! used for the left solution temp2 = bs(1,2) bs(1,2) = bs(2,1) bs(2,1) = temp2 elseif (mode=='1') then else stop '[bfield] mode not known' end if !if(myrank==master .and. debug) then ! write(17*iatom**2,'(" vnspll_old = ")') ! do ilm1=1,lmmaxd ! do ilm2=1,lmmaxd ! if(sum(abs(real(vnspll0(ilm1,ilm2,:))))>1e-8) then ! write(17*iatom**2,'(2i4,1000es16.8)') ilm1, ilm2, vnspll0(ilm1,ilm2,:) ! end if ! end do ! end do !end if if(bfield%lbfield_mt) then irend = imt1 else irend = irmdnew end if do i = 1,2 do j = 1,2 do ir=1,irend vnspll1(lmstart(i):lmend(i),lmstart(j):lmend(j),ir)=vnspll0(lmstart(i):lmend(i),lmstart(j):lmend(j),ir)-bs(i,j)*thetansll(1:lmmax,1:lmmax,ir) end do if(bfield%lbfield_mt) then !add non-spherical part of normal potential do ir=irend+1,irmdnew vnspll1(lmstart(i):lmend(i),lmstart(j):lmend(j),ir)=vnspll0(lmstart(i):lmend(i),lmstart(j):lmend(j),ir) end do end if end do end do !if(myrank==master .and. debug) then ! write(17*iatom**2,'(" vnspll_new = ")') ! do ilm1=1,lmmaxd ! do ilm2=1,lmmaxd ! if(sum(abs(real(vnspll1(ilm1,ilm2,:))))>1e-8) then ! write(17*iatom**2,'(2i4,1000es16.8)') ilm1, ilm2, vnspll1(ilm1,ilm2,:) ! end if ! end do ! end do !end if !close(17*iatom**2) end subroutine add_bfield !------------------------------------------------------------------------------------ !> Summary: Shape function LL' expansion !> Author: Sascha Brinker !> Category: KKRhost, geometry, new-mesh, shapefun !> Deprecated: False !> Calculates the LL' expansion of the shape function similarly to vllmat_new.f90 !> @note The input shapefunction (single L) uses pointer arrays for the lm index. !> The output does not need pointers! !> @endnote !------------------------------------------------------------------------------------ subroutine calc_thetallmat(thetansll, lmax, imt1, iend, irmdnew, thetasnew, ifunm, icleb, cleb) !use :: global_variables, only: ntotd, nfund implicit none integer , intent (in) :: lmax ! Angular momentum cut-off integer , intent (in) :: imt1 ! index muffin-tin radius integer , intent (in) :: iend ! Number of nonzero gaunt coefficients integer , intent (in) :: irmdnew ! number of radials point on the Cheby mesh integer, dimension (ncleb, 4), intent (in) :: icleb !! Pointer array real (kind=dp), dimension (ncleb), intent (in) :: cleb !! GAUNT coefficients (GAUNT) real (kind=dp) , dimension (irmdnew, nfund) , intent (in) :: thetasnew ! shapefun on the Cheby mesh integer , dimension (1:(2*lmax+1)**2) , intent (in) :: ifunm ! pointer array for shapefun ! Check index and dimensions!!!!! real(kind=dp) , dimension((lmax+1)**2,(lmax+1)**2,irmdnew) , intent (out) :: thetansll ! LL' expansion of the shapefunction !------------------------------------------------------------------------------------ real(kind=dp),parameter :: rfpi=3.5449077018110318 real(kind=dp),dimension(1:irmdnew,1:(2*lmax+1)**2) :: shapefun_mod real(kind=dp) :: c0ll integer :: lmmax integer :: lmmax2 integer :: ilm integer :: ifun integer :: ir integer :: lm1 integer :: lm2 integer :: lm3 integer :: j logical :: debug=.False. c0ll = 1d0/rfpi lmmax = (lmax+1)**2 lmmax2 = (2*lmax+1)**2 shapefun_mod(:,:) = 0.d0 shapefun_mod(1:imt1,1) = rfpi ! is multipled by C_LL^0 shapefun_mod(imt1+1:irmdnew,1) = thetasnew(imt1+1:irmdnew,1) ! convert from pointer to real ilmdo ilm=2,lmmax2 do ilm=2,lmmax2 ifun = ifunm(ilm) if(.not. ifun == 0) then !shapefun%lmused(ilm)==1) then !if(myrank==master .and. debug) write(17*iatom**2,'(" converted ifun= ",i4," to ilm= ",i4)') ifun, ilm shapefun_mod(imt1+1:irmdnew,ilm) = thetasnew(imt1+1:irmdnew,ifun) end if end do !if(myrank==master .and. debug) write(17*iatom**2,'(" cellnew%shapefun = ")') !do ilm= 1,lmmax2 ! if(sum(abs(thetasnew(:,ilm)))>1e-8) then ! if(myrank==master .and. debug) write(17*iatom**2,'(i4,1000es16.8)') ilm, thetasnew(:,ilm) ! end if !end do !if(myrank==master .and. debug) write(17*iatom**2,'(" shapefun_mod = ")') !do ilm= 1,lmmax2 ! if(sum(abs(shapefun_mod(:,ilm)))>1e-8) then ! if(myrank==master .and. debug) write(17*iatom**2,'(i4,1000es16.8)') ilm, shapefun_mod(:,ilm) ! end if !end do thetansll(:,:,:)=0.d0 ! diagonal part (not contained in gaunt-coeff) do ilm = 1,lmmax thetansll(ilm,ilm,:) = shapefun_mod(:,1)*c0ll end do !write(*,'("ifunm=",1000i4)') ifunm(:) do j = 1,iend !gauntcoeff%iend lm1 = icleb(j, 1)! gauntcoeff%icleb(j,1) ! lmax lm2 = icleb(j, 2)! gauntcoeff%icleb(j,2) ! lmax lm3 = icleb(j, 3)! gauntcoeff%icleb(j,3) ! 2*lmax !write(17*iatom**2,'("lm1,lm2,lm3 =",3i4,2es16.8)') lm1,lm2,lm3,cleb(j) if(lm1<= lmmax .and. lm2 <= lmmax .and. lm3<= lmmax2) then ifun = ifunm(lm3) if(.not. ifun == 0) then !shapefun%lmused(ilm)==1) then !write(*,'("lm1,lm2,lm3,cleb",3i4,10e16.8)') lm1,lm2,lm3,cleb(j) do ir = 1,irmdnew!cellnew%nrmaxnew thetansll(lm1,lm2,ir) = thetansll(lm1,lm2,ir)+cleb(j)*shapefun_mod(ir,lm3) thetansll(lm2,lm1,ir) = thetansll(lm2,lm1,ir)+cleb(j)*shapefun_mod(ir,lm3) end do end if end if end do !do lm1 = 1,lmmax ! do lm2 = 1,lm1-1 ! do ir = 1, irmdnew ! thetansll(ir,lm2,lm1) = thetansll(ir,lm1,lm2) ! end do ! end do !end do !if(myrank==master .and. debug) write(17*iatom**2,'(" thetansll = ")') !do lm1=1,lmmax ! do lm2=1,lmmax ! if(sum(abs(thetansll(:,lm1,lm2)))>1e-8) then ! if(myrank==master .and. debug) write(17*iatom**2,'(2i4,1000es16.8)') lm1, lm2, thetansll(:,lm1,lm2) ! end if ! end do !end do end subroutine calc_thetallmat end module mod_bfield