tmat_newsolver.F90 Source File


Source Code

!-----------------------------------------------------------------------------------------!
! 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: Calculation of the t-matrix for the new solver
!> Author: 
!> Calculation of the t-matrix for the new solver
!------------------------------------------------------------------------------------
module mod_tmatnewsolver

  implicit none

contains

  !-------------------------------------------------------------------------------
  !> Summary: Calculation of the t-matrix for the new solver
  !> Author: 
  !> Category: single-site, KKRhost
  !> Deprecated: False 
  !> Constructs potential matrix (2x2 for SOC) adding SOC potential with proper form 
  !> of small-component in the case of a scalar-relativistic calculation.
  !> Then creates source terms needed to solve Lippmann-Schwinger equations as described 
  !> in the PhD thesis of David Bauer.
  !-------------------------------------------------------------------------------
  !> @note 
  !> - in the case of using the `SRATRICK` (default behavior) first the spherical solutions are computed (diagonal)
  !>   which are then used to compute the non-spherical solutions in a second step
  !> - Jonathan Chico Apr. 2019: Removed inc.p dependencies and rewrote to Fortran90
  !> @endnote
  !-------------------------------------------------------------------------------
  subroutine tmat_newsolver(ielast,nspin,lmax,zat,socscale,ez,nsra,cleb,icleb,iend, &
    ncheb,npan_tot,rpan_intervall,ipan_intervall,rnew,vinsnew,theta,phi,i1,ipot,    &
    lmpot,lly,deltae,idoldau,lopt,wldau,t_dtmatjij_at,ispin)

#ifdef CPP_OMP
    use :: omp_lib ! necessary for omp functions
#endif
#ifdef CPP_MPI
    use :: mpi ! necessary for MPI functions
    use :: mod_mympi, only: mpiadapt, nranks
    use :: mod_timing, only: timing_start, timing_stop, timings_1a
#endif
    use :: mod_datatypes, only: dp
    use :: mod_runoptions, only: calc_exchange_couplings, disable_tmat_sratrick, formatted_file, stop_1b, &
      write_BdG_tests, write_pkkr_operators, write_rhoq_input, set_cheby_nospeedup, decouple_spin_cheby, &
      calc_wronskian, write_tmat_all, use_rllsll
    use :: mod_constants, only: czero, cone, cvlight
    use :: global_variables, only: ntotd, ncleb, nrmaxd, mmaxd, nspind, nspotd, iemxd, lmmaxd, korbit
    use :: mod_wunfiles, only: t_params
    use :: mod_profiling, only: memocc
    use :: mod_mympi, only: myrank, master, distribute_work_energies
    use :: mod_types, only: t_tgmat, t_inc, t_mpi_c_grid, init_tgmat, t_lloyd, init_tlloyd, type_dtmatjijdij, init_t_dtmatjij_at
    use :: mod_save_wavefun, only: t_wavefunctions, find_isave_wavefun, save_wavefunc
    use :: mod_jijhelp, only: calc_dtmatjij
    use :: mod_calcsph, only: calcsph
    use :: mod_rll_global_solutions, only: rll_global_solutions
    use :: mod_sll_global_solutions, only: sll_global_solutions ! MdSD: TEST
    use :: mod_rllsllsourceterms, only: rllsllsourceterms
    use :: mod_rllsll, only: rllsll
    use :: mod_spinorbit_ham, only: spinorbit_ham
    use :: mod_vllmat, only: vllmat
    use :: mod_vllmatsra, only: vllmatsra
    use :: mod_regns, only: zgeinv1
    use :: mod_wronskian, only: calcwronskian
    use :: mod_bfield, only: add_bfield
#ifdef CPP_BdG
    use :: mod_ioinput, only: ioinput ! to read in something from inputcard
#endif

    implicit none

    ! inputs
    integer, intent (in) :: i1               !! atom index
    integer, intent (in) :: ispin            !! spin index, only used for 'NOSOC' test option where external spin loop is used in main1a 
    integer, intent (in) :: lly              !! LLY /= 0: apply Lloyds formula
    integer, intent (in) :: lopt             !! angular momentum QNUM for the atoms on which LDA+U should be applied (-1 to switch it OFF)
    integer, intent (in) :: lmax             !! Maximum l component in wave function expansion
    integer, intent (in) :: nsra             !! use scalar-relativistic (nsra=2) or non-relativistic (nsra=1) wavefunctions  
    integer, intent (in) :: iend             !! Number of nonzero gaunt coefficients
    integer, intent (in) :: ipot             !! potential index (ipot=(iatom-1)*nspin+ispin)
    integer, intent (in) :: ncheb            !! Number of Chebychev pannels for the new solver
    integer, intent (in) :: nspin            !! Number of spin directions
    integer, intent (in) :: lmpot            !! maximal LM-value of potential expansion: (LPOT+1)**2
    integer, intent (in) :: ielast           !! number of energy points in contour
    integer, intent (in) :: npan_tot         !! total number of panels for Chebychev radial mesh
    integer, intent (in) :: idoldau          !! flag to perform LDA+U
    real (kind=dp), intent (in) :: zat       !! Nuclear charge for a given atom
    real (kind=dp), intent (in) :: phi       !! phi of local spin frame
    real (kind=dp), intent (in) :: theta     !! theta of local spin frame, relative to z-axis
    real (kind=dp), intent (in) :: socscale  !! Spin-orbit scaling for a given atom
    complex (kind=dp), intent (in) :: deltae !! Energy difference for numerical derivative
    integer, dimension (0:ntotd), intent (in) :: ipan_intervall !! indices where panels start in radial Chebychev mesh
    integer, dimension (ncleb, 4), intent (in) :: icleb         !! index array of nonzero Gaunt coefficients [mapping of (lm1, lm2) to lm3]
    real (kind=dp), dimension (ncleb), intent (in) :: cleb      !! values of GAUNT coefficients 
    real (kind=dp), dimension (nrmaxd), intent (in) :: rnew     !! radial mesh points in Chebychev mesh
    real (kind=dp), dimension (0:ntotd), intent (in) :: rpan_intervall        !! radial meshpoints of panel boundaries
    real (kind=dp), dimension (mmaxd, mmaxd, nspind), intent (in) :: wldau    !! potential matrix for LDA+U
    real (kind=dp), dimension (nrmaxd, lmpot, nspotd), intent (in) :: vinsnew !! potential interpolated to Chebychev radial mesh
    complex (kind=dp), dimension (iemxd), intent (in) :: ez  !! list of complex energy points in contour
    type (type_dtmatjijdij), intent (inout) :: t_dtmatjij_at !! derived Data type to store \[\Delta t\]-matrix for Jij calculation

    ! .. Local variables
    integer :: ir, irec, use_sratrick, nvec, lm1, lm2, ie, irmdnew, i11, i_stat
    integer :: lmmax0d !! size of lm-dimension without spin-doubling [ =(lmax+1)**2 ]
    integer :: use_fullgmat !! use (l,m,s) coupled matrices or not for 'NOSOC' test option (1/0)
    integer :: imt1             !! index muffin-tin radius
    complex (kind=dp) :: eryd !! energy in Ry
    complex (kind=dp), dimension (nspin*(lmax+1)) :: alphasph !! spherical part of alpha-matrix
    ! .. Local allocatable arrays
    integer, dimension (:), allocatable :: jlk_index
    real (kind=dp), dimension (:, :, :), allocatable :: vins     !! Non-spherical part of the potential
    complex (kind=dp), dimension (:, :), allocatable :: aux      ! LLY
    complex (kind=dp), dimension (:, :), allocatable :: tmat0    !
    complex (kind=dp), dimension (:, :), allocatable :: alpha0   ! LLY
    complex (kind=dp), dimension (:, :), allocatable :: tmatll   !! t-matrix
    complex (kind=dp), dimension (:, :), allocatable :: dtmatll  !! derivative of t-matrix for Lloyd
    complex (kind=dp), dimension (:, :), allocatable :: tmatsph  !! spherical part of t-matrix
    complex (kind=dp), dimension (:, :), allocatable :: alphall  !! alpha matrix for Lloyd
    complex (kind=dp), dimension (:, :), allocatable :: dalphall !! derivatve of alpha matrix for Lloyd
    complex (kind=dp), dimension (:, :, :), allocatable :: hlk
    complex (kind=dp), dimension (:, :, :), allocatable :: jlk
    complex (kind=dp), dimension (:, :, :), allocatable :: hlk2
    complex (kind=dp), dimension (:, :, :), allocatable :: jlk2
    complex (kind=dp), dimension (:, :, :), allocatable :: vnspll0
    complex (kind=dp), dimension (:, :, :, :), allocatable :: ull !! regular solution of radial equation
    complex (kind=dp), dimension (:, :, :, :), allocatable :: rll !! regular solution of radial equation
    complex (kind=dp), dimension (:, :, :, :), allocatable :: sll !! irregular solution of radial equation
    complex (kind=dp), dimension (:, :, :, :), allocatable :: vnspll
    complex (kind=dp), dimension (:, :, :, :), allocatable :: vnspll1
    complex (kind=dp), dimension (:, :, :), allocatable :: vnspll2
    complex (kind=dp), dimension (:, :, :, :), allocatable :: rllleft !! regular left solution of radial equation
    complex (kind=dp), dimension (:, :, :, :), allocatable :: sllleft !! irregular left solution of radial equation

    ! .. LDAU local variables
    integer :: lmlo, lmhi

    ! .. LLoyd local variables
    integer :: ideriv, signde
    complex (kind=dp) :: tralpha
    complex (kind=dp) :: gmatprefactor
    integer, dimension (:), allocatable :: ipiv ! LLY

    ! .. OMP local variables
    integer :: nth, ith !! total number of threads and thread id for openmp

