## ABINIT/m_paw_lmn [ Modules ]

[ Top ] [ Modules ]

NAME

```  m_paw_lmn
```

FUNCTION

```  This module provides tools to calculate tables commonly used to iterate
over the the (l,m,n) channels of the PAW partial waves.
```

``` Copyright (C) 2008-2018 ABINIT group (MG)
GNU General Public License, see ~abinit/COPYING
or http://www.gnu.org/copyleft/gpl.txt .
```

SOURCE

```18 #if defined HAVE_CONFIG_H
19 #include "config.h"
20 #endif
21
22 #include "abi_common.h"
23
24 MODULE m_paw_lmn
25
26  use defs_basis
27  use m_abicore
28  use m_errors
29
30  implicit none
31
32  private
33
34 ! Public procedures.
35  public :: ilm2lm          ! Returns the value of l and m in from the index ilm
36  public :: make_indlmn     ! Calculates the indlmn(6,lmn_size) table giving l,m,n,lm,ln,spin for i=lmn.
37  public :: make_indklmn    ! Calculates the indklmn(8,lmn2_size) table giving
38                            !   klm, kln, abs(il-jl), (il+jl), ilm and jlm, ilmn and jlmn for each symmetric klmn=(ilmn,jlmn)
39  public :: make_kln2ln     ! Calculates the kln2ln(6,ln2_size) table giving
40                            !   il, jl ,in, jn, iln, jln for each symmetric kln=(iln,jln)
41  public :: make_klm2lm     ! Calculates the klm2lm(6,lm2_size) table giving
42                            !   il, jl ,im, jm, ilm, jlm for each symmetric klm=(ilm,jlm)
43  public :: klmn2ijlmn      ! Calculates ilmn and jlmn from klmn.
44  public :: make_indln      ! Calculates indln(2,ln_size) giving l and n for i=ln
45  public :: uppert_index    ! The sequential index of an element in the upper triangle of a matrix
46
47 CONTAINS  !========================================================================================
```

