LCOV - code coverage report
Current view: top level - propcalc/dos - types_mcd.F90 (source / functions) Hit Total Coverage
Test: FLEUR test coverage Lines: 17 83 20.5 %
Date: 2024-05-15 04:28:08 Functions: 1 8 12.5 %

          Line data    Source code
       1             : !--------------------------------------------------------------------------------
       2             : ! Copyright (c) 2020 Peter Grünberg Institut, Forschungszentrum Jülich, Germany
       3             : ! This file is part of FLEUR and available as free software under the conditions
       4             : ! of the MIT license as expressed in the LICENSE file in more detail.
       5             : !--------------------------------------------------------------------------------
       6             : MODULE m_types_mcd
       7             :   use m_judft
       8             :   use m_types_eigdos
       9             :   implicit none
      10             :   PRIVATE
      11             :   public t_mcd
      12             :   TYPE,extends(t_eigdos):: t_mcd
      13             :     REAL                 :: emcd_lo, emcd_up, maxE_mcd
      14             :     INTEGER, ALLOCATABLE :: ncore(:)
      15             :     INTEGER,ALLOCATABLE  :: n_dos_to_type(:)
      16             :     REAL,    ALLOCATABLE :: e_mcd(:,:,:)
      17             :     REAL,    ALLOCATABLE :: mcd(:,:,:,:,:)
      18             :     COMPLEX, ALLOCATABLE :: m_mcd(:,:,:,:)
      19             :     REAL,    ALLOCATABLE :: mcd_grid(:)
      20             :   CONTAINS
      21             :     PROCEDURE,PASS :: init => mcd_init
      22             :     procedure      :: get_dos_grid
      23             :     PROCEDURE      :: make_dos
      24             :     PROCEDURE      :: get_weight_eig
      25             :     PROCEDURE      :: get_num_weights
      26             :     PROCEDURE      :: get_weight_name
      27             :     END TYPE t_mcd
      28             : contains
      29             : 
      30           0 : function get_dos_grid(this)
      31             :   class(t_mcd),intent(in):: this
      32             :   real,allocatable:: get_dos_grid(:)
      33             : 
      34             :   INTEGER :: ind,ntype,nc
      35             :   REAL:: e_core
      36           0 :   get_dos_grid=this%mcd_grid
      37             : end function
      38             : 
      39           0 : subroutine make_dos(eigdos,kpts,input,banddos,efermi)
      40             :     use m_types_banddos
      41             :     use m_types_input
      42             :     use m_types_kpts
      43             : 
      44             :     class(t_mcd),intent(inout)   :: eigdos
      45             :     type(t_banddos),intent(in)   :: banddos
      46             :     type(t_input),intent(in)     :: input
      47             :     type(t_kpts),intent(in)      :: kpts
      48             :     real,intent(in)              :: efermi
      49             : 
      50             :     integer ::n,i,ind,ntype,nc,k,l,jspin
      51             :     real    :: e1,e2,e_lo,e_up,fac
      52           0 :     real,allocatable:: dos(:,:,:)
      53           0 :     if (allocated(eigdos%dos)) return
      54             :     !Call the routine of the parent-class
      55           0 :     call t_eigdos_make_dos(eigdos,kpts,input,banddos,efermi)
      56             : 
      57             :     !Only unoccupied states
      58           0 :     DO n=1,size(eigdos%dos_grid)
      59           0 :       if (eigdos%dos_grid(n)<0.0)  eigdos%dos(n,:,:)=0.0
      60             :     enddo
      61             : 
      62             :     !Map the values to MCD grid
      63             : 
      64           0 :     e_lo =  minval(eigdos%e_mcd)-efermi-maxval(eigdos%dos_grid) - 3.0*banddos%sig_dos
      65           0 :     e_up =  eigdos%maxE_mcd-efermi + 3.0*banddos%sig_dos
      66           0 :     ALLOCATE(eigdos%mcd_grid(size(eigdos%dos_grid)))
      67           0 :     DO i=1,size(eigdos%dos_grid)
      68           0 :       eigdos%mcd_grid(i)=e_lo+(i-1)*(e_up-e_lo)/(size(eigdos%mcd_grid)-1)
      69             :     ENDDO
      70             : 
      71           0 :     allocate(dos,mold=eigdos%dos)
      72           0 :     dos=0.0
      73           0 :     ind=0
      74           0 :     DO ntype=1,size(eigdos%ncore)
      75           0 :       DO nc=1,eigdos%ncore(ntype)
      76           0 :         DO k = 1,3
      77           0 :           ind=ind+1
      78           0 :           DO jspin=1,size(eigdos%e_mcd,2)
      79           0 :             DO i=1,size(eigdos%dos_grid)-1
      80           0 :               e1=-1*eigdos%dos_grid(i)-efermi+eigdos%e_mcd(ntype,jspin,nc)
      81           0 :               e2=-1*eigdos%dos_grid(i+1)-efermi+eigdos%e_mcd(ntype,jspin,nc)
      82           0 :               DO l=1,size(eigdos%mcd_grid)
      83           0 :                 IF ((e2.LE.eigdos%mcd_grid(l)).AND. (e1.GT.eigdos%mcd_grid(l))) THEN
      84           0 :                   fac = (eigdos%mcd_grid(l)-e1)/(e2-e1)
      85           0 :                   dos(l,jspin,ind) = dos(l,jspin,ind)+ eigdos%dos(i,jspin,ind)*(1.-fac) + fac * eigdos%dos(i+1,jspin,ind)
      86             :                 ENDIF
      87             :               ENDDO
      88             :             ENDDO
      89             :           ENDDO
      90             :         ENDDO
      91             :       ENDDO
      92             :     ENDDO
      93           0 :     eigdos%dos=dos
      94           0 :   end subroutine
      95             : 
      96           0 : function get_weight_eig(this,id)
      97             :   class(t_mcd),intent(in):: this
      98             :   INTEGER,intent(in)         :: id
      99             :   real,allocatable:: get_weight_eig(:,:,:)
     100             : 
     101             :   INTEGER :: ind,ntype,nc
     102             : 
     103           0 :   ind=0
     104           0 :   DO ntype=1,size(this%ncore)
     105           0 :     DO nc=1,this%ncore(ntype)
     106           0 :       ind=ind+1
     107           0 :       if (ind==id) get_weight_eig=this%mcd(ntype,nc,:,:,:)
     108           0 :       ind=ind+1
     109           0 :       if (ind==id) get_weight_eig=this%mcd(ntype+1,nc,:,:,:)
     110           0 :       ind=ind+1
     111           0 :       if (ind==id) get_weight_eig=this%mcd(ntype+2,nc,:,:,:)
     112           0 :       IF(ind>id) return
     113             :     ENDDO
     114             :   ENDDO
     115           0 :   IF(ind>id)CALL judft_error("Types_mcd: data not found")
     116             : 
     117             : END function
     118             : 
     119           0 : integer function get_num_weights(this)
     120             :   class(t_mcd),intent(in):: this
     121           0 :   get_num_weights=3*sum(this%ncore)
     122           0 : end function
     123             : 
     124           0 :   character(len=20) function get_weight_name(this,id)
     125             :     class(t_mcd),intent(in):: this
     126             :     INTEGER,intent(in)         :: id
     127             : 
     128             :     character(len=3):: c
     129             :     INTEGER :: ind,n_dos,nc,n
     130           0 :     ind=0
     131           0 :     DO n=1,size(this%mcd,1)
     132           0 :       n_dos=(n-1)/3+1
     133           0 :       select case(mod(n,3))
     134             :       case(1)
     135           0 :         c="pos"
     136             :       case(2)
     137           0 :         c="neg"
     138             :       case(0)
     139           0 :         c="cir"
     140             :       end select
     141           0 :       DO nc=1,this%ncore(n_dos)
     142           0 :         ind=ind+1
     143           0 :         if (ind==id) THEN
     144           0 :           write(get_weight_name,"(a,i0,a,i0,a)") "At",this%n_dos_to_type(n_dos),"NC",nc,c
     145           0 :           RETURN
     146           0 :         ELSE IF(ind>id) then
     147           0 :           CALL judft_error("Types_mcd: data not found")
     148             :         ENDIF
     149             :       ENDDO
     150             :     ENDDO
     151             :   end function
     152             : 
     153             : 
     154             : 
     155         672 : SUBROUTINE mcd_init(thisMCD,banddos,input,atoms,kpts,eig)
     156             :   USE m_types_setup
     157             :   USE m_types_kpts
     158             : 
     159             :    IMPLICIT NONE
     160             : 
     161             :    CLASS(t_mcd),          INTENT(INOUT) :: thisMCD
     162             :    TYPE(t_banddos),       INTENT(IN)    :: banddos
     163             : 
     164             :    TYPE(t_input),         INTENT(IN)    :: input
     165             :    TYPE(t_atoms),         INTENT(IN)    :: atoms
     166             :    TYPE(t_kpts),          INTENT(IN)    :: kpts
     167             :    real,INTENT(IN)                      :: eig(:,:,:)
     168             : 
     169             :    integer :: ntype !no of types for which MCD is calculated
     170             : 
     171        1374 :    thisMCD%n_dos_to_type=banddos%dos_typelist
     172         672 :    ntype=size(banddos%dos_typelist)
     173         672 :    thisMCD%name_of_dos="MCD"
     174        2016 :    ALLOCATE (thisMCD%ncore(ntype))
     175        3360 :    ALLOCATE (thisMCD%e_mcd(ntype,input%jspins,29))
     176         672 :    IF (banddos%l_mcd) THEN
     177           0 :       thisMCD%emcd_lo = banddos%e_mcd_lo
     178           0 :       thisMCD%emcd_up = banddos%e_mcd_up
     179           0 :       ALLOCATE (thisMCD%m_mcd(29,(3+1)**2,3*ntype,2))
     180           0 :       ALLOCATE (thisMCD%mcd(3*ntype,29,input%neig,kpts%nkpt,input%jspins) )
     181           0 :       IF (.NOT.banddos%dos) WRITE (*,*) 'For mcd-spectra set banddos%dos=T!'
     182             :    ELSE
     183         672 :       ALLOCATE(thisMCD%dos(0,0,0)) !indicated no DOS should be calculated
     184         672 :       ALLOCATE (thisMCD%m_mcd(1,1,1,1))
     185        2016 :       ALLOCATE (thisMCD%mcd(1,1,1,1,input%jspins))
     186             :    ENDIF
     187             : 
     188         672 :    thisMCD%maxE_mcd = -1000000.0
     189         692 :    thisMCD%ncore = 0
     190       51944 :    thisMCD%e_mcd = 0.0
     191        6012 :    thisMCD%mcd = 0.0
     192        3360 :    thisMCD%m_mcd = CMPLX(0.0,0.0)
     193             : 
     194      406524 :    thisMCD%eig=eig
     195             : 
     196             : 
     197             : 
     198             : 
     199         672 : END SUBROUTINE mcd_init
     200           0 : end module m_types_mcd

Generated by: LCOV version 1.14