#ifdef CPP_MPI
    integer, dimension (0:nranks-1) :: ntot_pt, ioff_pt !! auxiliary arrays for MPI communication
#endif
    integer :: ie_end, ie_num, ie_start

    ! rhoqtest
    integer :: mu0, nscoef

    ! BdG
    character (len=100) :: filename
    complex (kind=dp) :: e_shift
    integer :: ier, KBdG
    character (len=:), allocatable :: uio
    !-------------------------------------------------------------------------------

#ifdef CPP_OMP
    ! determine if omp parallelisation is used (compiled with -openmp flag and OMP_NUM_THREADS>1)
    !$omp parallel shared(nth,ith)
    !$omp single
    nth = omp_get_num_threads()
    if (t_inc%i_write>0) write (1337, *) 'nth =', nth
    !$omp end single
    !$omp end parallel
#else
    nth = 1
    ith = 0
#endif

    lmmax0d = lmmaxd/(1+korbit)
    irmdnew = npan_tot*(ncheb+1)

    if (nsra==2) then
      use_sratrick = 1
      if (disable_tmat_sratrick) then
        if (myrank==master .and. ith==0 .and. i1==1 .and. ispin==1) then
          write (*, *) 'Found test option "nosph   ", deactivate SRATRICK'
        end if
        use_sratrick = 0
      end if
    else if (nsra==1) then
      use_sratrick = 0
    end if


    ! .. allocate and initialize arrays
    call allocate_locals_tmat_newsolver(1, irmdnew, lmpot, nspin/(nspin-korbit), vins, aux, ipiv, tmat0, tmatll, alpha0, dtmatll, alphall, dalphall, jlk_index, nsra, lmmaxd, nth, lmax, vnspll, &
      vnspll0, vnspll1, vnspll2, hlk, jlk, hlk2, jlk2, tmatsph, ull, rll, sll, rllleft, sllleft)

    vins(1:irmdnew, 1:lmpot, 1) = vinsnew(1:irmdnew, 1:lmpot, ipot)
    if (.not.decouple_spin_cheby) vins(1:irmdnew, 1:lmpot, nspin) = vinsnew(1:irmdnew, 1:lmpot, ipot+nspin-1)

    KBdG = 0
#ifdef CPP_BdG
    ! shift potential by EF to change referece point of energy to Fermi level
    ! should later be done automatically in main0
    if (write_BdG_tests) then
      ! e_shift = complex(0.723775735132693_dp, 0.0_dp)
      ! e_shift = complex(0.724775735132693_dp, 0.0_dp)

      call ioinput('eshift          ', uio, 1, 7, ier)
      if (ier==0) then
        read (unit=uio, fmt=*) e_shift
        write (*, *) 'e_shift=', e_shift
      else
        e_shift = czero
      end if
    else
      e_shift = czero
    end if
#endif

    ! set up the non-spherical ll' matrix for potential VLL' (done in VLLMAT)
    call vllmat(1, nrmaxd, irmdnew, lmmax0d, lmmaxd, vnspll0, vins, lmpot, cleb, icleb, iend, nspin/(nspin-korbit), zat, rnew, use_sratrick, ncleb)
    ! test writeout of VNSPLL1
    if (write_BdG_tests) then
      write (filename, '(A,I0.3,A)') 'vnspll_', i1, '.txt'
      open (7352834, file=trim(filename), form='formatted')
      write (7352834, '(A,3I9)') '# lmmaxd,lmmaxd,IRMDNEW=', lmmaxd, lmmaxd, irmdnew
      write (7352834, '(2ES25.9)') vnspll0(:, :, :)
      close (7352834)
    end if
    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! LDAU
    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    if (idoldau==1) then
      lmlo = lopt**2 + 1
      lmhi = (lopt+1)**2
      do ir = 1, irmdnew
        vnspll0(lmlo:lmhi, lmlo:lmhi, ir) = vnspll0(lmlo:lmhi, lmlo:lmhi, ir) + wldau(1:mmaxd, 1:mmaxd, 1)
      end do
      lmlo = lmlo + lmmax0d
      lmhi = lmhi + lmmax0d
      do ir = 1, irmdnew
        vnspll0(lmlo:lmhi, lmlo:lmhi, ir) = vnspll0(lmlo:lmhi, lmlo:lmhi, ir) + wldau(1:mmaxd, 1:mmaxd, 2)
      end do
    end if
    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    ! LDAU
    ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    ! start energy loop
    if (myrank==master .and. (t_inc%i_write>0)) write (1337, *) 'atom: ', i1, ' NSRA:', nsra

    ! handle mpi parallelization
    call distribute_work_energies(ielast)
#ifdef CPP_MPI
    ie_start = t_mpi_c_grid%ioff_pt2(t_mpi_c_grid%myrank_at)
    ie_end = t_mpi_c_grid%ntot_pt2(t_mpi_c_grid%myrank_at)
#else
    ie_start = 0
    ie_end = ielast
#endif
    ! Now initialize arrays for tmat, gmat, and gref
    call init_tgmat(t_inc, t_tgmat, t_mpi_c_grid)
    if (lly/=0) call init_tlloyd(t_inc, t_lloyd, t_mpi_c_grid)

    ! consistency check
    if (write_rhoq_input) then
      if (ielast/=3) stop 'Error: wrong energy contour for rhoqtest'
      ie_start = 1
      ie_end = 1
    end if

    ! For Jij-tensor calculation: allocate array to hold additional t-matrices
    call init_t_dtmatjij_at(t_inc, t_mpi_c_grid, t_dtmatjij_at)

    ! Initialize wfsave
    if (t_inc%i_iteration==0) then
      call find_isave_wavefun(t_wavefunctions)
      ! Reset Nwfsavemax to 0 if test option 'STOP1B  ' is found
      ! to prevent unnessesary storing of wavefunctions
      if (stop_1b .and. .not. write_pkkr_operators) then
        t_wavefunctions%nwfsavemax = 0
      end if
      ! MdSD: TEST
      ! if (myrank == 0) then
      !   write(*,'("In tmat_newsolver:")')
      !   write(*,'("nwfsavemax=",i4)') t_wavefunctions%nwfsavemax
      !   write(*,'("save_rll=",l4)') t_wavefunctions%save_rll
      !   write(*,'("save_sll=",l4)') t_wavefunctions%save_sll
      !   write(*,'("save_rllleft=",l4)') t_wavefunctions%save_rllleft
      !   write(*,'("save_sllleft=",l4)') t_wavefunctions%save_sllleft
      ! end if
    end if

