!-----------------------------------------------------------------------------------------! ! 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: Calculate the reference system for the decimation case !> Author: !> Calculate the reference system for the decimation case. !------------------------------------------------------------------------------------ module mod_tbref contains !------------------------------------------------------------------------------- !> Summary: Calculate the reference system for the decimation case !> Author: !> Category: reference-system, structural-greensfunction, single-site, KKRhost !> Deprecated: False !> Calculate the reference system for the decimation case. !------------------------------------------------------------------------------- subroutine tbref(ez,ielast,alatc,vref,iend,lmax,ncls,nineq,nref,cleb,rcls,atom, & cls,icleb,loflm,nacls,refpot,rmtref,tolrdif,tmpdir,itmpdir,iltmp,naez,lly) use :: mod_mympi, only: myrank, nranks, master, distribute_work_atoms use :: mod_types, only: t_tgmat, t_lloyd, t_inc use :: mod_types, only: t_mpi_c_grid, init_tgmat, init_tlloyd #ifdef CPP_MPI use :: mpi use :: mod_mympi, only: find_dims_2d #endif use :: mod_constants use :: mod_runoptions, only: formatted_file, print_program_flow, write_green_imp use :: mod_profiling, only: memocc use :: global_variables, only: lmgf0d, wlength, naezd, nembd, lm2d, nclsd, naclsd, ncleb, iemxd use :: mod_datatypes, only: dp use :: mod_calctref13, only: calctref13 use :: mod_getscratch, only: opendafile use :: mod_gll13, only: gll13 implicit none ! .. Input variables integer, intent (in) :: lly !! LLY <> 0 : alpply Lloyds formula integer, intent (in) :: iend integer, intent (in) :: lmax !! Maximum l component in wave function expansion integer, intent (in) :: ncls !! Number of reference clusters integer, intent (in) :: nref !! Number of diff. ref. potentials integer, intent (in) :: naez !! Number of atoms in unit cell integer, intent (in) :: nineq !! Number of ineq. positions in unit cell integer, intent (in) :: ielast real (kind=dp), intent (in) :: alatc real (kind=dp), intent (in) :: tolrdif !! For distance between scattering-centers smaller than [<TOLRDIF>], free GF is set to zero. Units are Bohr radii. integer, dimension (naezd+nembd), intent (in) :: cls !! Cluster around atomic sites integer, dimension (lm2d), intent (in) :: loflm !! l of lm=(l,m) (GAUNT) integer, dimension (nclsd), intent (in) :: nacls !! Number of atoms in cluster integer, dimension (naezd+nembd), intent (in) :: refpot !! Ref. pot. card at position integer, dimension (naclsd, naezd+nembd), intent (in) :: atom !! Atom at site in cluster integer, dimension (ncleb, 4), intent (in) :: icleb !! Pointer array real (kind=dp), dimension (nref), intent (in) :: vref real (kind=dp), dimension (nref), intent (in) :: rmtref !! Muffin-tin radius of reference system real (kind=dp), dimension (ncleb, 2), intent (in) :: cleb !! GAUNT coefficients (GAUNT) real (kind=dp), dimension (3, naclsd, nclsd), intent (in) :: rcls !! Real space position of atom in cluster ! .. In/Out variables integer, intent (inout) :: iltmp integer, intent (inout) :: itmpdir character (len=80), intent (inout) :: tmpdir complex (kind=dp), dimension (iemxd), intent (inout) :: ez ! .. Local variables integer :: i1, ic, icls, ie, lm1, naclsmax, lrecgrf, i_stat, i_all complex (kind=dp) :: eryd complex (kind=dp) :: lly_g0tr_ie ! LLY complex (kind=dp) :: lly_g0tr_dum ! LLY dummy variable used if no LLY is chosen to save memory ! .. Local Arrays complex (kind=dp), dimension (0:lmax, nref) :: alpharef ! LLY Lloyd Alpha matrix complex (kind=dp), dimension (0:lmax, nref) :: dalpharef ! LLY Derivative of the Lloyd Alpha matrix complex (kind=dp), dimension (lmgf0d, lmgf0d, nref) :: trefll ! LLY complex (kind=dp), dimension (lmgf0d, lmgf0d, nref) :: dtrefll ! LLY ! .. Local allocatable arrays complex (kind=dp), dimension (:, :), allocatable :: lly_g0tr ! LLY complex (kind=dp), dimension (:, :), allocatable :: dginp_dum ! LLY dummy variable used if no LLY is chosen to save memory complex (kind=dp), dimension (:, :, :), allocatable :: ginp complex (kind=dp), dimension (:, :, :), allocatable :: dginp #ifdef CPP_MPI ! .. ! .. MPI variables integer :: ntot1, idim integer, dimension (0:nranks-1) :: ntot_pt, ioff_pt complex (kind=dp), dimension (:, :, :), allocatable :: work #endif integer :: ie_start, ie_end integer :: i1_start, i1_end integer :: ie_num, ierr ! .. ! .. External Functions .. naclsmax = 1 do ic = 1, ncls if (nacls(ic)>naclsmax) naclsmax = nacls(ic) end do lrecgrf = wlength*4*naclsmax*lmgf0d*lmgf0d*ncls ! allocate and initialize ginp allocate (ginp(naclsmax*lmgf0d,lmgf0d,ncls), stat=i_stat) call memocc(i_stat, product(shape(ginp))*kind(ginp), 'GINP', 'TBREF') ginp = czero allocate (dginp_dum(naclsmax*lmgf0d,lmgf0d), stat=i_stat) call memocc(i_stat, product(shape(dginp_dum))*kind(dginp_dum), 'dginp_dum', 'TBREF') dginp_dum = czero if (lly/=0) then ! allocate and initialize dginp and lly_g0tr allocate (dginp(naclsmax*lmgf0d,lmgf0d,ncls), stat=i_stat) call memocc(i_stat, product(shape(dginp))*kind(dginp), 'DGINP', 'TBREF') dginp = czero allocate (lly_g0tr(ielast,nclsd), stat=i_stat) call memocc(i_stat, product(shape(lly_g0tr))*kind(lly_g0tr), 'LLY_G0TR', 'TBREF') lly_g0tr = czero end if if (t_tgmat%gref_to_file) then call opendafile(68, 'gref', 4, lrecgrf, tmpdir, itmpdir, iltmp) end if if (lly/=0) then if (t_lloyd%dgref_to_file) then call opendafile(681, 'dgrefde', 7, lrecgrf, tmpdir, itmpdir, iltmp) end if if (t_lloyd%g0tr_to_file) then open (682, file='lly_g0tr_ie.ascii', form='FORMATTED') end if end if ! ---------------------------------------------------------------------------- if (t_inc%i_write>0) write (1337, *) myrank, 'start tbref e-loop' ! get share of energy loop done by each rank #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) ! start energy loop do ie_num = 1, ie_end ie = ie_start + ie_num if (t_inc%i_write>0) write (1337, fmt='(A23,I5,2F14.8)') 'TBREF: GREF for energy:', ie, ez(ie) ! reset arrays to zero (needed in case of MPIatom energy/atom distribution ginp(:, :, :) = czero if (lly>0) then dginp(:, :, :) = czero lly_g0tr(ie, :) = czero dginp_dum = czero lly_g0tr_dum = czero end if ! skip this part with GREENIMP option if (write_green_imp) then if (myrank==master) write (*, *) 'Skipping atom loop in tbref for energy point', ie, 'of', ielast i1_start = 1 i1_end = 0 else i1_start = 1 i1_end = nref end if eryd = ez(ie) do i1 = i1_start, i1_end ! 1,NREF call calctref13(eryd, vref(i1), rmtref(i1), lmax, lm1 & ! LLY Lloyd , trefll(1,1,i1), dtrefll(1,1,i1), & ! LLY Lloyd alpharef(0,i1), dalpharef(0,i1), lmax+1, lmgf0d) ! LLY Lloyd if (print_program_flow .and. (t_inc%i_write>0)) write (1337, fmt=*) 'tll(ref), i1 = ', i1 end do if (print_program_flow .and. (t_inc%i_write>0)) write (1337, fmt=*) 't-mat(Ref) o.k.', ie ! ---------------------------------------------------------------------- ! distribute NCLS loop over atom ranks call distribute_work_atoms(ncls, i1_start, i1_end, distribute_rest=.false.) ! overwrite to skip this part with GREENIMP option if (write_green_imp) then i1_start = 1 i1_end = 0 end if do icls = i1_start, i1_end i1 = 1 ic = 0 do while (ic==0 .and. i1<=nineq) if (cls(i1)==icls) ic = i1 i1 = i1 + 1 end do if (ic==0) stop 'Error in CLS(*) array in tbref' if (print_program_flow .and. (t_inc%i_write>0)) then write (1337, fmt=*) 'CLUSTER ', icls, ' at ATOM ', ic end if call gll13(eryd,cleb(1,2),icleb,loflm,iend,trefll,dtrefll,atom(1,ic),refpot,& rcls(1,1,icls),nacls(icls),tolrdif,alatc,0,ginp(1,1,icls),dginp_dum, & naclsmax,lly_g0tr_dum,lly) ! copy from dummy variable to arrays if (lly/=0) then dginp(:, :, icls) = dginp_dum(:, :) lly_g0tr(ie, icls) = lly_g0tr_dum end if end do ! icls #ifdef CPP_MPI if (t_mpi_c_grid%nranks_ie>1) then ! gather results of ginp, dginp and lly_g0tr from above parallel loop idim = naclsmax*lmgf0d*lmgf0d*ncls allocate (work(naclsmax*lmgf0d,lmgf0d,ncls), stat=i_stat) call memocc(i_stat, product(shape(work))*kind(work), 'work', 'TBREF') call mpi_allreduce(ginp,work,idim,mpi_double_complex,mpi_sum, & t_mpi_c_grid%mympi_comm_ie,ierr) call zcopy(idim, work, 1, ginp, 1) i_all = -product(shape(work))*kind(work) deallocate (work, stat=i_stat) call memocc(i_stat, i_all, 'work', 'TBREF') if (lly/=0) then idim = naclsmax*lmgf0d*lmgf0d*ncls allocate (work(naclsmax*lmgf0d,lmgf0d,ncls), stat=i_stat) call memocc(i_stat, product(shape(work))*kind(work), 'work', 'TBREF') call mpi_allreduce(dginp,work,idim,mpi_double_complex,mpi_sum, & t_mpi_c_grid%mympi_comm_ie,ierr) call zcopy(idim, work, 1, dginp, 1) i_all = -product(shape(work))*kind(work) deallocate (work, stat=i_stat) call memocc(i_stat, i_all, 'work', 'TBREF') idim = ncls allocate (work(nclsd,1,1), stat=i_stat) call memocc(i_stat, product(shape(work))*kind(work), 'work', 'TBREF') call mpi_allreduce(lly_g0tr(ie,:),work,idim,mpi_double_complex,mpi_sum, & t_mpi_c_grid%mympi_comm_ie,ierr) call zcopy(idim, work, 1, lly_g0tr(ie,:), 1) i_all = -product(shape(work))*kind(work) deallocate (work, stat=i_stat) call memocc(i_stat, i_all, 'work', 'TBREF') end if end if ! t_mpi_c_grid%nranks_ie>1 #endif if (lly/=0) then ! LLY Lloyd lly_g0tr_ie = czero ! LLY Lloyd do i1 = 1, naez ! LLY Lloyd icls = cls(i1) ! LLY Lloyd lly_g0tr_ie = lly_g0tr_ie + lly_g0tr(ie, icls) ! LLY Lloyd end do ! LLY Lloyd end if ! LLY Lloyd ! ---------------------------------------------------------------------- if (t_tgmat%gref_to_file) then #ifdef CPP_MPI ! make sure only one processor writes for one energy point if (t_mpi_c_grid%myrank_ie==0) then write (68, rec=ie) ginp ! Gref end if ! if(t_mpi_c_grid%myrank_ie==0) then ! human readable writeout if test option is hit if (formatted_file) then ! test writeout do i1 = 0, nranks - 1 if (myrank==i1) then write (686868+myrank, *) myrank, ie write (686868+myrank, '(2ES21.9)') ginp end if call mpi_barrier(t_mpi_c_grid%mympi_comm_ie, ierr) end do ! end test writeout end if #else write (68, rec=ie) ginp ! Gref #endif else ! (t_tgmat%gref_to_file) t_tgmat%gref(:, :, :, ie_num) = ginp(:, :, :) end if ! (t_tgmat%gref_to_file) ! store result either to file or in memory if (lly/=0) then ! LLY Lloyd if (t_lloyd%dgref_to_file) then ! LLY Lloyd write (681, rec=ie) dginp ! dGref/dE ! LLY Lloyd if (formatted_file) then write (681681, '(i9,200000ES15.7)') ie, dginp end if else ! LLY Lloyd t_lloyd%dgref(:, :, :, ie_num) = dginp(:, :, :) ! LLY Lloyd end if ! LLY Lloyd if (t_lloyd%g0tr_to_file) then ! LLY Lloyd write (682, fmt='(2E24.16)') lly_g0tr_ie ! LLY Lloyd if (formatted_file) then write (682682, '(i9,200000ES15.7)') ie_num, lly_g0tr_ie end if else ! LLY Lloyd t_lloyd%g0tr(ie_num) = lly_g0tr_ie ! LLY Lloyd end if ! LLY Lloyd end if ! LLY.NE.0 ! LLY Lloyd if (print_program_flow .and. (t_inc%i_write>0)) write (1337, fmt=*) 'G(n,lm,n,lm) (Ref) o.k.' end do ! IE ! ---------------------------------------------------------------------------- if (t_tgmat%gref_to_file) then close (68) end if if (lly/=0 .and. t_lloyd%dgref_to_file) close (681) if (lly/=0 .and. t_lloyd%g0tr_to_file) close (682) i_all = -product(shape(ginp))*kind(ginp) deallocate (ginp, stat=i_stat) call memocc(i_stat, i_all, 'GINP', 'TBREF') if (lly/=0) then i_all = -product(shape(dginp))*kind(dginp) deallocate (dginp, stat=i_stat) call memocc(i_stat, i_all, 'DGINP', 'TBREF') i_all = -product(shape(lly_g0tr))*kind(lly_g0tr) deallocate (lly_g0tr, stat=i_stat) call memocc(i_stat, i_all, 'LLY_G0TR', 'TBREF') end if end subroutine tbref end module mod_tbref