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_common
30 : : !
31 : : use m_abicore
32 : : use m_errors
33 : : USE_MPI
34 : :
35 : : IMPLICIT NONE
36 : :
37 : : #if defined HAVE_MPI1
38 : : include 'mpif.h'
39 : : #endif
40 : : !
41 : : PRIVATE
42 : :
43 : : PUBLIC :: libtetrabz_initialize, libtetrabz_sort, libtetrabz_interpol_indx, &
44 : : & libtetrabz_tsmall_a1, libtetrabz_tsmall_b1, libtetrabz_tsmall_b2, libtetrabz_tsmall_b3, &
45 : : & libtetrabz_tsmall_c1, libtetrabz_tsmall_c2, libtetrabz_tsmall_c3, &
46 : : & libtetrabz_triangle_a1, libtetrabz_triangle_b1, &
47 : : & libtetrabz_triangle_b2, libtetrabz_triangle_c1, &
48 : : & libtetrabz_mpisum_d, libtetrabz_mpisum_dv, libtetrabz_mpisum_zv
49 : : !
50 : :
51 : : CONTAINS
52 : : !
53 : : ! define shortest diagonal line & define type of tetragonal
54 : : !
55 : 35 : SUBROUTINE libtetrabz_initialize(ltetra,nge,ngw,bvec,linterpol,wlsm,nk_local,nt_local,nkBZ,ik_global,ik_local,kvec,comm)
56 : : !
57 : : !IMPLICIT NONE
58 : : !
59 : : INTEGER,INTENT(IN) :: ltetra, nge(3), ngw(3)
60 : : REAL(8),INTENT(IN) :: bvec(3,3)
61 : : LOGICAL,INTENT(OUT) :: linterpol
62 : : REAL(8),INTENT(OUT) :: wlsm(4,20)
63 : : INTEGER,INTENT(OUT) :: nk_local, nt_local, nkBZ
64 : : INTEGER,INTENT(OUT),ALLOCATABLE :: ik_global(:,:), ik_local(:,:)
65 : : REAL(8),INTENT(OUT),ALLOCATABLE :: kvec(:,:)
66 : : INTEGER,INTENT(IN),OPTIONAL :: comm
67 : : !
68 : : INTEGER :: itype, i1, i2, i3, it, divvec(4,4), ivvec0(4), ivvec(3,20,6)
69 : : REAL(8) :: l(4), bvec2(3,3), bvec3(3,4)
70 : : !
71 [ + + ]: 140 : nkBZ = PRODUCT(nge(1:3))
72 [ + + + - ]: 140 : linterpol = .NOT. ALL(nge(1:3) == ngw(1:3))
73 : : !
74 [ + + ]: 140 : DO i1 = 1, 3
75 [ + + ]: 455 : bvec2(1:3,i1) = bvec(1:3,i1) / DBLE(nge(i1))
76 : : END DO
77 : : !
78 [ + + ]: 140 : bvec3(1:3,1) = -bvec2(1:3,1) + bvec2(1:3,2) + bvec2(1:3,3)
79 [ + + ]: 140 : bvec3(1:3,2) = bvec2(1:3,1) - bvec2(1:3,2) + bvec2(1:3,3)
80 [ + + ]: 140 : bvec3(1:3,3) = bvec2(1:3,1) + bvec2(1:3,2) - bvec2(1:3,3)
81 [ + + ]: 140 : bvec3(1:3,4) = bvec2(1:3,1) + bvec2(1:3,2) + bvec2(1:3,3)
82 : : !
83 : : ! length of delta bvec
84 : : !
85 [ + + ]: 175 : DO i1 = 1, 4
86 [ + + ]: 595 : l(i1) = DOT_PRODUCT(bvec3(1:3,i1),bvec3(1:3,i1))
87 : : END DO
88 : : !
89 [ + - + - : 210 : itype = MINLOC(l(1:4),1)
+ + + + ]
90 : : !
91 : : ! start & last
92 : : !
93 : 35 : ivvec0(1:4) = (/ 0, 0, 0, 0 /)
94 : : !
95 [ + + ]: 175 : divvec(1:4,1) = (/ 1, 0, 0, 0 /)
96 [ + + ]: 175 : divvec(1:4,2) = (/ 0, 1, 0, 0 /)
97 [ + + ]: 175 : divvec(1:4,3) = (/ 0, 0, 1, 0 /)
98 : : divvec(1:4,4) = (/ 0, 0, 0, 1 /)
99 : : !
100 : 35 : ivvec0(itype) = 1
101 : 35 : divvec(itype, itype) = - 1
102 : : !
103 : : ! Corners of tetrahedra
104 : : !
105 : 35 : it = 0
106 [ + + ]: 140 : DO i1 = 1, 3
107 [ + + ]: 455 : DO i2 = 1, 3
108 [ + + ]: 315 : IF(i2 == i1) CYCLE
109 [ + + ]: 945 : DO i3 = 1, 3
110 [ + + ]: 630 : IF(i3 == i1 .OR. i3 == i2) CYCLE
111 : : !
112 : 210 : it = it + 1
113 : : !
114 [ + + ]: 840 : ivvec(1:3,1,it) = ivvec0(1:3)
115 [ + + ]: 840 : ivvec(1:3,2,it) = ivvec(1:3,1,it) + divvec(1:3,i1)
116 [ + + ]: 840 : ivvec(1:3,3,it) = ivvec(1:3,2,it) + divvec(1:3,i2)
117 [ + + ]: 1155 : ivvec(1:3,4,it) = ivvec(1:3,3,it) + divvec(1:3,i3)
118 : : !
119 : : END DO
120 : : END DO
121 : : END DO
122 : : !
123 : : ! Additional points
124 : : !
125 [ + + + + ]: 875 : ivvec(1:3, 5,1:6) = 2 * ivvec(1:3,1,1:6) - ivvec(1:3,2,1:6)
126 [ + + + + ]: 875 : ivvec(1:3, 6,1:6) = 2 * ivvec(1:3,2,1:6) - ivvec(1:3,3,1:6)
127 [ + + + + ]: 875 : ivvec(1:3, 7,1:6) = 2 * ivvec(1:3,3,1:6) - ivvec(1:3,4,1:6)
128 [ + + + + ]: 875 : ivvec(1:3, 8,1:6) = 2 * ivvec(1:3,4,1:6) - ivvec(1:3,1,1:6)
129 : : !
130 [ + + + + ]: 875 : ivvec(1:3, 9,1:6) = 2 * ivvec(1:3,1,1:6) - ivvec(1:3,3,1:6)
131 [ + + + + ]: 875 : ivvec(1:3,10,1:6) = 2 * ivvec(1:3,2,1:6) - ivvec(1:3,4,1:6)
132 [ + + + + ]: 875 : ivvec(1:3,11,1:6) = 2 * ivvec(1:3,3,1:6) - ivvec(1:3,1,1:6)
133 [ + + + + ]: 875 : ivvec(1:3,12,1:6) = 2 * ivvec(1:3,4,1:6) - ivvec(1:3,2,1:6)
134 : : !
135 [ + + + + ]: 875 : ivvec(1:3,13,1:6) = 2 * ivvec(1:3,1,1:6) - ivvec(1:3,4,1:6)
136 [ + + + + ]: 875 : ivvec(1:3,14,1:6) = 2 * ivvec(1:3,2,1:6) - ivvec(1:3,1,1:6)
137 [ + + + + ]: 875 : ivvec(1:3,15,1:6) = 2 * ivvec(1:3,3,1:6) - ivvec(1:3,2,1:6)
138 [ + + + + ]: 875 : ivvec(1:3,16,1:6) = 2 * ivvec(1:3,4,1:6) - ivvec(1:3,3,1:6)
139 : : !
140 [ + + + + ]: 875 : ivvec(1:3,17,1:6) = ivvec(1:3,4,1:6) - ivvec(1:3,1,1:6) + ivvec(1:3,2,1:6)
141 [ + + + + ]: 875 : ivvec(1:3,18,1:6) = ivvec(1:3,1,1:6) - ivvec(1:3,2,1:6) + ivvec(1:3,3,1:6)
142 [ + + + + ]: 875 : ivvec(1:3,19,1:6) = ivvec(1:3,2,1:6) - ivvec(1:3,3,1:6) + ivvec(1:3,4,1:6)
143 [ + + + + ]: 875 : ivvec(1:3,20,1:6) = ivvec(1:3,3,1:6) - ivvec(1:3,4,1:6) + ivvec(1:3,1,1:6)
144 : : !
145 [ - + ]: 35 : IF(ltetra == 1) THEN
146 : : !
147 : : !WRITE(*,*) "[libtetrabz] Linear tetrahedron method is used."
148 : : !
149 : 0 : wlsm(1:4,1:20) = 0.0d0
150 : 0 : wlsm(1,1) = 1.0d0
151 : 0 : wlsm(2,2) = 1.0d0
152 : 0 : wlsm(3,3) = 1.0d0
153 : 0 : wlsm(4,4) = 1.0d0
154 : : !
155 [ + - ]: 35 : ELSE IF(ltetra == 2) THEN
156 : : !
157 : : !WRITE(*,*) "[libtetrabz] Improved tetrahedron method is used."
158 : : !
159 [ + + ]: 175 : wlsm(1, 1: 4) = DBLE((/1440, 0, 30, 0/))
160 [ + + ]: 175 : wlsm(2, 1: 4) = DBLE((/ 0, 1440, 0, 30/))
161 [ + + ]: 175 : wlsm(3, 1: 4) = DBLE((/ 30, 0, 1440, 0/))
162 [ + + ]: 175 : wlsm(4, 1: 4) = DBLE((/ 0, 30, 0, 1440/))
163 : : !
164 [ + + ]: 175 : wlsm(1, 5: 8) = DBLE((/ -38, 7, 17, -28/))
165 [ + + ]: 175 : wlsm(2, 5: 8) = DBLE((/ -28, -38, 7, 17/))
166 [ + + ]: 175 : wlsm(3, 5: 8) = DBLE((/ 17, -28, -38, 7/))
167 [ + + ]: 175 : wlsm(4, 5: 8) = DBLE((/ 7, 17, -28, -38/))
168 : : !
169 [ + + ]: 175 : wlsm(1, 9:12) = DBLE((/ -56, 9, -46, 9/))
170 [ + + ]: 175 : wlsm(2, 9:12) = DBLE((/ 9, -56, 9, -46/))
171 [ + + ]: 175 : wlsm(3, 9:12) = DBLE((/ -46, 9, -56, 9/))
172 [ + + ]: 175 : wlsm(4, 9:12) = DBLE((/ 9, -46, 9, -56/))
173 : : !
174 [ + + ]: 175 : wlsm(1,13:16) = DBLE((/ -38, -28, 17, 7/))
175 [ + + ]: 175 : wlsm(2,13:16) = DBLE((/ 7, -38, -28, 17/))
176 [ + + ]: 175 : wlsm(3,13:16) = DBLE((/ 17, 7, -38, -28/))
177 [ + + ]: 175 : wlsm(4,13:16) = DBLE((/ -28, 17, 7, -38/))
178 : : !
179 [ + + ]: 175 : wlsm(1,17:20) = DBLE((/ -18, -18, 12, -18/))
180 [ + + ]: 175 : wlsm(2,17:20) = DBLE((/ -18, -18, -18, 12/))
181 [ + + ]: 175 : wlsm(3,17:20) = DBLE((/ 12, -18, -18, -18/))
182 [ + + ]: 175 : wlsm(4,17:20) = DBLE((/ -18, 12, -18, -18/))
183 : : !
184 [ + + + + ]: 3535 : wlsm(1:4,1:20) = wlsm(1:4,1:20) / 1260d0
185 : : !
186 : : ELSE
187 : : !
188 : 0 : ABI_ERROR("[libtetrabz] STOP! ltetrta is invalid.")
189 : : !
190 : : END IF
191 : : !
192 [ + - ]: 35 : IF (PRESENT(comm)) THEN
193 [ - + - + : 35 : CALL libtetrabz_kgrid(linterpol,ivvec,nge,nkBZ,nk_local,nt_local,ik_global,ik_local,kvec,comm)
- + ]
194 : : ELSE
195 [ # # # # : 0 : CALL libtetrabz_kgrid(linterpol,ivvec,nge,nkBZ,nk_local,nt_local,ik_global,ik_local,kvec)
# # ]
196 : : END IF
197 : : !
198 : 35 : END SUBROUTINE libtetrabz_initialize
199 : : !
200 : : ! Initialize grid
201 : : !
202 : 35 : SUBROUTINE libtetrabz_kgrid(linterpol,ivvec,ng,nkBZ,nk_local,nt_local,ik_global,ik_local,kvec,comm)
203 : : !
204 : : !IMPLICIT NONE
205 : : !
206 : : LOGICAL,INTENT(INOUT) :: linterpol
207 : : INTEGER,INTENT(IN) :: ivvec(3,20,6), ng(3), nkBZ
208 : : INTEGER,INTENT(OUT) :: nk_local, nt_local
209 : : INTEGER,INTENT(OUT),ALLOCATABLE :: ik_global(:,:), ik_local(:,:)
210 : : REAL(8),INTENT(OUT),ALLOCATABLE :: kvec(:,:)
211 : : INTEGER,INTENT(IN),OPTIONAL :: comm
212 : : !
213 : 35 : INTEGER :: it, i1, i2, i3, ii, ikv(3), nt, ik, nt_front, loc2glob(nkBZ), glob2loc(nkBZ)
214 : : !
215 [ + - ]: 35 : IF(PRESENT(comm)) THEN
216 : 35 : CALL libtetrabz_divideMPI(comm,6 * nkBZ,nt_front,nt_local)
217 [ + - - + ]: 35 : linterpol = linterpol .OR. (6*nkBZ /= nt_local)
218 : : ELSE
219 : 0 : nt_front = 0
220 : 0 : nt_local = 6 * nkBZ
221 : : END IF
222 [ - + + - : 105 : ABI_MALLOC(ik_global, (20, nt_local))
+ - + - -
+ - + -
+ ]
223 [ - + + - : 70 : ABI_MALLOC(ik_local, (20, nt_local))
- + - + -
+ ]
224 : : !
225 : : ! k-index for energy (Global index)
226 : : !
227 : 35 : nt = 0
228 [ + + ]: 315 : DO i3 = 1, ng(3)
229 [ + + ]: 2555 : DO i2 = 1, ng(2)
230 [ + + ]: 20440 : DO i1 = 1, ng(1)
231 : : !
232 [ + + ]: 127680 : DO it = 1, 6
233 : : !
234 : 107520 : nt = nt + 1
235 [ + - - + ]: 107520 : IF(nt <= nt_front .OR. nt_front + nt_local < nt) CYCLE
236 : : !
237 [ + + ]: 2275840 : DO ii = 1, 20
238 : : !
239 [ + + ]: 8601600 : ikv(1:3) = (/i1, i2, i3/) + ivvec(1:3,ii,it) - 1
240 [ + + ]: 8601600 : ikv(1:3) = MODULO(ikv(1:3), ng(1:3))
241 : : !
242 : 2257920 : ik_global(ii,nt - nt_front) = 1 + ikv(1) + ng(1) * ikv(2) + ng(1) * ng(2) * ikv(3)
243 : : !
244 : : END DO
245 : : !
246 : : END DO
247 : : !
248 : : END DO
249 : : END DO
250 : : END DO
251 : : !
252 : : ! k-index for weight (Local index)
253 : : !
254 [ + - ]: 35 : IF(.NOT. linterpol) THEN
255 : 35 : nk_local = nkBZ
256 [ + + + + ]: 2257955 : ik_local(1:20,1:nt_local) = ik_global(1:20,1:nt_local)
257 : : RETURN
258 : : END IF
259 : : !
260 [ # # ]: 0 : glob2loc(1:nkBZ) = 0
261 : 0 : nk_local = 0
262 [ # # ]: 0 : DO nt = 1, nt_local
263 [ # # ]: 0 : DO ii = 1, 20
264 : : !
265 [ # # ]: 0 : IF(glob2loc(ik_global(ii,nt)) /= 0) THEN
266 : 0 : ik_local(ii,nt) = glob2loc(ik_global(ii,nt))
267 : : ELSE
268 : : !
269 : 0 : nk_local = nk_local + 1
270 : 0 : loc2glob(nk_local) = ik_global(ii,nt)
271 : 0 : glob2loc(ik_global(ii,nt)) = nk_local
272 : 0 : ik_local(ii,nt) = nk_local
273 : : !
274 : : END IF
275 : : !
276 : : END DO
277 : : END DO
278 : : !
279 : : ! k-vector in the fractional coordinate
280 : : !
281 [ # # # # : 0 : ABI_MALLOC(kvec, (3,nk_local))
# # # # #
# # # #
# ]
282 [ # # ]: 0 : DO ik = 1, nk_local
283 : : ! loc2glob(ik) - 1 = i1 + ng(1) * i2 + ng(1) * ng(2) * i3
284 : 0 : i1 = MOD(loc2glob(ik) - 1, ng(1))
285 : 0 : i2 = MOD((loc2glob(ik) - 1) / ng(1), ng(2))
286 : 0 : i3 = (loc2glob(ik) - 1) / (ng(1) * ng(2))
287 [ # # ]: 0 : kvec(1:3,ik) = DBLE((/i1, i2, i3/)) / DBLE(ng(1:3))
288 : : END DO
289 : : !
290 : : END SUBROUTINE libtetrabz_kgrid
291 : : !
292 : : ! Compute cnt and dsp
293 : : !
294 : 35 : SUBROUTINE libtetrabz_divideMPI(comm,nt,nt_front,nt_local)
295 : : !
296 : : !IMPLICIT NONE
297 : : !
298 : : INTEGER,INTENT(IN) :: comm, nt
299 : : INTEGER,INTENT(OUT) :: nt_front, nt_local
300 : : !
301 : : INTEGER :: petot = 1, my_rank = 0
302 : : #if defined(HAVE_MPI)
303 : : INTEGER :: ierr
304 : 35 : CALL MPI_COMM_SIZE(comm, petot, ierr)
305 : 35 : CALL MPI_COMM_RANK(comm, my_rank, ierr)
306 : : #endif
307 : : !
308 [ - + ]: 35 : IF(my_rank < MOD(nt, petot)) THEN
309 : 0 : nt_local = nt / petot + 1
310 : 0 : nt_front = my_rank * nt_local
311 : : ELSE
312 : 35 : nt_local = nt / petot
313 : 35 : nt_front = my_rank * nt_local + MOD(nt, petot)
314 : : END IF
315 : : !
316 : 35 : END SUBROUTINE libtetrabz_divideMPI
317 : : !
318 : : ! Simple sort
319 : : !
320 : 364560 : pure SUBROUTINE libtetrabz_sort(n,key,indx)
321 : : !
322 : : !IMPLICIT NONE
323 : : !
324 : : integer,INTENT(IN) :: n
325 : : REAL(8),INTENT(inout) :: key(n)
326 : : INTEGER,INTENT(OUT) :: indx(n)
327 : : !
328 : : INTEGER :: i, i0, indx0
329 : : REAL(8) :: key0
330 : : !
331 [ + + ]: 1673280 : DO i = 1, n
332 : 1673280 : indx(i) = i
333 : : END DO
334 : : !
335 [ + + ]: 1308720 : DO i = 1, n - 1
336 [ + - - + : 3627120 : key0 = MINVAL(key(i+1:n))
- - + + ]
337 [ + - + - : 2682960 : i0 = MINLOC(key(i+1:n),1) + i
- - + + +
+ ]
338 [ + + ]: 1308720 : IF(key(i) > key0) THEN
339 : 552154 : key(i0) = key(i)
340 : 552154 : key(i) = key0
341 : : !
342 : 552154 : indx0 = indx(i0)
343 : 552154 : indx(i0) = indx(i)
344 : 552154 : indx(i) = indx0
345 : : END IF
346 : : END DO
347 : : !
348 : 364560 : END SUBROUTINE libtetrabz_sort
349 : : !
350 : : ! Linear interpolation
351 : : !
352 : 0 : pure SUBROUTINE libtetrabz_interpol_indx(nintp,ng,kvec,kintp,wintp)
353 : : !
354 : : !IMPLICIT NONE
355 : : !
356 : : INTEGER,INTENT(in) :: nintp, ng(3)
357 : : REAL(8),INTENT(in) :: kvec(3)
358 : : INTEGER,INTENT(out) :: kintp(nintp)
359 : : REAL(8),INTENT(out) :: wintp(nintp)
360 : : !
361 : : INTEGER :: ikv(3,20), dikv(3,3), ii
362 : : REAL(8) :: x, y, z, xv(3)
363 : : !
364 : : ! Search nearest neighbor grid points.
365 : : !
366 [ # # ]: 0 : xv(1:3) = kvec(1:3) * DBLE(ng(1:3))
367 [ # # ]: 0 : ikv(1:3,1) = NINT(xv(1:3))
368 : 0 : dikv(1:3,1:3) = 0
369 [ # # ]: 0 : DO ii = 1, 3
370 [ # # ]: 0 : dikv(ii,ii) = ikv(ii,1) - FLOOR(xv(ii))
371 : 0 : dikv(ii,ii) = 1 - 2 * dikv(ii,ii)
372 : : END DO
373 [ # # ]: 0 : xv(1:3) = ABS(xv(1:3) - DBLE(ikv(1:3,1)))
374 : 0 : x = xv(1)
375 : 0 : y = xv(2)
376 : 0 : z = xv(3)
377 : : !
378 [ # # ]: 0 : ikv(1:3, 2) = ikv(1:3,1) + dikv(1:3,1)
379 [ # # ]: 0 : ikv(1:3, 3) = ikv(1:3,1) + dikv(1:3,2)
380 [ # # ]: 0 : ikv(1:3, 4) = ikv(1:3,1) + dikv(1:3,3)
381 : : !
382 [ # # ]: 0 : IF(nintp == 4) THEN
383 : : !
384 : 0 : wintp(1) = 1d0 - x - y - z
385 : 0 : wintp(2) = x
386 : 0 : wintp(3) = y
387 : 0 : wintp(4) = z
388 : : !
389 : : ELSE
390 : : !
391 [ # # # # ]: 0 : ikv(1:3, 5) = ikv(1:3,1) + SUM(dikv(1:3,1:3), 2)
392 : : !
393 [ # # ]: 0 : ikv(1:3, 6) = ikv(1:3,1) - dikv(1:3,1)
394 [ # # ]: 0 : ikv(1:3, 7) = ikv(1:3,1) - dikv(1:3,2)
395 [ # # ]: 0 : ikv(1:3, 8) = ikv(1:3,1) - dikv(1:3,3)
396 : : !
397 [ # # ]: 0 : ikv(1:3, 9) = ikv(1:3,1) + 2*dikv(1:3,1)
398 [ # # ]: 0 : ikv(1:3,10) = ikv(1:3,1) + 2*dikv(1:3,2)
399 [ # # ]: 0 : ikv(1:3,11) = ikv(1:3,1) + 2*dikv(1:3,3)
400 : : !
401 [ # # ]: 0 : ikv(1:3,12) = ikv(1:3,1) + dikv(1:3,2) + dikv(1:3,3)
402 [ # # ]: 0 : ikv(1:3,13) = ikv(1:3,1) + dikv(1:3,3) + dikv(1:3,1)
403 [ # # ]: 0 : ikv(1:3,14) = ikv(1:3,1) + dikv(1:3,1) + dikv(1:3,2)
404 : : !
405 [ # # ]: 0 : ikv(1:3,15) = ikv(1:3,1) - dikv(1:3,1) + dikv(1:3,3)
406 [ # # ]: 0 : ikv(1:3,16) = ikv(1:3,1) - dikv(1:3,2) + dikv(1:3,1)
407 [ # # ]: 0 : ikv(1:3,17) = ikv(1:3,1) - dikv(1:3,3) + dikv(1:3,2)
408 : : !
409 [ # # ]: 0 : ikv(1:3,18) = ikv(1:3,1) + dikv(1:3,1) - dikv(1:3,3)
410 [ # # ]: 0 : ikv(1:3,19) = ikv(1:3,1) + dikv(1:3,2) - dikv(1:3,1)
411 [ # # ]: 0 : ikv(1:3,20) = ikv(1:3,1) + dikv(1:3,3) - dikv(1:3,2)
412 : : !
413 : : wintp( 1) = ( (x - 2d0)*(x - 1d0)*(1d0 + x) &
414 : : & + (y - 2d0)*(y - 1d0)*(1d0 + y) &
415 : : & + (z - 2d0)*(z - 1d0)*(1d0 + z) &
416 : : & + 2d0*(x*y + y*z + z*x)*(x + y + z - 1d0) &
417 : 0 : & - 8d0*x*y*z - 4d0) * 0.5d0
418 : : wintp( 2) = x * ( 2d0 + x*(1d0 - x - y - z) &
419 : : & + y*(1d0 - 2d0*y + z) &
420 : 0 : & + z*(1d0 - 2d0*z + y)) * 0.5d0
421 : : wintp( 3) = y * ( 2d0 + y*(1d0 - x - y - z) &
422 : : & + x*(1d0 - 2d0*x + z) &
423 : 0 : & + z*(1d0 - 2d0*z + x)) * 0.5d0
424 : : wintp( 4) = z * ( 2d0 + z*(1d0 - x - y - z) &
425 : : & + y*(1d0 - 2d0*y + x) &
426 : 0 : & + x*(1d0 - 2d0*x + y)) * 0.5d0
427 : 0 : wintp( 5) = x * y * z
428 : 0 : wintp( 6) = x * (1d0 - x) * ( x + 3d0*y + 3d0*z - 2d0) / 6d0
429 : 0 : wintp( 7) = y * (1d0 - y) * (3d0*x + y + 3d0*z - 2d0) / 6d0
430 : 0 : wintp( 8) = z * (1d0 - z) * (3d0*x + 3d0*y + z - 2d0) / 6d0
431 : 0 : wintp( 9) = x * (x - 1d0) * (x + 1d0) / 6d0
432 : 0 : wintp(10) = y * (y - 1d0) * (y + 1d0) / 6d0
433 : 0 : wintp(11) = z * (z - 1d0) * (z + 1d0) / 6d0
434 : 0 : wintp(12) = y * z * (y + z - 2d0 * x) * 0.5d0
435 : 0 : wintp(13) = z * x * (z + x - 2d0 * y) * 0.5d0
436 : 0 : wintp(14) = x * y * (x + y - 2d0 * z) * 0.5d0
437 : 0 : wintp(15) = x * z * (x - 1d0) * 0.5d0
438 : 0 : wintp(16) = x * y * (y - 1d0) * 0.5d0
439 : 0 : wintp(17) = y * z * (z - 1d0) * 0.5d0
440 : 0 : wintp(18) = x * z * (z - 1d0) * 0.5d0
441 : 0 : wintp(19) = x * y * (x - 1d0) * 0.5d0
442 : 0 : wintp(20) = y * z * (y - 1d0) * 0.5d0
443 : : !
444 : : END IF
445 : : !
446 [ # # ]: 0 : DO ii = 1, nintp
447 [ # # ]: 0 : ikv(1:3,ii) = MODULO(ikv(1:3,ii), ng(1:3))
448 : 0 : kintp(ii) = 1 + ikv(1,ii) + ng(1) * ikv(2,ii) + ng(1) * ng(2) * ikv(3,ii)
449 : : END DO
450 : : !
451 : 0 : END SUBROUTINE libtetrabz_interpol_indx
452 : :
453 [ - + ]: 74760 : pure function a_from_e(e) result(a)
454 : :
455 : : !IMPLICIT NONE
456 : : REAL(8),INTENT(IN) :: e(4)
457 : : REAL(8) :: a(4,4)
458 : :
459 : : INTEGER :: ii
460 : : REAL(8) :: ediff(4)
461 : :
462 [ + + ]: 373800 : DO ii = 1, 4
463 [ + + ]: 1495200 : ediff = e(1:4) - e(ii)
464 [ + + + + ]: 1495200 : where (abs(ediff) < 1.e-10)
465 : : ediff = 1.e-10
466 : : end where
467 [ + + ]: 1569960 : a(1:4,ii) = (0d0 - e(ii)) / ediff
468 : : END DO
469 : :
470 : 74760 : end function a_from_e
471 : :
472 : : !
473 : : ! Cut small tetrahedron A1
474 : : !
475 : 0 : pure SUBROUTINE libtetrabz_tsmall_a1(e,V,tsmall)
476 : : !
477 : : !IMPLICIT NONE
478 : : !
479 : : REAL(8),INTENT(IN) :: e(4)
480 : : REAL(8),INTENT(OUT) :: V
481 : : REAL(8),INTENT(OUT) :: tsmall(4,4)
482 : : !
483 : : !INTEGER :: ii
484 : : REAL(8) :: a(4,4)
485 : : !
486 : 0 : a = a_from_e(e)
487 : : !DO ii = 1, 4
488 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
489 : : !END DO
490 : : !
491 : 0 : V = a(2,1) * a(3,1) * a(4,1)
492 : : !
493 [ # # ]: 0 : tsmall(1, 1:4) = (/ 1d0, 0d0, 0d0, 0d0/)
494 [ # # ]: 0 : tsmall(2, 1:4) = (/a(1,2), a(2,1), 0d0, 0d0/)
495 [ # # ]: 0 : tsmall(3, 1:4) = (/a(1,3), 0d0, a(3,1), 0d0/)
496 [ # # ]: 0 : tsmall(4, 1:4) = (/a(1,4), 0d0, 0d0, a(4,1)/)
497 : : !
498 : 0 : END SUBROUTINE libtetrabz_tsmall_a1
499 : : !
500 : : ! Cut small tetrahedron B1
501 : : !
502 : 0 : pure SUBROUTINE libtetrabz_tsmall_b1(e,V,tsmall)
503 : : !
504 : : !IMPLICIT NONE
505 : : !
506 : : REAL(8),INTENT(IN) :: e(4)
507 : : REAL(8),INTENT(OUT) :: V
508 : : REAL(8),INTENT(OUT) :: tsmall(4,4)
509 : : !
510 : : !INTEGER :: ii
511 : : REAL(8) :: a(4,4)
512 : : !
513 : 0 : a = a_from_e(e)
514 : : !DO ii = 1, 4
515 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
516 : : !END DO
517 : : !
518 : 0 : V = a(3,1) * a(4,1) * a(2,4)
519 : : !
520 [ # # ]: 0 : tsmall(1, 1:4) = (/ 1d0, 0d0, 0d0, 0d0/)
521 [ # # ]: 0 : tsmall(2, 1:4) = (/a(1,3), 0d0, a(3,1), 0d0/)
522 [ # # ]: 0 : tsmall(3, 1:4) = (/a(1,4), 0d0, 0d0, a(4,1)/)
523 [ # # ]: 0 : tsmall(4, 1:4) = (/ 0d0, a(2,4), 0d0, a(4,2)/)
524 : : !
525 : 0 : END SUBROUTINE libtetrabz_tsmall_b1
526 : : !
527 : : ! Cut small tetrahedron B2
528 : : !
529 : 0 : pure SUBROUTINE libtetrabz_tsmall_b2(e,V,tsmall)
530 : : !
531 : : !IMPLICIT NONE
532 : : !
533 : : REAL(8),INTENT(IN) :: e(4)
534 : : REAL(8),INTENT(OUT) :: V
535 : : REAL(8),INTENT(OUT) :: tsmall(4,4)
536 : : !
537 : : !INTEGER :: ii
538 : : REAL(8) :: a(4,4)
539 : : !
540 : 0 : a = a_from_e(e)
541 : : !DO ii = 1, 4
542 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
543 : : !END DO
544 : : !
545 : 0 : V = a(3,2) * a(4,2)
546 : : !
547 [ # # ]: 0 : tsmall(1, 1:4) = (/1d0, 0d0, 0d0, 0d0/)
548 [ # # ]: 0 : tsmall(2, 1:4) = (/0d0, 1d0, 0d0, 0d0/)
549 [ # # ]: 0 : tsmall(3, 1:4) = (/0d0, a(2,3), a(3,2), 0d0/)
550 [ # # ]: 0 : tsmall(4, 1:4) = (/0d0, a(2,4), 0d0, a(4,2)/)
551 : : !
552 : 0 : END SUBROUTINE libtetrabz_tsmall_b2
553 : : !
554 : : ! Cut small tetrahedron B3
555 : : !
556 : 0 : pure SUBROUTINE libtetrabz_tsmall_b3(e,V,tsmall)
557 : : !
558 : : !IMPLICIT NONE
559 : : !
560 : : REAL(8),INTENT(IN) :: e(4)
561 : : REAL(8),INTENT(OUT) :: V
562 : : REAL(8),INTENT(OUT) :: tsmall(4,4)
563 : : !
564 : : !INTEGER :: ii
565 : : REAL(8) :: a(4,4)
566 : : !
567 : 0 : a = a_from_e(e)
568 : : !DO ii = 1, 4
569 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
570 : : !END DO
571 : : !
572 : 0 : V = a(2,3) * a(3,1) * a(4,2)
573 : : !
574 [ # # ]: 0 : tsmall(1, 1:4) = (/ 1d0, 0d0, 0d0, 0d0/)
575 [ # # ]: 0 : tsmall(2, 1:4) = (/a(1,3), 0d0, a(3,1), 0d0/)
576 [ # # ]: 0 : tsmall(3, 1:4) = (/ 0d0, a(2,3), a(3,2), 0d0/)
577 [ # # ]: 0 : tsmall(4, 1:4) = (/ 0d0, a(2,4), 0d0, a(4,2)/)
578 : : !
579 : 0 : END SUBROUTINE libtetrabz_tsmall_b3
580 : : !
581 : : ! Cut small tetrahedron C1
582 : : !
583 : 0 : pure SUBROUTINE libtetrabz_tsmall_c1(e,V,tsmall)
584 : : !
585 : : !IMPLICIT NONE
586 : : !
587 : : REAL(8),INTENT(IN) :: e(4)
588 : : REAL(8),INTENT(OUT) :: V
589 : : REAL(8),INTENT(OUT) :: tsmall(4,4)
590 : : !
591 : : !INTEGER :: ii
592 : : REAL(8) :: a(4,4)
593 : : !
594 : 0 : a = a_from_e(e)
595 : : !DO ii = 1, 4
596 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
597 : : !END DO
598 : : !
599 : 0 : V = a(4,3)
600 : : !
601 [ # # ]: 0 : tsmall(1, 1:4) = (/1d0, 0d0, 0d0, 0d0/)
602 [ # # ]: 0 : tsmall(2, 1:4) = (/0d0, 1d0, 0d0, 0d0/)
603 [ # # ]: 0 : tsmall(3, 1:4) = (/0d0, 0d0, 1d0, 0d0/)
604 [ # # ]: 0 : tsmall(4, 1:4) = (/0d0, 0d0, a(3,4), a(4,3)/)
605 : : !
606 : 0 : END SUBROUTINE libtetrabz_tsmall_c1
607 : : !
608 : : ! Cut small tetrahedron C2
609 : : !
610 : 0 : pure SUBROUTINE libtetrabz_tsmall_c2(e,V,tsmall)
611 : : !
612 : : !IMPLICIT NONE
613 : : !
614 : : REAL(8),INTENT(IN) :: e(4)
615 : : REAL(8),INTENT(OUT) :: V
616 : : REAL(8),INTENT(OUT) :: tsmall(4,4)
617 : : !
618 : : !INTEGER :: ii
619 : : REAL(8) :: a(4,4)
620 : : !
621 : 0 : a = a_from_e(e)
622 : : !DO ii = 1, 4
623 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
624 : : !END DO
625 : : !
626 : 0 : V = a(3,4) * a(4,2)
627 : : !
628 [ # # ]: 0 : tsmall(1, 1:4) = (/1d0, 0d0, 0d0, 0d0/)
629 [ # # ]: 0 : tsmall(2, 1:4) = (/0d0, 1d0, 0d0, 0d0/)
630 [ # # ]: 0 : tsmall(3, 1:4) = (/0d0, a(2,4), 0d0, a(4,2)/)
631 [ # # ]: 0 : tsmall(4, 1:4) = (/0d0, 0d0, a(3,4), a(4,3)/)
632 : : !
633 : 0 : END SUBROUTINE libtetrabz_tsmall_c2
634 : : !
635 : : ! Cut small tetrahedron C3
636 : : !
637 : 0 : pure SUBROUTINE libtetrabz_tsmall_c3(e,V,tsmall)
638 : : !
639 : : !IMPLICIT NONE
640 : : !
641 : : REAL(8),INTENT(IN) :: e(4)
642 : : REAL(8),INTENT(OUT) :: V
643 : : REAL(8),INTENT(OUT) :: tsmall(4,4)
644 : : !
645 : : !INTEGER :: ii
646 : : REAL(8) :: a(4,4)
647 : : !
648 : 0 : a = a_from_e(e)
649 : : !DO ii = 1, 4
650 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
651 : : !END DO
652 : : !
653 : 0 : V = a(3,4) * a(2,4) * a(4,1)
654 : : !
655 [ # # ]: 0 : tsmall(1, 1:4) = (/ 1d0, 0d0, 0d0, 0d0/)
656 [ # # ]: 0 : tsmall(2, 1:4) = (/a(1,4), 0d0, 0d0, a(4,1)/)
657 [ # # ]: 0 : tsmall(3, 1:4) = (/ 0d0, a(2,4), 0d0, a(4,2)/)
658 [ # # ]: 0 : tsmall(4, 1:4) = (/ 0d0, 0d0, a(3,4), a(4,3)/)
659 : : !
660 : 0 : END SUBROUTINE libtetrabz_tsmall_c3
661 : : !
662 : : ! Cut triangle A1
663 : : !
664 : 28560 : pure SUBROUTINE libtetrabz_triangle_a1(e,V,tsmall)
665 : : !
666 : : !IMPLICIT NONE
667 : : !
668 : : REAL(8),INTENT(IN) :: e(4)
669 : : REAL(8),INTENT(OUT) :: V
670 : : REAL(8),INTENT(OUT) :: tsmall(3,4)
671 : : !
672 : : !INTEGER :: ii
673 : : REAL(8) :: a(4,4)
674 : : !
675 : 28560 : a = a_from_e(e)
676 : : !DO ii = 1, 4
677 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
678 : : !END DO
679 : : !
680 : : !V = 3d0 * a(2,1) * a(3,1) * a(4,1) / (0d0 - e(1))
681 : 28560 : V = 3d0 * a(2,1) * a(3,1) / (e(4) - e(1))
682 : : !
683 [ + + ]: 142800 : tsmall(1,1:4) = (/a(1,2), a(2,1), 0d0, 0d0/)
684 [ + + ]: 142800 : tsmall(2,1:4) = (/a(1,3), 0d0, a(3,1), 0d0/)
685 [ + + ]: 142800 : tsmall(3,1:4) = (/a(1,4), 0d0, 0d0, a(4,1)/)
686 : : !
687 : 28560 : END SUBROUTINE libtetrabz_triangle_a1
688 : : !
689 : : ! Cut triangle B1
690 : : !
691 : 17640 : pure SUBROUTINE libtetrabz_triangle_b1(e,V,tsmall)
692 : : !
693 : : !IMPLICIT NONE
694 : : !
695 : : REAL(8),INTENT(IN) :: e(4)
696 : : REAL(8),INTENT(OUT) :: V
697 : : REAL(8),INTENT(OUT) :: tsmall(3,4)
698 : : !
699 : : !INTEGER :: ii
700 : : REAL(8) :: a(4,4)
701 : : !
702 : 17640 : a = a_from_e(e)
703 : : !DO ii = 1, 4
704 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
705 : : !END DO
706 : : !
707 : : !V = 3d0 * a(3,1) * a(4,1) * a(2,4) / (0d0 - e(1))
708 : 17640 : V = 3d0 * a(4,1) * a(2,4) / (e(3) - e(1))
709 : : !
710 [ + + ]: 88200 : tsmall(1,1:4) = (/a(1,3), 0d0, a(3,1), 0d0/)
711 [ + + ]: 88200 : tsmall(2,1:4) = (/a(1,4), 0d0, 0d0, a(4,1)/)
712 [ + + ]: 88200 : tsmall(3,1:4) = (/ 0d0, a(2,4), 0d0, a(4,2)/)
713 : : !
714 : 17640 : END SUBROUTINE libtetrabz_triangle_b1
715 : : !
716 : : ! Cut triangle B2
717 : : !
718 : 17640 : pure SUBROUTINE libtetrabz_triangle_b2(e,V,tsmall)
719 : : !
720 : : !IMPLICIT NONE
721 : : !
722 : : REAL(8),INTENT(IN) :: e(4)
723 : : REAL(8),INTENT(OUT) :: V
724 : : REAL(8),INTENT(OUT) :: tsmall(3,4)
725 : : !
726 : : !INTEGER :: ii
727 : : REAL(8) :: a(4,4)
728 : : !
729 : 17640 : a = a_from_e(e)
730 : : !DO ii = 1, 4
731 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
732 : : !END DO
733 : : !
734 : : !V = 3d0 * a(2,3) * a(3,1) * a(4,2) / (0d0 - e(1))
735 : 17640 : V = 3d0 * a(2,3) * a(4,2) / (e(3) - e(1))
736 : : !
737 [ + + ]: 88200 : tsmall(1,1:4) = (/a(1,3), 0d0, a(3,1), 0d0/)
738 [ + + ]: 88200 : tsmall(2,1:4) = (/ 0d0, a(2,3), a(3,2), 0d0/)
739 [ + + ]: 88200 : tsmall(3,1:4) = (/ 0d0, a(2,4), 0d0, a(4,2)/)
740 : : !
741 : 17640 : END SUBROUTINE libtetrabz_triangle_b2
742 : : !
743 : : ! Cut triangle C1
744 : : !
745 : 10920 : pure SUBROUTINE libtetrabz_triangle_c1(e,V,tsmall)
746 : : !
747 : : !IMPLICIT NONE
748 : : !
749 : : REAL(8),INTENT(IN) :: e(4)
750 : : REAL(8),INTENT(OUT) :: V
751 : : REAL(8),INTENT(OUT) :: tsmall(3,4)
752 : : !
753 : : !INTEGER :: ii
754 : : REAL(8) :: a(4,4)
755 : : !
756 : 10920 : a = a_from_e(e)
757 : : !DO ii = 1, 4
758 : : ! a(1:4,ii) = (0d0 - e(ii)) / (e(1:4) - e(ii))
759 : : !END DO
760 : : !
761 : : !V = 3d0 * a(1,4) * a(2,4) * a(3,4) / (e(4) - 0d0)
762 : 10920 : V = 3d0 * a(1,4) * a(2,4) / (e(4) - e(3))
763 : : !
764 [ + + ]: 54600 : tsmall(1,1:4) = (/a(1,4), 0d0, 0d0, a(4,1)/)
765 [ + + ]: 54600 : tsmall(2,1:4) = (/ 0d0, a(2,4), 0d0, a(4,2)/)
766 [ + + ]: 54600 : tsmall(3,1:4) = (/ 0d0, 0d0, a(3,4), a(4,3)/)
767 : : !
768 : 10920 : END SUBROUTINE libtetrabz_triangle_c1
769 : : !
770 : : ! MPI_Allreduce for double scaler
771 : : !
772 : 0 : SUBROUTINE libtetrabz_mpisum_d(comm,scaler)
773 : : !
774 : : !IMPLICIT NONE
775 : : !
776 : : INTEGER :: comm
777 : : REAL(8) :: scaler
778 : : !
779 : : #if defined(HAVE_MPI)
780 : : INTEGER :: ierr
781 : : REAL(8) :: arr_scaler(1)
782 : : !
783 : : CALL MPI_allREDUCE([scaler], arr_scaler, 1, &
784 [ # # ]: 0 : & MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr)
785 : 0 : scaler=arr_scaler(1)
786 : : #endif
787 : : !
788 : 0 : END SUBROUTINE libtetrabz_mpisum_d
789 : : !
790 : : ! MPI_Allreduce for double vector
791 : : !
792 : 0 : SUBROUTINE libtetrabz_mpisum_dv(comm,ndim,vector)
793 : : !
794 : : !IMPLICIT NONE
795 : : !
796 : : INTEGER :: comm, ndim
797 : : REAL(8) :: vector(ndim)
798 : : !
799 : : #if defined(HAVE_MPI)
800 : : INTEGER :: ierr
801 : : #ifndef HAVE_MPI2_INPLACE
802 : : REAL(8) :: vector_out(ndim)
803 : : #endif
804 : : !
805 : : #ifdef HAVE_MPI2_INPLACE
806 : : CALL MPI_allREDUCE(MPI_IN_PLACE, vector, ndim, &
807 : 0 : & MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr)
808 : : #else
809 : : CALL MPI_allREDUCE(vector, vector_out, ndim, &
810 : : & MPI_DOUBLE_PRECISION, MPI_SUM, comm, ierr)
811 : : vector(1:ndim)=vector_out(1:ndim)
812 : : #endif
813 : : #endif
814 : : !
815 : 0 : END SUBROUTINE libtetrabz_mpisum_dv
816 : : !
817 : : ! MPI_Allreduce for double complex vector
818 : : !
819 : 0 : SUBROUTINE libtetrabz_mpisum_zv(comm,ndim,vector)
820 : : !
821 : : !IMPLICIT NONE
822 : : !
823 : : INTEGER :: comm, ndim
824 : : COMPLEX(8) :: vector(ndim)
825 : : !
826 : : #if defined(HAVE_MPI)
827 : : INTEGER :: ierr
828 : : #ifndef HAVE_MPI2_INPLACE
829 : : COMPLEX(8) :: vector_out(ndim)
830 : : #endif
831 : : !
832 : : #ifdef HAVE_MPI2_INPLACE
833 : : CALL MPI_allREDUCE(MPI_IN_PLACE, vector, ndim, &
834 : 0 : & MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr)
835 : : #else
836 : : CALL MPI_allREDUCE(vector, vector_out, ndim, &
837 : : & MPI_DOUBLE_COMPLEX, MPI_SUM, comm, ierr)
838 : : vector(1:ndim)=vector_out(1:ndim)
839 : : #endif
840 : : #endif
841 : : !
842 : 0 : END SUBROUTINE libtetrabz_mpisum_zv
843 : : !
844 : : END MODULE libtetrabz_common
|