#ifdef CPP_OMP
    !$omp parallel do default(none)                                            &
    !$omp private(eryd,ie,ir,nvec,lm1,lm2,gmatprefactor)                       &
    !$omp private(jlk_index,tmatll,ith,irec, ie_num)                           &
    !$omp private(tralpha, aux, ideriv, ipiv)                                  &
    !$omp private(alpha0)                                                      &
    !$omp private(alphall)                                                     &
    !$omp private(tmat0)                                                       &
    !$omp private(alphasph)                                                    &
    !$omp private(dtmatll)                                                     &
    !$omp private(dalphall)                                                    &
    !$omp shared(t_inc)                                                        &
    !$omp shared(nspin,nsra,lmax,lmmax0d,iend,ipot,ielast,npan_tot,ncheb)       &
    !$omp shared(zat,socscale,ez,cleb,rnew,nth,LMPOT,NRMAXD,lmmaxd,NTOTD)     &
    !$omp shared(rpan_intervall,vinsnew,ipan_intervall,NCLEB)                  &
    !$omp shared(use_sratrick,irmdnew,theta,phi,vins,vnspll0)                  &
    !$omp shared(vnspll1,vnspll,hlk,jlk,hlk2,jlk2,rll,sll,rllleft,sllleft)     &
    !$omp shared(tmatsph, ie_end,t_tgmat,t_lloyd, ie_start, t_dtmatjij_at)     &
    !$omp shared(lly,deltae,i1,t_mpi_c_grid, t_wavefunctions, icleb)           &
    !$omp shared(mu0, nscoef, e_shift, filename, use_fullgmat)
#endif

    do ie_num = 1, ie_end

      ie = ie_start + ie_num

#ifdef CPP_MPI
      ! start timing measurement for this pair of ie and i1, needed for MPIadapt
      call timing_start('time_1a_ieiatom')
#endif

      ! get current thread
      if (nth>=1) then
#ifdef CPP_OMP
        ith = omp_get_thread_num()
#endif
      else
        ith = 0
      end if

      ! In case of Lloyds formula the derivative of t is needed.
      ! Then calculate t at E+dE, E-dE and average for t, subtract for dt/dE
      tmatll = czero
      alphall = czero              ! LLY
      dtmatll = czero              ! LLY
      dalphall = czero             ! LLY
      ideriv = 0
      if (lly/=0) ideriv = 1
      do signde = -ideriv, ideriv, 2
        eryd = ez(ie) + real(signde, kind=dp)*deltae/2.0_dp ! LLY

#ifdef CPP_OMP
        !$omp critical
#endif
#ifdef CPP_BdG
        if (write_BdG_tests) then
          write (*, '(A,4ES21.7)') 'shifting energy by e_fermi:', eryd, e_shift
          eryd = eryd + e_shift
        end if
#endif

        if (t_inc%i_write>0) write (1337, *) 'energy:', ie, '', eryd
#ifdef CPP_OMP
        if (ie==1 .and. (t_inc%i_write>0)) write (1337, *) 'nested omp?', omp_get_nested()
        !$omp end critical
#endif

        if ( .not. decouple_spin_cheby) then
          ! Contruct the spin-orbit coupling hamiltonian and add to potential
          call spinorbit_ham(lmax, lmmax0d, vins, rnew, eryd, zat, cvlight, socscale, nspin, lmpot, theta, phi, ipan_intervall, rpan_intervall, npan_tot, ncheb, irmdnew, nrmaxd, &
            vnspll0(:,:,:), vnspll2(:,:,:), '1')
        else
          vnspll2(:,:,:) = vnspll0(:,:,:)
        end if
  
        ! Add magnetic field
        if (t_params%bfield%lbfield) then
          ! MdSD: constraining fields
          if (t_inc%i_write>1) then
            write (1337,'("tmat_newsolver: myrank=",i8,"  iatom=",i8)') myrank, i1
            do ir=1,t_params%natyp
              write (1337,'("  iatom=",i8,"  bfield=",3es16.8,"  bconstr=",3es16.8)') ir, t_params%bfield%bfield(ir,:), t_params%bfield%bfield_constr(ir,:)
            end do
          end if
          imt1 = ipan_intervall(t_params%npan_log+t_params%npan_eq) + 1
          call add_bfield(t_params%bfield,i1,lmax,nspin,irmdnew,imt1,iend,ncheb,theta,phi,t_params%ifunm1(:,t_params%ntcell(i1)),&
                          t_params%icleb,t_params%cleb(:,1),t_params%thetasnew(1:irmdnew,:,t_params%ntcell(i1)),'1',vnspll2(:,:,:), &
                          vnspll1(:,:,:,ith),t_params%bfield%thetallmat(:,:,1:irmdnew,t_params%ntcell(i1)))
        else
          vnspll1(:,:,:,ith) = vnspll2(:,:,:)
        end if

#ifdef CPP_OMP
        !$omp critical
#endif
        ! test writeout of VNSPLL1
        if (write_BdG_tests) then
          write (filename, '(A,I0.3,A,I0.3,A)') 'vnspll_SOC_', i1, '_energ_', ie, '.txt'
          open (7352834, file=trim(filename), form='formatted')
          write (7352834, '(A,3I9)') '# lmmaxd,lmmaxd,IRMDNEW=', lmmaxd, lmmaxd, irmdnew
          write (7352834, '(2ES25.9)') vnspll1(:, :, :, ith)
          close (7352834)
        end if
#ifdef CPP_OMP
        !$omp end critical
#endif

        ! now extend matrix for the SRA treatment
        vnspll(:, :, :, ith) = czero

        if (nsra==2) then
          if (use_sratrick==0) then
            call vllmatsra(vnspll1(:,:,:,ith),vnspll(:,:,:,ith),rnew,lmmaxd,       &
              irmdnew,nrmaxd,eryd,lmax,0,'Ref=0')
          else if (use_sratrick==1) then
            call vllmatsra(vnspll1(:,:,:,ith),vnspll(:,:,:,ith),rnew,lmmaxd,       &
              irmdnew,nrmaxd,eryd,lmax,0,'Ref=Vsph')
          end if
        else
          vnspll(:, :, :, ith) = vnspll1(:, :, :, ith)
        end if

#ifdef CPP_OMP
        !$omp critical
#endif
        ! test writeout of VNPSLL
        if (write_BdG_tests) then
          write (filename, '(A,I0.3,A,I0.3,A)') 'vnspll_sra_', i1, '_energ_', ie, '.txt'
          open (7352834, file=trim(filename), form='formatted')
          if (nsra==2) then
            write (7352834, '(A,3I9)') '# 2*lmmaxd,2*lmmaxd,IRMDNEW=', 2*lmmaxd, 2*lmmaxd, irmdnew
          else
            write (7352834, '(A,3I9)') '# lmmaxd,lmmaxd,IRMDNEW=', lmmaxd, lmmaxd, irmdnew
          end if
          write (7352834, '(2ES25.9)') vnspll(:, :, :, ith)
          close (7352834)
        end if
#ifdef CPP_OMP
        !$omp end critical
#endif


        ! Calculate the source terms in the Lippmann-Schwinger equation
        ! these are spherical hankel and bessel functions
        hlk(:, :, ith) = czero
        jlk(:, :, ith) = czero
        hlk2(:, :, ith) = czero
        jlk2(:, :, ith) = czero
        gmatprefactor = czero
        if (decouple_spin_cheby) then
          use_fullgmat = 0
        else
          use_fullgmat = 1
        end if
