Branch data Line data Source code
1 : :
2 : : #if defined HAVE_CONFIG_H
3 : : #include "config.h"
4 : : #endif
5 : :
6 : : #include "abi_common.h"
7 : : !
8 : : ! Copyright (C) 2014 Mitsuaki Kawamura
9 : : !
10 : : ! Permission is hereby granted, free of charge, to any person obtaining a
11 : : ! copy of this software and associated documentation files (the
12 : : ! "Software"), to deal in the Software without restriction, including
13 : : ! without limitation the rights to use, copy, modify, merge, publish,
14 : : ! distribute, sublicense, and/or sell copies of the Software, and to
15 : : ! permit persons to whom the Software is furnished to do so, subject to
16 : : ! the following conditions:
17 : : !
18 : : ! The above copyright notice and this permission notice shall be included
19 : : ! in all copies or substantial portions of the Software.
20 : : !
21 : : ! THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 : : ! OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 : : ! MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
24 : : ! IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
25 : : ! CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 : : ! TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 : : ! SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28 : : !
29 : : MODULE libtetrabz_dbldelta_mod
30 : : !
31 : :
32 : : use m_abicore
33 : : use m_errors
34 : :
35 : : !IMPLICIT NONE
36 : : !
37 : : PRIVATE
38 : : PUBLIC :: libtetrabz_dbldelta
39 : : !
40 : : CONTAINS
41 : : !
42 : : ! Compute doubledelta
43 : : !
44 : 35 : SUBROUTINE libtetrabz_dbldelta(ltetra,bvec,nb,nge,eig1,eig2,ngw,wght,comm)
45 : : !
46 : : use, intrinsic :: iso_c_binding
47 : : USE libtetrabz_common, ONLY : libtetrabz_initialize, libtetrabz_interpol_indx, libtetrabz_mpisum_dv
48 : : !IMPLICIT NONE
49 : : !
50 : : INTEGER(C_INT),INTENT(IN) :: ltetra, nb, nge(3), ngw(3)
51 : : REAL(C_DOUBLE),INTENT(IN) :: bvec(9), eig1(nb,PRODUCT(nge(1:3))), eig2(nb,PRODUCT(nge(1:3)))
52 : : REAL(C_DOUBLE),INTENT(OUT) :: wght(nb*nb,PRODUCT(ngw(1:3)))
53 : : INTEGER(C_INT),INTENT(IN),OPTIONAL :: comm
54 : : !
55 : : LOGICAL :: linterpol
56 : : INTEGER :: nt_local, nk_local, nkBZ, ik, kintp(20), nintp
57 : 35 : INTEGER,ALLOCATABLE :: ik_global(:,:), ik_local(:,:)
58 : : REAL(8) :: wlsm(4,20), wintp(1,20)
59 : 35 : REAL(8),ALLOCATABLE :: wghtd(:,:,:), kvec(:,:)
60 : : !
61 : 35 : nintp = 16 * ltetra - 12
62 : : !
63 [ + - ]: 35 : IF(PRESENT(comm)) THEN
64 : : CALL libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,&
65 : 35 : & nt_local,nkBZ,ik_global,ik_local,kvec,comm)
66 : : ELSE
67 : : CALL libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,&
68 : 0 : & nt_local,nkBZ,ik_global,ik_local,kvec)
69 : : END IF
70 : : !
71 [ - + ]: 35 : IF(linterpol) THEN
72 : : !
73 [ # # # # : 0 : ABI_MALLOC(wghtd, (nb*nb,1,nk_local))
# # # # #
# # # # #
# # ]
74 : 0 : CALL libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkBZ,eig1,eig2,nk_local,wghtd)
75 : : !
76 : : ! Interpolation
77 : : !
78 [ # # # # : 0 : wght(1:nb*nb,1:PRODUCT(ngw(1:3))) = 0d0
# # ]
79 [ # # ]: 0 : DO ik = 1, nk_local
80 : 0 : CALL libtetrabz_interpol_indx(nintp,ngw,kvec(1:3,ik),kintp,wintp)
81 : : wght(1:nb*nb,kintp(1:nintp)) = wght(1:nb*nb, kintp(1:nintp)) &
82 [ # # # # : 0 : & + MATMUL(wghtd(1:nb*nb,1:1,ik), wintp(1:1,1:nintp))
# # # # #
# # # # #
# # # # #
# # # # #
# # # # #
# # # ]
83 : : END DO ! ik = 1, nk_local
84 [ # # ]: 0 : ABI_FREE(wghtd)
85 [ # # ]: 0 : ABI_FREE(kvec)
86 : : !
87 [ # # # # ]: 0 : IF(PRESENT(comm)) CALL libtetrabz_mpisum_dv(comm, nb*nb*PRODUCT(ngw(1:3)), wght)
88 : : !
89 : : ELSE
90 : 35 : CALL libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkBZ,eig1,eig2,nk_local,wght)
91 : : END IF
92 : : !
93 [ - + ]: 35 : ABI_FREE(ik_global)
94 [ - + ]: 35 : ABI_FREE(ik_local)
95 : : !
96 [ - + ]: 35 : END SUBROUTINE libtetrabz_dbldelta
97 : : !
98 : : ! Main SUBROUTINE for Delta(E1) * Delta(E2)
99 : : !
100 : 35 : SUBROUTINE libtetrabz_dbldelta_main(wlsm,nt_local,ik_global,ik_local,nb,nkBZ,eig1,eig2,nk_local,dbldelta)
101 : : !
102 : : USE libtetrabz_common, ONLY : libtetrabz_sort, &
103 : : & libtetrabz_triangle_a1, libtetrabz_triangle_b1, &
104 : : & libtetrabz_triangle_b2, libtetrabz_triangle_c1
105 : : !IMPLICIT NONE
106 : : !
107 : : INTEGER,INTENT(IN) :: nt_local, nb, nkBZ, nk_local, &
108 : : & ik_global(20,nt_local), ik_local(20,nt_local)
109 : : REAL(8),INTENT(IN) :: wlsm(4,20), eig1(nb,nkBZ), eig2(nb,nkBZ)
110 : : REAL(8),INTENT(OUT) :: dbldelta(nb,nb,nk_local)
111 : : !
112 : : INTEGER :: ib, indx(4), it
113 : 70 : REAL(8) :: e(4), ei1(4,nb), ej1(4,nb), ej2(3,nb), V, thr = 1d-10, &
114 : 35 : & tsmall(3,4), w1(nb,4), w2(nb,3)
115 : : !
116 [ + + + + : 125475 : dbldelta(1:nb,1:nb,1:nk_local) = 0d0
+ + ]
117 : : !
118 : : !$OMP PARALLEL DEFAULT(NONE) &
119 : : !$OMP & SHARED(dbldelta,eig1,eig2,ik_global,ik_local,nb,nt_local,thr,wlsm) &
120 : : !$OMP & PRIVATE(e,ei1,ej1,ej2,ib,indx,it,tsmall,V,w1,w2)
121 : : !
122 [ + + ]: 107555 : DO it = 1, nt_local
123 : : !
124 [ + + ]: 322560 : DO ib = 1, nb
125 [ + + + + : 27095040 : ei1(1:4,ib) = MATMUL(wlsm(1:4,1:20), eig1(ib, ik_global(1:20,it)))
+ + + + ]
126 [ + + + + : 27417600 : ej1(1:4,ib) = MATMUL(wlsm(1:4,1:20), eig2(ib, ik_global(1:20,it)))
+ + + + ]
127 : : END DO
128 : : !
129 : : !$OMP DO
130 [ + + ]: 322595 : DO ib = 1, nb
131 : : !
132 [ + + + + ]: 2795520 : w1(1:nb,1:4) = 0d0
133 [ + + ]: 1075200 : e(1:4) = ei1(1:4, ib)
134 : 215040 : CALL libtetrabz_sort(4,e,indx)
135 : : !
136 [ + + + + ]: 215040 : IF(e(1) < 0d0 .AND. 0d0 <= e(2)) THEN
137 : : !
138 : 28560 : CALL libtetrabz_triangle_a1(e,V,tsmall)
139 : : !
140 [ + - ]: 28560 : IF(V > thr) THEN
141 : : !
142 [ + + + + : 1570800 : ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
+ - + + +
+ + + + +
+ + + - ]
143 : 28560 : CALL libtetrabz_dbldelta2(nb,ej2,w2)
144 : : w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
145 [ - + + - : 1942080 : & + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
+ - - + -
+ + + + +
+ + + + +
+ + + + +
+ - ]
146 : : !
147 : : END IF
148 : : !
149 [ + + + + ]: 186480 : ELSE IF( e(2) < 0d0 .AND. 0d0 <= e(3)) THEN
150 : : !
151 : 17640 : CALL libtetrabz_triangle_b1(e,V,tsmall)
152 : : !
153 [ + - ]: 17640 : IF(V > thr) THEN
154 : : !
155 [ + + + + : 970200 : ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
+ - + + +
+ + + + +
+ + + - ]
156 : 17640 : CALL libtetrabz_dbldelta2(nb,ej2,w2)
157 : : w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
158 [ - + + - : 1199520 : & + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
+ - - + -
+ + + + +
+ + + + +
+ + + + +
+ - ]
159 : : !
160 : : END IF
161 : : !
162 : 17640 : CALL libtetrabz_triangle_b2(e,V,tsmall)
163 : : !
164 [ + - ]: 17640 : IF(V > thr) THEN
165 : : !
166 [ + + + + : 970200 : ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
+ - + + +
+ + + + +
+ + + - ]
167 : 17640 : CALL libtetrabz_dbldelta2(nb,ej2,w2)
168 : : w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
169 [ - + + - : 1199520 : & + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
+ - - + -
+ + + + +
+ + + + +
+ + + + +
+ - ]
170 : : !
171 : : END IF
172 : : !
173 [ + + + + ]: 168840 : ELSE IF(e(3) < 0d0 .AND. 0d0 < e(4)) THEN
174 : : !
175 : 10920 : CALL libtetrabz_triangle_c1(e,V,tsmall)
176 : : !
177 [ + - ]: 10920 : IF(V > thr) THEN
178 : : !
179 [ + + + + : 600600 : ej2(1:3,1:nb) = MATMUL(tsmall(1:3,1:4), ej1(indx(1:4),1:nb))
+ - + + +
+ + + + +
+ + + - ]
180 : 10920 : CALL libtetrabz_dbldelta2(nb,ej2,w2)
181 : : w1(1:nb,indx(1:4)) = w1(1:nb, indx(1:4)) &
182 [ - + + - : 742560 : & + V * MATMUL(w2(1:nb,1:3), tsmall(1:3,1:4))
+ - - + -
+ + + + +
+ + + + +
+ + + + +
+ - ]
183 : : !
184 : : END IF
185 : : !
186 : : END IF
187 : : !
188 : : dbldelta(1:nb,ib,ik_local(1:20,it)) = dbldelta(1:nb,ib, ik_local(1:20,it)) &
189 [ - + + - : 95800320 : & + MATMUL(w1(1:nb,1:4), wlsm(1:4,1:20))
+ - - + -
+ + + + +
+ + + + +
+ + + + +
+ + + + +
- ]
190 : : !
191 : : END DO ! ib
192 : : !$OMP END DO NOWAIT
193 : : !
194 : : END DO ! it
195 : : !
196 : : !$OMP END PARALLEL
197 : : !
198 [ + + + + : 125475 : dbldelta(1:nb,1:nb,1:nk_local) = dbldelta(1:nb,1:nb,1:nk_local) / DBLE(6 * nkBZ)
+ + ]
199 : : !
200 : 35 : END SUBROUTINE libtetrabz_dbldelta_main
201 : : !
202 : : ! 2nd step of tetrahedra method.
203 : : !
204 : 74760 : SUBROUTINE libtetrabz_dbldelta2(nb,ej,w)
205 : : !
206 : : USE libtetrabz_common, ONLY : libtetrabz_sort
207 : : !IMPLICIT NONE
208 : : !
209 : : INTEGER,INTENT(IN) :: nb
210 : : REAL(8),INTENT(IN) :: ej(3,nb)
211 : : REAL(8),INTENT(INOUT) :: w(nb,3)
212 : : !
213 : : INTEGER :: ib, ii, indx(3)
214 : : REAL(8) :: a(3,3), e(3), V
215 : : REAL(8) :: ediff(3)
216 : : !character(len=500) :: msg
217 : : !
218 [ + + ]: 224280 : DO ib = 1, nb
219 : : !
220 [ - + + - : 747600 : IF(maxval(ABS(ej(1:3,ib))) < 1d-10) then
+ + - + ]
221 : : ! MG reduce tolerance wrt original version.
222 : : !IF(maxval(ABS(ej(1:3,ib))) < 1d-22) then
223 : : !write(std_out, ej(1:3,ib))
224 : : !write(msg, *)"Nesting for band index:", ib, "ej:", ej(1:3,ib)
225 : : !ABI_WARNING(msg)
226 : : !ABI_ERROR(msg)
227 : : !ABI_ERROR("STOP Nesting !!")
228 [ # # ]: 0 : w(ib,1:3) = 0d0
229 : : cycle
230 : : end if
231 : : !
232 [ + + ]: 598080 : w(ib,1:3) = 0d0
233 [ + + ]: 598080 : e(1:3) = ej(1:3, ib)
234 : 149520 : CALL libtetrabz_sort(3,e,indx)
235 : : !
236 [ + + ]: 598080 : DO ii = 1, 3
237 [ + + ]: 1794240 : ediff = e(1:3) - e(ii)
238 [ + + + + ]: 1794240 : where (abs(ediff) < 1.e-10)
239 : : ediff = 1.e-10
240 : : end where
241 [ + + ]: 1943760 : a(1:3,ii) = (0d0 - e(ii)) / ediff
242 : : !a(1:3,ii) = (0d0 - e(ii)) / (e(1:3) - e(ii))
243 : : END DO
244 : : !
245 [ + + + + : 224280 : IF((e(1) < 0d0 .AND. 0d0 <= e(2)) .OR. (e(1) <= 0d0 .AND. 0d0 < e(2))) THEN
+ + - + ]
246 : : !
247 : : !V = a(2,1) * a(3,1) / (0d0 - e(1))
248 : 7355 : V = a(2,1) / (e(3) - e(1))
249 : : !
250 : 7355 : w(ib,indx(1)) = V * (a(1,2) + a(1,3))
251 : 7355 : w(ib,indx(2)) = V * a(2,1)
252 : 7355 : w(ib,indx(3)) = V * a(3,1)
253 : : !
254 [ + + + + : 142165 : ELSE IF((e(2) <= 0d0 .AND. 0d0 < e(3)) .OR. (e(2) < 0d0 .AND. 0d0 <= e(3))) THEN
+ + - + ]
255 : : !
256 : : !V = a(1,3) * a(2,3) / (e(3) - 0d0)
257 : 6848 : V = a(2,3) / (e(3) - e(1))
258 : : !
259 : 6848 : w(ib,indx(1)) = V * a(1,3)
260 : 6848 : w(ib,indx(2)) = V * a(2,3)
261 : 6848 : w(ib,indx(3)) = V * (a(3,1) + a(3,2))
262 : : !
263 : : END IF
264 : : !
265 : : END DO ! ib
266 : : !
267 : 74760 : END SUBROUTINE libtetrabz_dbldelta2
268 : : !
269 [ - - + - : 289800 : END MODULE libtetrabz_dbldelta_mod
+ - + - +
- + - ]
|