pwdft  0.1
PW-DFT code for education
libtetrabz_dbldelta_mod.F90
Go to the documentation of this file.
1 !
2 ! Copyright (c) 2014 Mitsuaki Kawamura
3 !
4 ! Permission is hereby granted, free of charge, to any person obtaining a
5 ! copy of this software and associated documentation files (the
6 ! "Software"), to deal in the Software without restriction, including
7 ! without limitation the rights to use, copy, modify, merge, publish,
8 ! distribute, sublicense, and/or sell copies of the Software, and to
9 ! permit persons to whom the Software is furnished to do so, subject to
10 ! the following conditions:
11 !
12 ! The above copyright notice and this permission notice shall be included
13 ! in all copies or substantial portions of the Software.
14 !
15 ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16 ! OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 ! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 ! IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 ! CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 ! TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 ! SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 !
24  !
25  IMPLICIT NONE
26  !
27  PRIVATE
28  PUBLIC libtetrabz_dbldelta
29  !
30 CONTAINS
31 !
32 ! Compute doubledelta
33 !
34 SUBROUTINE libtetrabz_dbldelta(ltetra,bvec,nb,nge,eig1,eig2,ngw,wght,comm) BIND(C)
35  !
36  USE iso_c_binding
38  IMPLICIT NONE
39  !
40  INTEGER(C_INT),INTENT(IN) :: ltetra, nb, nge(3), ngw(3)
41  REAL(c_double),INTENT(IN) :: bvec(9), eig1(nb,product(nge(1:3))), eig2(nb,product(nge(1:3)))
42  REAL(c_double),INTENT(OUT) :: wght(nb*nb,product(ngw(1:3)))
43  INTEGER(C_INT),INTENT(IN),OPTIONAL :: comm
44  !
45  LOGICAL :: linterpol
46  INTEGER :: nt_local, nk_local, nkbz, ik, kintp(8)
47  INTEGER,ALLOCATABLE :: ik_global(:,:), ik_local(:,:)
48  REAL(8) :: wlsm(4,20), wintp(1,8)
49  REAL(8),ALLOCATABLE :: wghtd(:,:,:), kvec(:,:)
50  !
51  IF(PRESENT(comm)) THEN
52  CALL libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,&
53  & nt_local,nkbz,ik_global,ik_local,kvec,comm)
54  ELSE
55  CALL libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,&
56  & nt_local,nkbz,ik_global,ik_local,kvec)
57  END IF
58  !
59  IF(linterpol) THEN
60  !
61  ALLOCATE(wghtd(nb*nb,1,nk_local))
62  CALL libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkbz,eig1,eig2,nk_local,wghtd)
63  !
64  ! Interpolation
65  !
66  wght(1:nb*nb,1:product(ngw(1:3))) = 0d0
67  DO ik = 1, nk_local
68  CALL libtetrabz_interpol_indx(ngw,kvec(1:3,ik),kintp,wintp)
69  wght(1:nb*nb,kintp(1:8)) = wght(1:nb*nb, kintp(1:8)) &
70  & + matmul(wghtd(1:nb*nb,1:1,ik), wintp(1:1,1:8))
71  END DO ! ik = 1, nk_local
72  DEALLOCATE(wghtd, kvec)
73  !
74  IF(PRESENT(comm)) CALL libtetrabz_mpisum_dv(comm, nb*nb*product(ngw(1:3)), wght)
75  !
76  ELSE
77  CALL libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkbz,eig1,eig2,nk_local,wght)
78  END IF
79  !
80  DEALLOCATE(ik_global, ik_local)
81  !
82 END SUBROUTINE libtetrabz_dbldelta
83 !
84 ! Main SUBROUTINE for Delta(E1) * Delta(E2)
85 !
86 SUBROUTINE libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkBZ,eig1,eig2,nk_local,dbldelta)
87  !
88  USE libtetrabz_common, ONLY : libtetrabz_sort, &
91  IMPLICIT NONE
92  !
93  INTEGER,INTENT(IN) :: nt_local, nb, nkBZ, nk_local, &
94  & ik_global(20,nt_local), ik_local(20,nt_local)
95  REAL(8),INTENT(IN) :: wlsm(4,20), eig1(nb,nkBZ), eig2(nb,nkBZ)
96  REAL(8),INTENT(OUT) :: dbldelta(nb,nb,nk_local)
97  !
98  INTEGER :: ib, indx(4), it
99  REAL(8) :: e(4), ei1(4,nb), ej1(4,nb), ej2(3,nb), V, thr = 1d-10, &
100  & tsmall(3,4), w1(nb,4), w2(nb,3)
101  !
102  dbldelta(1:nb,1:nb,1:nk_local) = 0d0
103  !
104  !$OMP PARALLEL DEFAULT(NONE) &
105  !$OMP & SHARED(dbldelta,eig1,eig2,ik_global,ik_local,nb,nt_local,thr,wlsm) &
106  !$OMP & PRIVATE(e,ei1,ej1,ej2,ib,indx,it,tsmall,V,w1,w2)
107  !
108  DO it = 1, nt_local
109  !
110  DO ib = 1, nb
111  ei1(1:4,ib) = matmul(wlsm(1:4,1:20), eig1(ib, ik_global(1:20,it)))
112  ej1(1:4,ib) = matmul(wlsm(1:4,1:20), eig2(ib, ik_global(1:20,it)))
113  END DO
114  !
115  !$OMP DO
116  DO ib = 1, nb
117  !
118  w1(1:nb,1:4) = 0d0
119  e(1:4) = ei1(1:4, ib)
120  CALL libtetrabz_sort(4,e,indx)
121  !
122  IF(e(1) < 0d0 .AND. 0d0 <= e(2)) THEN
123  !
124  CALL libtetrabz_triangle_a1(e,v,tsmall)
125  !
126  IF(v > thr) THEN
127  !
128  ej2(1:3,1:nb) = matmul(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
129  CALL libtetrabz_dbldelta2(nb,ej2,w2)
130  w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
131  & + v * matmul(w2(1:nb,1:3), tsmall(1:3,1:4))
132  !
133  END IF
134  !
135  ELSE IF( e(2) < 0d0 .AND. 0d0 <= e(3)) THEN
136  !
137  CALL libtetrabz_triangle_b1(e,v,tsmall)
138  !
139  IF(v > thr) THEN
140  !
141  ej2(1:3,1:nb) = matmul(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
142  CALL libtetrabz_dbldelta2(nb,ej2,w2)
143  w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
144  & + v * matmul(w2(1:nb,1:3), tsmall(1:3,1:4))
145  !
146  END IF
147  !
148  CALL libtetrabz_triangle_b2(e,v,tsmall)
149  !
150  IF(v > thr) THEN
151  !
152  ej2(1:3,1:nb) = matmul(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
153  CALL libtetrabz_dbldelta2(nb,ej2,w2)
154  w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
155  & + v * matmul(w2(1:nb,1:3), tsmall(1:3,1:4))
156  !
157  END IF
158  !
159  ELSE IF(e(3) < 0d0 .AND. 0d0 < e(4)) THEN
160  !
161  CALL libtetrabz_triangle_c1(e,v,tsmall)
162  !
163  IF(v > thr) THEN
164  !
165  ej2(1:3,1:nb) = matmul(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
166  CALL libtetrabz_dbldelta2(nb,ej2,w2)
167  w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
168  & + v * matmul(w2(1:nb,1:3), tsmall(1:3,1:4))
169  !
170  END IF
171  !
172  END IF
173  !
174  dbldelta(1:nb,ib,ik_local(1:20,it)) = dbldelta(1:nb,ib, ik_local(1:20,it)) &
175  & + matmul(w1(1:nb,1:4), wlsm(1:4,1:20))
176  !
177  END DO ! ib
178  !$OMP END DO NOWAIT
179  !
180  END DO ! it
181  !
182  !$OMP END PARALLEL
183  !
184  dbldelta(1:nb,1:nb,1:nk_local) = dbldelta(1:nb,1:nb,1:nk_local) / dble(6 * nkbz)
185  !
186 END SUBROUTINE libtetrabz_dbldelta_main
187 !
188 ! 2nd step of tetrahedra method.
189 !
190 SUBROUTINE libtetrabz_dbldelta2(nb,ej,w)
191  !
193  IMPLICIT NONE
194  !
195  INTEGER,INTENT(IN) :: nb
196  REAL(8),INTENT(IN) :: ej(3,nb)
197  REAL(8),INTENT(INOUT) :: w(nb,3)
198  !
199  INTEGER :: ib, ii, indx(3)
200  REAL(8) :: a(3,3), e(3), V
201  !
202  DO ib = 1, nb
203  !
204  IF(maxval(abs(ej(1:3,ib))) < 1d-10) stop "Nesting !!"
205  !
206  w(ib,1:3) = 0d0
207  e(1:3) = ej(1:3, ib)
208  CALL libtetrabz_sort(3,e,indx)
209  !
210  DO ii = 1, 3
211  a(1:3,ii) = (0d0 - e(ii)) / (e(1:3) - e(ii))
212  END DO
213  !
214  IF((e(1) < 0d0 .AND. 0d0 <= e(2)) .OR. (e(1) <= 0d0 .AND. 0d0 < e(2))) THEN
215  !
216  !V = a(2,1) * a(3,1) / (0d0 - e(1))
217  v = a(2,1) / (e(3) - e(1))
218  !
219  w(ib,indx(1)) = v * (a(1,2) + a(1,3))
220  w(ib,indx(2)) = v * a(2,1)
221  w(ib,indx(3)) = v * a(3,1)
222  !
223  ELSE IF((e(2) <= 0d0 .AND. 0d0 < e(3)) .OR. (e(2) < 0d0 .AND. 0d0 <= e(3))) THEN
224  !
225  !V = a(1,3) * a(2,3) / (e(3) - 0d0)
226  v = a(2,3) / (e(3) - e(1))
227  !
228  w(ib,indx(1)) = v * a(1,3)
229  w(ib,indx(2)) = v * a(2,3)
230  w(ib,indx(3)) = v * (a(3,1) + a(3,2))
231  !
232  END IF
233  !
234  END DO ! ib
235  !
236 END SUBROUTINE libtetrabz_dbldelta2
237 !
238 END MODULE libtetrabz_dbldelta_mod
libtetrabz_common::libtetrabz_triangle_b2
subroutine, public libtetrabz_triangle_b2(e, V, tsmall)
Definition: libtetrabz_common.F90:614
libtetrabz_dbldelta_mod::libtetrabz_dbldelta
subroutine, public libtetrabz_dbldelta(ltetra, bvec, nb, nge, eig1, eig2, ngw, wght, comm)
Definition: libtetrabz_dbldelta_mod.F90:35
libtetrabz_common::libtetrabz_mpisum_dv
subroutine, public libtetrabz_mpisum_dv(comm, ndim, vector)
Definition: libtetrabz_common.F90:687
libtetrabz_common::libtetrabz_triangle_c1
subroutine, public libtetrabz_triangle_c1(e, V, tsmall)
Definition: libtetrabz_common.F90:640
libtetrabz_common::libtetrabz_initialize
subroutine, public libtetrabz_initialize(ltetra, nge, ngw, bvec, linterpol, wlsm, nk_local, nt_local, nkBZ, ik_global, ik_local, kvec, comm)
Definition: libtetrabz_common.F90:40
libtetrabz_dbldelta_mod::libtetrabz_dbldelta2
subroutine libtetrabz_dbldelta2(nb, ej, w)
Definition: libtetrabz_dbldelta_mod.F90:191
libtetrabz_common::libtetrabz_interpol_indx
subroutine, public libtetrabz_interpol_indx(ng, kvec, kintp, wintp)
Definition: libtetrabz_common.F90:340
libtetrabz_common::libtetrabz_triangle_a1
subroutine, public libtetrabz_triangle_a1(e, V, tsmall)
Definition: libtetrabz_common.F90:562
libtetrabz_dbldelta_mod
Definition: libtetrabz_dbldelta_mod.F90:23
libtetrabz_common
Definition: libtetrabz_common.F90:23
libtetrabz_dbldelta_mod::libtetrabz_dbldelta_main
subroutine libtetrabz_dbldelta_main(wlsm, nt_local, ik_global, ik_local, nb, nkBZ, eig1, eig2, nk_local, dbldelta)
Definition: libtetrabz_dbldelta_mod.F90:87
libtetrabz_common::libtetrabz_sort
subroutine, public libtetrabz_sort(n, key, indx)
Definition: libtetrabz_common.F90:308
libtetrabz_common::libtetrabz_triangle_b1
subroutine, public libtetrabz_triangle_b1(e, V, tsmall)
Definition: libtetrabz_common.F90:588