!RZ
        call rllsllsourceterms(nsra, nvec, eryd, rnew, irmdnew, nrmaxd, lmax, lmmaxd, use_fullgmat, jlk_index, &
          hlk(:,:,ith), jlk(:,:,ith), hlk2(:,:,ith), jlk2(:,:,ith), gmatprefactor)

#ifdef CPP_OMP
        !$omp critical
#endif
#ifdef CPP_BdG
        if (write_BdG_tests) then
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_source_jlk_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES21.9)') jlk(:, :, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_source_hlk_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES21.9)') hlk(:, :, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_source_jlk2_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES21.9)') jlk2(:, :, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_source_hlk2_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES21.9)') hlk2(:, :, ith)
          close (888888)
        end if
#endif
#ifdef CPP_OMP
        !$omp end critical
#endif

        ! Using spherical potential as reference
        if (use_sratrick==1) then
          tmatsph(:, ith) = czero
          call calcsph(nsra, irmdnew, nrmaxd, lmax, nspin/(nspin-korbit), zat, eryd, lmpot, lmmaxd, rnew, vins, ncheb, npan_tot, rpan_intervall, jlk_index, hlk(:,:,ith), jlk(:,:,ith), &
            hlk2(:,:,ith), jlk2(:,:,ith), gmatprefactor, tmatsph(:,ith), alphasph, use_sratrick, .true.)
#ifdef CPP_BdG
        if (write_BdG_tests) then
          write (filename, '(A,I0.3,A,I0.3,A)') 'tmatsph_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,I9)') '# dimension: lmmaxd=', lmmaxd, ' lmmaxd=', lmmaxd
          write (888888, '(2ES25.16)') tmatsph(:, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_sph_jlk_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES25.16)') jlk(:, :, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_sph_hlk_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES25.16)') hlk(:, :, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_sph_jlk2_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES25.16)') jlk2(:, :, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_sph_hlk2_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: 4*(LMAX+1)=', 4*(lmax+1), ' IRMDNEW=', irmdnew, ' ; ERYD=', eryd
          write (888888, '(2ES25.16)') hlk2(:, :, ith)
          close (888888)
        end if
#endif
        end if
        ! Calculate the tmat and wavefunctions
        rll(:, :, :, ith) = czero
        sll(:, :, :, ith) = czero

        ! Right solutions
        tmat0 = czero
        alpha0 = czero             ! LLY
        if (use_rllsll) then
        ! MdSD: this is the old interface
          call rllsll(rpan_intervall, rnew, vnspll(:,:,:,ith), rll(:,:,:,ith), sll(:,:,:,ith), tmat0(:,:), ncheb, npan_tot, lmmaxd, nvec*lmmaxd, nsra*(1+korbit)*(lmax+1), irmdnew, nsra, &
            jlk_index, hlk(:,:,ith), jlk(:,:,ith), hlk2(:,:,ith), jlk2(:,:,ith), gmatprefactor, '1', '1', '0', use_sratrick, alpha0(:,:))
        else
        ! faster calculation of RLL.
        ! no irregular solutions are needed in self-consistent iterations
        ! because the t-matrix depends only on RLL
          call rll_global_solutions(rpan_intervall, rnew, vnspll(:,:,:,ith), ull(:,:,:,ith), rll(:,:,:,ith), tmat0(:,:), ncheb, npan_tot, lmmaxd, nvec*lmmaxd, &
            nsra*(1+korbit)*(lmax+1), irmdnew, nsra, jlk_index, hlk(:,:,ith), jlk(:,:,ith), hlk2(:,:,ith), jlk2(:,:,ith), gmatprefactor, '1', use_sratrick, alpha0(:,:))
          ! MdSD: check if these are actually needed except in rhovalnew
          if (calc_wronskian) then
            call sll_global_solutions(rpan_intervall, rnew, vnspll(:,:,:,ith), sll(:,:,:,ith), ncheb, npan_tot, lmmaxd, nvec*lmmaxd, &
             nsra*(1+korbit)*(lmax+1), irmdnew, nsra, jlk_index, hlk(:,:,ith), jlk(:,:,ith), hlk2(:,:,ith), jlk2(:,:,ith), gmatprefactor, '1', use_sratrick)
          end if
        end if
        ! MdSD: if using the old rllsll check if this is needed
        if (nsra==2) then
          rll(lmmaxd+1:nvec*lmmaxd, :, :, ith) = rll(lmmaxd+1:nvec*lmmaxd, :, :, ith)/cvlight
          sll(lmmaxd+1:nvec*lmmaxd, :, :, ith) = sll(lmmaxd+1:nvec*lmmaxd, :, :, ith)/cvlight
        end if
#ifdef CPP_OMP
        !$omp critical
#endif
#ifdef CPP_BdG
        if (write_BdG_tests) then
          write (filename, '(A,I0.3,A,I0.3,A)') 'rll_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,I9)') '# dimension: lmmaxd*nvec=', nvec*lmmaxd, ' lmmaxd=', lmmaxd, ' irmdnew=', irmdnew
          write (888888, '(2ES21.9)') rll(:, :, :, ith)
          close (888888)
          write (filename, '(A,I0.3,A,I0.3,A)') 'sll_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,I9)') '# dimension: lmmaxd*nvec=', nvec*lmmaxd, ' lmmaxd=', lmmaxd, ' irmdnew=', irmdnew
          write (888888, '(2ES21.9)') sll(:, :, :, ith)
          close (888888)
        end if
#endif
#ifdef CPP_OMP
        !$omp end critical
#endif

        ! add spherical contribution of tmatrix
        if (use_sratrick==1) then
          do lm1 = 1, lmmaxd
            tmat0(lm1, lm1) = tmat0(lm1, lm1) + tmatsph(jlk_index(lm1), ith)
          end do
          if (lly/=0) then
            do lm2 = 1, lmmaxd
              do lm1 = 1, lmmaxd
                ! alphasph is multiplied not added
                alpha0(lm1, lm2) = alphasph(jlk_index(lm1))*alpha0(lm1, lm2) ! LLY
              end do
            end do
          end if                   ! LLY
        end if
        tmatll(:, :) = tmatll(:, :) + tmat0(:, :)
        if (lly/=0) then
          alphall(:, :) = alphall(:, :) + alpha0(:, :)
          dtmatll(:, :) = dtmatll(:, :) + real(signde, kind=dp)*tmat0(:, :) ! LLY
          dalphall(:, :) = dalphall(:, :) + real(signde, kind=dp)*alpha0(:, :) ! LLY
        end if

#ifdef CPP_OMP
        !$omp critical
#endif
        if (write_tmat_all) then
          write (filename, '(A,I0.3,A,I0.3,A)') 'tmat_atom_', i1, '_energ_', ie, '.dat'
          open (888888, file=trim(filename), form='formatted')
          write (888888, '(A,I9,A,I9,A,2ES15.7)') '# dimension: lmmaxd=', lmmaxd, ' lmmaxd=', lmmaxd, ' ; ERYD=', eryd
          write (888888, '(2ES25.16)') tmatll(:, :)
          close (888888)
        end if
#ifdef CPP_OMP
        !$omp end critical
