Line data Source code
1 : !!****m* ABINIT/m_paw_slater
2 : !! NAME
3 : !! m_paw_slater
4 : !!
5 : !! FUNCTION
6 : !! This module defines objects and procedures to evaluate Slater-like integrals
7 : !! using real spherical Harmonics.
8 : !!
9 : !! COPYRIGHT
10 : !! Copyright (C) 2008-2026 ABINIT group (MG)
11 : !! This file is distributed under the terms of the
12 : !! GNU General Public License, see ~abinit/COPYING
13 : !! or http://www.gnu.org/copyleft/gpl.txt .
14 : !!
15 : !! NOTES
16 : !! * Routines tagged with "@type_name" are tightly connected to the definition of the data type.
17 : !! Tightly connected means that the proper functioning of the implementation relies on the
18 : !! assumption that the tagged procedure is consistent with the type declaration.
19 : !! Every time a developer changes the structure "type_name" adding new entries, he/she has to make sure
20 : !! that all the tightly connected routines are changed accordingly to accommodate the modification of the data type.
21 : !! Typical examples of tightly connected routines are creation, destruction or reset methods.
22 : !!
23 : !! SOURCE
24 :
25 : #if defined HAVE_CONFIG_H
26 : #include "config.h"
27 : #endif
28 :
29 : #include "abi_common.h"
30 :
31 : MODULE m_paw_slater
32 :
33 : use defs_basis
34 : use m_abicore
35 : use m_errors
36 : use m_splines
37 :
38 : use m_fstrings, only : basename
39 : use m_paw_atomorb, only : atomorb_type, print_atomorb, destroy_atomorb, get_overlap
40 : use m_pawpsp, only : pawpsp_init_core
41 : use m_crystal, only : crystal_t
42 : use m_paw_io, only : pawio_print_ij
43 : use m_pawang, only : pawang_type
44 : use m_paw_sphharm, only : realgaunt
45 : use m_pawrad, only : pawrad_type, pawrad_free, pawrad_isame, &
46 : & pawrad_deducer0, simp_gen, calc_slatradl,pawrad_copy
47 : use m_pawtab, only : pawtab_type
48 : use m_pawrhoij, only : pawrhoij_type
49 : use m_paw_lmn, only : make_kln2ln, make_klm2lm, make_indln, klmn2ijlmn
50 :
51 : implicit none
52 :
53 : private
54 :
55 : public :: paw_sigxcore ! The onsite matrix elements of the Fock operator generated by (closed) core shells.
56 : public :: paw_mkdijexc_core ! Calculate the onsite matrix element of the Fock operator generated by the core.
57 : public :: paw_dijhf ! Compute the onsite D_{ij} strengths of the exchange parth of the self energy.
58 : !!***
59 :
60 : !!****t* m_paw_slater/slatrad_t
61 : !! NAME
62 : !! slatrad_t
63 : !!
64 : !! FUNCTION
65 : !! Object used to store radial integrals of the form.
66 : !!
67 : !! $ F_{ijkl}^L = \dfrac{4\pi}{2L+1} \int u_i(1) u_j(1) \dfrac{r_<^L}{r_>^{L+1}} u_k(2) u_l(2) d1d2 $
68 : !!
69 : !! for a given quadruple (i,j,k,l) as a function L \in [L_min, L_max].
70 : !! i,j,k,l are shorthand indices for (nn,ll) quantum numbers.
71 : !!
72 : !! NOTES
73 : !! Basic symmetry properties:
74 : !! 1) invariant under the exchange (i<-->j) and (k<-->l).
75 : !! 2) invariant under the exchange (i,j) <--> (k,l).
76 : !!
77 : !! Memory saving is achieved by storing the upper triangle of the (ij) (kl) matrix
78 : !! and, for each dimension, only the upper triangle of the two matrices (iln,jln) (kln,lln).
79 : !!
80 : !! Some matrix elements will never contribute to <ij|1/|1-2||kl> due to selection rules
81 : !! introduced by the integration of the angular part.
82 : !!
83 : !! SOURCE
84 :
85 : type,public :: slatrad_t
86 :
87 : integer :: iln,jln,kln,lln
88 : ! The (l,n) indices associated to the partial waves.
89 :
90 : integer :: lslat_min
91 : ! Min l+1 in the expansion of the Coulomb potential.
92 :
93 : integer :: lslat_max
94 : ! Max l+1 in the expansion of the Coulomb potential.
95 :
96 : integer :: nintgl
97 : ! The number of non-zero integrals stored in intgl.
98 :
99 : integer,allocatable :: intgl_select(:)
100 : ! intgl_select(lslat_min:lslat_max)
101 : ! Index of the non-zero integrals in intgl, 0 if intgl has not been
102 : ! calculated thanks to selection rules coming from the angular integration.
103 :
104 : real(dp),allocatable :: intgl(:)
105 : ! intgl(1:nintgl)
106 : ! The integrals:
107 : ! \dfrac{4\pi}{2L+1} \int \phi_{\ni\li}(1) \phi_{\nj\lj}(1) \dfrac{r_<^L}{r_>^{L+1}} \phi_{\nk\lk}(2) \phi_{\nl\ll} d1d2
108 : ! for given (i,j,k,l) as a function L = |il-jl|, |il-jl|+2, ..., |il+il| and ilnc = (lc,nc).
109 :
110 : end type slatrad_t
111 :
112 : public :: slatrad_init ! Creation method
113 : public :: slatrad_free ! Free memory
114 : !!***
115 :
116 : interface slatrad_free
117 : module procedure slatrad_free_0D
118 : module procedure slatrad_free_1D
119 : end interface slatrad_free
120 :
121 : !----------------------------------------------------------------------
122 :
123 : !!****t* m_paw_slater/slatang_cshell_t
124 : !! NAME
125 : !! slatang_cshell_t
126 : !!
127 : !! FUNCTION
128 : !! Object used to store:
129 : !! $ F^{lsl,lc}_{li,lj,mi,mj} = sum_{msl mc} \<li mi|lsl msl;lc mc\> \<lsl msl;lc mc| lj mj\> $
130 : !! This (less general) type of radial integral is needed to evaluate the Exchange term generated
131 : !! by a closed-shell atom. In the equation, (lc,mc) are the set of angular quantum number associated
132 : !! to (closed) core electrons while (lsl,msl) comes from the expansion of 1/|r1-r2|.
133 : !! Since the F is invariant under exchange of i and j we use an array of structures indexed
134 : !! by kln = (iln,jln) in packed form.
135 : !!
136 : !! SOURCE
137 :
138 : type, public :: slatang_cshell_t
139 :
140 : integer :: nsggsel
141 : ! Number of non null matrix elements
142 :
143 : integer :: lslat_max
144 : ! Max l+1 in the expansion of the Coulomb potential
145 :
146 : integer :: lslat_min
147 : ! Min l+1 in the expansion of the Coulomb potential
148 :
149 : integer :: lc_max
150 : ! Max l+1 for orbitals summed over (usually core orbitals)
151 :
152 : integer,allocatable :: sggselect(:,:)
153 : ! sggselect(lslat_max,lc_max)
154 : ! Index of non null sgg, 0 if sgg is zero by symmetry.
155 :
156 : real(dp),allocatable :: sgg(:)
157 : ! sgg(nsggsel)
158 : ! Non null matrix elements in packed form. The index is given by sggselect.
159 :
160 : end type slatang_cshell_t
161 :
162 : public :: slatang_cshell_init ! Creation method for slatang_cshell_t.
163 : public :: slatang_cshell_free ! Destruction method for the slatang_cshell_t.
164 : !!***
165 :
166 : !----------------------------------------------------------------------
167 :
168 : !!****t* m_paw_slater/slatrad_cshell_t
169 : !! NAME
170 : !! slatrad_cshell_t
171 : !!
172 : !! FUNCTION
173 : !! Object used to store the set of radial integrals:
174 : !!
175 : !! $ \dfrac{4\pi}{2L+1} \times
176 : !! \int \phi_{\ni\li}(1) \phic_{\nc\lc}(1) \dfrac{r_<^L}{r_>^{L+1}} \phic_{\nc\lc}(2) \phi_{\nj\lj} d1d2 $
177 : !!
178 : !! for given (in,il) and (jn,jl) as a function L = |il-jl|, |il-jl|+2, ..., |il+il| and ilnc = (lc,nc).
179 : !! This (less general) type of radial integral is needed to evaluate the Exchange term generated
180 : !! by a closed-shell atom. In the equation, (\nc,\lc) are the set of angular quantum number associated
181 : !! to core electrons while (lsl,msl) comes from the expansion of 1/|r1-r2|.
182 : !! Since the F is invariant under exchange of i and j we use an array of structures indexed
183 : !! by kln = (iln,jln) in packed form.
184 : !!
185 : !! SOURCE
186 :
187 : type,public :: slatrad_cshell_t
188 :
189 : integer :: lnc_size
190 : ! Number of (n,l) channel for core orbitals.
191 :
192 : integer :: lslat_max
193 : ! Max l+1 in the expansion of the Coulomb potential
194 :
195 : integer :: lslat_min
196 : ! Min l+1 in the expansion of the Coulomb potential
197 :
198 : integer :: nrlphic_int
199 : ! The number of non-zero integrals stored in rlphic_int.
200 :
201 : integer,allocatable :: rlphic_select(:,:)
202 : ! rlphic_select(lslat_max,lnc_size) TODO should be allocated with lslat_min:lslat_max
203 : ! Index of the non-zero integrals in rlphic_int, 0 if rlphic_int has not been
204 : ! calculated thanks to selection rules coming from the angular integration.
205 :
206 : real(dp),allocatable :: rlphic_int(:)
207 : ! rlphic_int(1:nrlphic_int)
208 : ! The integrals:
209 : ! \dfrac{4\pi}{2L+1} \int \phi_{\ni\li}(1) \phic_{nc\lc}(1) \dfrac{r_<^L}{r_>^{L+1}} \phic_{nc\lc}(2) \phi_{\nj\lj} d1d2
210 : ! for given (in,il) and (jn,jl) as a function L = |il-jl|, |il-jl|+2, ..., |il+il| and ilnc = (lc,nc).
211 :
212 : end type slatrad_cshell_t
213 :
214 :
215 : CONTAINS !========================================================================================
216 : !!***
217 :
218 : !!****f* m_paw_slater/slatang_cshell_init
219 : !! NAME
220 : !! slatang_cshell_init
221 : !!
222 : !! FUNCTION
223 : !! Initialize the structure slatrad_cshell_t containing radial integrals, see below.
224 : !!
225 : !! INPUTS
226 : !! l_max= max. value of ang. momentum l+1;
227 : !! Gaunt coeffs up to [(2*l_max-1,m),(l_max,m),(l_max,m)] are computed
228 : !! lc_max=Max Lc+1 for core states used to contrusct \Sigma_x^\core.
229 : !! lm2_size=Number of symmetrix elements in the (l,m) basis set.
230 : !! NB: lm2_size = (l_max**2)*(l_max**2+1)/2.
231 : !! klm2lm(6,lm2_size)=Table giving il, jl ,im, jm, ilm and jlm for each klm=(ilm,jlm)
232 : !! where ilm=(il,im) and ilm<=jlm. NB: klm2lm is an application and not a bijection.
233 : !!
234 : !! OUTPUT
235 : !! Slatang3l(lm2_size) <type(slatang_cshell_t)> = Object storing :
236 : !!
237 : !! $ F^{ilsl,ilc}_{klm} = sum_{msl,mc} <li mi|lsl msl;lc mc> <lsl msl;lc mc|lj mj> $
238 : !!
239 : !! where klm = runs over the upper triangle of the ((il,im),(jl,jm)) matrix.
240 : !! ilc runs from 1 up to lc_max and |li-lc| <= lsl <= |li+lc|
241 : !!
242 : !! NOTES
243 : !! Selection rules for F
244 : !! 1) mi = mj
245 : !! 2) In the case of closed shells, one sums for all possible mc"s values from -lc up to +lc.
246 : !! In this particular case, one can use the symmetry properties of Clebsch-Gordan
247 : !! coefficients to show that F is non null only if li==lj. In particular, F can be rewritten as:
248 : !!
249 : !! $ F^{ilsl,ilc}_{klm} = \delta{li,lj}\delta{mi,mj} \times
250 : !! \Gaunt^{lsl,0}_{lc,0;li,0} \sqrt{ \dfrac{(2*lc+1) (2*lsl+1)}{4\pi*(2*li+1)} } $
251 : !!
252 : !! SOURCE
253 :
254 21 : subroutine slatang_cshell_init(Slatang3l,l_max,lm2_size,lc_max,klm2lm)
255 :
256 : !Arguments ------------------------------------
257 : !scalars
258 : integer,intent(in) :: l_max,lc_max,lm2_size
259 : !arrays
260 : integer,intent(in) :: klm2lm(6,lm2_size)
261 : type(slatang_cshell_t),intent(out) :: Slatang3l(lm2_size)
262 :
263 : !Local variables-------------------------------
264 : !scalars
265 : integer :: ilm,ilm0,jlm,lgnt_max,ngnt,ilsl,ilc,lc,ilm0c,lsl
266 : integer :: klm_ci,ilm0sl,li,il,jl,im,jm,ig000
267 : integer :: klm,k0lm_i,k0lm_j,k0lm_c,nsggsel,lslat_max,lslat_min
268 : real(dp) :: dum
269 : !arrays
270 1 : integer,allocatable :: gntselect(:,:)
271 1 : real(dp),allocatable :: realgnt(:),tmp_sgg(:)
272 1 : real(dp),allocatable :: g000(:,:,:)
273 :
274 : ! *************************************************************************
275 :
276 : !@slatang_cshell_t
277 :
278 : ! * Calculate $\Gaunt^{lsl,msl}_{lc,mc;li,mi}$
279 1 : lgnt_max = MAX(l_max,lc_max)
280 3 : ABI_MALLOC( realgnt,((2*lgnt_max-1)**2*(lgnt_max)**4))
281 4 : ABI_MALLOC(gntselect,((2*lgnt_max-1)**2, lgnt_max**2*(lgnt_max**2+1)/2))
282 :
283 1 : call realgaunt(lgnt_max,ngnt,gntselect,realgnt)
284 :
285 : ! Below we need $\Gaunt_{lsl,0}_{lc,0;li,0}$
286 6 : ABI_MALLOC(g000,(2*lgnt_max-1,lc_max,l_max))
287 19 : g000 = zero
288 :
289 4 : do ilsl=1,2*lgnt_max-1
290 3 : lsl = ilsl-1
291 3 : ilm0sl = 1+lsl**2+lsl
292 10 : do il=1,l_max
293 6 : li = il-1
294 6 : ilm0 = 1+li**2+li
295 6 : k0lm_i = ilm0 *(ilm0-1)/2
296 21 : do ilc=1,lc_max
297 12 : lc = ilc-1
298 12 : ilm0c = 1+lc**2+lc
299 12 : k0lm_c= ilm0c * (ilm0c-1)/2
300 12 : if (ilm0c > ilm0) then
301 3 : klm_ci = k0lm_c + ilm0
302 : else
303 9 : klm_ci = k0lm_i + ilm0c
304 : end if
305 12 : ig000 = gntselect(ilm0sl,klm_ci) ! Index of $\Gaunt_{lsl,0}_{lc,0;li,0}$
306 18 : if (ig000 > 0) g000(ilsl,ilc,il)=realgnt(ig000)
307 : end do
308 : end do
309 : end do
310 :
311 1 : ABI_FREE(realgnt)
312 1 : ABI_FREE(gntselect)
313 :
314 : ! === Loop over klm channels in packed form ===
315 11 : do klm=1,lm2_size
316 10 : il = klm2lm(1,klm); im = klm2lm(3,klm)
317 10 : jl = klm2lm(2,klm); jm = klm2lm(4,klm)
318 :
319 10 : nsggsel=0
320 10 : lslat_min = 1 !FIXME find better way
321 10 : lslat_max = il+lc_max-1
322 :
323 10 : Slatang3l(klm)%lslat_min = lslat_min
324 10 : Slatang3l(klm)%lslat_max = lslat_max
325 10 : Slatang3l(klm)%lc_max = lc_max
326 :
327 30 : ABI_MALLOC(tmp_sgg,(lslat_max*lc_max))
328 62 : tmp_sgg = zero
329 :
330 : ! === Calculate F^{lsl,lc}_{li,mi;lj,mj} ===
331 : ! * Selection rule: mi = mj and li==lj
332 10 : if (im == jm .and. il==jl) then
333 4 : li = il-1
334 4 : ilm = klm2lm(5,klm); k0lm_i = ilm *(ilm -1)/2
335 4 : jlm = klm2lm(6,klm); k0lm_j = jlm *(jlm -1)/2
336 :
337 16 : ABI_MALLOC(Slatang3l(klm)%sggselect,(lslat_max,lc_max))
338 34 : Slatang3l(klm)%sggselect = 0
339 :
340 15 : do ilsl=lslat_min,lslat_max
341 : !% do ilsl=lslat_min,lslat_max,2
342 11 : lsl = ilsl-1
343 37 : do ilc=1,lc_max
344 22 : lc = ilc-1
345 22 : dum = SQRT( (two*lc+1)*(two*lsl+1) / (four_pi*(two*li+1)) ) * g000(ilsl,ilc,il)
346 33 : if (ABS(dum)>=tol12) then ! * Store results and progressive index if non null.
347 11 : nsggsel = nsggsel + 1
348 11 : tmp_sgg(nsggsel) = dum
349 11 : Slatang3l(klm)%sggselect(ilsl,ilc) = nsggsel
350 : end if
351 : end do !ilc
352 : end do !ilsl
353 : end if ! Selection rule li=lj and mi == mj
354 : !
355 : ! * Finalize the object.
356 10 : Slatang3l(klm)%nsggsel = nsggsel
357 10 : if (nsggsel > 0) then
358 12 : ABI_MALLOC(Slatang3l(klm)%sgg,(nsggsel))
359 19 : Slatang3l(klm)%sgg = tmp_sgg(1:nsggsel)
360 : end if
361 11 : ABI_FREE(tmp_sgg)
362 : end do !klm
363 :
364 1 : ABI_FREE(g000)
365 :
366 : #if 0
367 : ! Debugging code
368 : do klm=1,lm2_size
369 : if (Slatang3l(klm)%nsggsel>0) then
370 : il = klm2lm(1,klm)
371 : jl = klm2lm(2,klm)
372 : im = klm2lm(3,klm)
373 : jm = klm2lm(4,klm)
374 : write(std_out,*)"--for li, mi",il-1,im-il
375 : lslat_min = Slatang3l(klm)%lslat_min
376 : lslat_max = Slatang3l(klm)%lslat_max
377 :
378 : do ilc=1,lc_max
379 : do ilsl=lslat_min,lslat_max
380 : ii = Slatang3l(klm)%sggselect(ilsl,ilc)
381 : if (ii>0) write(std_out,*)" lc, lslat, sgg",ilc-1,ilsl-1,Slatang3l(klm)%sgg(ii)
382 : end do
383 : end do
384 : end if
385 : end do
386 : #endif
387 :
388 1 : end subroutine slatang_cshell_init
389 : !!***
390 :
391 : !----------------------------------------------------------------------
392 :
393 : !!****f* m_paw_slater/slatang_cshell_free
394 : !! NAME
395 : !! slatang_cshell_free
396 : !!
397 : !! FUNCTION
398 : !! Free the dynamic memory allocated in a structure of type slatang_cshell_t
399 : !!
400 : !! SIDE EFFECTS
401 : !! Slatang3l(lm2_size) <type(slatang_cshell_t)> = Object containing radial integrals
402 : !!
403 : !! SOURCE
404 :
405 1 : subroutine slatang_cshell_free(Slatang3l)
406 :
407 : !Arguments ------------------------------------
408 : !scalars
409 : type(slatang_cshell_t),intent(inout) :: Slatang3l(:)
410 :
411 : !Local variables-------------------------------
412 : integer :: ii
413 : ! *********************************************************************
414 :
415 : !@slatang_cshell_t
416 11 : do ii=1,SIZE(Slatang3l)
417 10 : ABI_SFREE(Slatang3l(ii)%sggselect)
418 11 : ABI_SFREE(Slatang3l(ii)%sgg)
419 : end do
420 :
421 1 : end subroutine slatang_cshell_free
422 : !!***
423 :
424 : !----------------------------------------------------------------------
425 :
426 : !!****f* m_paw_slater/slatrad_cshell_free
427 : !! NAME
428 : !! slatrad_cshell_free
429 : !!
430 : !! FUNCTION
431 : !! Free the dynamic memory allocated in a structure of type slatrad_cshell_t
432 : !!
433 : !! SIDE EFFECTS
434 : !! Slatrad3l(ln2_size) <type(slarad3l_type)> = Object containing radial integrals
435 : !!
436 : !! SOURCE
437 :
438 1 : subroutine slatrad_cshell_free(Slatrad3l)
439 :
440 : !Arguments ------------------------------------
441 : !scalars
442 : type(slatrad_cshell_t),intent(inout) :: Slatrad3l(:)
443 :
444 : !Local variables-------------------------------
445 : integer :: ii
446 : ! *********************************************************************
447 :
448 : !@slatrad_cshell_t
449 11 : do ii=1,SIZE(Slatrad3l)
450 10 : ABI_SFREE(Slatrad3l(ii)%rlphic_select)
451 11 : ABI_SFREE(Slatrad3l(ii)%rlphic_int)
452 : end do
453 :
454 1 : end subroutine slatrad_cshell_free
455 : !!***
456 :
457 : !----------------------------------------------------------------------
458 :
459 : !!****f* m_paw_slater/slatrad_cshell_init
460 : !! NAME
461 : !! slatrad_cshell_init
462 : !!
463 : !! FUNCTION
464 : !! Initialize the structure storing the radial part of Slater"s integrals.
465 : !!
466 : !! INPUTS
467 : !! ln2_size=Number of symmetrical (l,n) channels
468 : !! Pawrad<pawrad_type>=paw radial mesh and related data
469 : !! Pawtab<pawtab_type>=paw tabulated starting data
470 : !! Atm<atomorb_type>=Object containing core orbitals.
471 : !! Atmrad<pawrad_type>=paw radial mesh and related data for the atom.
472 : !! kln_mask
473 : !!
474 : !! OUTPUT
475 : !! Slatrad3l<slatrad_cshell_t>=The object completely initialized.
476 : !!
477 : !! SOURCE
478 :
479 21 : subroutine slatrad_cshell_init(Slatrad3l,ln2_size,Pawrad,Pawtab,Atm,Atmrad,kln_mask)
480 :
481 : !Arguments ------------------------------------
482 : !scalars
483 : integer,intent(in) :: ln2_size
484 : !arrays
485 : integer,optional,intent(in) :: kln_mask(ln2_size)
486 : type(atomorb_type),intent(in) :: Atm
487 : type(pawrad_type),target,intent(in) :: Atmrad,Pawrad
488 : type(pawtab_type),target,intent(in) :: Pawtab
489 : type(slatrad_cshell_t),intent(out) :: Slatrad3l(ln2_size)
490 :
491 : !Local variables ---------------------------------------
492 : !scalars
493 : integer :: cmesh_size,dmesh_size
494 : integer :: il,iln,ilnc,isl,in,jl,jln,jn,kln,ll,lnc_size
495 : integer :: lslat_max,lslat_min,lc_max,nintg
496 : integer :: lmn_size,lmn2_size,do_spline,ln_size,whichdenser,isppol
497 : real(dp) :: intg,intg1,ybcbeg,ybcend
498 : logical :: hasameq
499 : !arrays
500 1 : integer,allocatable :: kln2ln(:,:)
501 1 : integer, pointer :: indklmn(:,:),indlmn(:,:)
502 1 : real(dp),allocatable :: ff1(:),ff2(:),tmp_integrals(:)
503 1 : real(dp),ABI_CONTIGUOUS pointer :: phi_i(:),phi_j(:)
504 1 : real(dp),allocatable,target :: phi_spl(:,:)
505 1 : real(dp),allocatable :: der(:),ypp(:)
506 1 : real(dp),ABI_CONTIGUOUS pointer :: crad(:),drad(:),phi_in(:)
507 :
508 : ! *************************************************************************
509 :
510 1 : ABI_CHECK(ln2_size==Pawtab%ij_size,"Wrong ln2_size")
511 1 : if (PRESENT(kln_mask)) then
512 0 : ABI_ERROR("kln_mask is present")
513 : end if
514 :
515 : !@slatrad_cshell_t
516 1 : lmn_size = Pawtab%lmn_size
517 1 : lmn2_size = Pawtab%lmn2_size
518 1 : ln_size = Pawtab%basis_size
519 :
520 1 : lnc_size = Atm%ln_size
521 1 : lc_max = Atm%l_max
522 :
523 1 : call pawrad_isame(Atmrad,Pawrad,hasameq,whichdenser)
524 :
525 1 : do_spline=0
526 1 : if (.not.hasameq) then
527 1 : do_spline=1
528 1 : if (whichdenser/=1) &
529 1 : & ABI_COMMENT("Pawrad is denser than Atmrad!")
530 : else
531 0 : ABI_CHECK(whichdenser==1,"Pawrad is denser than Atmrad!")
532 : end if
533 :
534 1 : dmesh_size = Atmrad%mesh_size
535 1 : cmesh_size = Pawtab%mesh_size
536 :
537 1 : drad => Atmrad%rad(1:dmesh_size)
538 1 : crad => Pawrad%rad(1:cmesh_size)
539 :
540 : ! === Spline valence basis set onto core mesh (natural spline) ===
541 1 : if (do_spline==1) then
542 1 : ABI_COMMENT("Splining in init_slatrad3l")
543 4 : ABI_MALLOC(phi_spl,(dmesh_size,ln_size))
544 3 : ABI_MALLOC(der,(cmesh_size))
545 2 : ABI_MALLOC(ypp,(cmesh_size))
546 :
547 5 : do iln=1,ln_size
548 4 : phi_in => Pawtab%phi(:,iln)
549 2484 : ypp(:) = zero; ybcbeg = zero; ybcend = zero
550 4 : call spline(crad,phi_in,cmesh_size,ybcbeg,ybcend,ypp)
551 5 : call splint(cmesh_size,crad,phi_in,ypp,dmesh_size,drad,phi_spl(:,iln))
552 : end do
553 :
554 1 : ABI_FREE(der)
555 1 : ABI_FREE(ypp)
556 : end if
557 :
558 1 : indlmn => Pawtab%indlmn(1:6,1:lmn_size)
559 1 : indklmn => Pawtab%indklmn(1:8,1:lmn2_size)
560 :
561 3 : ABI_MALLOC(kln2ln,(6,ln2_size))
562 :
563 1 : call make_kln2ln(lmn_size,lmn2_size,ln2_size,indlmn,indklmn,kln2ln)
564 :
565 3 : ABI_MALLOC(ff1,(dmesh_size))
566 2 : ABI_MALLOC(ff2,(dmesh_size))
567 :
568 : ! * Loop over the upper triangle of the [(in,il), (jn,il)] matrix.
569 1 : ABI_CHECK(Atm%nsppol==1,"nsppol==2 not tested")
570 :
571 2 : do isppol=1,Atm%nsppol
572 12 : do kln=1,ln2_size
573 10 : il = kln2ln(1,kln)
574 10 : jl = kln2ln(2,kln)
575 10 : in = kln2ln(3,kln)
576 10 : jn = kln2ln(4,kln)
577 10 : iln = kln2ln(5,kln)
578 10 : jln = kln2ln(6,kln)
579 :
580 10 : lslat_max = MAX((il+lc_max),(jl+lc_max)) - 1 ! These are indices, not l-values.
581 : !lslat_min = MIN(ABS(il-lc_max),ABS(jl-lc_max)) + 1
582 10 : lslat_min = 1 ! FIXME find better way
583 :
584 10 : Slatrad3l(kln)%lnc_size = lnc_size
585 10 : Slatrad3l(kln)%lslat_min = lslat_min
586 10 : Slatrad3l(kln)%lslat_max = lslat_max
587 :
588 10 : Slatrad3l(kln)%nrlphic_int = 0
589 :
590 40 : ABI_MALLOC(Slatrad3l(kln)%rlphic_select,(lslat_max,lnc_size))
591 121 : Slatrad3l(kln)%rlphic_select(:,:) = 0
592 :
593 : !if (PRESENT(kln_mask)) then !FIXME THIS IS WRONG, move it below in case
594 : ! if (kln_mask(kln)==0) CYCLE
595 : !end if
596 :
597 10 : if (do_spline==1) then
598 10 : ABI_COMMENT("Performing spline of valence phi")
599 10 : phi_i => phi_spl(:,iln)
600 10 : phi_j => phi_spl(:,jln)
601 : else
602 0 : phi_i => Pawtab%phi(:,iln)
603 0 : phi_j => Pawtab%phi(:,jln)
604 : end if
605 :
606 : ! * Loop over (n,l) channels for Atom orbitals
607 30 : ABI_MALLOC(tmp_integrals,(lslat_max*lnc_size))
608 91 : tmp_integrals(:) = zero
609 : nintg=0
610 :
611 40 : do ilnc=1,lnc_size
612 : ! phicore => Atm%phi(:,ilnc,isppol)
613 41520 : ff1 = phi_i * Atm%phi(:,ilnc,isppol)
614 41520 : ff2 = phi_j * Atm%phi(:,ilnc,isppol)
615 121 : do isl=lslat_min,lslat_max ! L coming from Coulomb expansion
616 81 : ll = isl-1
617 81 : call calc_slatradl(ll,dmesh_size,ff2,ff1,Atmrad,intg1)
618 81 : call calc_slatradl(ll,dmesh_size,ff1,ff2,Atmrad,intg)
619 :
620 : !call calc_slatradl(ll,cmesh_size,ff2,ff1,Pawrad,intg1)
621 : !call calc_slatradl(ll,cmesh_size,ff1,ff2,Pawrad,intg)
622 :
623 81 : if (ABS(intg1-intg)>tol6) write(std_out,*)"DEBUG ",ll,il,in,jl,jn,intg1,intg
624 :
625 : ! * Store results
626 192 : if (ABS(intg)>=tol12) then
627 81 : nintg = nintg +1
628 81 : Slatrad3l(kln)%rlphic_select(isl,ilnc) = nintg
629 81 : tmp_integrals(nintg) = intg
630 : end if
631 : end do !ll
632 : end do ! ilnc
633 :
634 : ! Finalize the object
635 10 : Slatrad3l(kln)%nrlphic_int = nintg
636 30 : ABI_MALLOC(Slatrad3l(kln)%rlphic_int,(nintg))
637 101 : if (nintg>0) Slatrad3l(kln)%rlphic_int(:) = tmp_integrals(1:nintg)
638 :
639 11 : ABI_FREE(tmp_integrals)
640 : end do !kln
641 : end do !isppol
642 :
643 1 : ABI_FREE(ff1)
644 1 : ABI_FREE(ff2)
645 1 : ABI_FREE(kln2ln)
646 :
647 1 : if (do_spline==1) then
648 1 : ABI_FREE(phi_spl)
649 : end if
650 :
651 3 : end subroutine slatrad_cshell_init
652 : !!***
653 :
654 : !----------------------------------------------------------------------
655 :
656 : !!****f* m_paw_slater/paw_sigxcore
657 : !! NAME
658 : !! paw_sigxcore
659 : !!
660 : !! FUNCTION
661 : !! Calculate the integrals:
662 : !! \dfrac{4\pi}{2L+1} \int \phi_{\ni\li}(1) orb_{nl}(1) \dfrac{r_<^L}{r_>^{L+1}} orb_{nl}(2) \phi_{\nj\lj} d1d2!!
663 : !! for given (in,il) and (jn,jl) as a function of (nc,lc) and L = |il-jl|, |il-jl|+2, ..., |il+il|
664 : !!
665 : !! INPUTS
666 : !! cplex_dij=1 if dijexc_core is real, 2 if they are complex
667 : !! lmn2_size=Number of (klmn) channels
668 : !! ndij=Usually ndij=nspden, except for spin-orbit (where ndij=nspinor**2)
669 : !! Pawtab<pawtab_type>=paw tabulated starting data
670 : !! Atm<atomorb_type>=Structure containing core orbitals
671 : !! Atmrad<pawrad_type>=The radial mesh for core orbitals
672 : !!
673 : !! OUTPUT
674 : !! dijexc_core(cplex_dij*lmn2_size,ndij)
675 : !!
676 : !! SOURCE
677 :
678 1 : subroutine paw_sigxcore(cplex_dij,lmn2_size,ndij,Pawrad,Pawtab,Atm,Atmrad,dijexc_core)
679 :
680 : !Arguments ------------------------------------
681 : !scalars
682 : integer,intent(in) :: lmn2_size,cplex_dij,ndij
683 : !arrays
684 : real(dp),intent(out) :: dijexc_core(cplex_dij*lmn2_size,ndij)
685 : type(atomorb_type),intent(in) :: Atm
686 : type(pawrad_type),intent(in) :: Atmrad
687 : type(pawrad_type),intent(in) :: Pawrad
688 : type(pawtab_type),target,intent(in) :: Pawtab
689 :
690 : !Local variables ---------------------------------------
691 : !scalars
692 : integer :: ilnc,ilc,lnc_size,l_max
693 : integer :: lm2_size,ln_size,ln2_size,lmn_size
694 : integer :: lm_size,klmn,kln,klm
695 : integer :: lc_max,ilsl,isgg,israd,opt_l,pawprtvol
696 : real(dp) :: tmp,sgg,intgrl
697 : !character(len=500) :: msg
698 : !arrays
699 : integer :: opt_l_index(0,0),pack2ij(0)
700 1 : integer,allocatable :: kln2ln(:,:),klm2lm(:,:)
701 : integer, pointer :: indklmn(:,:),indlmn(:,:)
702 : type(slatang_cshell_t),allocatable :: Slatang3l(:)
703 1 : type(slatrad_cshell_t),allocatable :: Slatrad3l(:)
704 :
705 : ! *************************************************************************
706 :
707 : ! * Consistency check
708 1 : ABI_CHECK(cplex_dij==1,"cplex_dij must be 1")
709 :
710 1 : ABI_CHECK(ndij==1,"ndij must be 1")
711 :
712 1 : ABI_CHECK(lmn2_size==Pawtab%lmn2_size,"Wrong lmn2_size")
713 :
714 1 : lmn_size = Pawtab%lmn_size
715 1 : ln_size = Pawtab%basis_size
716 1 : ln2_size = Pawtab%ij_size
717 1 : l_max = (Pawtab%l_size-1)/2 +1
718 1 : lm_size = l_max**2
719 1 : lm2_size = lm_size*(lm_size+1)/2
720 :
721 1 : indlmn => Pawtab%indlmn(1:6,1:lmn_size)
722 1 : indklmn => Pawtab%indklmn(1:8,1:lmn2_size)
723 :
724 : ! * Setup of useful tables.
725 3 : ABI_MALLOC(kln2ln,(6,ln2_size))
726 1 : call make_kln2ln(lmn_size,lmn2_size,ln2_size,indlmn,indklmn,kln2ln)
727 :
728 3 : ABI_MALLOC(klm2lm,(6,lm2_size))
729 1 : call make_klm2lm(lmn_size,lmn2_size,lm2_size,indlmn,indklmn,klm2lm)
730 :
731 : ! * Integrate angular part.
732 1 : lnc_size = Atm%ln_size
733 1 : lc_max = Atm%l_max
734 :
735 13 : ABI_MALLOC(Slatang3l,(lm2_size))
736 1 : call slatang_cshell_init(Slatang3l,l_max,lm2_size,lc_max,klm2lm)
737 :
738 1 : ABI_FREE(klm2lm)
739 :
740 : ! * Integrate radial part.
741 13 : ABI_MALLOC(Slatrad3l,(ln2_size))
742 :
743 1 : call slatrad_cshell_init(Slatrad3l,ln2_size,Pawrad,Pawtab,Atm,Atmrad)
744 :
745 : ! === Calculate matrix elements of Sigma_x^core ===
746 : ! * $<\phi_i|\Sigma_x^\core|\phi_j>$
747 38 : dijexc_core = zero
748 37 : do klmn=1,lmn2_size
749 36 : klm = Pawtab%indklmn(1,klmn)
750 36 : kln = Pawtab%indklmn(2,klmn)
751 : !
752 : ! * Summing over (lc,nc) and lslat
753 36 : tmp = zero
754 36 : if (Slatang3l(klm)%nsggsel >0) then
755 48 : do ilnc=1,Atm%ln_size
756 36 : ilc = 1+Atm%indln(1,ilnc)
757 147 : do ilsl=1,Slatang3l(klm)%lslat_max !FIXME check this
758 : !do ilsl=Slatang3l(klm)%lslat_min,Slatang3l(klm)%lslat_max
759 99 : isgg = Slatang3l(klm)%sggselect(ilsl,ilc)
760 99 : israd = Slatrad3l(kln)%rlphic_select(ilsl,ilnc)
761 135 : if (isgg>0 .and. israd>0) then
762 45 : sgg = Slatang3l(klm)%sgg(isgg)
763 45 : intgrl = Slatrad3l(kln)%rlphic_int(israd)
764 45 : tmp = tmp + intgrl*sgg
765 : end if
766 : end do
767 : end do
768 : end if
769 :
770 37 : dijexc_core(klmn,1) = -tmp ! Store results.
771 : end do
772 :
773 : ! * Print values
774 1 : call wrtout(std_out," ************** Dij Fock_core ************ ",'COLL')
775 1 : opt_l=-1; pawprtvol=-1
776 1 : call pawio_print_ij(std_out,dijexc_core(:,1),lmn2_size,cplex_dij,lmn_size,opt_l,opt_l_index,0,pawprtvol,pack2ij,-one,1)
777 :
778 : ! * Free memory.
779 1 : ABI_FREE(kln2ln)
780 1 : call slatang_cshell_free(Slatang3l)
781 11 : ABI_FREE(Slatang3l)
782 1 : call slatrad_cshell_free(Slatrad3l)
783 11 : ABI_FREE(Slatrad3l)
784 :
785 1 : end subroutine paw_sigxcore
786 : !!***
787 :
788 : !----------------------------------------------------------------------
789 :
790 : !!****f* m_paw_slater/paw_mkdijexc_core
791 : !! NAME
792 : !! paw_mkdijexc_core
793 : !!
794 : !! FUNCTION
795 : !! Driver routine to calculate the onsite matrix element of the Fock operator between two
796 : !! all-electron partial waves.
797 : !!
798 : !! INPUTS
799 : !! ndij=Usually ndij=nspden, except for spin-orbit (where ndij=nspinor**2)
800 : !! cplex_dij=1 if dijexc_core is real, 2 if they are complex
801 : !! lmn2_size_max=Max Number of (klmn) channels over type of atoms.
802 : !! Cryst<crystal_t>=Structure describing the crystal structure and its symmmetries.
803 : !! Pawtab(ntypat)<pawtab_type>=paw tabulated starting data
804 : !! Pawrad(ntypat)<pawrad_type>=paw radial mesh and related data
805 : !! pawprtvol=Flags governing the verbosity of the output.
806 : !! filpsp(ntypat)=names of the files containing the all-electron core WF
807 : !!
808 : !! OUTPUT
809 : !! dijexc_core(cplex_dij*lmn2_size_max,ndij,ntypat)= On-site matrix elements $ \<\phi_i|Sigma_x^\core|\phi_j\>
810 : !! for each type of atom.
811 : !!
812 : !! SOURCE
813 :
814 1 : subroutine paw_mkdijexc_core(ndij,cplex_dij,lmn2_size_max,Cryst,Pawtab,Pawrad,dijexc_core,pawprtvol,filpsp)
815 :
816 : !Arguments ------------------------------------
817 : !scalars
818 : integer,intent(in) :: pawprtvol,ndij,cplex_dij,lmn2_size_max
819 : type(crystal_t),intent(in) :: Cryst
820 : !arrays
821 : real(dp),intent(out) :: dijexc_core(cplex_dij*lmn2_size_max,ndij,Cryst%ntypat) !TODO use ragged arrays pawij?
822 : character(len=fnlen) :: filpsp(Cryst%ntypat)
823 : type(Pawtab_type),target,intent(in) :: Pawtab(Cryst%ntypat)
824 : type(Pawrad_type),intent(in) :: Pawrad(Cryst%ntypat)
825 :
826 : !Local variables ---------------------------------------
827 : !scalars
828 : integer :: itypat,lmn_size,lmn2_size,ln_size,isppol
829 : real(dp) :: rcut
830 : character(len=500) :: header
831 : !arrays
832 1 : integer,allocatable :: phi_indln(:,:)
833 1 : real(dp),ABI_CONTIGUOUS pointer :: phi(:,:)
834 1 : real(dp),allocatable :: overlap(:,:)
835 1 : type(atomorb_type),allocatable :: Atm(:)
836 1 : type(Pawrad_type),allocatable :: Radatm(:)
837 :
838 : ! *************************************************************************
839 :
840 4 : ABI_MALLOC(Atm,(Cryst%ntypat))
841 4 : ABI_MALLOC(Radatm,(Cryst%ntypat))
842 :
843 1 : ABI_CHECK(ndij==1 ,"spinor+HF not available")
844 1 : ABI_CHECK(cplex_dij==1,"spinor+HF not available")
845 2 : ABI_CHECK(lmn2_size_max==MAXVAL(Pawtab(:)%lmn2_size),"Wrong lmn2_size_max")
846 :
847 : !allocate(dijexc_core(cplex_dij*lmn2_size_max,ndij,Cryst%ntypat)) !TODO use ragged arrays pawij?
848 39 : dijexc_core=zero
849 :
850 2 : do itypat=1,Cryst%ntypat
851 :
852 : ! Read core orbitals for this atom type.
853 1 : rcut=Pawtab(itypat)%rpaw
854 1 : call pawpsp_init_core(Atm(itypat),psp_filename=trim(filpsp(itypat)),rcut_in=rcut)
855 1 : call pawrad_copy(Atm(itypat)%radmesh,Radatm(itypat))
856 :
857 1 : write(header,'(a,i4,a)')" === Atom type = ",itypat," === "
858 1 : call print_atomorb(Atm(itypat),header,unit=std_out,prtvol=pawprtvol)
859 : !
860 : ! * Calculate $ \<\phi_i|Sigma_x^\core|\phi_j\> $ for this atom type.
861 1 : lmn_size = Pawtab(itypat)%lmn_size
862 1 : lmn2_size = Pawtab(itypat)%lmn2_size
863 :
864 : call paw_sigxcore(cplex_dij,lmn2_size,ndij,&
865 1 : & Pawrad(itypat),Pawtab(itypat),Atm(itypat),Radatm(itypat),dijexc_core(1:lmn2_size,:,itypat))
866 :
867 1 : ln_size = Pawtab(itypat)%basis_size
868 1 : phi => Pawtab(itypat)%phi
869 :
870 3 : ABI_MALLOC(phi_indln,(2,ln_size))
871 1 : call make_indln(lmn_size,ln_size,Pawtab(itypat)%indlmn(:,:),phi_indln)
872 :
873 4 : ABI_MALLOC(overlap,(Atm(itypat)%ln_size,ln_size))
874 1 : isppol=1 ! hardcoded
875 1 : call get_overlap(Atm(itypat),Radatm(itypat),Pawrad(itypat),isppol,ln_size,phi,phi_indln,overlap)
876 :
877 1 : ABI_FREE(phi_indln)
878 2 : ABI_FREE(overlap)
879 : end do ! ntypat
880 :
881 : ! Free memory
882 1 : call pawrad_free(Radatm)
883 2 : do itypat=1,Cryst%ntypat
884 2 : call destroy_atomorb(Atm(itypat))
885 : end do
886 :
887 2 : ABI_FREE(Atm)
888 2 : ABI_FREE(Radatm)
889 :
890 1 : end subroutine paw_mkdijexc_core
891 : !!****
892 :
893 : !----------------------------------------------------------------------
894 :
895 : !!****f* m_paw_slater/slatrad_free_0D
896 : !! NAME
897 : !! slatrad_free_0D
898 : !!
899 : !! FUNCTION
900 : !! Free the dynamic memory allocated in a structure of type slatrad_t
901 : !!
902 : !! SOURCE
903 :
904 0 : subroutine slatrad_free_0D(Slatrad)
905 :
906 : !Arguments ------------------------------------
907 : !scalars
908 : type(slatrad_t),intent(inout) :: Slatrad
909 :
910 : ! *********************************************************************
911 :
912 : !@slatrad_t
913 0 : ABI_SFREE(Slatrad%intgl_select)
914 0 : ABI_SFREE(Slatrad%intgl)
915 :
916 0 : end subroutine slatrad_free_0D
917 : !!***
918 :
919 : !----------------------------------------------------------------------
920 :
921 : !!****f* m_paw_slater/slatrad_free_1D
922 : !! NAME
923 : !! slatrad_free_1D
924 : !!
925 : !! FUNCTION
926 : !! Free the dynamic memory allocated in a structure of type slatrad_t
927 : !!
928 : !! SOURCE
929 :
930 0 : subroutine slatrad_free_1D(Slatrad)
931 :
932 : !Arguments ------------------------------------
933 : !scalars
934 : type(slatrad_t),intent(inout) :: Slatrad(:)
935 :
936 : !Local variables-------------------------------
937 : integer :: ii
938 : ! *********************************************************************
939 :
940 0 : do ii=1,SIZE(Slatrad)
941 0 : call slatrad_free_0D(Slatrad(ii))
942 : end do
943 :
944 0 : end subroutine slatrad_free_1D
945 : !!***
946 :
947 : !----------------------------------------------------------------------
948 :
949 : !!****f* m_paw_slater/slatrad_init
950 : !! NAME
951 : !! slatrad_init
952 : !!
953 : !! FUNCTION
954 : !! Initialize the structure storing the radial part of Slater"s integrals.
955 : !!
956 : !! INPUTS
957 : !! which_intg= Option defining what kind of integrals have to be calculated:
958 : !! -- 1 for Slater integral of AE partial waves only.
959 : !! A = \frac{4\pi}{2L+1} \int u_i(1) u_j(1) \frac{r_<^L}{r_^{L+1}} u_k(2)u_l(2) d1d2
960 : !1
961 : !! -- 2 for Slater integral of (AE-PS) partial waves
962 : !! B = \frac{4\pi}{2L+1} \int u_i(1) u_j(1) \frac{r_<^L}{r_^{L+1}} u_k(2) u_l(2) d1d2 -
963 : !! \frac{4\pi}{2L+1} \int tu_i(1) tu_j(1) \frac{r_<^L}{r_^{L+1}} tu_k(2) tu_l(2) d1d2
964 : !!
965 : !! -- 3 for Slater integral of (AE-PS-compensation charges)
966 : !! C = A -
967 : !! \frac{4\pi}{2L+1} \int [tu_i(1) tu_j(1) + qhat^L_\ij r_1^2 g^L(1) ] \frac{r_<^L}{r_^{L+1}}*
968 : !! [tu_k(2) tu_l(2) + qhat^L_\kl r_2^2 g^L(2) ] d1d2
969 : !!
970 : !! where u = \phi/r; tu = \tphi/r; and qhat^L_\ij are related to q^\LM_\ij via
971 : !! q^\LM_\ij = \Gaunt_\ij^\LM qhat^L_\ij => qhat^L\ij = \int (u_i*u_j - tu_i*tu_j) r^L
972 : !!
973 : !! ln2_size=Number of symmetrical (l,n) channels for this atom type type.
974 : !! Pawrad<pawrad_type>=paw radial mesh and related data
975 : !! Pawtab<pawtab_type>=paw tabulated starting data
976 : !!
977 : !! OUTPUT
978 : !! Slatrad4<slatrad_t>=The object completely initialized.
979 : !!
980 : !! NOTES
981 : !! Slater integrals S_ij are invariant under exchange of the indices,
982 : !! but the results reported by calc_slatradl are not due to numerical roundoff errors (err < 10^-9).
983 : !! However this does not cause any problem since only the upper triangle of the S_ij matrix
984 : !! is stored and used in the other routines.
985 : !!
986 : !! SOURCE
987 :
988 0 : subroutine slatrad_init(Slatrad4,which_intg,ln2_size,Pawrad,Pawtab)
989 :
990 : !Arguments ------------------------------------
991 : !scalars
992 : integer,intent(in) :: ln2_size,which_intg
993 : !arrays
994 : type(pawrad_type),target,intent(in) :: Pawrad
995 : type(pawtab_type),target,intent(in) :: Pawtab
996 : type(slatrad_t),intent(out) :: Slatrad4(ln2_size*(ln2_size+1)/2)
997 :
998 : !Local variables ---------------------------------------
999 : !scalars
1000 : integer :: mesh_size,il,iln,isl,in,jl,jln,jn,sln1,sln2,l_slat
1001 : integer :: kn,kl,ln,ll,kln,lln,lslat_max,lslat_min,nintgl
1002 : integer :: lmn_size,lmn2_size,ln_size,slt_idx
1003 : real(dp) :: ae_intg,ps_intg,pshat_intg,intg,tqij_L,tqkl_L !intg1
1004 : character(len=500) :: msg
1005 : !arrays
1006 0 : integer,allocatable :: kln2ln(:,:)
1007 0 : integer, pointer :: indklmn(:,:),indlmn(:,:)
1008 0 : real(dp),allocatable :: uiuj(:),ukul(:),tuituj(:),tuktul(:),tuituj_tqgl(:),tuktul_tqgl(:)
1009 0 : real(dp),allocatable :: tmp_integrals(:),ff(:)
1010 0 : real(dp),ABI_CONTIGUOUS pointer :: phi_i(:),phi_j(:),phi_k(:),phi_l(:)
1011 0 : real(dp),ABI_CONTIGUOUS pointer :: tphi_i(:),tphi_j(:),tphi_k(:),tphi_l(:)
1012 0 : real(dp),ABI_CONTIGUOUS pointer :: shapefunc(:),rad(:)
1013 :
1014 : ! *************************************************************************
1015 :
1016 : DBG_ENTER("COLL")
1017 :
1018 0 : ABI_CHECK(ln2_size==Pawtab%ij_size,"Wrong ln2_size")
1019 :
1020 0 : if ( ALL(which_intg /= (/1,2,3/)) ) then
1021 0 : write(msg,'(a,i0)')"Wrong value for which_intg: ",which_intg
1022 0 : ABI_ERROR(msg)
1023 : end if
1024 :
1025 : !@slatrad_t
1026 0 : lmn_size = Pawtab%lmn_size
1027 0 : lmn2_size = Pawtab%lmn2_size
1028 0 : ln_size = Pawtab%basis_size
1029 0 : mesh_size = Pawtab%mesh_size
1030 : !
1031 : ! Useful table for looping.
1032 0 : indlmn => Pawtab%indlmn(1:6,1:lmn_size)
1033 0 : indklmn => Pawtab%indklmn(1:8,1:lmn2_size)
1034 :
1035 0 : ABI_MALLOC(kln2ln,(6,ln2_size))
1036 0 : call make_kln2ln(lmn_size,lmn2_size,ln2_size,indlmn,indklmn,kln2ln)
1037 :
1038 0 : ABI_MALLOC(uiuj,(mesh_size))
1039 0 : ABI_MALLOC(ukul,(mesh_size))
1040 0 : ABI_MALLOC(ff,(mesh_size))
1041 0 : ABI_MALLOC(tuituj,(mesh_size))
1042 0 : ABI_MALLOC(tuktul,(mesh_size))
1043 0 : ABI_MALLOC(tuituj_tqgl,(mesh_size))
1044 0 : ABI_MALLOC(tuktul_tqgl,(mesh_size))
1045 0 : rad => Pawrad%rad
1046 : !
1047 : ! * Loop over (k,l) channels in packed form.
1048 0 : do sln2=1,ln2_size
1049 0 : kl = kln2ln(1,sln2)
1050 0 : ll = kln2ln(2,sln2)
1051 0 : kn = kln2ln(3,sln2)
1052 0 : ln = kln2ln(4,sln2)
1053 0 : kln = kln2ln(5,sln2)
1054 0 : lln = kln2ln(6,sln2)
1055 : !write(std_out,*)"sln2, kln, lln",sln2,kln,lln
1056 :
1057 0 : phi_k => Pawtab%phi (:,kln)
1058 0 : tphi_k => Pawtab%tphi(:,kln)
1059 :
1060 0 : phi_l => Pawtab%phi (:,lln)
1061 0 : tphi_l => Pawtab%tphi(:,lln)
1062 : !
1063 : ! * Loop over (i,j) channels in packed form AND only for the upper triangle of sln2, sln1
1064 0 : do sln1=1,sln2
1065 0 : il = kln2ln(1,sln1)
1066 0 : jl = kln2ln(2,sln1)
1067 0 : in = kln2ln(3,sln1)
1068 0 : jn = kln2ln(4,sln1)
1069 0 : iln = kln2ln(5,sln1)
1070 0 : jln = kln2ln(6,sln1)
1071 : !write(std_out,*)"sln1, iln, jln",sln1,iln,jln
1072 :
1073 0 : slt_idx = sln1 + sln2*(sln2-1)/2 ! index for packed storage.
1074 :
1075 0 : phi_i => Pawtab%phi (:,iln)
1076 0 : tphi_i => Pawtab%tphi(:,iln)
1077 :
1078 0 : phi_j => Pawtab%phi (:,jln)
1079 0 : tphi_j => Pawtab%tphi(:,jln)
1080 :
1081 0 : lslat_min = MAX(ABS(il-jl),ABS(kl-ll)) + 1 ! We use indices not l-values.
1082 0 : lslat_max = MIN((il+jl),(kl+ll)) - 1
1083 :
1084 : !lslat_min = MIN(ABS(il-jl),ABS(kl-ll)) + 1
1085 : !lslat_max = MAX((il+jl),(kl+ll)) - 1
1086 :
1087 0 : Slatrad4(slt_idx)%lslat_min = lslat_min
1088 0 : Slatrad4(slt_idx)%lslat_max = lslat_max
1089 :
1090 0 : Slatrad4(slt_idx)%iln = iln
1091 0 : Slatrad4(slt_idx)%jln = jln
1092 0 : Slatrad4(slt_idx)%kln = kln
1093 0 : Slatrad4(slt_idx)%lln = lln
1094 :
1095 0 : ABI_MALLOC(Slatrad4(slt_idx)%intgl_select,(lslat_min:lslat_max))
1096 0 : Slatrad4(slt_idx)%intgl_select(:) = 0
1097 0 : Slatrad4(slt_idx)%nintgl = 0
1098 :
1099 0 : if (lslat_min > lslat_max) then
1100 : ! e.g. (1 2) (1 1). Due to angular selection rules, this integral do not contribue
1101 : !write(std_out,*)"lslat_min, lslat_max",lslat_min,lslat_max
1102 : !write(std_out,*)"il,jl,kl,ll",il,jl,kl,ll
1103 : !ABI_ERROR("")
1104 0 : ABI_MALLOC(Slatrad4(slt_idx)%intgl,(0))
1105 0 : CYCLE
1106 : end if
1107 :
1108 0 : uiuj = phi_i * phi_j ! The AE part.
1109 0 : ukul = phi_k * phi_l
1110 0 : tuituj = tphi_i * tphi_j ! The pseudized part.
1111 0 : tuktul = tphi_k * tphi_l
1112 : !
1113 : ! Calculate L-depedent integrals where L come from the expansion the Coulomb interaction.
1114 0 : ABI_MALLOC(tmp_integrals,(MAX(lslat_min,lslat_max)))
1115 0 : tmp_integrals=zero
1116 : nintgl=0
1117 :
1118 0 : do isl=lslat_min,lslat_max
1119 : !do isl=lslat_min,lslat_max,2 ! TODO Here I can reduce the number of iterations using a step of 2.
1120 0 : l_slat = isl-1
1121 0 : call calc_slatradl(l_slat,mesh_size,uiuj,ukul,Pawrad,ae_intg)
1122 0 : intg = ae_intg
1123 :
1124 : #if 0
1125 : call calc_slatradl(l_slat,mesh_size,ukul,uiuj,Pawrad,intg1)
1126 : if (ABS(intg1-ae_intg)>tol12) then
1127 : write(msg,'(a,es16.8)')"s_ij and s_ij differ by ",intg1-ae_intg
1128 : ABI_WARNING(msg)
1129 : end if
1130 : #endif
1131 0 : if (which_intg == 2) then ! Subtract the pseudo part.
1132 0 : call calc_slatradl(l_slat,mesh_size,tuituj,tuktul,Pawrad,ps_intg)
1133 0 : intg = intg - ps_intg
1134 :
1135 0 : else if (which_intg == 3) then ! Subtract (pseudo + compensation charges)
1136 : !
1137 : ! Evaluate tqij_L and tqkl_L (without M-dependent part).
1138 0 : ff(1)=zero
1139 0 : ff(2:mesh_size)=(pawtab%phiphj(2:mesh_size,sln1)-pawtab%tphitphj(2:mesh_size,sln1))*rad(2:mesh_size)**l_slat
1140 0 : if (l_slat==0.and.kl==1.and.ll==1) then
1141 0 : call pawrad_deducer0(ff,mesh_size,pawrad)
1142 : end if
1143 0 : call simp_gen(tqij_L,ff,pawrad)
1144 :
1145 0 : ff(1)=zero
1146 0 : ff(2:mesh_size)=(pawtab%phiphj(2:mesh_size,sln2)-pawtab%tphitphj(2:mesh_size,sln2))*rad(2:mesh_size)**l_slat
1147 0 : if (l_slat==0.and.il==1.and.jl==1) then
1148 0 : call pawrad_deducer0(ff,mesh_size,pawrad)
1149 : end if
1150 0 : call simp_gen(tqkl_L,ff,pawrad)
1151 :
1152 0 : shapefunc => Pawtab%shapefunc(:,isl) ! Recheck this part, in particular the convention
1153 0 : tuituj_tqgl = tuituj + tqij_L * shapefunc * rad**2
1154 0 : tuktul_tqgl = tuktul + tqkl_L * shapefunc * rad**2
1155 :
1156 0 : call calc_slatradl(l_slat,mesh_size,tuituj_tqgl,tuktul_tqgl,Pawrad,pshat_intg)
1157 0 : intg = intg - pshat_intg
1158 : end if
1159 : !
1160 : ! * Store results
1161 0 : if (ABS(intg)>=tol12) then
1162 0 : nintgl = nintgl +1
1163 0 : Slatrad4(slt_idx)%intgl_select(isl) = nintgl
1164 0 : tmp_integrals(nintgl) = intg
1165 : end if
1166 : end do !isl
1167 : !
1168 : ! Finalize the object.
1169 0 : Slatrad4(slt_idx)%nintgl = nintgl
1170 0 : ABI_MALLOC(Slatrad4(slt_idx)%intgl,(nintgl))
1171 0 : if (nintgl>0) Slatrad4(slt_idx)%intgl(:) = tmp_integrals(1:nintgl)
1172 0 : ABI_FREE(tmp_integrals)
1173 : end do !sln1
1174 : end do !sln2
1175 : !
1176 : ! Free memory
1177 0 : ABI_FREE(kln2ln)
1178 0 : ABI_FREE(uiuj)
1179 0 : ABI_FREE(ukul)
1180 0 : ABI_FREE(tuituj)
1181 0 : ABI_FREE(tuktul)
1182 0 : ABI_FREE(ff)
1183 0 : ABI_FREE(tuituj_tqgl)
1184 0 : ABI_FREE(tuktul_tqgl)
1185 :
1186 : DBG_EXIT("COLL")
1187 :
1188 0 : end subroutine slatrad_init
1189 : !!***
1190 :
1191 : !----------------------------------------------------------------------
1192 :
1193 : !!****f* m_paw_slater/paw_dijhf
1194 : !! NAME
1195 : !! paw_dihf
1196 : !!
1197 : !! FUNCTION
1198 : !! This routine calculates the onsite D_{ij} strengths of the exchange part of the self energy.
1199 : !!
1200 : !! INPUTS
1201 : !! ndij=Usually ndij=nspden, except for spin-orbit (where ndij=nspinor**2)
1202 : !! cplex_dij=1 if sigx_dij is real, 2 if they are complex
1203 : !! qphase=2 if dij contains a exp(-i.q.r) phase (as in the q<>0 RF case), 1 if not
1204 : !! lmn2_size_max=Max Number of (klmn) channels over type of atoms.
1205 : !! my_natom=number of atoms treated by current process
1206 : !! ntypat=number of atom types
1207 : !! Pawtab(ntypat)<pawtab_type>=paw tabulated starting data
1208 : !! Pawrad(ntypat)<pawrad_type>=paw radial mesh and related data
1209 : !! Pawang<type(pawang_type)>=paw angular mesh and related data
1210 : !! pawprtvol=Flags governing the verbosity of the output.
1211 : !!
1212 : !! OUTPUT
1213 : !! sigx_dij(cplex_dij*lmn2_size_max,ndij,my_natom)=
1214 : !! For each atom, the Pseudopotential strengths of the on-site operator Sigma_x
1215 : !!
1216 : !! NOTES
1217 : !! The on-site contribution to the matrix elements of the exchange part of the self-energy is given by:
1218 : !! <\tpsi_a| [\sum_{ij} |tprj_i\> D_{ij} \<tprj_j|] |\tpsi_b\>.
1219 : !!
1220 : !! When compensation charges are used one obtains:
1221 : !!
1222 : !! D_{ij} = - sum_{kl} \rho_lk [ \Phi_{ikjl} - \Phihat_{ijkl} =
1223 : !!
1224 : !! = - sum_{kl} \rho_lk \sum_{LM} \Gaunt_{ik}^{LM} \Gaunt_{jl}^{LM} [S_{ikjl}^L - tS{ikjl}^L}]
1225 : !!
1226 : !! where S and tS are Slater-like integrals given by
1227 : !!
1228 : !! 1) S_{ijkl}^L = dfrac{4\pi}{2L+1} \iint u_i(1)u_j(1) u_k(2) u_l(2) \dfrac{r_<^L/}{r_>^{L+1}} d1d2.
1229 : !! 1) tS_{ijkl}^L = dfrac{4\pi}{2L+1} \iint [u_i(1)u_j(1)+ tq_{ij}^L g^L(1)]
1230 : !! [u_k(2)u_l(2)+ tq_{kl}^L g^L(2)] \dfrac{r_<^L/}{r_>^{L+1}} d1d2.
1231 : !!
1232 : !! tq_{ij}^L is defined in terms of q_{ij}^L via: q_{ij]^{LM} = tq_{ij}^L \Gaunt_{ij}^{LM}
1233 : !!
1234 : !! SOURCE
1235 :
1236 0 : subroutine paw_dijhf(ndij,cplex_dij,qphase,lmn2_size_max,my_natom,ntypat,Pawtab,Pawrad,Pawang,Pawrhoij,&
1237 0 : & sigx_dij,pawprtvol)
1238 :
1239 : !Arguments ------------------------------------
1240 : !scalars
1241 : integer,intent(in) :: pawprtvol,ndij,cplex_dij,lmn2_size_max,my_natom,ntypat,qphase
1242 : type(pawang_type),intent(in) :: Pawang
1243 : !arrays
1244 : real(dp),target,intent(out) :: sigx_dij(cplex_dij*lmn2_size_max,ndij,my_natom) !TODO use ragged arrays pawij?
1245 : type(pawtab_type),intent(in) :: Pawtab(ntypat)
1246 : type(pawrad_type),intent(in) :: Pawrad(ntypat)
1247 : type(pawrhoij_type),intent(in) :: Pawrhoij(my_natom)
1248 :
1249 : !Local variables ---------------------------------------
1250 : !scalars
1251 : integer,parameter :: cplex=1 ! FIXME preliminary implementation
1252 : integer :: cplex_rhoij,iatom,iq,iq0_dij,iq0_rhoij,itypat,lmn_size,lmn2_size,ispden,nspden,ln2_size
1253 : integer :: lm2_size !,isppol ln_size,
1254 : integer :: irhoij,jrhoij
1255 : integer :: rho_lmn !,rho_klm,rho_kln,rho_lmin,rho_lmax,rho_iln,rho_jln
1256 : integer :: klmn
1257 : integer :: i_lmn,j_lmn,k_lmn,l_lmn
1258 : integer :: which_intg,l_max,opt_l
1259 : real(dp) :: ro,slt_ikjl,slt_iljk
1260 : !character(len=500) :: msg
1261 : !arrays
1262 : integer :: opt_l_index(0,0),pack2ij(0)
1263 0 : real(dp), ABI_CONTIGUOUS pointer :: sigx_atm(:,:)
1264 0 : type(slatrad_t),allocatable :: Slatrad4(:)
1265 :
1266 : ! *************************************************************************
1267 :
1268 : DBG_ENTER("COLL")
1269 :
1270 0 : ABI_CHECK(ndij/=4,"ndij=4 not coded")
1271 0 : ABI_CHECK(cplex_dij==1,"cplex_dij/=2 not coded")
1272 0 : ABI_CHECK(lmn2_size_max==MAXVAL(Pawtab(:)%lmn2_size),"Wrong lmn2_size_max")
1273 :
1274 0 : if (my_natom>0) then
1275 0 : if (pawrhoij(1)%qphase<cplex) then
1276 0 : ABI_BUG('Must have pawrhoij()%qphase >= cplex !')
1277 : end if
1278 : end if
1279 :
1280 0 : sigx_dij=zero
1281 :
1282 0 : do iatom=1,my_natom
1283 0 : itypat =Pawrhoij(iatom)%itypat
1284 0 : lmn_size =Pawtab(itypat)%lmn_size
1285 0 : lmn2_size=Pawtab(itypat)%lmn2_size
1286 0 : l_max =(Pawtab(itypat)%l_size+1)/2
1287 0 : lm2_size = (l_max**2)*(l_max**2+1)/2
1288 0 : cplex_rhoij=Pawrhoij(iatom)%cplex_rhoij
1289 : !write(std_out,*)"in atom ",iatom,"lm2_size=",lm2_size
1290 :
1291 : ! Calculate Slater integral for this atom type.
1292 : ! TODO obviously these tables should be stored in Pawtab!
1293 0 : ln2_size = Pawtab(itypat)%ij_size
1294 0 : ABI_MALLOC(Slatrad4,(ln2_size*(ln2_size+1)/2))
1295 0 : which_intg=3
1296 0 : call slatrad_init(Slatrad4,which_intg,ln2_size,Pawrad(itypat),Pawtab(itypat))
1297 :
1298 0 : sigx_atm => sigx_dij(:,:,iatom)
1299 :
1300 : ! Loop over phase exp(iqr) phase real/imaginary part, if any
1301 0 : do iq=1,qphase
1302 : !First loop: we store the real part in dij(1 -> lmn2_size)
1303 : !2nd loop: we store the imaginary part in dij(lmn2_size+1 -> 2*lmn2_size)
1304 0 : iq0_dij=merge(0,cplex_dij*lmn2_size,iq==1)
1305 0 : iq0_rhoij=merge(0,cplex_rhoij*lmn2_size,iq==1)
1306 :
1307 : ! * Loop over spin components.
1308 0 : nspden=ndij
1309 0 : do ispden=1,ndij
1310 : !
1311 : ! ============================================================
1312 : ! ==== Summing over the non-zero lk channels of \rho_{lk} ====
1313 : ! ============================================================
1314 0 : jrhoij=1+iq0_rhoij
1315 0 : do irhoij=1,pawrhoij(iatom)%nrhoijsel
1316 0 : rho_lmn=pawrhoij(iatom)%rhoijselect(irhoij)
1317 :
1318 : ! check wheter rho_lmin is consistent with the Indexing used in slatrad
1319 : !rho_klm =pawtab(itypat)%indklmn(1,rho_lmn)
1320 : !rho_kln =pawtab(itypat)%indklmn(2,rho_lmn)
1321 : !rho_lmin=pawtab(itypat)%indklmn(3,rho_lmn)
1322 : !rho_lmax=pawtab(itypat)%indklmn(4,rho_lmn)
1323 :
1324 : ! Retrieve rhoij for this ispden.
1325 0 : if (nspden/=2) then
1326 0 : ro=pawrhoij(iatom)%rhoijp(jrhoij,ispden)
1327 : else
1328 0 : ABI_ERROR("Recheck this part")
1329 0 : if (ispden==1) then
1330 0 : ro=pawrhoij(iatom)%rhoijp(jrhoij,1) + pawrhoij(iatom)%rhoijp(jrhoij,2)
1331 0 : else if (ispden==2) then
1332 0 : ro=pawrhoij(iatom)%rhoijp(jrhoij,1)
1333 : end if
1334 : end if
1335 : !
1336 : ! Avoid double-counting the diagonal of rho.
1337 0 : ro=ro*pawtab(itypat)%dltij(rho_lmn)*half
1338 :
1339 0 : call klmn2ijlmn(rho_lmn,lmn_size,k_lmn,l_lmn)
1340 :
1341 : ! Loop over the upper triangle of the D_{ij) matrix and accumulate:
1342 : ! sum_\lk rho_\kl [ \Phi_{ikjl} + \Phi_{iljk} - \Phihat_{ikjl} - \Phihat_{iljk} ]
1343 0 : do klmn=1,lmn2_size
1344 : ! Calculate the indices in the Slatrad4 structure.
1345 0 : call klmn2ijlmn(klmn,lmn_size,i_lmn,j_lmn)
1346 :
1347 : ! My formula
1348 0 : slt_ikjl = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,k_lmn,j_lmn,l_lmn)
1349 0 : slt_iljk = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,l_lmn,j_lmn,k_lmn)
1350 :
1351 : !slt_ikjl = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,k_lmn,l_lmn,j_lmn)
1352 : !slt_iljk = slat_intg(Slatrad4,Pawtab(itypat),Pawang,i_lmn,l_lmn,k_lmn,j_lmn)
1353 : !slt_iljk = slt_ikjl
1354 :
1355 0 : sigx_atm(klmn+iq0_dij,ispden) = sigx_atm(klmn,ispden) + ro * (slt_ikjl + slt_iljk)
1356 : end do ! klmn
1357 :
1358 0 : jrhoij=jrhoij+cplex_rhoij
1359 : end do ! irhoij
1360 : end do ! iq
1361 : end do ! ispden
1362 :
1363 0 : if (ABS(pawprtvol)>=1) then ! * Print values
1364 0 : call wrtout(std_out," ************** Dij Fock ************ ",'COLL')
1365 0 : opt_l=-1
1366 0 : call pawio_print_ij(std_out,sigx_atm(:,1),lmn2_size,cplex_dij,lmn_size,opt_l,opt_l_index,0,pawprtvol,pack2ij,-one,1)
1367 : end if
1368 :
1369 0 : call slatrad_free(Slatrad4)
1370 0 : ABI_FREE(Slatrad4)
1371 : end do ! iatom
1372 :
1373 : ! Factor half cancels in the derivation wrt rho_ij.
1374 0 : sigx_dij = - sigx_dij
1375 :
1376 : DBG_EXIT("COLL")
1377 :
1378 0 : end subroutine paw_dijhf
1379 : !!****
1380 :
1381 : !----------------------------------------------------------------------
1382 :
1383 : !!****f* m_paw_slater/summ_2gaunt
1384 : !! NAME
1385 : !! summ_2gaunt
1386 : !!
1387 : !! FUNCTION
1388 : !! Helper function returning \sum_M G_{ij}^{LM} G_{kl}^{LM}
1389 : !!
1390 : !! INPUTS
1391 : !! ij_lm=index of (i_lm,j_lm) element in packed form.
1392 : !! kl_lm=index of (k_lm,l_lm) element in packed form.
1393 : !! ll_idx=Index for L (thus L+1).
1394 : !! Pawang<type(pawang_type)>=paw angular mesh and related data
1395 : !!
1396 : !! SOURCE
1397 :
1398 0 : function summ_2gaunt(Pawang,ij_lm,kl_lm,ll_idx)
1399 :
1400 : !Arguments ------------------------------------
1401 : !scalars
1402 : integer,intent(in) :: ij_lm,kl_lm,ll_idx
1403 : real(dp) :: summ_2gaunt
1404 : type(pawang_type),intent(in) :: Pawang
1405 : !arrays
1406 :
1407 : !Local variables-------------------------------
1408 : !scalars
1409 : integer :: ignt1,ignt2,idx_LM,max_klm,mm,ii,ll
1410 : character(len=500) :: msg
1411 :
1412 : !************************************************************************
1413 :
1414 : ! FIXME: size of gntselect depends on pawxcdev!
1415 : ! Consistency check on input arguments.
1416 0 : max_klm = pawang%l_max**2*(pawang%l_max**2+1)/2
1417 : if (ij_lm>max_klm.or.kl_lm>max_klm.or.ij_lm<1.or.kl_lm<1.or.&
1418 0 : & ll_idx>pawang%l_size_max.or.ll_idx<1) then
1419 0 : write(msg,'(a,3i0)')"Wrong indices, check pawxcdev ",ij_lm,kl_lm,ll_idx
1420 0 : ABI_ERROR(msg)
1421 : end if
1422 :
1423 0 : ll = ll_idx-1
1424 0 : summ_2gaunt=zero; ii=0
1425 0 : do mm=-ll,ll
1426 0 : idx_LM = 1 + ll**2 + ll + mm
1427 0 : ignt1 = Pawang%gntselect(idx_LM,ij_lm)
1428 0 : ignt2 = Pawang%gntselect(idx_LM,kl_lm)
1429 0 : if (ignt1>0 .and. ignt2>0) then
1430 0 : summ_2gaunt = summ_2gaunt + Pawang%realgnt(ignt1)*Pawang%realgnt(ignt2)
1431 0 : ii=ii+1
1432 0 : write(std_out,'(a,4(i2,1x),f8.5,i2)')"ll, mm, ij_lm, kl_lm: ",ll,mm,ij_lm,kl_lm,summ_2gaunt,ii
1433 0 : if (ii/=1) ABI_WARNING("ii>1")
1434 : end if
1435 : end do
1436 :
1437 0 : end function summ_2gaunt
1438 : !!***
1439 :
1440 : !----------------------------------------------------------------------
1441 :
1442 : !!****f* m_paw_slater/slat_intg
1443 : !! NAME
1444 : !! slat_intg
1445 : !!
1446 : !! FUNCTION
1447 : !! Helper function returning the slater integral
1448 : !! \int_\Omega \phi_i(1)\phi_j(1) \dfrac{1}{|1-2|} \phi_k(2)\phi_l(2) d1d2
1449 : !!
1450 : !! INPUTS
1451 : !!
1452 : !! SOURCE
1453 :
1454 0 : function slat_intg(Slatrad4,Pawtab,Pawang,i_lmn,j_lmn,k_lmn,l_lmn)
1455 :
1456 : !Arguments ------------------------------------
1457 : !scalars
1458 : integer,intent(in) :: i_lmn,j_lmn,k_lmn,l_lmn
1459 : real(dp) :: slat_intg
1460 : type(pawtab_type),intent(in) :: Pawtab
1461 : type(pawang_type),intent(in) :: Pawang
1462 : !arrays
1463 : type(slatrad_t),intent(in) :: Slatrad4(:)
1464 :
1465 : !Local variables-------------------------------
1466 : !scalars
1467 : integer :: ij_lmn,kl_lmn,kl_ln,ij_lm,kl_lm,ilsum,ij_ln
1468 : integer :: isel,slt_idx
1469 : integer :: iln,jln,kln,lln,ii
1470 : real(dp) :: sltL_ijkl,angintL_ijkl
1471 : !character(len=500) :: msg
1472 :
1473 : !************************************************************************
1474 :
1475 : ! The lmn packed indices for (ij) and (kl).
1476 0 : if (j_lmn>=i_lmn) then
1477 0 : ij_lmn = i_lmn + j_lmn*(j_lmn-1)/2
1478 : else
1479 0 : ij_lmn = j_lmn + i_lmn*(i_lmn-1)/2
1480 : end if
1481 :
1482 0 : if (l_lmn>=k_lmn) then
1483 0 : kl_lmn = k_lmn + l_lmn*(l_lmn-1)/2
1484 : else
1485 0 : kl_lmn = l_lmn + k_lmn*(k_lmn-1)/2
1486 : end if
1487 : !
1488 : ! The lm indices for (ij) and (kl) in packed storage.
1489 0 : ij_lm = pawtab%indklmn(1,ij_lmn)
1490 0 : ij_ln = pawtab%indklmn(2,ij_lmn)
1491 :
1492 0 : kl_lm = pawtab%indklmn(1,kl_lmn)
1493 0 : kl_ln = pawtab%indklmn(2,kl_lmn)
1494 : !
1495 : ! The index of (ijkl) in the Slatrad4 database.
1496 0 : if (kl_ln>=ij_ln) then
1497 0 : slt_idx = ij_ln +kl_ln*(kl_ln-1)/2
1498 : else
1499 0 : slt_idx = kl_ln +ij_ln*(ij_ln-1)/2
1500 : end if
1501 :
1502 : !BEGIN DEBUG
1503 0 : iln = Slatrad4(slt_idx)%iln
1504 0 : jln = Slatrad4(slt_idx)%jln
1505 0 : kln = Slatrad4(slt_idx)%kln
1506 0 : lln = Slatrad4(slt_idx)%lln
1507 :
1508 0 : ii = kln + lln*(lln-1)/2
1509 0 : if (slt_idx /= (iln + jln*(jln-1)/2 + ii*(ii-1)/2 )) then
1510 0 : write(std_out,*)"slt_idx, iln, jln, kln, lln",slt_idx, iln, jln, kln, lln
1511 0 : ABI_BUG("Check indices")
1512 : end if
1513 : !END DEBUG
1514 : !
1515 : ! Calculate the integral by summing over ilsum.
1516 0 : slat_intg=zero
1517 0 : if (Slatrad4(slt_idx)%nintgl>0) then
1518 0 : do ilsum=Slatrad4(slt_idx)%lslat_min,Slatrad4(slt_idx)%lslat_max
1519 : !% do ilsum=Slatrad4(slt_idx)%lslat_min,Slatrad4(slt_idx)%lslat_max,2
1520 0 : isel = Slatrad4(slt_idx)%intgl_select(ilsum)
1521 0 : if (isel/=0) then
1522 0 : sltL_ijkl = Slatrad4(slt_idx)%intgl(isel)
1523 0 : angintL_ijkl = summ_2gaunt(Pawang,ij_lm,kl_lm,ilsum)
1524 0 : slat_intg = slat_intg + sltL_ijkl * angintL_ijkl
1525 : end if
1526 : end do
1527 : end if
1528 :
1529 0 : end function slat_intg
1530 : !!***
1531 :
1532 : !----------------------------------------------------------------------
1533 :
1534 0 : END MODULE m_paw_slater
1535 : !!***
|