LCOV - code coverage report
Current view: top level - cdn - cdntot.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 90 120 75.0 %
Date: 2024-04-27 04:44:07 Functions: 3 5 60.0 %

          Line data    Source code
       1             : MODULE m_cdntot
       2             : #ifdef CPP_MPI
       3             :    use mpi
       4             : #endif
       5             : !     ********************************************************
       6             : !     calculate the total charge density in the interstial.,
       7             : !     vacuum, and mt regions      c.l.fu
       8             : !     ********************************************************
       9             : CONTAINS
      10        1531 :    SUBROUTINE integrate_cdn(stars,nococonv,atoms,sym,vacuum,input,cell , integrand, &
      11        1531 :                                    q, qis, qmt, qvac, qtot, qistot, fmpi)
      12             :       ! if called with fmpi variable, distribute the calculation of the pwint 
      13             :       ! over fmpi processes in fmpi%mpi_comm
      14             :       USE m_intgr, ONLY : intgr3
      15             :       USE m_constants
      16             :       USE m_qsf
      17             :       USE m_pwint
      18             :       USE m_types
      19             :       USE m_juDFT
      20             :       IMPLICIT NONE
      21             :       TYPE(t_stars),INTENT(IN)  :: stars
      22             :       TYPE(t_nococonv),INTENT(IN):: nococonv
      23             :       TYPE(t_atoms),INTENT(IN)  :: atoms
      24             :       TYPE(t_sym),INTENT(IN)    :: sym
      25             :       TYPE(t_vacuum),INTENT(IN) :: vacuum
      26             :       TYPE(t_input),INTENT(IN)  :: input
      27             :       TYPE(t_cell),INTENT(IN)   :: cell
      28             :        
      29             :       TYPE(t_potden),INTENT(IN) :: integrand
      30             :       REAL, INTENT(OUT)         :: q(input%jspins), qis(input%jspins), qmt(atoms%ntype,input%jspins),&
      31             :                                    qvac(2,input%jspins), qtot, qistot
      32             :       TYPE(t_mpi),INTENT(IN),OPTIONAL :: fmpi
      33             :       INTEGER                   :: jsp, j, ivac, nz, n, irank, nsize, intstart, intstop, chunk_size, leftover
      34        1531 :       REAL                      :: q2(vacuum%nmz), w(4), rht1(vacuum%nmzd,2,input%jspins)
      35             :       REAL                      :: sum_over_ng3
      36        1531 :       COMPLEX,ALLOCATABLE       :: x(:) !(1:stars%ng3), may be distributed over fmpi ranks
      37             :       COMPLEX                   :: w_off
      38             : #ifdef CPP_MPI
      39             :       INTEGER ierr
      40             : #endif
      41        1531 :       IF (PRESENT(fmpi)) THEN
      42        1352 :          irank = fmpi%irank
      43        1352 :          nsize = fmpi%isize
      44             :       ELSE
      45             :          irank = 0
      46             :          nsize = 1
      47             :       ENDIF
      48             : 
      49        1531 :       qtot = 0.0
      50        1531 :       qistot = 0.0
      51        8869 :       qvac=0.0
      52        3977 :       q=0.0
      53        3977 :       qis=0.0
      54        8209 :       qmt=0.0
      55        1531 :       IF (irank.EQ.0) THEN   
      56             : !     -----mt charge
      57        2365 :             DO n = 1,atoms%ntype
      58        4045 :                DO jsp=1,size(integrand%mt,4)
      59        4045 :                    CALL intgr3(integrand%mt(:,0,n,jsp),atoms%rmsh(:,n),atoms%dx(n),atoms%jri(n),w(jsp))
      60             :                enddo
      61        1510 :                if (size(integrand%pw,2)>2) THEN 
      62             :                   !this is a noco-calculation
      63         307 :                   if (size(integrand%mt,4)==4) THEN
      64          78 :                      w_off=cmplx(w(3),w(4))
      65             :                   else  
      66         229 :                      w_off=0.0
      67             :                   endif
      68             :                   !rotate into global frame
      69         307 :                   call nococonv%rotdenmat(n,w(1),w(2),w_off,toGlobal=.true.)
      70             :                endif
      71        4744 :                DO jsp=1,input%jspins       
      72        2379 :                   qmt(n, jsp) = w(jsp)*sfp_const
      73        3889 :                   q(jsp) = q(jsp) + atoms%neq(n)*qmt(n,jsp)
      74             :                ENDDO   
      75             :             ENDDO
      76         855 :          IF (input%film) THEN
      77             : !     -----vacuum region
      78         258 :             DO jsp = 1,input%jspins        
      79         455 :                DO ivac = 1,vacuum%nvac
      80       49447 :                   DO nz = 1,vacuum%nmz
      81       49447 :                      rht1(nz,ivac,jsp) =  REAL(integrand%vac(nz,1,ivac,jsp))
      82             :                     END DO
      83         197 :                   CALL qsf(vacuum%delz,rht1(1,ivac,jsp),q2,vacuum%nmz,0)
      84         197 :                   qvac(ivac,jsp) = q2(1)*cell%area
      85             :                   
      86         346 :                      q(jsp) = q(jsp) + qvac(ivac,jsp)*2./real(vacuum%nvac)
      87             :                ENDDO
      88             :             enddo
      89             :          END IF
      90             :       END IF ! irank = 0
      91             : 
      92        3977 :       DO jsp = 1,input%jspins
      93             : !     -----is region
      94        2446 :          chunk_size = stars%ng3/nsize
      95        2446 :          leftover = stars%ng3 - chunk_size*nsize
      96        2446 :          IF ( leftover > irank ) THEN
      97         904 :             chunk_size = chunk_size + 1
      98         904 :             intstart = irank * chunk_size + 1
      99             :          ELSE
     100        1542 :             intstart = leftover * (chunk_size+1) + (irank - leftover) * chunk_size + 1
     101             :          ENDIF 
     102        2446 :          intstop = intstart + chunk_size -1
     103        7338 :          ALLOCATE(x(intstart:intstop))
     104        2446 :          CALL pwint_all(stars,atoms,sym ,cell,intstart,intstop,x)
     105        2446 :          sum_over_ng3 = 0.0
     106     3458706 :          DO j = intstart,intstop
     107     3458706 :             sum_over_ng3 = sum_over_ng3 + integrand%pw(j,jsp)*x(j)*stars%nstr(j)
     108             :          ENDDO
     109        2446 :          DEALLOCATE(x)
     110             : #ifdef CPP_MPI
     111        2446 :          IF (PRESENT(fmpi)) THEN
     112        2140 :             CALL MPI_reduce(sum_over_ng3,qis(jsp),1,MPI_DOUBLE_PRECISION,MPI_SUM,0,fmpi%mpi_comm,ierr)
     113             :          ELSE
     114         306 :             qis(jsp) = sum_over_ng3
     115             :          ENDIF
     116             : #else
     117             :          qis(jsp) = sum_over_ng3
     118             : #endif
     119        2446 :          qistot = qistot + qis(jsp)
     120        2446 :          q(jsp) = q(jsp) + qis(jsp)
     121        3977 :          qtot = qtot + q(jsp)
     122             :       END DO ! loop over spins
     123        1531 :    END SUBROUTINE integrate_cdn
     124             : 
     125           0 :    SUBROUTINE integrate_realspace(xcpot, atoms, sym, sphhar, input, &
     126           0 :                                   stars, cell,   vacuum, noco, mt, is, hint)
     127             :       use m_types
     128             :       use m_mt_tofrom_grid
     129             :       use m_pw_tofrom_grid
     130             :       use m_constants
     131             :       implicit none
     132             :       CLASS(t_xcpot), INTENT(inout)   :: xcpot
     133             :       TYPE(t_atoms),INTENT(IN)      :: atoms
     134             :       TYPE(t_sym), INTENT(in)       :: sym
     135             :       TYPE(t_sphhar), INTENT(IN)    :: sphhar
     136             :       TYPE(t_input), INTENT(IN)     :: input
     137             :       TYPE(t_stars), INTENT(IN)     :: stars
     138             :       TYPE(t_cell), INTENT(IN)      :: cell
     139             :        
     140             :       TYPE(t_vacuum), INTENT(in)    :: vacuum
     141             :       TYPE(t_noco), INTENT(in)      :: noco
     142             :       real, intent(inout)           :: mt(:,:,:), is(:,:)
     143             :       character(len=*), intent(in), optional :: hint
     144             :       integer                       :: n_atm, i
     145             : 
     146           0 :       TYPE(t_potden)                :: tmp_potden
     147           0 :       REAL                          :: q(input%jspins), qis(input%jspins), &
     148           0 :                                        qmt(atoms%ntype,input%jspins), qvac(2,input%jspins),&
     149             :                                        qtot, qistot
     150             : 
     151           0 :       call tmp_potden%init(stars, atoms, sphhar, vacuum, noco, input%jspins, POTDEN_TYPE_DEN)
     152           0 :       call init_mt_grid(input%jspins, atoms, sphhar, xcpot%needs_grad(), sym)
     153           0 :       do n_atm =1,atoms%ntype
     154             :          call mt_from_grid(atoms, sym, sphhar, n_atm, input%jspins, mt(:,:,n_atm), &
     155           0 :                            tmp_potden%mt(:,0:,n_atm,:))
     156             : 
     157           0 :          do i=1,atoms%jri(n_atm)
     158           0 :             tmp_potden%mt(i,:,n_atm,:) = tmp_potden%mt(i,:,n_atm,:) * atoms%rmsh(i,n_atm)**2
     159             :          enddo
     160             :       enddo
     161           0 :       call finish_mt_grid()
     162             : 
     163           0 :       call init_pw_grid(stars, sym, cell,xcpot)
     164           0 :       call pw_from_grid( stars, is, tmp_potden%pw)  !THIS CODE SEEMS TO BE BROKEN!!
     165           0 :       call finish_pw_grid()
     166             : 
     167           0 :       call judft_error("Bug, integrate_realspace in cdntot")
     168             :       !call integrate_cdn(stars,atoms,sym,vacuum,input,cell , tmp_potden, &
     169             :       !                             q, qis, qmt, qvac, qtot, qistot)
     170             : 
     171           0 :       call print_cdn_inte(q, qis, qmt, qvac, qtot, qistot, hint)
     172           0 :    END SUBROUTINE integrate_realspace
     173             : 
     174        1531 :    SUBROUTINE cdntot(stars,nococonv,atoms,sym,vacuum,input,cell ,&
     175             :                      den,l_printData,qtot,qistot,fmpi,l_par)
     176             : 
     177             :       USE m_types
     178             :       USE m_juDFT
     179             :       IMPLICIT NONE
     180             : 
     181             : !     .. Scalar Arguments ..
     182             :       TYPE(t_stars),INTENT(IN)  :: stars
     183             :       TYPE(t_nococonv),INTENT(IN):: nococonv
     184             :       TYPE(t_atoms),INTENT(IN)  :: atoms
     185             :       TYPE(t_sym),INTENT(IN)    :: sym
     186             :       TYPE(t_vacuum),INTENT(IN) :: vacuum
     187             :       TYPE(t_input),INTENT(IN)  :: input
     188             :        
     189             :       TYPE(t_cell),INTENT(IN)   :: cell
     190             :       TYPE(t_potden),INTENT(IN) :: den
     191             :       LOGICAL,INTENT(IN)        :: l_printData,l_par
     192             :       REAL,INTENT(OUT)          :: qtot,qistot
     193             :       TYPE(t_mpi),INTENT(IN)    :: fmpi
     194             : 
     195             : !     .. Local Scalars ..
     196        1531 :       REAL q(input%jspins),qis(input%jspins),w,mtCharge
     197             : !     ..
     198             : !     .. Local Arrays ..
     199        1531 :       REAL qmt(atoms%ntype,input%jspins),qvac(2,input%jspins)
     200             : 
     201        1531 :       CALL timestart("cdntot")
     202        1531 :       IF (l_par) THEN
     203             :          CALL integrate_cdn(stars,nococonv,atoms,sym,vacuum,input,cell , den, &
     204        1352 :                                    q, qis, qmt, qvac, qtot, qistot, fmpi)
     205             :       ELSE
     206             :          CALL integrate_cdn(stars,nococonv,atoms,sym,vacuum,input,cell , den, &
     207         179 :                                    q, qis, qmt, qvac, qtot, qistot)
     208             :       ENDIF
     209             : 
     210        1531 :       IF (fmpi%irank.EQ.0) CALL cdntot_writings(atoms,vacuum,input,l_printData,q,qis,qmt,qvac,qtot)
     211        1531 :       CALL timestop("cdntot")
     212        1531 :    END SUBROUTINE cdntot
     213             : 
     214         776 :    SUBROUTINE cdntot_writings(atoms,vacuum,input,l_printData,q,qis,qmt,qvac,qtot)
     215             : 
     216             :       USE m_constants
     217             :       USE m_types
     218             :       USE m_juDFT
     219             :       USE m_xmlOutput
     220             :       IMPLICIT NONE
     221             : 
     222             : !     .. Scalar Arguments ..
     223             :       TYPE(t_atoms),INTENT(IN)  :: atoms
     224             :       TYPE(t_vacuum),INTENT(IN) :: vacuum
     225             :       TYPE(t_input),INTENT(IN)  :: input
     226             :       LOGICAL,INTENT(IN)        :: l_printData
     227             :       REAL,INTENT(IN)           :: q(input%jspins),qis(input%jspins)
     228             :       REAL,INTENT(IN)           :: qmt(atoms%ntype,input%jspins),qvac(2,input%jspins)
     229             :       REAL,INTENT(IN)           :: qtot
     230             : 
     231             : !     .. Local Scalars ..
     232             :       REAL mtCharge
     233             :       INTEGER i,jsp,n
     234             : !     ..
     235             : !     .. Local Arrays ..
     236         776 :       INTEGER, ALLOCATABLE :: lengths(:,:)
     237             :       CHARACTER(LEN=20) :: attributes(6), names(6)
     238             : 
     239             : 
     240         776 :       IF (input%film) THEN
     241         392 :          ALLOCATE(lengths(4+vacuum%nvac,2))
     242             :       ELSE
     243         678 :          ALLOCATE(lengths(4,2))
     244             :       END IF
     245             : 
     246        2020 :       DO jsp = 1,input%jspins
     247        1244 :          WRITE (oUnit,FMT=8000) jsp,q(jsp),qis(jsp), (qmt(n,jsp),n=1,atoms%ntype)
     248        1420 :             IF (input%film) WRITE (oUnit,FMT=8010) (i,qvac(i,jsp),i=1,vacuum%nvac)
     249        3405 :             mtCharge = SUM(qmt(1:atoms%ntype,jsp) * atoms%neq(1:atoms%ntype))
     250        1244 :             names(1) = 'spin'         ; WRITE(attributes(1),'(i0)')    jsp      ; lengths(1,1)=4  ; lengths(1,2)=1
     251        1244 :             names(2) = 'total'        ; WRITE(attributes(2),'(f14.7)') q(jsp)   ; lengths(2,1)=5  ; lengths(2,2)=14
     252        1244 :             names(3) = 'interstitial' ; WRITE(attributes(3),'(f14.7)') qis(jsp) ; lengths(3,1)=12 ; lengths(3,2)=14
     253        1244 :             names(4) = 'mtSpheres'    ; WRITE(attributes(4),'(f14.7)') mtCharge ; lengths(4,1)=9  ; lengths(4,2)=14
     254        2020 :             IF(l_printData) THEN
     255        1100 :                IF(input%film) THEN
     256         270 :                   DO i = 1, vacuum%nvac
     257         155 :                      WRITE(names(4+i),'(a6,i0)') 'vacuum', i
     258         155 :                      WRITE(attributes(4+i),'(f14.7)') qvac(i,jsp)
     259         155 :                      lengths(4+i,1)=7
     260         270 :                      lengths(4+i,2)=14
     261             :                   END DO
     262             :                   CALL writeXMLElementFormPoly('spinDependentCharge',names(1:4+vacuum%nvac),&
     263         115 :                                             attributes(1:4+vacuum%nvac),lengths)
     264             :                ELSE
     265         985 :                   CALL writeXMLElementFormPoly('spinDependentCharge',names(1:4),attributes(1:4),lengths)
     266             :                END IF
     267             :             END IF
     268             :          END DO ! loop over spins
     269         776 :          WRITE (oUnit,FMT=8020) qtot
     270         776 :          IF(l_printData) THEN
     271        2073 :             CALL writeXMLElementFormPoly('totalCharge',(/'value'/),(/qtot/),reshape((/5,20/),(/1,2/)))
     272             :          END IF
     273             : 8000     FORMAT (/,10x,'total charge for spin',i3,'=',f12.6,/,10x,&
     274             :                'interst. charge =   ',f12.6,/,&
     275             :                (10x,'mt charge=          ',4f12.6,/))
     276             : 8010     FORMAT (10x,'vacuum ',i2,'  charge=  ',f12.6)
     277             : 8020     FORMAT (/,10x,'total charge  =',f12.6)
     278             : 
     279         776 :    END SUBROUTINE cdntot_writings
     280             : 
     281           0 :    SUBROUTINE print_cdn_inte(q, qis, qmt, qvac, qtot, qistot, hint)
     282             :       use  ieee_arithmetic
     283             :       implicit none
     284             :       REAL, INTENT(in)                       :: q(:), qis(:), qmt(:,:), qvac(:,:), qtot, qistot
     285             :       character(len=*), intent(in), optional :: hint
     286             :       integer                                :: n_mt
     287             : 
     288             : 
     289           0 :       if(present(hint)) write (*,*) "DEN of ", hint
     290           0 :       write (*,*) "q   = ", q
     291           0 :       write (*,*) "qis = ", qis
     292             : 
     293           0 :       write (*,*) "qmt"
     294           0 :       do n_mt = 1,size(qmt, dim=1)
     295           0 :          write (*,*) "mt = ", n_mt, qmt(n_mt,:)
     296             :       enddo
     297             : 
     298             :       if(.not. any(ieee_is_nan(qvac))) then
     299           0 :          write (*, *) "qvac",    qvac
     300             :       endif
     301           0 :       write (*, *) "qtot",    qtot
     302           0 :       write (*, *) "qis_tot", qistot
     303           0 :       write (*, *) "-------------------------"
     304           0 :    END SUBROUTINE print_cdn_inte
     305             : END MODULE m_cdntot

Generated by: LCOV version 1.14