## m_paw_lmn/ilm2lm [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```  ilm2lm
```

FUNCTION

```  Returns the value of l and m in from the index ilm
```

INPUTS

```  ilm=The contracted index for (l,m).
```

OUTPUT

```  ll=The angular momentun defined in [0,1,2,3,4].
mm=The magnetic number in the interval [-l,....+l].
```

PARENTS

CHILDREN

SOURCE

``` 70 subroutine ilm2lm(ilm,ll,mm)
71
72
73 !This section has been created automatically by the script Abilint (TD).
74 !Do not modify the following lines by hand.
75 #undef ABI_FUNC
76 #define ABI_FUNC 'ilm2lm'
77 !End of the abilint section
78
79  implicit none
80
81 !Arguments ------------------------------------
82 !scalars
83  integer,intent(in) :: ilm
84  integer,intent(out) :: ll,mm
85
86 !Local variables-------------------------------
87  integer :: ii
88 ! *********************************************************************
89
90  if (ilm<1) then
91    MSG_ERROR("Wrong ilm")
92  end if
93
94  ll = -1
95  do ii=0,100
96   if ( (ii+1)**2 >= ilm) then
97    ll = ii
98    EXIT
99   end if
100  end do
101
102  mm = ilm - ll**2 -ll-1
103
104  if (ll==-1) then
105    MSG_ERROR("l>100 not programmed!")
106  end if
107
108 end subroutine ilm2lm
```

## m_paw_lmn/klmn2ijlmn [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```  klmn2ijlmn
```

FUNCTION

```  Find ilmn and jlmn from klmn and lmn_size.
```

INPUTS

```  lmn_size=Number of (l,m,n) elements for the PAW basis set.
klmn=The index corresponding to (ilmn,jlmn) in packed form.
```

OUTPUT

```  jlmn, ilmn=The two symmetrix indices corresponding to klmn. NB: jlmn >= ilmn
```

PARENTS

```      m_paw_lmn,m_paw_slater
```

CHILDREN

SOURCE

```495 subroutine klmn2ijlmn(klmn,lmn_size,ilmn,jlmn)
496
497
498 !This section has been created automatically by the script Abilint (TD).
499 !Do not modify the following lines by hand.
500 #undef ABI_FUNC
501 #define ABI_FUNC 'klmn2ijlmn'
502 !End of the abilint section
503
504  implicit none
505
506 !Arguments ------------------------------------
507 !scalars
508  integer,intent(in) :: klmn,lmn_size
509  integer,intent(out) :: ilmn,jlmn
510
511 !Local variables ------------------------------
512 !scalars
513  integer :: ii,jj,k0
514 !************************************************************************
515
516  ilmn=-1; jlmn=-1
517
518  do jj=1,lmn_size
519    k0=jj*(jj-1)/2
520    do ii=1,jj
521      if (klmn==ii+k0) then
522        ilmn = ii
523        jlmn = jj; RETURN
524      end if
525    end do
526  end do
527
528  MSG_BUG("Not able to found ilmn and jlmn")
529
530 end subroutine klmn2ijlmn
```

## m_paw_lmn/make_indklmn [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```  make_indklmn
```

FUNCTION

```  Performs the setup of the indklmn table for PAW calculations.
Compute the indklmn indexes giving klm, kln, abs(il-jl) and (il+jl), ilm and jlm, ilmn and jlmn
for each klmn=(ilmn,jlmn) with jlmn >= ilmn
```

INPUTS

```  lcutdens=Maximum l for densities/potentials moments computations
lmn_size=Number of (l,m,n) elements for the PAW basis set.
lmn2_size=Number of elements in the symmetric basis set: lmn2_size=lmn_size*(lmn_size+1)/2
indlmn(6,lmn_size)=Array giving l,m,n,lm,ln,spin for i=lmn.
```

OUTPUT

```  indklmn(6,lmn2_size)=Array giving klm, kln, abs(il-jl), (il+jl), ilm and jlm, ilmn and jlmn
for each klmn=(ilmn,jlmn). Note: ilmn=(il,im,in) and ilmn<=jlmn
klm_diag(lmn2_size)=1 il==jl and im==jm, 0 otherwise.
```

PARENTS

```      m_atom
```

CHILDREN

SOURCE

```213 subroutine make_indklmn(lcutdens,lmn_size,lmn2_size,indlmn,indklmn,klm_diag)
214
215
216 !This section has been created automatically by the script Abilint (TD).
217 !Do not modify the following lines by hand.
218 #undef ABI_FUNC
219 #define ABI_FUNC 'make_indklmn'
220 !End of the abilint section
221
222  implicit none
223
224 !Arguments ------------------------------------
225 !scalars
226  integer,intent(in) :: lmn2_size,lmn_size
227  integer,intent(in) ::  lcutdens
228 !scalars
229  integer,intent(in) :: indlmn(6,lmn_size)
230  integer,intent(out) :: indklmn(8,lmn2_size)
231  integer,intent(out) :: klm_diag(lmn2_size)
232
233 !Local variables ------------------------------
234 !scalars
235  integer :: i0lm,i0ln,il,ilm,ilmn,iln
236  integer :: j0lm,j0lmn,j0ln,jl,jlm,jlmn,jln,klmn
237
238 !************************************************************************
239
240  klm_diag=0
241
242  do jlmn=1,lmn_size
243   jl= indlmn(1,jlmn); jlm=indlmn(4,jlmn); jln=indlmn(5,jlmn)
244   j0lmn=jlmn*(jlmn-1)/2
245   j0lm =jlm *(jlm -1)/2
246   j0ln =jln *(jln -1)/2
247   do ilmn=1,jlmn
248    il=indlmn(1,ilmn); ilm=indlmn(4,ilmn); iln=indlmn(5,ilmn)
249    klmn=j0lmn+ilmn
250    if (ilm<=jlm) then
251     indklmn(1,klmn)=j0lm+ilm     !klm
252    else
253     i0lm=ilm*(ilm-1)/2
254     indklmn(1,klmn)=i0lm+jlm
255    end if
256    if (iln<=jln) then
257     indklmn(2,klmn)=j0ln+iln     !kln
258    else
259     i0ln=iln*(iln-1)/2
260     indklmn(2,klmn)=i0ln+jln
261    end if
262    !MG This is not safe, what happens if lcutdens < |il-jl|?
263    indklmn(3,klmn)=MIN(ABS(il-jl),lcutdens)  ! abs(li-lj) NB this is a l-value, not an index >=1.
264    indklmn(4,klmn)=MIN(il+jl,lcutdens)       ! abs(li+lj) NB this is a l-value, not an index >=1.
265
266    indklmn(5,klmn)=ilm                       ! ilm
267    indklmn(6,klmn)=jlm                       ! jlm
268
269    indklmn(7,klmn)=ilmn                      ! ilmn
270    indklmn(8,klmn)=jlmn                      ! jlmn
271
272
273    if (ilm==jlm) klm_diag(klmn)=1
274   end do
275  end do
276
277 end subroutine make_indklmn
```

## m_paw_lmn/make_indlmn [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```  make_indlmn
```

FUNCTION

```  Performs the setup of the indlmn table for PAW calculations (indices for (l,m,n) basis)
```

INPUTS

```  ln_size= Total number of nl components
lmn_size= Second dimension in indlmn. Total number of (l,m,n) components for this atom.
orbitals(ln_size)=Give the value of l for each element of the augmented basis set.
```

OUTPUT

```  indlmn(6,lmn_size)=array giving l,m,n,lm,ln,s for i=lmn
```

PARENTS

```      m_atom
```

CHILDREN

SOURCE

```135 subroutine make_indlmn(ln_size,lmn_size,orbitals,indlmn)
136
137
138 !This section has been created automatically by the script Abilint (TD).
139 !Do not modify the following lines by hand.
140 #undef ABI_FUNC
141 #define ABI_FUNC 'make_indlmn'
142 !End of the abilint section
143
144  implicit none
145
146 !Arguments ------------------------------------
147 !scalars
148  integer,intent(in) :: ln_size,lmn_size
149  integer,intent(in) :: orbitals(ln_size)
150 !scalars
151  integer,intent(out) :: indlmn(6,lmn_size)
152
153 !Local variables ------------------------------
154 !scalars
155  integer :: ilmn,ib,il,iln,ilm
156 !arrays
157  integer,allocatable :: nprj(:)
158
159 !************************************************************************
160
161  ABI_ALLOCATE(nprj,(0:MAXVAL(orbitals)))
162
163  ilmn=0; iln=0; nprj=0
164  do ib=1,ln_size
165    il=orbitals(ib)
166    nprj(il)=nprj(il)+1
167    iln=iln+1
168    do ilm=1,2*il+1
169      indlmn(1,ilmn+ilm)=il           ! l
170      indlmn(2,ilmn+ilm)=ilm-(il+1)   ! m
171      indlmn(3,ilmn+ilm)=nprj(il)     ! n
172      indlmn(4,ilmn+ilm)=il*il+ilm    ! lm index
173      indlmn(5,ilmn+ilm)=iln          ! ln index
174      indlmn(6,ilmn+ilm)=1            ! spin (not yet used!)
175    end do
176    ilmn=ilmn+2*il+1
177  end do
178
179  ABI_DEALLOCATE(nprj)
180
181 end subroutine make_indlmn
```

## m_paw_lmn/make_indln [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```  make_indln
```

FUNCTION

```  Performs the setup of the indln table for PAW calculations.
Compute the indln indexes giving ilmn=(l,m,n)
```

INPUTS

```  lmn_size=Number of (l,m,n) elements for the PAW basis set.
ln_size=Number of (l,n) elements
indlmn(6,lmn_size)=Array giving l,m,n,lm,ln,spin for i=lmn.
```

OUTPUT

```  indln(2,ln_size)=Array giving l and n for i=ln
```

PARENTS

```      m_paw_slater
```

CHILDREN

SOURCE

```558 subroutine make_indln(lmn_size,ln_size,indlmn,indln)
559
560
561 !This section has been created automatically by the script Abilint (TD).
562 !Do not modify the following lines by hand.
563 #undef ABI_FUNC
564 #define ABI_FUNC 'make_indln'
565 !End of the abilint section
566
567  implicit none
568
569 !Arguments ------------------------------------
570 !scalars
571  integer,intent(in) :: lmn_size,ln_size
572 !arrays
573  integer,intent(in) :: indlmn(6,lmn_size)
574  integer,intent(out) :: indln(2,ln_size)
575
576 !Local variables ------------------------------
577 !scalars
578  integer :: ilmn,ll,nn,ll_old,nn_old,ii
579 !************************************************************************
580
581  ii=0; ll_old=-1; nn_old=-1
582  do ilmn=1,lmn_size
583   ll=indlmn(1,ilmn)
584   nn=indlmn(3,ilmn)
585   if (ll/=ll_old.or.nn/=nn_old) then
586    ll_old=ll
587    nn_old=nn
588    ii=ii+1
589    indln(1,ii)=ll
590    indln(2,ii)=nn
591   end if
592  end do
593
594  ABI_CHECK(ii==ln_size,"ii/=ln_size")
595
596 end subroutine make_indln
```

## m_paw_lmn/make_klm2lm [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```  make_klm2lm
```

FUNCTION

```  Performs the setup of the klm2lm table for PAW calculations.
```

INPUTS

```  lmn_size=Number of (l,m,n) elements for the PAW basis set.
lmn2_size=Number of elements in the symmetric basis set: lmn2_size=lmn_size*(lmn_size+1)/2
lm2_size)=Number of (l.m) elements in the symmetric basis set.
indlmn(6,lmn_size)=Array giving l,m,n,lm,ln,spin for i=lmn.
indklmn(8,lmn2_size)=Array giving klm, kln, abs(il-jl), (il+jl), ilm and jlm
for each klmn=(ilmn,jlmn). Note: ilmn=(il,im,in) and ilmn<=jlmn
```

OUTPUT

```  klm2lm(6,lm2_size)=Table giving il, jl ,im, jm, ilm, jlm for each klm=(ilm,jlm)
where ilm=(il,im) and ilm<=jlm. NB: klm2lm is an application and not a bijection.
```

NOTES

```  klm2lm can be calculated easily if we assume that all (l,m) channels
are ordered by increasing l and m. This is the standard convention
used in most of the PAW datasets. This routines, howevever, works
works also in the unlikely case in with (l,m) are not ordered.
```

PARENTS

```      m_paw_slater
```

CHILDREN

SOURCE

```400 subroutine make_klm2lm(lmn_size,lmn2_size,lm2_size,indlmn,indklmn,klm2lm)
401
402
403 !This section has been created automatically by the script Abilint (TD).
404 !Do not modify the following lines by hand.
405 #undef ABI_FUNC
406 #define ABI_FUNC 'make_klm2lm'
407 !End of the abilint section
408
409  implicit none
410
411 !Arguments ------------------------------------
412 !scalars
413  integer,intent(in) :: lmn2_size,lmn_size,lm2_size
414 !arrays
415  integer,intent(in) :: indlmn(6,lmn_size)
416  integer,intent(in) :: indklmn(8,lmn2_size)
417  integer,intent(out) :: klm2lm(6,lm2_size)
418
419 !Local variables ------------------------------
420 !scalars
421  integer :: il,ilm,ilmn,jl,jlm,jlmn,im,jm
422  integer :: klmn,klm,klm_old !,iklm
423
424 !************************************************************************
425
426  klm2lm = 0
427  klm_old = -1
428  do klmn=1,lmn2_size
429    klm = indklmn(1,klmn)
430    if (klm /= klm_old) then
431      klm_old = klm
432
433      ilm = indklmn(5,klmn)
434      jlm = indklmn(6,klmn)
435
436      call klmn2ijlmn(klmn,lmn_size,ilmn,jlmn)
437
438      il=indlmn(1,ilmn); im=indlmn(2,ilmn)
439      jl=indlmn(1,jlmn); jm=indlmn(2,jlmn)
440
441      !shift to have the index instead of l or m.
442      klm2lm(1,klm) = il +1       ! il
443      klm2lm(2,klm) = jl +1       ! jl
444      klm2lm(3,klm) = im + il +1  ! im
445      klm2lm(4,klm) = jm + jl +1  ! jm
446      klm2lm(5,klm) = ilm         ! ilm
447      klm2lm(6,klm) = jlm         ! jlm
448    end if
449  end do !klmn
450
451  if (ANY(klm2lm==0)) then
452    MSG_BUG("check klm2lm")
453  end if
454
455 !DEBUG
456 #if 0
457  write(std_out,*)"Debugging make_klm2lm:"
458  do iklm=1,lm2_size
459   il  = klm2lm(1,iklm) -1      ! li
460   jl  = klm2lm(2,iklm) -1      ! lj
461   im  = klm2lm(3,iklm) -il -1  ! mi
462   jm  = klm2lm(4,iklm) -jl -1  ! mj
463   ilm = klm2lm(5,iklm)         ! ilm
464   jlm = klm2lm(6,iklm)         ! jlm
465   write(std_out,'(i3,2(a,2i3,a))')"iklm ",iklm," l m (",il,im,")"," l m (",jl,jm,")"
466  end do
467 #endif
468
469 end subroutine make_klm2lm
```

## m_paw_lmn/make_kln2ln [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```  make_kln2ln
```

FUNCTION

```  Performs the setup of the kln2ln table for PAW calculations.
```

INPUTS

```  lmn_size=Number of (l,m,n) elements for the PAW basis set.
lmn2_size=Number of elements in the symmetric basis set: lmn2_size=lmn_size*(lmn_size+1)/2
ln2_size=Number of symmetric (l,n) channels i.e. ln_size*(ln_size+1)/2
indlmn(6,lmn_size)=Array giving l,m,n,lm,ln,spin for i=lmn.
indklmn(8,lmn2_size)=Array giving klm, kln, abs(il-jl), (il+jl), ilm and jlm, ilmn and jlmn
for each klmn=(ilmn,jlmn). Note: ilmn=(il,im,in) and ilmn<=jlmn
```

OUTPUT

```  kln2ln(6,ln2_size)=Table giving il, jl ,in, jn, iln, jln for each kln=(iln,jln)
where iln=(il,in) and iln<=jln. NB: kln2ln is an application and not a bijection
```

PARENTS

```      m_atom,m_paw_slater
```

CHILDREN

SOURCE

```308 subroutine make_kln2ln(lmn_size,lmn2_size,ln2_size,indlmn,indklmn,kln2ln)
309
310
311 !This section has been created automatically by the script Abilint (TD).
312 !Do not modify the following lines by hand.
313 #undef ABI_FUNC
314 #define ABI_FUNC 'make_kln2ln'
315 !End of the abilint section
316
317  implicit none
318
319 !Arguments ------------------------------------
320 !scalars
321  integer,intent(in) :: lmn2_size,lmn_size,ln2_size
322 !arrays
323  integer,intent(in) :: indlmn(6,lmn_size)
324  integer,intent(in) :: indklmn(8,lmn2_size)
325  integer,intent(out) :: kln2ln(6,ln2_size)
326
327 !Local variables ------------------------------
328 !scalars
329  integer :: il,in,ilmn,iln
330  integer :: jl,jn,jlmn,jln
331  integer :: klmn,kln,kln_old
332
333 !************************************************************************
334
335  kln2ln = 0
336
337  kln_old = -1
338  do klmn=1,lmn2_size
339    kln = indklmn(2,klmn)
340    if (kln /= kln_old) then
341      kln_old = kln
342
343      call klmn2ijlmn(klmn,lmn_size,ilmn,jlmn)
344
345      il= indlmn(1,ilmn); iln=indlmn(5,ilmn)
346      jl= indlmn(1,jlmn); jln=indlmn(5,jlmn)
347      !\$in = indklmn(9 ,klmn) !=indlmn(3,ilmn)
348      !\$jn = indklmn(10,klmn) !=indlmn(3,jlmn)
349
350      in = indlmn(3,ilmn)
351      jn = indlmn(3,jlmn)
352
353      ! Shift il to have the index instead of the value of l.
354      kln2ln(1,kln) = il +1
355      kln2ln(2,kln) = jl +1
356      kln2ln(3,kln) = in
357      kln2ln(4,kln) = jn
358      kln2ln(5,kln) = iln
359      kln2ln(6,kln) = jln
360    end if
361  end do !klmn
362
363 end subroutine make_kln2ln
```

## m_paw_lmn/uppert_index [ Functions ]

[ Top ] [ m_paw_lmn ] [ Functions ]

NAME

```   uppert_index
```

FUNCTION

```  Helper function returning the sequential index of an element in the upper triangle of a matrix
given the row-index ii and the column-index jj. If ii>jj the index of the element a_{jj,ii} is returned.
```

INPUTS

```  ii=Row index
jj=column index
```

PARENTS

SOURCE

```617 function uppert_index(ii,jj)
618
619
620 !This section has been created automatically by the script Abilint (TD).
621 !Do not modify the following lines by hand.
622 #undef ABI_FUNC
623 #define ABI_FUNC 'uppert_index'
624 !End of the abilint section
625
626  implicit none
627
628 !Arguments ------------------------------------
629 !scalars
630  integer,intent(in) :: ii,jj
631  integer :: uppert_index
632 !scalars
633
634 !************************************************************************
635
636  if (jj>=jj) then
637    uppert_index = ii + jj*(jj-1)/2
638  else
639    uppert_index = jj + ii*(ii-1)/2
640  end if
641
642 end function uppert_index
```