#endif

      end do                       ! signde=-ideriv,ideriv,2 ! lly

      ! Average values of t-matrix and alpha at e+de and e-de
      tmatll(:, :) = tmatll(:, :)/real(1+ideriv, kind=dp) ! LLY
      if (lly/=0) then
        alphall(:, :) = alphall(:, :)/real(1+ideriv, kind=dp) ! LLY
        ! Contruct derivative of t-matrix and alpha
        dtmatll(:, :) = dtmatll(:, :)/deltae ! LLY
        dalphall(:, :) = dalphall(:, :)/deltae ! LLY
      end if
      if (lly/=0) then
        ! calculate Tr[alpha^-1*dalpha/de] for LLoyd's formula
        alpha0 = czero             ! LLY
        aux = czero                ! LLY
        call zgeinv1(alphall, alpha0, aux, ipiv, lmmaxd)
        call zgemm('N','N',lmmaxd,lmmaxd,lmmaxd,cone,alpha0,lmmaxd,dalphall,    &
          lmmaxd,czero,aux,lmmaxd) ! LLY
        ! Trace of AUX
        tralpha = czero            ! LLY
        do lm1 = 1, lmmaxd
          tralpha = tralpha + aux(lm1, lm1) ! LLY
        end do
      end if                       ! LLY

      if (write_rhoq_input .and. ie==2) then
        ! read in mu0 atom index
        open (9999, file='mu0')
        read (9999, *) mu0, nscoef
        close (9999)
      end if

      !----------------------------------------------------------------------------
      ! Calculate the left-hand side solution
      !----------------------------------------------------------------------------
      if ( calculate_left(i1, ie) .or. &
           t_dtmatjij_at%calculate .or. &
           ((write_rhoq_input .and. ie==2) .and. (i1==mu0)) & ! rhoqtest
         ) then ! MdSD: seems to make more sense to check here than below
            
        ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        ! Calculate the left-hand side solution this needs to be done for the
        ! calculation of t-matrices for Jij tensor or if wavefunctions should be saved
        ! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        ! Contruct the spin-orbit coupling hamiltonian and add to potential
        call spinorbit_ham(lmax,lmmax0d,vins,rnew,eryd,zat,cvlight,socscale,nspin,   &
          lmpot,theta,phi,ipan_intervall,rpan_intervall,npan_tot,ncheb,irmdnew,     &
          nrmaxd,vnspll0(:,:,:),vnspll2(:,:,:),'transpose')
        
        ! Add magnetic field 
        if (t_params%bfield%lbfield) then
          call add_bfield(t_params%bfield,i1,lmax,nspin,irmdnew,imt1,iend,ncheb,theta,phi,t_params%ifunm1(:,t_params%ntcell(i1)),&
                          t_params%icleb,t_params%cleb(:,1),t_params%thetasnew(1:irmdnew,:,t_params%ntcell(i1)),'transpose',vnspll2(:,:,:), &
                          vnspll1(:,:,:,ith),t_params%bfield%thetallmat(:,:,1:irmdnew,t_params%ntcell(i1)))
        else
          vnspll1(:,:,:,ith) = vnspll2(:,:,:)
        end if

        ! Extend matrix for the SRA treatment
        vnspll(:, :, :, ith) = czero
        if (nsra==2) then
          if (use_sratrick==0) then
            call vllmatsra(vnspll1(:,:,:,ith),vnspll(:,:,:,ith),rnew,lmmaxd,       &
              irmdnew,nrmaxd,eryd,lmax,0,'Ref=0')
          else if (use_sratrick==1) then
            call vllmatsra(vnspll1(:,:,:,ith),vnspll(:,:,:,ith),rnew,lmmaxd,       &
              irmdnew,nrmaxd,eryd,lmax,0,'Ref=Vsph')
          end if
        else
          vnspll(:, :, :, ith) = vnspll1(:, :, :, ith)
        end if
        

        ! Calculate the source terms in the Lippmann-Schwinger equation
        ! these are spherical hankel and bessel functions
        hlk(:, :, ith) = czero
        jlk(:, :, ith) = czero
        hlk2(:, :, ith) = czero
        jlk2(:, :, ith) = czero
        gmatprefactor = czero
        jlk_index = 0
        call rllsllsourceterms(nsra, nvec, eryd, rnew, irmdnew, nrmaxd, lmax, lmmaxd, use_fullgmat, jlk_index, hlk(:,:,ith), jlk(:,:,ith), hlk2(:,:,ith), jlk2(:,:,ith), gmatprefactor)

        ! Using spherical potential as reference
        ! notice that exchange the order of left and right hankel/bessel functions
        if (use_sratrick==1) then
          tmatsph(:, ith) = czero
          call calcsph(nsra, irmdnew, nrmaxd, lmax, nspin/(nspin-korbit), zat, eryd, lmpot, lmmaxd, rnew, vins, ncheb, npan_tot, rpan_intervall, jlk_index, hlk2(:,:,ith), jlk2(:,:,ith), &
            hlk(:,:,ith), jlk(:,:,ith), gmatprefactor, alphasph, tmatsph(:,ith), use_sratrick, .true.)
        end if

        ! Calculate the tmat and wavefunctions
        rllleft(:, :, :, ith) = czero
        sllleft(:, :, :, ith) = czero

        ! Left solutions
        ! notice that exchange the order of left and right hankel/bessel functions
        tmat0 = czero
        alpha0 = czero             ! LLY
        if (use_rllsll) then
        ! MdSD: this is the old interface
          call rllsll(rpan_intervall, rnew, vnspll(:,:,:,ith), rllleft(:,:,:,ith), sllleft(:,:,:,ith), tmat0, ncheb, npan_tot, lmmaxd, nvec*lmmaxd, nsra*(1+korbit)*(lmax+1), irmdnew, nsra, &
            jlk_index, hlk2(:,:,ith), jlk2(:,:,ith), hlk(:,:,ith), jlk(:,:,ith), gmatprefactor, '1', '1', '0', use_sratrick, alpha0)
        else
          call rll_global_solutions(rpan_intervall, rnew, vnspll(:,:,:,ith), ull(:,:,:,ith), rllleft(:,:,:,ith), tmat0, ncheb, npan_tot, lmmaxd, nvec*lmmaxd, &
            nsra*(1+korbit)*(lmax+1), irmdnew, nsra, jlk_index, hlk2(:,:,ith), jlk2(:,:,ith), hlk(:,:,ith), jlk(:,:,ith), gmatprefactor, '1', use_sratrick, alpha0)
          ! MdSD: check if these are actually needed except in rhovalnew
          if (calc_wronskian) then
            call sll_global_solutions(rpan_intervall, rnew, vnspll(:,:,:,ith), sllleft(:,:,:,ith), ncheb, npan_tot, lmmaxd, nvec*lmmaxd, &
              nsra*(1+korbit)*(lmax+1), irmdnew, nsra, jlk_index, hlk2(:,:,ith), jlk2(:,:,ith), hlk(:,:,ith), jlk(:,:,ith), gmatprefactor, '1', use_sratrick)
          end if
        end if
        ! MdSD: if using the old rllsll check if this is needed
        if (nsra==2) then
          rllleft(lmmaxd+1:nvec*lmmaxd, :, :, ith) = rllleft(lmmaxd+1:nvec*lmmaxd, :, :, ith)/cvlight
          sllleft(lmmaxd+1:nvec*lmmaxd, :, :, ith) = sllleft(lmmaxd+1:nvec*lmmaxd, :, :, ith)/cvlight
        end if

        if (write_rhoq_input) then
#ifdef CPP_OMP
          write (*, *) 'rhoqtest does not work in OMP version!!'
          write (*, *) 'please use hybrid compilation mode'
          stop
