Line data Source code
1 : !--------------------------------------------------------------------------------
2 : ! Copyright (c) 2016 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_hsmt
7 : USE m_juDFT
8 : IMPLICIT NONE
9 : CONTAINS
10 : !> Setup of MT-part of the Hamiltonian and the overlap matrix
11 : !!
12 : !! Here the MT-components are added to the matrices.
13 : !! 1. The spherical part in hsmt_sph()
14 : !! 2. The non-spherical part in hsmt_nonsph()
15 : !! 3. The lo-part in hsmt_lo()
16 : !!
17 : !! - In the case of a noco-calculation (but not spin-spiral), first a temporary matrix is set-up
18 : !! for each atom in its local spin-frame and this matrix is the rotated into the global frame and added to the full matrix
19 : !! - In the spin-spiral case, a loop over the global spin is performed and the four parts of the matrix are calculated one-by-one
20 : !! @todo
21 : !! The off-diagonal contribution in first-variation soc and constraint calculations is still missing
22 :
23 7342 : SUBROUTINE hsmt(atoms,sym,enpara,&
24 7342 : isp,input,fmpi,noco,nococonv,cell,lapw,usdus,td,smat,hmat)
25 : USE m_types
26 : USE m_types_mpimat
27 : USE m_hsmt_nonsph
28 : USE m_hsmt_sph
29 : USE m_hsmt_lo
30 : USE m_hsmt_distspins
31 : USE m_hsmt_fjgj
32 : USE m_hsmt_spinor
33 : USE m_hsmt_soc_offdiag
34 : USE m_hsmt_mtNocoPot_offdiag
35 : USE m_hsmt_offdiag
36 : IMPLICIT NONE
37 : TYPE(t_mpi),INTENT(IN) :: fmpi
38 : TYPE(t_input),INTENT(IN) :: input
39 : TYPE(t_noco),INTENT(IN) :: noco
40 : TYPE(t_nococonv),INTENT(IN) :: nococonv
41 : TYPE(t_sym),INTENT(IN) :: sym
42 : TYPE(t_cell),INTENT(IN) :: cell
43 : TYPE(t_atoms),INTENT(IN) :: atoms
44 : TYPE(t_enpara),INTENT(IN) :: enpara
45 : TYPE(t_lapw),INTENT(IN) :: lapw
46 : TYPE(t_tlmplm),INTENT(IN) :: td
47 : TYPE(t_usdus),INTENT(IN) :: usdus
48 : CLASS(t_mat),INTENT(INOUT) :: smat(:,:),hmat(:,:)
49 : ! ..
50 : ! .. Scalar Arguments ..
51 : INTEGER, INTENT (IN) :: isp !This is the global spin in a collinear calculation
52 :
53 : !locals
54 7342 : TYPE(t_fjgj)::fjgj
55 : INTEGER :: ilSpinPr,ilSpin !local spin in atom
56 : INTEGER :: igSpinPr,igSpin,n
57 : COMPLEX :: chi(2,2),chi_one
58 :
59 7342 : CLASS(t_mat),ALLOCATABLE::smat_tmp,hmat_tmp
60 :
61 : !
62 7342 : IF (noco%l_noco.AND..NOT.noco%l_ss) THEN
63 662 : IF (fmpi%n_size==1) THEN
64 88 : ALLOCATE(t_mat::hmat_tmp)
65 88 : ALLOCATE(t_mat::smat_tmp)
66 : ELSE
67 574 : ALLOCATE(t_mpimat::hmat_tmp)
68 574 : ALLOCATE(t_mpimat::smat_tmp)
69 : ENDIF
70 662 : CALL smat_tmp%init(hmat(1,1))
71 662 : CALL hmat_tmp%init(hmat(1,1))
72 : !$acc enter data copyin(smat_tmp,hmat_tmp)create(smat_tmp%data_c,smat_tmp%data_r,hmat_tmp%data_c,hmat_tmp%data_r)
73 : ENDIF
74 :
75 22026 : CALL fjgj%alloc(MAXVAL(lapw%nv),atoms%lmaxd,isp,noco)
76 : !$acc data copyin(fjgj) create(fjgj%fj,fjgj%gj)
77 7342 : igSpinPr=1;igSpin=1;chi_one=1.0 !Defaults in non-noco case
78 23584 : DO n=1,atoms%ntype
79 40884 : DO ilSpinPr=MERGE(1,isp,noco%l_noco),MERGE(2,isp,noco%l_noco)
80 17300 : CALL timestart("fjgj coefficients")
81 17300 : CALL fjgj%calculate(input,atoms,cell,lapw,noco,usdus,n,ilSpinPr)
82 : !$acc update device(fjgj%fj,fjgj%gj)
83 17300 : CALL timestop("fjgj coefficients")
84 51900 : DO ilSpin=ilSpinPr,MERGE(2,isp,noco%l_noco)
85 35658 : IF (.NOT.noco%l_noco) THEN
86 : !This is for collinear calculations: the (1,1) element of the matrices is all
87 : !that is needed and allocated
88 :
89 15184 : CALL hsmt_sph(n,atoms,fmpi,ilSpinPr,input,nococonv,1,1,chi_one,lapw,enpara%el0,td%e_shift(n,ilSpinPr),usdus,fjgj,smat(1,1),hmat(1,1),.FALSE.,.FALSE.)
90 15184 : CALL hsmt_nonsph(n,fmpi,sym,atoms,ilSpinPr,ilSpin,1,1,chi_one,noco,nococonv,cell,lapw,td,fjgj,hmat(1,1),.FALSE.)
91 15184 : CALL hsmt_lo(input,atoms,sym,cell,fmpi,noco,nococonv,lapw,usdus,td,fjgj,n,chi_one,ilSpinPr,ilSpin,igSpinPr,igSpin,hmat(1,1),.FALSE.,.FALSE.,.FALSE.,smat=smat(1,1))
92 3174 : ELSEIF(noco%l_noco.AND..NOT.noco%l_ss) THEN
93 : !The NOCO but non-spinspiral setup follows:
94 : !The Matrix-elements are first calculated in the local frame of the atom and
95 : !stored in tmp-variables. Then these are distributed (rotated) into the 2x2
96 : !global spin-matrices.
97 3072 : IF (ilSpinPr==ilSpin) THEN !local spin-diagonal contribution
98 : !initialize the non-LO part of hmat_tmp matrix with zeros
99 2048 : CALL hsmt_nonsph(n,fmpi,sym,atoms,ilSpinPr,ilSpinPr,1,1,chi_one,noco,nococonv,cell,lapw,td,fjgj,hmat_tmp,.TRUE.)
100 : !initialize the smat_tmp matrix with zeros
101 2048 : CALL hsmt_sph(n,atoms,fmpi,ilSpinPr,input,nococonv,1,1,chi_one,lapw,enpara%el0,td%e_shift(n,ilSpinPr),usdus,fjgj,smat_tmp,hmat_tmp,.TRUE.,.FALSE.)
102 : !initialize the LO part of the matrices with zeros
103 2048 : CALL hsmt_lo(input,atoms,sym,cell,fmpi,noco,nococonv,lapw,usdus,td,fjgj,n,chi_one,ilSpinPr,ilSpin,igSpinPr,igSpin,hmat_tmp,.TRUE.,.FALSE.,.FALSE.,smat=smat_tmp)
104 2048 : CALL hsmt_spinor(ilSpinPr,n,nococonv,chi)
105 2048 : CALL timestart("hsmt_distspins")
106 2048 : CALL hsmt_distspins(chi,smat_tmp,smat)
107 2048 : CALL hsmt_distspins(chi,hmat_tmp,hmat)
108 2048 : CALL timestop("hsmt_distspins")
109 : ELSE !Add off-diagonal contributions to Hamiltonian if needed
110 1024 : IF (noco%l_unrestrictMT(n).OR.noco%l_spinoffd_ldau(n)) THEN
111 222 : CALL hsmt_mtNocoPot_offdiag(n,input,fmpi,sym,atoms,noco,nococonv,cell,lapw,usdus,td,fjgj,igSpinPr,igSpin,hmat_tmp,hmat)
112 : ENDIF
113 1024 : IF (noco%l_constrained(n)) CALL hsmt_offdiag(n,atoms,fmpi,nococonv,lapw,td,usdus,fjgj,ilSpinPr,ilSpin,igSpinPr,igSpin,hmat)
114 1024 : IF (noco%l_soc) CALL hsmt_soc_offdiag(n,atoms,cell,fmpi,nococonv,lapw,sym,usdus,td,fjgj,hmat)
115 : ENDIF
116 : ELSE
117 : !In the spin-spiral case the loop over the interstitial=global spin has to
118 : !be performed explicitely
119 102 : CALL hsmt_spinor(ilSpinPr,n,nococonv,chi)
120 306 : DO igSpinPr=1,2
121 714 : DO igSpin=1,2
122 612 : IF (ilSpinPr==ilSpin) THEN !local diagonal spin
123 : CALL hsmt_sph(n,atoms,fmpi,ilSpinPr,input,nococonv,igSpinPr,igSpin,chi(igSpinPr,igSpin),&
124 272 : lapw,enpara%el0,td%e_shift(n,ilSpinPr),usdus,fjgj,smat(igSpinPr,igSpin),hmat(igSpinPr,igSpin),.FALSE.,.FALSE.)
125 : CALL hsmt_nonsph(n,fmpi,sym,atoms,ilSpinPr,ilSpin,igSpinPr,igSpin,chi(igSpinPr,igSpin),noco,nococonv,cell,&
126 272 : lapw,td,fjgj,hmat(igSpinPr,igSpin),.FALSE.)
127 : CALL hsmt_lo(input,atoms,sym,cell,fmpi,noco,nococonv,lapw,usdus,td,fjgj,&
128 272 : n,chi(igSpinPr,igSpin),ilSpinPr,ilSpin,igSpinPr,igSpin,hmat(igSpinPr,igSpin),.FALSE.,.FALSE.,.FALSE.,smat=smat(igSpinPr,igSpin))
129 : ELSE
130 272 : IF (any(noco%l_unrestrictMT).OR.noco%l_spinoffd_ldau(n)) call hsmt_mtNocoPot_offdiag(n,input,fmpi,sym,atoms,noco,nococonv,cell,lapw,usdus,td,fjgj,igSpinPr,igSpin,hmat_tmp,hmat)
131 272 : IF (any(noco%l_constrained)) CALL hsmt_offdiag(n,atoms,fmpi,nococonv,lapw,td,usdus,fjgj,ilSpinPr,ilSpin,igSpinPr,igSpin,hmat)
132 : ENDIF
133 : ENDDO
134 : ENDDO
135 : ENDIF
136 : ENDDO
137 : ENDDO
138 : END DO
139 : !$acc end data
140 : if (noco%l_noco.AND..NOT.noco%l_ss) then
141 : !$acc exit data delete(smat_tmp%data_c,smat_tmp%data_r,hmat_tmp%data_c,hmat_tmp%data_r)
142 : !$acc exit data delete(smat_tmp,hmat_tmp)
143 : endif
144 7342 : RETURN
145 7342 : END SUBROUTINE hsmt
146 : END MODULE m_hsmt
|