Branch data Line data Source code
1 : : !!****m* ABINIT/m_ephtk
2 : : !! NAME
3 : : !! m_ephtk
4 : : !!
5 : : !! FUNCTION
6 : : !! Helper functions common to e-ph calculations.
7 : : !!
8 : : !! COPYRIGHT
9 : : !! Copyright (C) 2008-2026 ABINIT group (MG)
10 : : !! This file is distributed under the terms of the
11 : : !! GNU General Public License, see ~abinit/COPYING
12 : : !! or http://www.gnu.org/copyleft/gpl.txt .
13 : : !!
14 : : !! SOURCE
15 : :
16 : : #if defined HAVE_CONFIG_H
17 : : #include "config.h"
18 : : #endif
19 : :
20 : : #include "abi_common.h"
21 : :
22 : : module m_ephtk
23 : :
24 : : use defs_basis
25 : : use m_abicore
26 : : use m_errors
27 : : use m_xmpi
28 : : use m_dtset
29 : : use m_ebands
30 : : use m_crystal
31 : : use m_krank
32 : : use m_xmpi
33 : :
34 : : use m_fstrings, only : itoa, sjoin, ltoa, ftoa, ktoa
35 : : use m_bz_mesh, only : isamek
36 : : use m_fftcore, only : get_kg
37 : :
38 : : implicit none
39 : :
40 : : private
41 : :
42 : : public :: ephtk_set_phmodes_skip ! Setup a mask to skip accumulating the contribution of certain phonon modes.
43 : : public :: ephtk_set_pertables ! Set tables for parallelism over perturbations from my_npert and comm
44 : : public :: ephtk_mkqtabs ! Build tables with correspondence between q-points as needed by complete_gamma.
45 : : public :: ephtk_gam_atm2qnu ! Compute phonon linewidths from gamma matrix in reduced coordinates.
46 : : public :: ephtk_gkknu_from_atm ! Transform the gkk matrix elements from (atom, red_direction) basis to phonon-mode basis.
47 : : public :: ephtk_update_ebands ! Update ebands according to dtset%occopt, tsmear, mbpt_sciss, eph_fermie, eph_extrael
48 : : public :: ephtk_get_mpw_gmax ! Compute maximum number of plane-waves over k and k+q where k and k+q are in the BZ.
49 : : public :: ephtk_v1atm_to_vqnu ! Receive potentials in atomic representation and return potential in phonon representation
50 : : public :: ephtk_skip_phmode ! Ignore contribution of phonon mode depending on phonon frequency value or mode index.
51 : : !!***
52 : :
53 : : real(dp),public,parameter :: EPHTK_WTOL = tol6
54 : : ! Tolerance for phonon frequencies to be ignored.
55 : : ! Lambda coefficients are set to zero when abs(w) < EPHTK_WTOL
56 : : ! This tolerance is also used in the integrals of a2F(w).
57 : :
58 : : contains !=====================================================
59 : : !!***
60 : :
61 : : !!****f* m_ephtk/ephtk_set_phmodes_skip
62 : : !! NAME
63 : : !! ephtk_set_phmodes_skip
64 : : !!
65 : : !! FUNCTION
66 : : !! Setup a mask to skip accumulating the contribution of certain phonon modes.
67 : : !!
68 : : !! INPUT
69 : : !! eph_phrange=Abinit input variable.
70 : : !!
71 : : !! OUTPUT
72 : : !! phmodes_skip(natom3) For each mode: 1 to skip the contribution given by this phonon branch else 0
73 : : !!
74 : : !! SOURCE
75 : :
76 : 65 : subroutine ephtk_set_phmodes_skip(natom, eph_phrange, phmodes_skip)
77 : :
78 : : !Arguments ------------------------------------
79 : : integer,intent(in) :: natom
80 : : !arrays
81 : : integer,intent(in) :: eph_phrange(2)
82 : : integer,allocatable,intent(out) :: phmodes_skip(:)
83 : :
84 : : !Local variables ------------------------------
85 : : integer :: natom3
86 : : ! *************************************************************************
87 : :
88 : : ! Setup a mask to skip accumulating the contribution of certain phonon modes.
89 : : ! By default do not skip, if set skip all but specified
90 : 65 : natom3 = natom * 3
91 [ - + + - : 195 : ABI_MALLOC(phmodes_skip, (natom3))
+ - + - -
+ - + -
+ ]
92 [ + + ]: 452 : phmodes_skip = 0
93 : :
94 [ + + + + : 67 : if (all(eph_phrange /= 0)) then
+ + ]
95 : : if (minval(abs(eph_phrange)) < 1 .or. &
96 [ + + + + : 5 : maxval(abs(eph_phrange)) > natom3 .or. &
+ - - + ]
97 : : abs(eph_phrange(2)) < abs(eph_phrange(1))) then
98 : 0 : ABI_ERROR('Invalid range for eph_phrange. Should be between [1, 3*natom] and eph_modes(2) > eph_modes(1)')
99 : : end if
100 [ + + + - : 3 : if (all(eph_phrange > 0)) then
+ - ]
101 : 1 : call wrtout(std_out, sjoin(" Including phonon modes between [", itoa(eph_phrange(1)), ',', itoa(eph_phrange(2)), "]"))
102 [ + + ]: 7 : phmodes_skip = 1
103 [ + + ]: 7 : phmodes_skip(eph_phrange(1):eph_phrange(2)) = 0
104 [ # # # # : 0 : else if (all(eph_phrange < 0)) then
# # ]
105 : : call wrtout(std_out, sjoin(" Excluding phonon modes between [", &
106 : 0 : itoa(abs(eph_phrange(1))), ',', itoa(abs(eph_phrange(2))), "]"))
107 [ # # ]: 0 : phmodes_skip = 0
108 [ # # ]: 0 : phmodes_skip(abs(eph_phrange(1)):abs(eph_phrange(2))) = 1
109 : : else
110 : 0 : ABI_ERROR(sjoin("Invalid eph_phrange: ", itoa(eph_phrange(1)), ',', itoa(eph_phrange(2))))
111 : : end if
112 : : end if
113 : :
114 : 65 : end subroutine ephtk_set_phmodes_skip
115 : : !!***
116 : :
117 : : !!****f* m_ephtk/ephtk_set_pertables
118 : : !! NAME
119 : : !! ephtk_set_pertables
120 : : !!
121 : : !! FUNCTION
122 : : !! Build tables for parallelism over perturbations from my_npert and comm
123 : : !!
124 : : !! INPUT
125 : : !! natom: Number of atoms
126 : : !! my_npert: Number of atomic perturbations or phonon modes treated by this MPI rank.
127 : : !! comm: MPI communicator for parallelism over atomic perturbations.
128 : : !!
129 : : !! OUTPUT
130 : : !! integer,allocatable :: my_pinfo(:,:)
131 : : !! my_pinfo(3, my_npert)
132 : : !! my_pinfo(1, ip) gives the `idir` index of the ip-th perturbation.
133 : : !! my_pinfo(2, ip) gives the `ipert` index of the ip-th perturbation.
134 : : !! my_pinfo(3, ip) gives `pertcase`=idir + (ipert-1)*3
135 : : !! integer,allocatable :: pert_table(:,:)
136 : : !! pert_table(2, natom3)
137 : : !! pert_table(1, npert): rank of the processor treating this atomic perturbation.
138 : : !! pert_table(2, npert): imyp index in my_pinfo table, -1 if this rank is not treating ipert.
139 : : !!
140 : : !! SOURCE
141 : :
142 : 58 : subroutine ephtk_set_pertables(natom, my_npert, pert_table, my_pinfo, comm)
143 : :
144 : : !Arguments ------------------------------------
145 : : integer,intent(in) :: natom, my_npert, comm
146 : : !arrays
147 : : integer,allocatable,intent(out) :: pert_table(:,:), my_pinfo(:,:)
148 : :
149 : : !Local variables ------------------------------
150 : : !scalars
151 : : integer :: iatom, idir, pertcase, bstart, bstop, ii, ip, natom3, my_rank, nproc
152 : : !arrays
153 : 116 : integer :: all_pinfo(3, natom*3)
154 : : ! *************************************************************************
155 : :
156 : 58 : my_rank = xmpi_comm_rank(comm); nproc = xmpi_comm_size(comm)
157 : :
158 : : ! Build table with list of perturbations treated by this CPU.
159 : 58 : natom3 = natom * 3
160 [ - + + - : 174 : ABI_MALLOC(my_pinfo, (3, my_npert))
+ - + - -
+ - + -
+ ]
161 [ - + + - : 174 : ABI_MALLOC(pert_table, (2, natom3))
+ - + - -
+ - + -
+ ]
162 : :
163 [ + + ]: 173 : do iatom=1,natom
164 [ + + ]: 518 : do idir=1,3
165 : 345 : pertcase = idir + (iatom-1) * 3
166 [ + + ]: 1380 : all_pinfo(:, pertcase) = [idir, iatom, pertcase]
167 : 460 : pert_table(1, pertcase) = (pertcase - 1) / (natom3 / nproc)
168 : : end do
169 : : end do
170 : 58 : bstart = (natom3 / nproc) * my_rank + 1
171 : 58 : bstop = bstart + my_npert - 1
172 [ + - - + : 1496 : my_pinfo = all_pinfo(:, bstart:bstop)
- - + + +
+ ]
173 : :
174 [ + + ]: 403 : pert_table(2, :) = -1
175 [ + + ]: 403 : do ii=1,my_npert
176 : 345 : ip = my_pinfo(3, ii)
177 : 403 : pert_table(2, ip) = ii
178 : : end do
179 : : !write(std_out,*)"my_npert", my_npert, "nproc", nproc; write(std_out,*)"my_pinfo", my_pinfo
180 : :
181 : 58 : end subroutine ephtk_set_pertables
182 : : !!***
183 : :
184 : : !!****f* m_ephtk/ephtk_mkqtabs
185 : : !! NAME
186 : : !! ephtk_mkqtabs
187 : : !!
188 : : !! FUNCTION
189 : : !! Build tables with correspondence between q-points in the IBZ/BZ as needed by complete_gamma.
190 : : !!
191 : : !! INPUT
192 : : !! cryst<crystal_t>=Crystal structure.
193 : : !! nqibz, qibz = Points in the IBZ
194 : : !! nqbz, qbz = Points in the BZ
195 : : !!
196 : : !! OUTPUT
197 : : !! qirredtofull(nqibz) = mapping irred to full qpoints
198 : : !! qpttoqpt(2, cryst%nsym, nqbz)) = qpoint index mapping under symops.
199 : : !!
200 : : !! SOURCE
201 : :
202 : 10 : subroutine ephtk_mkqtabs(cryst, nqibz, qibz, nqbz, qbz, qirredtofull, qpttoqpt)
203 : :
204 : : !Arguments ------------------------------------
205 : : type(crystal_t),intent(in) :: cryst
206 : : integer,intent(in) :: nqibz, nqbz
207 : : !arrays
208 : : real(dp),intent(in) :: qibz(3, nqibz), qbz(3, nqbz)
209 : : integer,allocatable :: qirredtofull(:),qpttoqpt(:,:,:)
210 : :
211 : : !Local variables ------------------------------
212 : : !scalars
213 : : integer :: iq_bz, iq_ibz, isq_bz, isym
214 : 10 : type(krank_t) :: qrank
215 : : !arrays
216 : : integer :: g0(3)
217 : : real(dp) :: qirr(3), tmp_qpt(3)
218 : : ! *************************************************************************
219 : :
220 : 10 : call qrank%init(nqbz, qbz)
221 : :
222 : : ! Compute index of IBZ q-point in the BZ array
223 [ - + + - : 152 : ABI_CALLOC(qirredtofull, (nqibz))
+ - + - -
+ - + - +
+ + ]
224 : :
225 [ + + ]: 132 : do iq_ibz=1,nqibz
226 [ + + ]: 488 : qirr = qibz(:,iq_ibz)
227 : 122 : iq_bz = qrank%get_index(qirr)
228 [ + - ]: 132 : if (iq_bz /= -1) then
229 [ - + ]: 122 : ABI_CHECK(isamek(qirr, qbz(:,iq_bz), g0), "isamek")
230 : 122 : qirredtofull(iq_ibz) = iq_bz
231 : : else
232 : 0 : ABI_ERROR(sjoin("Full BZ does not contain IBZ q-point:", ktoa(qirr)))
233 : : end if
234 : : end do
235 : :
236 : : ! Build qpttoqpt table. See also mkqptequiv
237 [ - + + - : 40 : ABI_MALLOC(qpttoqpt, (2, cryst%nsym, nqbz))
- + + - +
- + - - +
- + - + ]
238 [ + + + + : 222730 : qpttoqpt = -1
+ + ]
239 [ + + ]: 1546 : do iq_bz=1,nqbz
240 [ + + ]: 75274 : do isym=1,cryst%nsym
241 [ + + + + : 1843200 : tmp_qpt = matmul(cryst%symrec(:,:,isym), qbz(:,iq_bz))
+ + + + +
- ]
242 : :
243 : 73728 : isq_bz = qrank%get_index(tmp_qpt)
244 [ - + ]: 73728 : if (isq_bz == -1) then
245 : 0 : ABI_ERROR("Looks like no kpoint equiv to q by symmetry without time reversal!")
246 : : end if
247 : 73728 : qpttoqpt(1,isym,isq_bz) = iq_bz
248 : :
249 : : ! q --> -q
250 [ + + ]: 294912 : tmp_qpt = -tmp_qpt
251 : 73728 : isq_bz = qrank%get_index(tmp_qpt)
252 [ - + ]: 73728 : if (isq_bz == -1) then
253 : 0 : ABI_ERROR("Looks like no kpoint equiv to q by symmetry with time reversal!")
254 : : end if
255 : 75264 : qpttoqpt(2,isym,isq_bz) = iq_bz
256 : : end do
257 : : end do
258 : :
259 : 10 : call qrank%free()
260 : :
261 [ - + - + : 10 : end subroutine ephtk_mkqtabs
- + ]
262 : : !!***
263 : :
264 : : !----------------------------------------------------------------------
265 : :
266 : : !!****f* m_ephtk/ephtk_gam_atm2qnu
267 : : !! NAME
268 : : !! ephtk_gam_atm2qnu
269 : : !!
270 : : !! FUNCTION
271 : : !! This routine takes the gamma matrices in the atomic representation and
272 : : !! multiplies them by the displ_red matrices. Based on gam_mult_displ
273 : : !!
274 : : !! INPUTS
275 : : !! natom3 = number of phonon branches (3*natom)
276 : : !! displ_red = phonon mode displacement vectors in reduced coordinates.
277 : : !! gam_bare = bare gamma matrices before multiplication
278 : : !!
279 : : !! OUTPUT
280 : : !! gam_now = output gamma matrices multiplied by displacement matrices
281 : : !!
282 : : !! SOURCE
283 : :
284 : 15200 : subroutine ephtk_gam_atm2qnu(natom3, displ_red, gam_atm, gam_qnu)
285 : :
286 : : !Arguments -------------------------------
287 : : integer, intent(in) :: natom3
288 : : real(dp), intent(in) :: displ_red(2,natom3,natom3), gam_atm(2,natom3,natom3)
289 : : real(dp), intent(out) :: gam_qnu(natom3)
290 : :
291 : : !Local variables -------------------------
292 : : integer,save :: enough = 0
293 : : integer :: nu
294 : : character(len=500) :: msg
295 : 30400 : real(dp) :: zgemm_tmp_mat(2,natom3,natom3), gam_now(2,natom3,natom3)
296 : : ! *********************************************************************
297 : :
298 : 15200 : call zgemm('c','n',natom3, natom3, natom3, cone, displ_red, natom3, gam_atm, natom3, czero, zgemm_tmp_mat, natom3)
299 : :
300 [ + + + + : 471200 : gam_now = zero
+ + ]
301 : 15200 : call zgemm('n','n',natom3,natom3,natom3,cone,zgemm_tmp_mat,natom3,displ_red,natom3,czero,gam_now,natom3)
302 : :
303 : : ! Extract gamma(q,nu)
304 [ + + ]: 60800 : do nu=1,natom3
305 : 45600 : gam_qnu(nu) = gam_now(1, nu, nu)
306 [ - + ]: 60800 : if (abs(gam_now(2, nu, nu)) > tol8) then
307 : 0 : enough = enough + 1
308 [ # # ]: 0 : if (enough <= 30) then
309 : 0 : write (msg,'(a,i0,a,es16.8)')' non-zero imaginary part for branch: ',nu,', img: ',gam_now(2, nu, nu)
310 : 0 : ABI_WARNING(msg)
311 : : end if
312 : : end if
313 : : end do
314 : :
315 : 15200 : end subroutine ephtk_gam_atm2qnu
316 : : !!***
317 : :
318 : : !----------------------------------------------------------------------
319 : :
320 : : !!****f* m_ephtk/ephtk_gkknu_from_atm
321 : : !! NAME
322 : : !! ephtk_gkknu_from_atm
323 : : !!
324 : : !! FUNCTION
325 : : !! Transform the gkk matrix elements from (atom, red_direction) basis to phonon-mode basis.
326 : : !!
327 : : !! INPUTS
328 : : !! nb1,nb2=Number of bands in gkq_atm matrix.
329 : : !! nk=Number of k-points (usually 1)
330 : : !! natom=Number of atoms.
331 : : !! gkq_atm(2,nb1,nb2,3*natom)=EPH matrix elements in the atomic basis.
332 : : !! phfrq(3*natom)=Phonon frequencies in Ha
333 : : !! displ_red(2,3*natom,3*natom)=Phonon displacement in reduced coordinates.
334 : : !!
335 : : !! OUTPUT
336 : : !! gkq_nu(2,nb1,nb2,3*natom)=EPH matrix elements in the phonon-mode basis.
337 : : !!
338 : : !! SOURCE
339 : :
340 : 135493 : subroutine ephtk_gkknu_from_atm(nb1, nb2, nk, natom, gkq_atm, phfrq, displ_red, gkq_nu)
341 : :
342 : : !Arguments ------------------------------------
343 : : !scalars
344 : : integer,intent(in) :: nb1, nb2, nk, natom
345 : : !arrays
346 : : real(dp),intent(in) :: phfrq(3*natom), displ_red(2,3*natom,3*natom)
347 : : real(dp),intent(in) :: gkq_atm(2,nb1,nb2,nk,3*natom)
348 : : real(dp),intent(out) :: gkq_nu(2,nb1,nb2,nk,3*natom)
349 : :
350 : : !Local variables-------------------------
351 : : integer :: nu,ipc
352 : : ! *************************************************************************
353 : :
354 [ + + + + : 16285561 : gkq_nu = zero
+ + + + +
+ ]
355 : :
356 : : ! Loop over phonon branches.
357 [ + + ]: 945895 : do nu=1,3*natom
358 : : ! Ignore negative or too small frequencies
359 [ + + ]: 810402 : if (phfrq(nu) < EPHTK_WTOL) cycle
360 : :
361 : : ! Transform the gkk from (atom, reduced direction) basis to phonon mode representation.
362 [ + + ]: 5599368 : do ipc=1,3*natom
363 : : gkq_nu(1,:,:,:,nu) = gkq_nu(1,:,:,:,nu) &
364 : : + gkq_atm(1,:,:,:,ipc) * displ_red(1,ipc,nu) &
365 [ + + + + : 46034268 : - gkq_atm(2,:,:,:,ipc) * displ_red(2,ipc,nu)
+ + ]
366 : : gkq_nu(2,:,:,:,nu) = gkq_nu(2,:,:,:,nu) &
367 : : + gkq_atm(1,:,:,:,ipc) * displ_red(2,ipc,nu) &
368 [ + + + + : 46834722 : + gkq_atm(2,:,:,:,ipc) * displ_red(1,ipc,nu)
+ + ]
369 : : end do
370 : :
371 [ + + + + : 16062697 : gkq_nu(:,:,:,:,nu) = gkq_nu(:,:,:,:,nu) / sqrt(two * phfrq(nu))
+ + + + ]
372 : : end do
373 : :
374 : 135493 : end subroutine ephtk_gkknu_from_atm
375 : : !!***
376 : :
377 : : !----------------------------------------------------------------------
378 : :
379 : : !!****f* m_ephtk/ephtk_update_ebands
380 : : !! NAME
381 : : !! ephtk_update_ebands
382 : : !!
383 : : !! FUNCTION
384 : : !! Update ebands according to dtset%occopt, tsmear, mbpt_sciss, eph_fermie, eph_extrael
385 : : !!
386 : : !! INPUTS
387 : : !! dtset<dataset_type>=All input variables for this dataset.
388 : : !! fileqpdatain: QPDATA file
389 : : !!
390 : : !! SOURCE
391 : :
392 : 99 : subroutine ephtk_update_ebands(dtset, ebands, header)
393 : :
394 : : !Arguments ------------------------------------
395 : : !scalars
396 : : type(dataset_type),intent(in) :: dtset
397 : : type(ebands_t),intent(inout) :: ebands
398 : : character(len=*),intent(in) :: header
399 : :
400 : : !Local variables-------------------------
401 : : !scalars
402 : : real(dp),parameter :: nholes = zero
403 : : character(len=500) :: msg
404 : : integer :: units(2)
405 : : ! *************************************************************************
406 : :
407 [ + + ]: 297 : units = [std_out, ab_out]
408 : :
409 [ - + ]: 99 : if (abs(dtset%mbpt_sciss) > tol6) then
410 : : ! Apply the scissor operator
411 : : call wrtout(units, sjoin(" Applying scissors operator to the conduction states with value: ", &
412 : 0 : ftoa(dtset%mbpt_sciss * Ha_eV, fmt="(f6.2)"), " (eV)"))
413 : 0 : call ebands%apply_scissors(dtset%mbpt_sciss)
414 : : end if
415 : :
416 [ + + - + ]: 99 : if (dtset%occopt /= ebands%occopt .or. abs(dtset%tsmear - ebands%tsmear) > tol12) then
417 : : write(msg,"(2a,2(a,i0,a,f14.6,a))")&
418 : 21 : " Changing occupation scheme as input occopt and tsmear differ from those read from WFK file.",ch10,&
419 : 21 : " From WFK file: occopt = ",ebands%occopt,", tsmear = ",ebands%tsmear,ch10,&
420 : 42 : " From input: occopt = ",dtset%occopt,", tsmear = ",dtset%tsmear,ch10
421 : 21 : call wrtout(units, msg)
422 : 21 : call ebands%set_scheme(dtset%occopt, dtset%tsmear, dtset%spinmagntarget, dtset%prtvol)
423 : : end if
424 : :
425 : : ! Default value of eph_fermie is zero hence no tolerance is used!
426 [ + + ]: 99 : if (dtset%eph_fermie /= zero) then
427 [ - + ]: 1 : ABI_CHECK(dtset%eph_extrael == zero, "eph_fermie and eph_extrael are mutually exclusive")
428 : 1 : call wrtout(units, sjoin(" Fermi level set by the user at:", ftoa(dtset%eph_fermie * Ha_eV, fmt="(f6.2)"), " (eV)"))
429 : 1 : call ebands%set_fermie(dtset%eph_fermie, msg)
430 : 1 : call wrtout(units, msg)
431 : :
432 [ + + ]: 98 : else if (abs(dtset%eph_extrael) > zero) then
433 : 20 : call wrtout(units, sjoin(" Adding eph_extrael:", ftoa(dtset%eph_extrael), "to input nelect:", ftoa(ebands%nelect)))
434 : 20 : call ebands%set_scheme(dtset%occopt, dtset%tsmear, dtset%spinmagntarget, dtset%prtvol, update_occ=.False.)
435 : 20 : call ebands%set_extrael(dtset%eph_extrael, nholes, dtset%spinmagntarget, msg)
436 : 20 : call wrtout(units, msg)
437 : : end if
438 : :
439 : : ! Recompute occupations. This is needed if WFK files have been produced in a NSCF run
440 : : ! since occ are set to zero, and fermie is taken from the previous density.
441 [ + + ]: 99 : if (dtset%kptopt > 0) then
442 : 98 : call ebands%update_occ(dtset%spinmagntarget, prtvol=dtset%prtvol)
443 [ + + ]: 196 : call ebands%print([std_out], header=header, prtvol=dtset%prtvol)
444 : : end if
445 : :
446 : 99 : end subroutine ephtk_update_ebands
447 : : !!***
448 : :
449 : : !----------------------------------------------------------------------
450 : :
451 : : !!****f* m_ephtk/ephtk_get_mpw_gmax
452 : : !! NAME
453 : : !! ephtk_get_mpw_gmax
454 : : !!
455 : : !! FUNCTION
456 : : !! Compute maximum number of plane-waves over k and k+q where k and k+q are in the BZ.
457 : : !! we also need the max components of the G-spheres (k, k+q) in order to allocate the workspace array work
458 : : !! used to symmetrize the wavefunctions in G-space.
459 : : !! Note that we loop over the full BZ instead of the IBZ(k)
460 : : !! This part is slow for very dense meshes, should try to use a geometrical approach...
461 : : !!
462 : : !! INPUTS
463 : : !!
464 : : !! SOURCE
465 : :
466 : 60 : subroutine ephtk_get_mpw_gmax(nkpt, kpts, ecut, gmet, mpw, gmax, comm, init_with_zero)
467 : :
468 : : !Arguments ------------------------------------
469 : : integer,intent(in) :: nkpt
470 : : integer,intent(out) :: mpw, gmax(3)
471 : : real(dp),intent(in) :: ecut, kpts(3,nkpt), gmet(3,3)
472 : : integer,intent(in) :: comm
473 : : logical,optional,intent(in) :: init_with_zero
474 : :
475 : : !Local variables ------------------------------
476 : : integer,parameter :: istwfk1 = 1
477 : : integer :: ik,i1,i2,i3,cnt,ipw,ii,onpw,my_mpw,my_gmax(3),ierr, my_rank, nprocs
478 : : real(dp) :: kk(3), kq(3)
479 : 60 : integer,allocatable :: gtmp(:,:)
480 : : logical :: init_with_zero__
481 : : ! *************************************************************************
482 : :
483 : 60 : my_rank = xmpi_comm_rank(comm); nprocs = xmpi_comm_size(comm)
484 : :
485 [ + + ]: 60 : init_with_zero__ = .True.; if (present(init_with_zero)) init_with_zero__ = init_with_zero
486 : :
487 [ + - ]: 2 : if (init_with_zero__) then
488 : 60 : mpw = 0; gmax = 0
489 : : end if
490 : :
491 : : cnt = 0
492 [ + + ]: 358 : do ik=1,nkpt
493 [ + + ]: 1192 : kk = kpts(:, ik)
494 [ + + ]: 1252 : do i3=-1,1
495 [ + + ]: 3874 : do i2=-1,1
496 [ + + ]: 11622 : do i1=-1,1
497 [ - + ]: 8046 : cnt = cnt + 1; if (mod(cnt, nprocs) /= my_rank) cycle ! MPI parallelism inside comm
498 [ + + ]: 32184 : kq = kk + half * [i1, i2, i3]
499 : : ! TODO: g0 umklapp here can enter into play gmax may not be large enough!
500 [ - + ]: 8046 : call get_kg(kq, istwfk1, 1.1_dp * ecut, gmet, onpw, gtmp)
501 : 8046 : mpw = max(mpw, onpw)
502 [ + + ]: 6937057 : do ipw=1,onpw
503 [ + + ]: 27724090 : do ii=1,3
504 : 27716044 : gmax(ii) = max(gmax(ii), abs(gtmp(ii, ipw)))
505 : : end do
506 : : end do
507 [ - + ]: 10728 : ABI_FREE(gtmp)
508 : : end do
509 : : end do
510 : : end do
511 : : end do
512 : :
513 : 60 : my_mpw = mpw; call xmpi_max(my_mpw, mpw, comm, ierr)
514 : 60 : my_gmax = gmax; call xmpi_max(my_gmax, gmax, comm, ierr)
515 : :
516 [ - + ]: 60 : end subroutine ephtk_get_mpw_gmax
517 : : !!***
518 : :
519 : : !!****f* m_epthk/ephtk_v1atm_to_vqnu
520 : : !! NAME
521 : : !! ephtk_v1atm_to_vqnu
522 : : !!
523 : : !! FUNCTION
524 : : !! Receive potentials in atomic representation and return potential in phonon representation
525 : : !!
526 : : !! INPUTS
527 : : !!
528 : : !! OUTPUT
529 : : !!
530 : : !! SOURCE
531 : :
532 : 0 : pure subroutine ephtk_v1atm_to_vqnu(cplex, nfft, nspden, natom3, v1_atm, displ_red, v1_qnu)
533 : :
534 : : !Arguments ------------------------------------
535 : : !scalars
536 : : integer,intent(in) :: cplex, nfft, nspden, natom3
537 : : !arrays
538 : : real(dp),intent(in) :: v1_atm(cplex, nfft, nspden, natom3)
539 : : real(dp),intent(out) :: v1_qnu(2, nfft, nspden, natom3)
540 : : real(dp),intent(in) :: displ_red(2, natom3, natom3)
541 : :
542 : : !Local variables-------------------------------
543 : : !scalars
544 : : integer :: nu, ip, ispden
545 : : !************************************************************************
546 : :
547 [ # # ]: 0 : do nu=1,natom3
548 : : ! v1_qnu = \sum_{ka} phdispl{ka}(q,nu) D_{ka,q} V_scf(r)
549 : : ! NOTE: prefactor 1/sqrt(2 w(q,nu)) is not included in the potentials.
550 : : ! v1_qnu(2, nfft, nspden, natom3), v1_atm(cplex, nfft, nspden, natom3)
551 [ # # # # : 0 : v1_qnu(:, :, :, nu) = zero
# # ]
552 [ # # ]: 0 : do ip=1,natom3
553 [ # # ]: 0 : do ispden=1,nspden
554 [ # # ]: 0 : if (cplex == 2) then
555 : : v1_qnu(1, :, ispden, nu) = v1_qnu(1, :, ispden, nu) + &
556 [ # # ]: 0 : displ_red(1,ip,nu) * v1_atm(1,:,ispden,ip) - displ_red(2,ip,nu) * v1_atm(2,:,ispden,ip)
557 : : v1_qnu(2, :, ispden, nu) = v1_qnu(2, :, ispden, nu) + &
558 [ # # ]: 0 : displ_red(2,ip,nu) * v1_atm(1,:,ispden,ip) + displ_red(1,ip,nu) * v1_atm(2,:,ispden,ip)
559 : : else
560 : : ! Gamma point. d(q) = d(-q)* --> d is real.
561 [ # # ]: 0 : v1_qnu(1, :, ispden, nu) = v1_qnu(1, :, ispden, nu) + displ_red(1,ip,nu) * v1_atm(1,:,ispden,ip)
562 : : end if
563 : : end do
564 : : end do
565 : : end do
566 : :
567 : 0 : end subroutine ephtk_v1atm_to_vqnu
568 : : !!***
569 : :
570 : : !!****f* m_ephtk/ephtk_skip_phmode
571 : : !! NAME
572 : : !! ephtk_skip_mode
573 : : !!
574 : : !! FUNCTION
575 : : !! Ignore contribution of phonon mode depending on phonon frequency value or mode index.
576 : : !!
577 : : !! INPUTS
578 : : !! nu: mode index
579 : : !! wqnu: phonon frequency
580 : : !! eph_phrange_w: range for phonon frequency.
581 : : !!
582 : : !! SOURCE
583 : :
584 [ - + ]: 155448 : pure logical function ephtk_skip_phmode(nu, wqnu, phmodes_skip, eph_phrange_w) result(skip)
585 : :
586 : : !Arguments ------------------------------------
587 : : integer,intent(in) :: nu, phmodes_skip(:)
588 : : real(dp),intent(in) :: wqnu, eph_phrange_w(2)
589 : : ! *************************************************************************
590 : :
591 [ + + - + ]: 155448 : skip = wqnu < EPHTK_WTOL .or. phmodes_skip(nu) == 1
592 : :
593 : : ! Check frequency range
594 [ + + ]: 155448 : if (abs(eph_phrange_w(2)) > tol12) then
595 [ + - ]: 1716 : if (eph_phrange_w(2) > zero) then
596 : : ! wqnu must be inside range
597 [ + + + - : 1716 : skip = skip .or. .not. (wqnu >= eph_phrange_w(1) .and. wqnu <= eph_phrange_w(2))
- + ]
598 : : else
599 : : ! wqnu must be outside range
600 [ # # # # : 0 : skip = skip .or. (wqnu >= eph_phrange_w(1) .and. wqnu <= eph_phrange_w(2))
# # ]
601 : : end if
602 : : end if
603 : :
604 : 155448 : end function ephtk_skip_phmode
605 : : !!***
606 : :
607 : 73728 : end module m_ephtk
608 : : !!***
|