#else
          open (9999, file='params.txt')
          write (9999, *) lmmaxd, t_params%natyp
          write (9999, *) t_params%naez, t_params%nclsd, t_params%nr, t_params%nembd1 - 1, t_params%lmax
          write (9999, *) t_params%alat
          close (9999)

          open (9999, file='host.txt')
          write (9999, *) t_params%rbasis(1:3, 1:t_params%natyp)
          write (9999, *) t_params%rcls(1:3, 1:t_params%nclsd, 1:t_params%nclsd),t_params%rr(1:3, 0:t_params%nr),t_params%atom(1:t_params%nclsd,1:t_params%naez+t_params%nembd1-1)
          write (9999, *) t_params%cls(1:t_params%naez+t_params%nembd1-1), t_params%ezoa(1:t_params%nclsd, 1:t_params%naez+t_params%nembd1-1), t_params%nacls(1:t_params%nclsd)
          close (9999)

          open (9999, file='wavefunctions.txt')
          write (9999, '(100I9)') ntotd, npan_tot, ncheb, nsra, irmdnew
          write (9999, '(1000E26.17)') rnew(1:irmdnew)
          do ir = 1, irmdnew
            do lm1 = 1, nsra*lmmaxd
              do lm2 = 1, lmmaxd
                write (9999, '(20000E16.7)') rll(lm1, lm2, ir, ith), rllleft(lm1, lm2, ir, ith)
              end do
            end do
          end do
          do lm1 = 0, npan_tot
            write (9999, '(E16.7,I9)') rpan_intervall(lm1), ipan_intervall(lm1)
          end do
          close (9999)
#endif
        end if                     ! write_rhoq_input

      end if                       ! t_dtmatJij_at%calculate .or. t_wavefunctions%Nwfsavemax>0
      !----------------------------------------------------------------------------
      ! Calculate the left-hand side solution
      !----------------------------------------------------------------------------

      ! save_wavefuncions
      if (t_wavefunctions%nwfsavemax>0) then
        ! here all four (left, right, regular and irregular) are stored, the memory demand cound be reduced by a factor 2 if only the right solution would be computed here and saved and the left solution would be calculated later in main1c
        call save_wavefunc(t_wavefunctions,rll,rllleft,sll,sllleft,i1,ie,nsra,      &
          lmmaxd,irmdnew,ith)
      end if

      if (t_dtmatjij_at%calculate) then
        call calc_dtmatjij(lmmax0d,lmmaxd,lmpot,ntotd,nrmaxd,nsra,irmdnew,nspin,    &
          vins,rllleft(:,:,:,ith),rll(:,:,:,ith),rpan_intervall,ipan_intervall,     &
          npan_tot,ncheb,cleb,icleb,iend,ncleb,rnew,t_dtmatjij_at%dtmat_xyz(:,:,:,ie_num))

      end if                       ! t_dtmatJij_at%calculate

      ! writeout
#ifdef CPP_OMP
      !$omp critical
#endif
      if (t_tgmat%tmat_to_file) then
#ifndef CPP_OMP
        if (write_rhoq_input) then

          if (ie_num==1 .and. i1==1) then
            write (*, *)           ! status bar
            write (*, *) 'rhoq: write-out t-mat', ie_end, t_params%natyp
            write (*, '("Loop over points:|",5(1X,I2,"%",5X,"|"),1X,I3,"%")') 0, 20, 40, 60, 80, 100
            write (*, fmt=100, advance='no') ! beginning of statusbar
          end if

          if (myrank==master) then
            if (t_params%natyp*ie_end>=50) then
              if (mod(i1+t_params%natyp*(ie_num-1),(t_params%natyp*ie_end/50))==0) write (6, fmt=110, advance='no')
            else
              write (6, fmt=110, advance='no')
            end if
          end if

          ! write(*,*) 'rotating with', theta, phi
          ! lmGF0D= (LMAXD+1)**2
          ! caLL ROTATEMATRIX(TMATLL,THETA,PHI,LMGF0D,0)

        end if                     ! write_rhoq_input
#endif
        irec = ie + ielast*(ispin-1) + ielast*nspin/(1+korbit)*(i1-1)
        ! this test writeout maybe helps to get rid of issue #114
        if (t_inc%i_write>0) write(1337,*) 'writing tmat to file', ie, ispin, i1, shape(tmatll)
        write (69, rec=irec) tmatll(:, :)
        ! human readable writeout if test option is hit
        if (formatted_file) then
          write (696969, '(i9,20000F15.7)') irec, tmatll(:, :)
        end if
      else
#ifdef CPP_MPI
        i11 = i1-t_mpi_c_grid%ioff_pt1(t_mpi_c_grid%myrank_ie)
#else
        i11 = i1
#endif
        irec = ie_num + ie_end*(ispin-1) + ie_end*nspin/(1+korbit)*(i11-1)
        t_tgmat%tmat(:, :, irec) = tmatll(:, :)
      end if
      if (lly/=0) then
        if (t_lloyd%dtmat_to_file) then
          irec = ie + ielast*(ispin-1) + ielast*nspin/(1+korbit)*(i1-1)
          write (691, rec=irec) dtmatll(:, :) ! LLY
          if (formatted_file) then
            write (691691691, '(i9,20000F15.7)') irec, dtmatll(:, :)
          end if
        else
          irec = ie_num + ie_end*(ispin-1) + ie_end*nspin/(1+korbit)*(i1-1)
          t_lloyd%dtmat(:, :, irec) = dtmatll(:, :)
        end if
        if (t_lloyd%tralpha_to_file) then
          irec = ie + ielast*(ispin-1) + ielast*nspin/(1+korbit)*(i1-1)
          write (692, rec=irec) tralpha ! LLY
          if (formatted_file) then
            write (692692692, '(i9,20000F15.7)') irec, tralpha
          end if
        else
          irec = ie_num + ie_end*(ispin-1) + ie_end*nspin/(1+korbit)*(i1-1)
          t_lloyd%tralpha(irec) = tralpha
        end if
      end if
#ifdef CPP_OMP
      !$omp end critical
#endif

#ifdef CPP_MPI
      ! stop timing measurement for this pair of ie and i1, needed for MPIadapt
      if (mpiadapt>0) call timing_stop('time_1a_ieiatom', save_out=timings_1a(ie,i1))
#endif

      !#######################################################
      ! Calculation of the Wronskian. Just for nummerical checks
      !#######################################################
      if ( calc_wronskian ) then
        open(9999, file='test_rmesh', form='formatted')
        write(9999, '(50000E26.17)') rnew(1:irmdnew)
        close(9999)
        if (korbit==1) then
          call calcwronskian(rll(:,:,:,ith), sll(:,:,:,ith), rllleft(:,:,:,ith), sllleft(:,:,:,ith), &
            ncheb, npan_tot, ipan_intervall, rpan_intervall)
        else
          call calcwronskian(rll(:,:,:,ith), sll(:,:,:,ith), rll(:,:,:,ith), sll(:,:,:,ith), &
            ncheb, npan_tot, ipan_intervall, rpan_intervall)
        end if
        stop
      end if

    end do                         ! IE loop
#ifdef CPP_OMP
    !$omp end parallel do
#endif

