LCOV - code coverage report
Current view: top level - shared/libpaw/src - m_paw_atomorb.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 95.0 % 219 208
Test Date: 2026-09-19 15:24:51 Functions: 71.4 % 7 5

            Line data    Source code
       1              : !!****m* ABINIT/m_paw_atomorb
       2              : !! NAME
       3              : !!  m_paw_atomorb
       4              : !!
       5              : !! FUNCTION
       6              : !!  This module provides the definition of the atomorb_type used
       7              : !!  to store atomic orbitals on a radial mesh as well
       8              : !!  as methods to operate on it.
       9              : !!
      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              : !! SOURCE
      16              : 
      17              : #include "libpaw.h"
      18              : 
      19              : MODULE m_paw_atomorb
      20              : 
      21              :  USE_DEFS
      22              :  USE_MSG_HANDLING
      23              :  USE_MPI_WRAPPERS
      24              :  USE_MEMORY_PROFILING
      25              : 
      26              :  use m_paw_numeric
      27              :  use m_libpaw_tools,  only : libpaw_basename, libpaw_get_free_unit
      28              :  use m_pawrad,        only : pawrad_type, pawrad_init, bound_deriv,pawrad_copy, &
      29              : &                            pawrad_free, pawrad_print, pawrad_isame, pawrad_ifromr, simp_gen,pawrad_deducer0
      30              : 
      31              :  implicit none
      32              : 
      33              :  private
      34              : !!***
      35              : 
      36              : !!****t* m_paw_atomorb/atomorb_type
      37              : !! NAME
      38              : !!
      39              : !! FUNCTION
      40              : !!  Defines the atomorb_type datastructure type.
      41              : !!  It contains the atomic orbitals on a radial mesh for a given type of atom.
      42              : !!
      43              : !! NOTES
      44              : !!  * Should the radial mesh included in the object or not?
      45              : !!  * We might have different meshes, useful for deep states in heavy atoms!
      46              : !!  * Methods to be added: corekin
      47              : !!
      48              : !! SOURCE
      49              : 
      50              :  type, public :: atomorb_type
      51              : 
      52              : !scalars
      53              :   integer :: ixc
      54              :    ! Exchange and correlation functional used to generate the orbitals
      55              : 
      56              :   integer :: method
      57              :   ! 1 for restricted, compatible only with nsppol=1.
      58              :   ! 2 for spin unrestricted, compatible only with nsppol=2.
      59              : 
      60              :   integer :: nspden
      61              :    ! Number of spin-density components.
      62              : 
      63              :   integer :: nsppol
      64              :    ! Number of independent spin-components.
      65              :    ! FIXME: here a lot of quantities might depend on nsppol in the
      66              :    ! case of magnetic atoms!
      67              : 
      68              :   integer :: nspinor
      69              :    ! Number of spinorial components
      70              :    ! TODO this is a quite delicate issue, for S.O. one should use J = L+S instead of L!
      71              :    ! If we use scalar relativistic then...
      72              : 
      73              :   integer :: l_max
      74              :    ! Maximum value of angular momentum l+1
      75              : 
      76              :   integer :: l_size
      77              :   ! Maximum value of l+1 leading to non zero Gaunt coeffs
      78              :   ! l_size=2*l_max-1
      79              : 
      80              :   integer :: ln_size
      81              :   ! Number of (l,n) components.
      82              : 
      83              :   integer :: ln2_size
      84              :   ! ln2_size=ln_size*(ln_size+1)/2
      85              :   ! where ln_size is the number of (l,n) elements for core orbitals.
      86              : 
      87              :   integer :: lmn_size
      88              :   ! Number of (l,m,n) elements.
      89              : 
      90              :   integer :: lmn2_size
      91              :    ! lmn2_size=lmn_size*(lmn_size+1)/2
      92              :    ! where lmn_size is the number of (l,m,n) elements for core orbitals.
      93              : 
      94              :   integer :: mesh_size
      95              :   ! Dimension of the radial mesh.
      96              : 
      97              :   integer :: mult
      98              :   ! Number of atoms of the same typat
      99              : 
     100              :   logical :: dirac
     101              :   ! Dirac relativism or not
     102              : 
     103              :   logical :: nc_conv
     104              :   ! nc has converged ?
     105              : 
     106              :   logical :: zcore_conv
     107              :   ! zcore has converged ?
     108              : 
     109              :   real(dp) :: edcc
     110              :   ! DC core energy
     111              : 
     112              :   real(dp) :: eeigc
     113              :   ! Core eigenvalue energy contribution
     114              : 
     115              :   real(dp) :: ehnzc
     116              :   ! Core Hartree nc+Z energy
     117              : 
     118              :   real(dp) :: ekinc
     119              :   ! Core kinetic energy
     120              : 
     121              :   real(dp) :: eigshift
     122              :   ! Eigenenergy shift due to truncation of local potentiel to the sphere in rcpaw
     123              : 
     124              :   real(dp) :: min_eigv
     125              :   ! Minimal eigenvalue of the  valence orbitals
     126              : 
     127              :   real(dp) :: nresid_c
     128              :   ! Residual error on core density
     129              : 
     130              :   real(dp) :: rcore
     131              :   ! Radius of the sphere used to describe core electrons.
     132              :   ! It should be <= rpaw
     133              : 
     134              :   real(dp) :: zion
     135              :    ! zionpsp
     136              :    ! The ionic pseudo-charge, (giving raise to a long-range coulomb potential)
     137              : 
     138              :   real(dp) :: zcore
     139              :    ! Number of core electrons
     140              : 
     141              :   real(dp) :: zcore_orig
     142              :    ! original zcore
     143              :    ! This is used in RCPAW
     144              : 
     145              :   ! TODO alchemy?
     146              :   !real(dp) :: ziontypat
     147              :    ! ziontypat
     148              :    !  For each type of atom (might be alchemy wrt psps), the ionic pseudo-charge
     149              :    ! (giving raise to a long-range coulomb potential)
     150              : 
     151              :   real(dp) :: znucl
     152              :    ! The atomic number of the atom.
     153              : 
     154              :   ! TODO alchemy?
     155              :   !real(dp) :: znucltypat
     156              :    ! znucltypat
     157              :    ! The atomic number of each type of atom (might be alchemy wrt psps)
     158              : 
     159              :   character(len=fnlen) :: fname
     160              :    ! The filename for temporary storage.
     161              : 
     162              :   type(pawrad_type) :: radmesh
     163              :   ! Radial mesh
     164              : 
     165              : !arrays
     166              :   integer, allocatable :: indlmn(:,:)
     167              :   ! indlmn(6,lmn_size)
     168              :   ! Array giving l,m,n,lm,ln,spin for i=lmn.
     169              : 
     170              :   integer, allocatable :: indln(:,:)
     171              :   ! indln(2,ln_size)
     172              :   ! Array giving l and n for i=ln
     173              : 
     174              :   integer, allocatable :: indklmn(:,:)
     175              :    ! indklmn(8,lmn2_size)
     176              :    ! Array giving klm, kln, abs(il-jl), (il+jl), ilm and jlm, ilmn and jlmn for each klmn=(ilmn,jlmn)
     177              :    ! Note: ilmn=(il,im,in) and ilmn<=jlmn
     178              : 
     179              :   !integer, allocatable :: klm2lm TODO add
     180              :    !  klm2lm(6,lm2_size)=Table giving il, jl ,im, jm, ilm, jlm for each klm=(ilm,jlm)
     181              :    !  where ilm=(il,im) and ilm<=jlm. NB: klm2lm is an application and not a bijection.
     182              : 
     183              :   integer, allocatable :: klm_diag(:)
     184              :    ! klm_diag(lmn2_size)
     185              :    ! 1 il==jl and im==jm, 0 otherwise.
     186              : 
     187              :   integer, allocatable :: klmntomn(:,:)
     188              :    ! klmntomn(4,lmn2_size)
     189              :    ! Array giving im, jm ,in, and jn for each klmn=(ilmn,jlmn)
     190              :    ! Note: ilmn=(il,im,in) and ilmn<=jlmn
     191              :    ! NB: klmntomn is an application and not a bijection
     192              : 
     193              :   integer, allocatable :: kln2ln(:,:)
     194              :    ! kln2ln(6,ln2_size)
     195              :    ! Table giving il, jl ,in, jn, iln, jln for each kln=(iln,jln)
     196              :    ! where iln=(il,in) and iln<=jln. NB: kln2ln is an application and not a bijection
     197              : 
     198              :   integer, allocatable :: kappa(:)
     199              :   ! Kappa for dirac relativism
     200              : 
     201              :   integer, allocatable :: mode(:,:,:)
     202              :   ! mode(ln_size,nsppol,2)
     203              :   ! Flag defining how the orbital is treated.
     204              :   ! During the pseudopotential generation we can have: ORB_FROZEN or ORB_VALENCE
     205              :   ! For calculations in extended systems we can have:  ORB_FROZEN or ORB_RELAXED_CORE
     206              :   ! Namely different treatment depending of the degree of localization.
     207              :   ! For example the 1s in plutonium might be treated as ORB_FROZEN during
     208              :   ! a relaxed core calculation.
     209              :   ! Last index: 1 for current status, 2 for input status
     210              :   ! TODO define function to test the type, much safer!
     211              : 
     212              :   real(dp), allocatable :: eig(:,:)
     213              :   ! eig(ln_size,nsppol)
     214              :   ! Eigenvalues for each ln channel and spin.
     215              : 
     216              :   real(dp), allocatable :: max_occ(:,:)
     217              :   ! max_occ(ln_size,nsppol)
     218              :   ! Maximal occupancy for each, used in RCPAW
     219              : 
     220              :   real(dp), allocatable :: occ(:,:)
     221              :   ! occ(ln_size,nsppol)
     222              :   ! Occupation for each ln channel and spin.
     223              : 
     224              :   real(dp), allocatable :: occ_res(:,:)
     225              :   ! occ_res(ln_size,nsppol)
     226              :   ! Occupation residue for each ln channel and spin, used in RCPAW
     227              : 
     228              :   real(dp), allocatable :: occ_respc(:,:)
     229              :   ! occ_respc(ln_size,nsppol)
     230              :   ! Occupation preconditionned residue for each ln channel and spin, used in RCPAW.
     231              : 
     232              :   real(dp), allocatable :: phi(:,:,:)
     233              :   ! phi(mesh_size,ln_size,nsppol)
     234              :   ! Here we might have different meshes, useful for deep states in heavy atoms!
     235              : 
     236              :   ! this might be retrieved with  a method get_atomden
     237              :   !real(dp), allocatable :: density(:)
     238              :    ! density(mesh_size,nspden)
     239              :    ! Gives the core density of the atom for each spin channel
     240              :    ! Total charge in first dimension,up component in second one (if present)
     241              : 
     242              :   real(dp), allocatable :: vhtnzc_orig(:)
     243              :    ! vhtnzc_orig(size(pawtab(itypat)%vhtnzc))
     244              :    ! Original vhtnzc, used in RCPAW
     245              : 
     246              :  end type atomorb_type
     247              : 
     248              : ! public procedures.
     249              :  public :: destroy_atomorb
     250              :  public :: copy_atomorb
     251              :  public :: print_atomorb
     252              :  public :: get_overlap
     253              : !!***
     254              : 
     255              : !----------------------------------------------------------------------
     256              : 
     257              :  integer,public,parameter :: ORB_FROZEN       =0
     258              :  integer,public,parameter :: ORB_RELAXED_CORE =1
     259              :  integer,public,parameter :: ORB_VALENCE      =2
     260              : 
     261              : 
     262              : CONTAINS  !=========================================================================================================================
     263              : !!***
     264              : 
     265              : !----------------------------------------------------------------------
     266              : 
     267              : !!****f* m_paw_atomorb/destroy_atomorb
     268              : !! NAME
     269              : !!  destroy_atomorb
     270              : !!
     271              : !! FUNCTION
     272              : !!  Free the dynamic memory allocated in a structure of type atomorb_type.
     273              : !!
     274              : !! SIDE EFFECTS
     275              : !!  Atm <type(atomorb_type)>=datastructure containing atomic orbitals for a given type of atom.
     276              : !!
     277              : !! SOURCE
     278              : 
     279           11 : subroutine destroy_atomorb(Atm)
     280              : 
     281              : !Arguments ------------------------------------
     282              : !scalars
     283              :  type(atomorb_type),intent(inout) :: Atm
     284              : 
     285              : !************************************************************************
     286              : 
     287              :  !@atomorb_type
     288              : 
     289              :  ! integers
     290           11 :  if (allocated(Atm%indlmn)) then
     291           11 :    LIBPAW_DEALLOCATE(Atm%indlmn)
     292              :  end if
     293           11 :  if (allocated(Atm%indln)) then
     294           11 :    LIBPAW_DEALLOCATE(Atm%indln)
     295              :  end if
     296           11 :  if (allocated(Atm%indklmn)) then
     297           11 :    LIBPAW_DEALLOCATE(Atm%indklmn)
     298              :  end if
     299           11 :  if (allocated(Atm%klm_diag)) then
     300           11 :    LIBPAW_DEALLOCATE(Atm%klm_diag)
     301              :  end if
     302           11 :  if (allocated(Atm%klmntomn)) then
     303           11 :    LIBPAW_DEALLOCATE(Atm%klmntomn)
     304              :  end if
     305           11 :  if (allocated(Atm%kln2ln)) then
     306            0 :    LIBPAW_DEALLOCATE(Atm%kln2ln)
     307              :  end if
     308           11 :  if (allocated(Atm%kappa)) then
     309            3 :    LIBPAW_DEALLOCATE(Atm%kappa)
     310              :  end if
     311           11 :  if (allocated(Atm%mode)) then
     312           11 :    LIBPAW_DEALLOCATE(Atm%mode)
     313              :  end if
     314              : 
     315              :  !real
     316           11 :  if (allocated(Atm%eig)) then
     317           11 :    LIBPAW_DEALLOCATE(Atm%eig)
     318              :  end if
     319           11 :  if (allocated(Atm%max_occ)) then
     320           11 :    LIBPAW_DEALLOCATE(Atm%max_occ)
     321              :  end if
     322           11 :  if (allocated(Atm%occ)) then
     323           11 :    LIBPAW_DEALLOCATE(Atm%occ)
     324              :  end if
     325           11 :  if (allocated(Atm%occ_res)) then
     326           11 :    LIBPAW_DEALLOCATE(Atm%occ_res)
     327              :  end if
     328           11 : if (allocated(Atm%occ_respc)) then
     329           11 :    LIBPAW_DEALLOCATE(Atm%occ_respc)
     330              :  end if
     331           11 :  if (allocated(Atm%phi)) then
     332           11 :    LIBPAW_DEALLOCATE(Atm%phi)
     333              :  end if
     334           11 :  if(allocated(atm%vhtnzc_orig)) then
     335            5 :    LIBPAW_DEALLOCATE(atm%vhtnzc_orig)
     336              :  endif
     337           11 :  call pawrad_free(atm%radmesh)
     338              : 
     339           11 : end subroutine destroy_atomorb
     340              : !!***
     341              : 
     342              : 
     343              : !!****f* m_paw_atomorb/copy_atomorb
     344              : !! NAME
     345              : !!  copy_atomorb
     346              : !!
     347              : !! FUNCTION
     348              : !!
     349              : !! SIDE EFFECTS
     350              : !!
     351              : !! SOURCE
     352              : 
     353            1 : subroutine copy_atomorb(Atm_in,Atm_out)
     354              : 
     355              : !Arguments ------------------------------------
     356              : !scalars
     357              :  type(atomorb_type),intent(in) :: Atm_in
     358              :  type(atomorb_type),intent(inout) :: Atm_out
     359              : !Local ------------------------------------
     360              : !scalars
     361              :  integer :: s1,s2,s3
     362              : 
     363              : !************************************************************************
     364            1 :    Atm_out%ixc=Atm_in%ixc
     365            1 :    Atm_out%method=Atm_in%method
     366            1 :    Atm_out%nspden=Atm_in%nspden
     367            1 :    Atm_out%nsppol=Atm_in%nsppol
     368            1 :    Atm_out%nspinor=Atm_in%nspinor
     369            1 :    Atm_out%l_max=Atm_in%l_max
     370            1 :    Atm_out%l_size=Atm_in%l_size
     371            1 :    Atm_out%ln_size=Atm_in%ln_size
     372            1 :    Atm_out%ln2_size=Atm_in%ln2_size
     373            1 :    Atm_out%lmn_size=Atm_in%lmn_size
     374            1 :    Atm_out%lmn2_size=Atm_in%lmn2_size
     375            1 :    Atm_out%mesh_size=Atm_in%mesh_size
     376            1 :    Atm_out%mult=Atm_in%mult
     377            1 :    Atm_out%dirac=Atm_in%dirac
     378            1 :    Atm_out%nc_conv=Atm_in%nc_conv
     379            1 :    Atm_out%zcore_conv=Atm_in%zcore_conv
     380            1 :    Atm_out%edcc=Atm_in%edcc
     381            1 :    Atm_out%eeigc=Atm_in%eeigc
     382            1 :    Atm_out%ehnzc=Atm_in%ehnzc
     383            1 :    Atm_out%ekinc=Atm_in%ekinc
     384            1 :    Atm_out%eigshift=Atm_in%eigshift
     385            1 :    Atm_out%min_eigv=Atm_in%min_eigv
     386            1 :    Atm_out%nresid_c=Atm_in%nresid_c
     387            1 :    Atm_out%rcore=Atm_in%rcore
     388            1 :    Atm_out%zion=Atm_in%zion
     389            1 :    Atm_out%zcore=Atm_in%zcore
     390            1 :    Atm_out%zcore_orig=Atm_in%zcore_orig
     391            1 :    Atm_out%znucl=Atm_in%znucl
     392            1 :    Atm_out%fname=Atm_in%fname
     393            1 :    call pawrad_copy(Atm_in%radmesh,Atm_out%radmesh)
     394              : 
     395              : 
     396            1 :    if(allocated(Atm_in%indlmn)) then 
     397            1 :      s1=size(Atm_in%indlmn(1,:))
     398            1 :      s2=size(Atm_in%indlmn(:,1))
     399            4 :      LIBPAW_ALLOCATE(Atm_out%indlmn,(s2,s1))
     400          202 :      Atm_out%indlmn=Atm_in%indlmn
     401              :    endif
     402              : 
     403            1 :    if(allocated(Atm_in%indln)) then
     404            1 :      s1=size(Atm_in%indln(1,:))
     405            1 :      s2=size(Atm_in%indln(:,1))
     406            4 :      LIBPAW_ALLOCATE(Atm_out%indln,(s2,s1))
     407           14 :      Atm_out%indln=Atm_in%indln
     408              :    endif
     409              : 
     410            1 :    if(allocated(Atm_in%indklmn)) then
     411            1 :      s1=size(Atm_in%indklmn(1,:))
     412            1 :      s2=size(Atm_in%indklmn(:,1)) 
     413            4 :      LIBPAW_ALLOCATE(Atm_out%indklmn,(s2,s1))
     414         1892 :      Atm_out%indklmn=Atm_in%indklmn
     415              :    endif
     416              : 
     417            1 :    if(allocated(Atm_in%klm_diag)) then
     418            1 :      s1=size(Atm_in%klm_diag(:))
     419            3 :      LIBPAW_ALLOCATE(Atm_out%klm_diag,(s1))
     420          212 :      Atm_out%klm_diag=Atm_in%klm_diag
     421              :    endif
     422              : 
     423            1 :    if(allocated(Atm_in%klmntomn)) then
     424            1 :      s1=size(Atm_in%klmntomn(1,:))
     425            1 :      s2=size(Atm_in%klmntomn(:,1))
     426            4 :      LIBPAW_ALLOCATE(Atm_out%klmntomn,(s2,s1))
     427         1052 :      Atm_out%klmntomn=Atm_in%klmntomn
     428              :    endif
     429              : 
     430            1 :    if(allocated(Atm_in%kln2ln)) then
     431            0 :      s1=size(Atm_in%kln2ln(1,:))
     432            0 :      s2=size(Atm_in%kln2ln(:,1))
     433            0 :      LIBPAW_ALLOCATE(Atm_out%kln2ln,(s2,s1))
     434            0 :      Atm_out%kln2ln=Atm_in%kln2ln
     435              :    endif
     436              :  
     437            1 :    if(allocated(Atm_in%kappa)) then
     438            1 :      s1=size(Atm_in%kappa(:))
     439            3 :      LIBPAW_ALLOCATE(Atm_out%kappa,(s1))
     440            6 :      Atm_out%kappa=Atm_in%kappa
     441              :    endif
     442              : 
     443            1 :    if(allocated(Atm_in%mode)) then
     444            1 :      s1=size(Atm_in%mode(1,1,:))
     445            1 :      s2=size(Atm_in%mode(1,:,1))
     446            1 :      s3=size(Atm_in%mode(:,1,1))
     447            5 :      LIBPAW_ALLOCATE(Atm_out%mode,(s3,s2,s1))
     448           14 :      Atm_out%mode=Atm_in%mode
     449              :    endif
     450              : 
     451            1 :    if(allocated(Atm_in%eig)) then
     452            1 :      s1=size(Atm_in%eig(1,:))
     453            1 :      s2=size(Atm_in%eig(:,1))
     454            4 :      LIBPAW_ALLOCATE(Atm_out%eig,(s2,s1))
     455            7 :      Atm_out%eig=Atm_in%eig
     456              :    endif
     457              : 
     458            1 :    if(allocated(Atm_in%max_occ)) then
     459            1 :      s1=size(Atm_in%max_occ(1,:))
     460            1 :      s2=size(Atm_in%max_occ(:,1))
     461            4 :      LIBPAW_ALLOCATE(Atm_out%max_occ,(s2,s1))
     462            7 :      Atm_out%max_occ=Atm_in%max_occ
     463              :    endif
     464              : 
     465            1 :    if(allocated(Atm_in%occ)) then
     466            1 :      s1=size(Atm_in%occ(1,:))
     467            1 :      s2=size(Atm_in%occ(:,1))
     468            4 :      LIBPAW_ALLOCATE(Atm_out%occ,(s2,s1))
     469            7 :      Atm_out%occ=Atm_in%occ
     470              :    endif
     471              : 
     472            1 :    if(allocated(Atm_in%occ_res)) then
     473            1 :      s1=size(Atm_in%occ_res(1,:))
     474            1 :      s2=size(Atm_in%occ_res(:,1))
     475            4 :      LIBPAW_ALLOCATE(Atm_out%occ_res,(s2,s1))
     476            7 :      Atm_out%occ_res=Atm_in%occ_res
     477              :    endif
     478              : 
     479            1 :    if(allocated(Atm_in%occ_respc)) then
     480            1 :      s1=size(Atm_in%occ_respc(1,:))
     481            1 :      s2=size(Atm_in%occ_respc(:,1))
     482            4 :      LIBPAW_ALLOCATE(Atm_out%occ_respc,(s2,s1))
     483            7 :      Atm_out%occ_respc=Atm_in%occ_respc
     484              :    endif
     485              : 
     486            1 :    if(allocated(Atm_in%phi)) then
     487            1 :      s1=size(Atm_in%phi(1,1,:))
     488            1 :      s2=size(Atm_in%phi(1,:,1))
     489            1 :      s3=size(Atm_in%phi(:,1,1))
     490            5 :      LIBPAW_ALLOCATE(Atm_out%phi,(s3,s2,s1))
     491         8011 :      Atm_out%phi=Atm_in%phi
     492              :    endif
     493              : 
     494            1 :    if(allocated(atm_in%vhtnzc_orig)) then
     495            1 :      s1=size(Atm_in%vhtnzc_orig(:))
     496            3 :      LIBPAW_ALLOCATE(atm_out%vhtnzc_orig,(s1))
     497         2003 :      atm_out%vhtnzc_orig=atm_in%vhtnzc_orig
     498              :    endif
     499            1 : end subroutine copy_atomorb
     500              : !!***
     501              : 
     502              : 
     503              : !----------------------------------------------------------------------
     504              : 
     505              : 
     506              : !!****f* m_paw_atomorb/get_atomorb_charge
     507              : !! NAME
     508              : !!  get_atomorb_charge
     509              : !!
     510              : !! FUNCTION
     511              : !!  Get core charge from a structure of type atomorb_type
     512              : !!  and optionally core density.
     513              : !!
     514              : !! INPUTS
     515              : !!  Atm<atomorb_type>=Structure defining the set of core orbitals.
     516              : !!  Radmesh<pawrad_type>=Info oh the Radial mesh used for core electrons.
     517              : !!
     518              : !! OUTPUT
     519              : !!  nele=core charge
     520              : !!  raddens(mesh_size)=core density (optional)
     521              : !!
     522              : !! SOURCE
     523              : 
     524              : subroutine get_atomorb_charge(Atm,Radmesh,nele,radens)
     525              : 
     526              : !Arguments ------------------------------------
     527              : !scalars
     528              :  real(dp),intent(out) :: nele
     529              :  type(atomorb_type),intent(in) :: Atm
     530              :  type(pawrad_type),intent(in) :: Radmesh
     531              : !arrays
     532              :  real(dp),optional,intent(out) :: radens(Atm%mesh_size,Atm%nspden)
     533              : 
     534              : !Local variables-------------------------------
     535              : !scalars
     536              :  integer :: iln,isppol
     537              :  real(dp) :: intg,focc
     538              :  real(dp),allocatable :: phi2nl(:)
     539              : 
     540              : !************************************************************************
     541              : 
     542              :  if (Atm%nsppol==2) then
     543              :    LIBPAW_ERROR("nsppol==2 is Working in progress")
     544              :  end if
     545              : 
     546              :  LIBPAW_ALLOCATE(phi2nl,(Atm%mesh_size))
     547              :  if (PRESENT(radens)) radens = zero
     548              : 
     549              :  nele = zero
     550              :  do isppol=1,Atm%nsppol
     551              :    do iln=1,Atm%ln_size
     552              :      !Atm%mode(iln,isppol) TODO add option to select particular states
     553              :      focc   = Atm%occ(iln,isppol)
     554              :      if (ABS(focc) > tol16) then
     555              :        phi2nl = Atm%phi(:,iln,isppol)**2
     556              :        call simp_gen(intg,phi2nl,Radmesh)
     557              :        nele = nele + focc*intg
     558              : !       if (PRESENT(radens)) then  !FIXME maybe it is better to rr**2 radens
     559              : !        radens(2:Atm%mesh_size) = radens(2:Atm%mesh_size) &
     560              : !&         + focc * phi2nl(2:Atm%mesh_size)/(four_pi*Radmesh%rad(2:Atm%mesh_size)**2)
     561              : !       end if
     562              :      end if
     563              :    end do
     564              :  end do
     565              : 
     566              :  LIBPAW_DEALLOCATE(phi2nl)
     567              : 
     568              : end subroutine get_atomorb_charge
     569              : !!***
     570              : 
     571              : !----------------------------------------------------------------------
     572              : 
     573              : 
     574              : !!****f* m_paw_atomorb/get_overlap
     575              : !! NAME
     576              : !!  get_overlap
     577              : !!
     578              : !! FUNCTION
     579              : !!  Get overlap between core and valence states
     580              : !!
     581              : !! INPUTS
     582              : !!  Atm<atomorb_type>=Structure defining the set of core states
     583              : !!  Atmesh<pawrad_type>=Info oh the Radial mesh used for core states
     584              : !!  isppol=index for spin component
     585              : !!  nphi=number of core states
     586              : !!  phi(Radmesh2%mesh_size,nphi)=valence states
     587              : !!  phi_indln(nphi)=Array giving l and and n for i=1,nphi
     588              : !!  Radmesh2<pawrad_type>=Info oh the Radial mesh used for valence states
     589              : !!
     590              : !! OUTPUT
     591              : !!  overlap(ln_size,nphi)=core-valence overlap matrix
     592              : !!
     593              : !! SOURCE
     594              : 
     595            1 : subroutine get_overlap(Atm,Atmesh,Radmesh2,isppol,nphi,phi,phi_indln,overlap)
     596              : 
     597              : !Arguments ------------------------------------
     598              : !scalars
     599              :  integer,intent(in) :: nphi,isppol
     600              :  type(atomorb_type),intent(in) :: Atm
     601              :  type(pawrad_type),target,intent(in) :: Atmesh,Radmesh2
     602              : !arrays
     603              :  integer,intent(in) :: phi_indln(2,nphi)
     604              :  real(dp),target,intent(in) :: phi(Radmesh2%mesh_size,nphi)
     605              :  real(dp),intent(out) :: overlap(Atm%ln_size,nphi)
     606              : 
     607              : !Local variables-------------------------------
     608              : !scalars
     609              :  integer :: iln_atm,iphi,ll_phi,ll_atm,do_spline,iln
     610              :  integer :: whichdenser,size4spl,my_mesh_size
     611              :  real(dp) :: ybcbeg,ybcend,intg
     612              :  logical :: hasameq
     613              : !arrays
     614            1 :  real(dp),pointer :: ff_spl(:,:)
     615            1 :  real(dp),allocatable :: der(:),ypp(:),func(:)
     616            1 :  real(dp),pointer :: rad4spl(:),my_pts(:)
     617              : 
     618              : !************************************************************************
     619              : 
     620            1 :  if(isppol<=0.or.isppol>Atm%nsppol) LIBPAW_ERROR("Wrong isppol")
     621              : 
     622            1 :  call pawrad_isame(Atmesh,Radmesh2,hasameq,whichdenser)
     623              : 
     624            1 :  do_spline= 0; if (.not.hasameq) do_spline=1
     625              : 
     626            1 :  my_mesh_size = MIN(Atmesh%mesh_size,Radmesh2%mesh_size)
     627            1 :  ff_spl => phi
     628              : 
     629              :  ! === Spline valence onto Atom mesh (natural spline) ===
     630            1 :  if (do_spline==1) then
     631            1 :    LIBPAW_COMMENT("Splining in overlap")
     632              : 
     633            1 :    my_mesh_size  =  Atmesh%mesh_size
     634            1 :    my_pts        => Atmesh%rad(1:my_mesh_size)
     635            4 :    LIBPAW_ALLOCATE(ff_spl,(my_mesh_size,nphi))
     636              : 
     637            1 :    size4spl =  Radmesh2%mesh_size
     638            1 :    rad4spl  => Radmesh2%rad
     639            3 :    LIBPAW_ALLOCATE(der,(size4spl))
     640            2 :    LIBPAW_ALLOCATE(ypp,(size4spl))
     641              : 
     642            5 :    do iln=1,nphi
     643         2484 :      ypp(:) = zero; ybcbeg = zero; ybcend = zero
     644            4 :      call paw_spline(rad4spl,phi(:,iln),size4spl,ybcbeg,ybcend,ypp)
     645              : 
     646            5 :      call paw_splint(size4spl,rad4spl,phi(:,iln),ypp,my_mesh_size,my_pts,ff_spl(:,iln))
     647              :    end do
     648              : 
     649            1 :    LIBPAW_DEALLOCATE(der)
     650            1 :    LIBPAW_DEALLOCATE(ypp)
     651              :  end if
     652              : 
     653            3 :  LIBPAW_ALLOCATE(func,(my_mesh_size))
     654           17 :  overlap = zero
     655              : 
     656            5 :  do iphi=1,nphi
     657            4 :    ll_phi = phi_indln(1,iphi)
     658           17 :    do iln_atm=1,Atm%ln_size
     659           12 :      ll_atm = Atm%indln(1,iln_atm)
     660              : 
     661           16 :      if (ll_atm == ll_phi) then ! selection rule on l
     662         8298 :        func(:) = Atm%phi(1:my_mesh_size,iln_atm,isppol) * ff_spl(1:my_mesh_size,iphi)
     663            6 :        call simp_gen(intg,func,Atmesh)
     664            6 :        overlap(iln_atm,iphi)=intg
     665            6 :        write(std_out,*)"overlap <phic_i|phi_j> for ll_phi",ll_phi,"ll_phic",ll_atm,"=",intg
     666              :      end if
     667              : 
     668              :    end do
     669              :  end do
     670            1 :  LIBPAW_DEALLOCATE(func)
     671              : 
     672            1 :  if (do_spline==1)  then
     673            1 :    LIBPAW_DEALLOCATE(ff_spl)
     674              :  end if
     675              : 
     676            2 : end subroutine get_overlap
     677              : !!***
     678              : 
     679              : !----------------------------------------------------------------------
     680              : 
     681              : !!****f* m_paw_atomorb/print_atomorb
     682              : !! NAME
     683              : !!  print_atomorb
     684              : !!
     685              : !! FUNCTION
     686              : !!  Reports info on a structure of type atomorb_type.
     687              : !!
     688              : !! INPUTS
     689              : !!  Atm <type(atomorb_type)>=datastructure containing atomic orbitals for a given type of atom.
     690              : !!
     691              : !! OUTPUT
     692              : !!
     693              : !! SOURCE
     694              : 
     695            1 : subroutine print_atomorb(Atm,header,unit,prtvol,mode_paral)
     696              : 
     697              : !Arguments ------------------------------------
     698              : !scalars
     699              :  type(atomorb_type),intent(in) :: Atm
     700              :  integer,optional,intent(in) :: prtvol,unit
     701              :  character(len=*),optional,intent(in) :: header
     702              :  character(len=4),optional,intent(in) :: mode_paral
     703              : 
     704              : !Local variables-------------------------------
     705              :  integer :: my_unt,my_prtvol,iln,ll,nn,isppol
     706              :  character(len=4) :: my_mode
     707              :  character(len=500) :: msg
     708              : ! ************************************************************************
     709              : 
     710              :  !@atomorb_type
     711            1 :  my_unt   =std_out; if (PRESENT(unit      )) my_unt   =unit
     712            1 :  my_prtvol=0      ; if (PRESENT(prtvol    )) my_prtvol=prtvol
     713            1 :  my_mode  ='COLL' ; if (PRESENT(mode_paral)) my_mode  =mode_paral
     714              : 
     715            1 :  msg=' ==== Info on the atomorb_type ==== '
     716            1 :  if (PRESENT(header)) msg=header
     717            1 :  call wrtout(my_unt,msg,my_mode)
     718              : 
     719            2 :  select case (Atm%method)
     720              :  case (1)
     721            1 :    msg = "  Spin restricted"
     722              :  case(2)
     723            0 :    msg = "  Spin unrestricted"
     724              :  case default
     725            0 :    write(msg,'(a,i3)')" Wrong method= ",Atm%method
     726            1 :    LIBPAW_BUG(msg)
     727              :  end select
     728            1 :  call wrtout(my_unt,msg,my_mode)
     729              : 
     730              :  write(msg,'(7(a,i5,a),(a,f8.5,a))')&
     731            1 : & '  Number of spinorial components ...... ',Atm%nspinor,ch10,&
     732            1 : & '  Number of ind. spin polarizations ... ',Atm%nsppol,ch10,&
     733            1 : & '  Number of spin-density components ... ',Atm%nspden,ch10,&
     734            1 : & '  Maximum angular momentum + 1 ........ ',Atm%l_max,ch10,&
     735            1 : & '  Number of (l,n) orbitals  ........... ',Atm%ln_size,ch10,&
     736            1 : & '  Number of (l,m,n) orbitals  ......... ',Atm%lmn_size,ch10,&
     737            1 : & '  Dimensions of radial mesh ........... ',Atm%mesh_size,ch10,&
     738            2 : & '  Core Radius  ........................ ',Atm%rcore,ch10
     739            1 :  call wrtout(my_unt,msg,my_mode)
     740              : 
     741              :  write(msg,'(2(a,f8.5,a))')&
     742            1 : & '  Ionic charge ........................ ',Atm%zion,ch10,&
     743            2 : & '  Atomic number ....................... ',Atm%znucl,ch10
     744            1 :  call wrtout(my_unt,msg,my_mode)
     745              : 
     746            2 :  do isppol=1,Atm%nsppol
     747            5 :    do iln=1,Atm%ln_size
     748            3 :      ll = Atm%indln(1,iln)
     749            3 :      nn = Atm%indln(2,iln)
     750              :      write(msg,'(" n=",i2,", l=",i2,", spin=",i2,", nocc=",f15.7,", energy=",f15.7,2x,"(",a,")")')&
     751            3 : &      nn,ll,isppol,Atm%occ(iln,isppol),Atm%eig(iln,isppol),TRIM(my_mode2str(Atm%mode(iln,isppol,1)))
     752            4 :      call wrtout(my_unt,msg,my_mode)
     753              :    end do
     754              :  end do
     755              : 
     756            1 : end subroutine print_atomorb
     757              : !!***
     758              : 
     759              : !----------------------------------------------------------------------
     760              : 
     761              : !!****f* m_paw_atomorb/my_mode2str
     762              : !! NAME
     763              : !!  my_mode2str
     764              : !!
     765              : !! FUNCTION
     766              : !!  Converts an integer flags defining the way an orbital is treated to a string.
     767              : !!
     768              : !! INPUTS
     769              : !!  mode=Integer
     770              : !!
     771              : !! OUTPUT
     772              : !!  str=mode. Either "Frozen", "Relazed Core", "Valence"
     773              : !!
     774              : !! SOURCE
     775              : 
     776            3 : function my_mode2str(mode) result(str)
     777              : 
     778              : !Arguments ------------------------------------
     779              : !scalars
     780              :  integer,intent(in) :: mode
     781              :  character(len=50) :: str
     782              : 
     783              : !Local variables
     784              :  character(len=500) :: msg
     785              : 
     786              : !************************************************************************
     787              : 
     788            6 :  select case (mode)
     789              :  case (ORB_FROZEN)
     790            3 :    str="Frozen Orbital"
     791              :  case (ORB_RELAXED_CORE)
     792            0 :    str="Relaxed Core Orbital"
     793              :  case (ORB_VALENCE)
     794            0 :    str="Valence Orbital"
     795              :  case default
     796            0 :    write(msg,'(a,i3)')" Wrong mode= ",mode
     797            3 :    ABI_BUG(msg)
     798              :  end select
     799              : 
     800            3 : end function my_mode2str
     801              : !!***
     802              : 
     803            0 : END MODULE m_paw_atomorb
     804              : !!***
        

Generated by: LCOV version 2.3-1