100 format ('                 |')  ! status bar
110 format ('|')                   ! status bar
    if (write_rhoq_input .and. i1==t_params%natyp .and. myrank==master) write (6, *) ! status bar
    ! finished kpts status bar

    ! deallocate arrays
    call allocate_locals_tmat_newsolver(-1,irmdnew,lmpot,nspin,vins,aux,ipiv,tmat0, &
      tmatll,alpha0,dtmatll,alphall,dalphall,jlk_index,nsra,lmmaxd,nth,lmax,vnspll,&
      vnspll0,vnspll1,vnspll2,hlk,jlk,hlk2,jlk2,tmatsph,ull,rll,sll,rllleft,sllleft)

  end subroutine tmat_newsolver


  !-------------------------------------------------------------------------------
  !> Summary: Wrapper routine for the allocation/deallocation of the arrays for the t-matrix
  !> calculation 
  !> Author: Philipp Ruessmann
  !> Category: single-site, profiling, KKRhost
  !> Deprecated: False 
  !> Wrapper routine for the allocation/deallocation of the arrays for the t-matrix
  !> calculation.
  !-------------------------------------------------------------------------------
  subroutine allocate_locals_tmat_newsolver(allocmode,irmdnew,lmpot,nspin,vins,aux, &
    ipiv,tmat0,tmatll,alpha0,dtmatll,alphall,dalphall,jlk_index,nsra,lmmaxd,nth,   &
    lmax,vnspll,vnspll0,vnspll1,vnspll2,hlk,jlk,hlk2,jlk2,tmatsph,ull,rll,sll,rllleft,sllleft)
    use :: mod_datatypes, only: dp
    use :: mod_runoptions, only: calc_exchange_couplings, write_rhoq_input, calc_wronskian
    use :: mod_constants, only: czero
    use :: global_variables, only: korbit
    use :: mod_profiling, only: memocc
    use :: mod_save_wavefun, only: t_wavefunctions
    implicit none

    ! array dimensions
    integer, intent (in) :: allocmode !! allocation mode (1: allocate and initialize, other: deallocate)
    integer, intent (in) :: irmdnew   !! number of radial points in Chebycheb mesh
    integer, intent (in) :: lmpot     !! lm-cutoff of potential expansion
    integer, intent (in) :: nspin     !! number of spin channels
    integer, intent (in) :: nsra      !! scalar-relativistic (nsra=2) or non-relativistic (nsra=1)
    integer, intent (in) :: lmmaxd   !! cutoff of combined (l,m,s) index
    integer, intent (in) :: nth       !! number of OpenMP threads
    integer, intent (in) :: lmax      !! lmax cutoff

    ! allocatable arrays
    real (kind=dp), allocatable, intent (inout) :: vins(:, :, :)
    complex (kind=dp), allocatable, intent (inout) :: aux(:, :), tmat0(:, :), tmatll(:, :), alpha0(:, :), dtmatll(:, :), alphall(:, :), dalphall(:, :)
    integer, allocatable, intent (inout) :: ipiv(:), jlk_index(:)
    complex (kind=dp), allocatable, dimension (:, :, :, :), intent (inout) :: vnspll
    complex (kind=dp), allocatable, dimension (:, :, :), intent (inout) :: vnspll0
    complex (kind=dp), allocatable, dimension (:, :, :, :), intent (inout) :: vnspll1
    complex (kind=dp), allocatable, dimension (:, :, :), intent (inout) :: vnspll2
    complex (kind=dp), allocatable, dimension (:, :, :), intent (inout) :: jlk
    complex (kind=dp), allocatable, dimension (:, :, :), intent (inout) :: hlk
    complex (kind=dp), allocatable, dimension (:, :, :), intent (inout) :: jlk2
    complex (kind=dp), allocatable, dimension (:, :, :), intent (inout) :: hlk2
    complex (kind=dp), allocatable, dimension (:, :), intent (inout) :: tmatsph
    complex (kind=dp), allocatable, dimension (:, :, :, :), intent (inout) :: ull
    complex (kind=dp), allocatable, dimension (:, :, :, :), intent (inout) :: rll
    complex (kind=dp), allocatable, dimension (:, :, :, :), intent (inout) :: sll
    complex (kind=dp), allocatable, dimension (:, :, :, :), intent (inout) :: rllleft
    complex (kind=dp), allocatable, dimension (:, :, :, :), intent (inout) :: sllleft

    ! local
    integer :: i_stat



    if (allocmode==1) then ! allocate and initialize

      ! potential arrays
      allocate (vnspll(nsra*lmmaxd,nsra*lmmaxd,irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(vnspll))*kind(vnspll), 'VNSPLL', 'allocate_locals_tmat_newsolver')
      vnspll = czero
      allocate (vnspll0(lmmaxd,lmmaxd,irmdnew), stat=i_stat)
      call memocc(i_stat, product(shape(vnspll0))*kind(vnspll0), 'VNSPLL0', 'allocate_locals_tmat_newsolver')
      vnspll0 = czero
      allocate (vnspll1(lmmaxd,lmmaxd,irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(vnspll1))*kind(vnspll1), 'VNSPLL1', 'allocate_locals_tmat_newsolver')
      vnspll1 = czero
      allocate (vnspll2(lmmaxd,lmmaxd,irmdnew), stat=i_stat)
      call memocc(i_stat, product(shape(vnspll2))*kind(vnspll2), 'VNSPLL2', 'allocate_locals_tmat_newsolver')
      vnspll2 = czero

      ! source terms (bessel and hankel functions)
      allocate (hlk(1:nsra*(1+korbit)*(lmax+1),irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(hlk))*kind(hlk), 'HLK', 'allocate_locals_tmat_newsolver')
      hlk = czero
      allocate (jlk(1:nsra*(1+korbit)*(lmax+1),irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(jlk))*kind(jlk), 'JLK', 'allocate_locals_tmat_newsolver')
      jlk = czero
      allocate (hlk2(1:nsra*(1+korbit)*(lmax+1),irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(hlk2))*kind(hlk2), 'HLK2', 'allocate_locals_tmat_newsolver')
      hlk2 = czero
      allocate (jlk2(1:nsra*(1+korbit)*(lmax+1),irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(jlk2))*kind(jlk2), 'JLK2', 'allocate_locals_tmat_newsolver')
      jlk2 = czero

      ! Spherical part of tmatrix (used with SRATRICK)
      allocate (tmatsph(nspin*(lmax+1),0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(tmatsph))*kind(tmatsph), 'TMATSPH', 'allocate_locals_tmat_newsolver')
      tmatsph = czero

      ! Regular and irregular wavefunctions
      allocate (ull(nsra*lmmaxd,lmmaxd,irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(ull))*kind(ull), 'ULL', 'allocate_locals_tmat_newsolver')
      ull = czero
      allocate (rll(nsra*lmmaxd,lmmaxd,irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(rll))*kind(rll), 'RLL', 'allocate_locals_tmat_newsolver')
      rll = czero
      allocate (sll(nsra*lmmaxd,lmmaxd,irmdnew,0:nth-1), stat=i_stat)
      call memocc(i_stat, product(shape(sll))*kind(sll), 'SLL', 'allocate_locals_tmat_newsolver')
      sll = czero

      ! Left regular and irregular wavefunctions (used here only in case of XCPL or saving of left wavefunctions)
      if (calculate_left(-1, -1)) then
        allocate (rllleft(nsra*lmmaxd,lmmaxd,irmdnew,0:nth-1), stat=i_stat)
        call memocc(i_stat, product(shape(rllleft))*kind(rllleft), 'RLLLEFT', 'allocate_locals_tmat_newsolver')
        rllleft = czero
        allocate (sllleft(nsra*lmmaxd,lmmaxd,irmdnew,0:nth-1), stat=i_stat)
        call memocc(i_stat, product(shape(sllleft))*kind(sllleft), 'SLLLEFT', 'allocate_locals_tmat_newsolver')
        sllleft = czero
      else
        allocate (rllleft(1,1,1,0:nth-1), stat=i_stat)
        call memocc(i_stat, product(shape(rllleft))*kind(rllleft), 'RLLLEFT', 'allocate_locals_tmat_newsolver')
        rllleft = czero
        allocate (sllleft(1,1,1,0:nth-1), stat=i_stat)
        call memocc(i_stat, product(shape(sllleft))*kind(sllleft), 'SLLLEFT', 'allocate_locals_tmat_newsolver')
        sllleft = czero
      end if                       ! ( calc_exchange_couplings .or. ... )

      allocate (vins(irmdnew,lmpot,nspin), stat=i_stat)
      call memocc(i_stat, product(shape(vins))*kind(vins), 'VINS', 'allocate_locals_tmat_newsolver')
      vins = 0.0_dp
      allocate (aux(lmmaxd,lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(aux))*kind(aux), 'AUX', 'allocate_locals_tmat_newsolver')
      aux = czero
      allocate (ipiv(lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(ipiv))*kind(ipiv), 'IPIV', 'allocate_locals_tmat_newsolver')
      ipiv = 0
      allocate (tmat0(lmmaxd,lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(tmat0))*kind(tmat0), 'TMAT0', 'allocate_locals_tmat_newsolver')
      tmat0 = czero
      allocate (tmatll(lmmaxd,lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(tmatll))*kind(tmatll), 'TMATLL', 'allocate_locals_tmat_newsolver')
      tmatll = czero
      allocate (alpha0(lmmaxd,lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(alpha0))*kind(alpha0), 'ALPHA0', 'allocate_locals_tmat_newsolver')
      alpha0 = czero
      allocate (dtmatll(lmmaxd,lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(dtmatll))*kind(dtmatll), 'DTMATLL', 'allocate_locals_tmat_newsolver')
      dtmatll = czero
      allocate (alphall(lmmaxd,lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(alphall))*kind(alphall), 'ALPHALL', 'allocate_locals_tmat_newsolver')
      alphall = czero
      allocate (dalphall(lmmaxd,lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(dalphall))*kind(dalphall), 'DALPHALL', 'allocate_locals_tmat_newsolver')
      dalphall = czero
      allocate (jlk_index(nsra*lmmaxd), stat=i_stat)
      call memocc(i_stat, product(shape(jlk_index))*kind(jlk_index), 'JLK_INDEX', 'allocate_locals_tmat_newsolver')
      jlk_index = 0

    else ! allocmode/=1: deallocate arrays

      if (nsra==2) then
        deallocate (vnspll, stat=i_stat)
        call memocc(i_stat, -product(shape(vnspll))*kind(vnspll), 'VNSPLL', 'allocate_locals_tmat_newsolver')
      else
        deallocate (vnspll, stat=i_stat)
        call memocc(i_stat, -product(shape(vnspll))*kind(vnspll), 'VNSPLL', 'allocate_locals_tmat_newsolver')
      end if
      deallocate (vnspll0, stat=i_stat)
      call memocc(i_stat, -product(shape(vnspll0))*kind(vnspll0), 'VNSPLL0', 'allocate_locals_tmat_newsolver')
      deallocate (vnspll1, stat=i_stat)
      call memocc(i_stat, -product(shape(vnspll1))*kind(vnspll1), 'VNSPLL1', 'allocate_locals_tmat_newsolver')
      deallocate (vnspll2, stat=i_stat)
      call memocc(i_stat, -product(shape(vnspll2))*kind(vnspll2), 'VNSPLL1', 'allocate_locals_tmat_newsolver')

      deallocate (hlk, stat=i_stat)
      call memocc(i_stat, -product(shape(hlk))*kind(hlk), 'HLK', 'allocate_locals_tmat_newsolver')
      deallocate (jlk, stat=i_stat)
      call memocc(i_stat, -product(shape(jlk))*kind(jlk), 'JLK', 'allocate_locals_tmat_newsolver')
      deallocate (hlk2, stat=i_stat)
      call memocc(i_stat, -product(shape(hlk2))*kind(hlk2), 'HLK2', 'allocate_locals_tmat_newsolver')
      deallocate (jlk2, stat=i_stat)
      call memocc(i_stat, -product(shape(jlk2))*kind(jlk2), 'JLK2', 'allocate_locals_tmat_newsolver')

      deallocate (tmatsph, stat=i_stat)
      call memocc(i_stat, -product(shape(tmatsph))*kind(tmatsph), 'TMATSPH', 'allocate_locals_tmat_newsolver')

      deallocate (ull, stat=i_stat)
      call memocc(i_stat, -product(shape(ull))*kind(ull), 'ULL', 'allocate_locals_tmat_newsolver')
      deallocate (rll, stat=i_stat)
      call memocc(i_stat, -product(shape(rll))*kind(rll), 'RLL', 'allocate_locals_tmat_newsolver')
      deallocate (sll, stat=i_stat)
      call memocc(i_stat, -product(shape(sll))*kind(sll), 'SLL', 'allocate_locals_tmat_newsolver')

      if (calculate_left(-1, -1)) then
        deallocate (rllleft, stat=i_stat)
        call memocc(i_stat, -product(shape(rllleft))*kind(rllleft), 'RLLLEFT', 'allocate_locals_tmat_newsolver')
        deallocate (sllleft, stat=i_stat)
        call memocc(i_stat, -product(shape(sllleft))*kind(sllleft), 'SLLLEFT', 'allocate_locals_tmat_newsolver')
      else
        deallocate (rllleft, stat=i_stat)
        call memocc(i_stat, -product(shape(rllleft))*kind(rllleft), 'RLLLEFT', 'allocate_locals_tmat_newsolver')
        deallocate (sllleft, stat=i_stat)
        call memocc(i_stat, -product(shape(sllleft))*kind(sllleft), 'SLLLEFT', 'allocate_locals_tmat_newsolver')
      end if                       ! ( calc_exchange_couplings .or. ... )

      deallocate (vins, stat=i_stat)
      call memocc(i_stat, -product(shape(vins))*kind(vins), 'VINS', 'allocate_locals_tmat_newsolver')
      deallocate (aux, stat=i_stat)
      call memocc(i_stat, -product(shape(aux))*kind(aux), 'AUX', 'allocate_locals_tmat_newsolver')
      deallocate (ipiv, stat=i_stat)
      call memocc(i_stat, -product(shape(ipiv))*kind(ipiv), 'IPIV', 'allocate_locals_tmat_newsolver')
      deallocate (tmat0, stat=i_stat)
      call memocc(i_stat, -product(shape(tmat0))*kind(tmat0), 'TMAT0', 'allocate_locals_tmat_newsolver')
      deallocate (tmatll, stat=i_stat)
      call memocc(i_stat, -product(shape(tmatll))*kind(tmatll), 'TMATLL', 'allocate_locals_tmat_newsolver')
      deallocate (alpha0, stat=i_stat)
      call memocc(i_stat, -product(shape(alpha0))*kind(alpha0), 'ALPHA0', 'allocate_locals_tmat_newsolver')
      deallocate (dtmatll, stat=i_stat)
      call memocc(i_stat, -product(shape(dtmatll))*kind(dtmatll), 'DTMATLL', 'allocate_locals_tmat_newsolver')
      deallocate (alphall, stat=i_stat)
      call memocc(i_stat, -product(shape(alphall))*kind(alphall), 'ALPHALL', 'allocate_locals_tmat_newsolver')
      deallocate (dalphall, stat=i_stat)
      call memocc(i_stat, -product(shape(dalphall))*kind(dalphall), 'DALPHALL', 'allocate_locals_tmat_newsolver')
      deallocate (jlk_index, stat=i_stat)
      call memocc(i_stat, -product(shape(jlk_index))*kind(jlk_index), 'JLK_INDEX', 'allocate_locals_tmat_newsolver')

    end if ! allocmode ==1 or /=1

  end subroutine allocate_locals_tmat_newsolver


  !-------------------------------------------------------------------------------
  !> Summary: Helper function which tells if the left wave functions are needed
  !> calculation 
  !> Author: Philipp Ruessmann
  !> Category: single-site, profiling, KKRhost
  !> Deprecated: False 
  !> 
  !-------------------------------------------------------------------------------
  logical function calculate_left(i1, ie)
    
    use :: mod_save_wavefun, only: t_wavefunctions
    use :: mod_runoptions, only: calc_wronskian, write_pkkr_operators, calc_exchange_couplings, write_rhoq_input
    use :: mod_types, only: type_dtmatjijdij
    implicit None
    integer, intent(in) :: i1, ie

    calculate_left = .false.
    if ( calc_exchange_couplings &
       .or. &
         write_pkkr_operators &
       .or. &
         calc_wronskian &
      ) then
      calculate_left = .true.
    end if

    if ( (t_wavefunctions%save_rllleft .or. t_wavefunctions%save_sllleft) ) then
      if (ie<0 .or. i1<0) then
        ! need special case for alloc/dealloc routines
        calculate_left = .true.
      elseif ( t_wavefunctions%isave_wavefun(i1,ie)>0 ) then
        calculate_left = .true.
      end if
    end if

    return

  end function calculate_left

end module mod_tmatnewsolver