LCOV - code coverage report
Current view: top level - src/68_dmft - m_matlu.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 63.9 % 1314 839
Test Date: 2026-11-10 16:57:26 Functions: 68.4 % 38 26
Branches: 48.0 % 2494 1197

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_matlu
       2                 :             : !! NAME
       3                 :             : !!  m_matlu
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!
       7                 :             : !! COPYRIGHT
       8                 :             : !! Copyright (C) 2006-2026 ABINIT group (BAmadon)
       9                 :             : !! This file is distributed under the terms of the
      10                 :             : !! GNU General Public License, see ~abinit/COPYING
      11                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      12                 :             : !!
      13                 :             : !! INPUTS
      14                 :             : !!
      15                 :             : !! OUTPUT
      16                 :             : !!
      17                 :             : !! NOTES
      18                 :             : !!  subroutines in this module must never call
      19                 :             : !!   a subroutine of m_oper, m_green, m_self
      20                 :             : !!   in order to avoid circular dependancies
      21                 :             : !!
      22                 :             : !! SOURCE
      23                 :             : 
      24                 :             : #if defined HAVE_CONFIG_H
      25                 :             : #include "config.h"
      26                 :             : #endif
      27                 :             : 
      28                 :             : 
      29                 :             : #include "abi_common.h"
      30                 :             : 
      31                 :             : MODULE m_matlu
      32                 :             : 
      33                 :             :  use, intrinsic :: iso_c_binding, only: c_size_t, c_loc
      34                 :             :  use defs_basis
      35                 :             :  use m_errors
      36                 :             :  use m_abicore
      37                 :             :  use m_gputk
      38                 :             :  use m_abi_linalg
      39                 :             : 
      40                 :             : #ifdef HAVE_GPU
      41                 :             :  use m_gpu_toolbox
      42                 :             : #endif
      43                 :             : 
      44                 :             :  use m_abi_linalg, only : abi_xgemm
      45                 :             :  use m_fstrings, only : int2char4
      46                 :             :  use m_hide_lapack, only : xginv
      47                 :             :  use m_io_tools, only : flush_unit
      48                 :             :  use m_matrix, only : blockdiago_fordsyev,blockdiago_forzheev
      49                 :             :  use m_paw_dmft, only : paw_dmft_type
      50                 :             :  use m_xmpi, only : xmpi_bcast,xmpi_sum
      51                 :             : 
      52                 :             :  implicit none
      53                 :             : 
      54                 :             :  private
      55                 :             : 
      56                 :             :  public :: init_matlu
      57                 :             :  public :: inverse_matlu
      58                 :             :  public :: destroy_matlu
      59                 :             :  public :: diff_matlu
      60                 :             :  public :: add_matlu
      61                 :             :  public :: print_matlu
      62                 :             :  public :: sym_matlu
      63                 :             :  public :: copy_matlu
      64                 :             :  public :: copy_matlu_from_ndat
      65                 :             :  public :: copy_matlu_to_ndat
      66                 :             :  public :: gather_matlu
      67                 :             :  public :: zero_matlu
      68                 :             :  public :: trace_matlu
      69                 :             :  public :: diag_matlu
      70                 :             :  public :: rotate_matlu
      71                 :             :  public :: shift_matlu
      72                 :             :  public :: checkdiag_matlu
      73                 :             :  public :: checkreal_matlu
      74                 :             :  public :: prod_matlu
      75                 :             :  public :: conjg_matlu
      76                 :             :  public :: ln_matlu
      77                 :             :  public :: slm2ylm_matlu
      78                 :             :  public :: fac_matlu
      79                 :             :  public :: printplot_matlu
      80                 :             :  public :: identity_matlu
      81                 :             :  public :: magmomforb_matlu
      82                 :             :  public :: magmomfspin_matlu
      83                 :             :  public :: magmomfzeeman_matlu
      84                 :             :  public :: chi_matlu
      85                 :             :  public :: trace_prod_matlu
      86                 :             :  public :: xmpi_matlu
      87                 :             :  public :: symmetrize_matlu
      88                 :             :  public :: ylm2jmj_matlu
      89                 :             :  public :: magnfield_matlu
      90                 :             :  public :: magmomjmj_matlu
      91                 :             : !!***
      92                 :             : 
      93                 :             : !!****t* m_matlu/matlu_type
      94                 :             : !! NAME
      95                 :             : !!  matlu_type
      96                 :             : !!
      97                 :             : !! FUNCTION
      98                 :             : !!  This structured datatype contains a matrix for the correlated subspace
      99                 :             : !!
     100                 :             : !! SOURCE
     101                 :             : 
     102                 :             :  type, public :: matlu_type ! for each atom
     103                 :             : 
     104                 :             :   integer :: lpawu
     105                 :             :   ! Value of the angular momentum for each correlated electrons
     106                 :             : 
     107                 :             : !  integer :: natom
     108                 :             :    ! number of atoms (given for each atom, not useful..could be changed)
     109                 :             : !
     110                 :             : !  integer :: mband
     111                 :             : !  ! Number of bands
     112                 :             : !
     113                 :             : !  integer :: mbandc
     114                 :             : !  ! Total number of bands in the Kohn-Sham Basis for PAW+DMFT
     115                 :             : !
     116                 :             : !  integer :: natpawu         ! Number of correlated atoms
     117                 :             : !
     118                 :             : !  integer :: nkpt
     119                 :             : !  ! Number of k-point in the IBZ.
     120                 :             :   !character(len=12) :: whichmatlu
     121                 :             :   ! describe the type of local matrix computed (greenDFT, etc..)
     122                 :             : !
     123                 :             :   integer :: gpu_option
     124                 :             :   ! Wether ks and matlu are stored on GPU
     125                 :             : !
     126                 :             :   integer :: ndat
     127                 :             :   ! Number of elements computed in batch
     128                 :             : !
     129                 :             :   integer :: nspinor
     130                 :             :   ! Number of spinorial components
     131                 :             : !
     132                 :             :   integer :: nsppol
     133                 :             :   ! Number of polarizations
     134                 :             : 
     135                 :             :   complex(dp), allocatable :: mat(:,:,:)
     136                 :             :   ! Local quantity
     137                 :             : 
     138                 :             :  end type matlu_type
     139                 :             : 
     140                 :             : !----------------------------------------------------------------------
     141                 :             : 
     142                 :             : 
     143                 :             : CONTAINS  !========================================================================================
     144                 :             : !!***
     145                 :             : 
     146                 :             : !!****f* m_matlu/init_matlu
     147                 :             : !! NAME
     148                 :             : !! init_matlu
     149                 :             : !!
     150                 :             : !! FUNCTION
     151                 :             : !!  Allocate variables used in type matlu_type.
     152                 :             : !!
     153                 :             : !! INPUTS
     154                 :             : !!  natom   = number of atoms
     155                 :             : !!  nspinor = number of spinorial components
     156                 :             : !!  nsppol  = number of polarisation components
     157                 :             : !!  lpawu_natom(natom) = value of lpawu for every atom
     158                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
     159                 :             : !!
     160                 :             : !! OUTPUTS
     161                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
     162                 :             : !!
     163                 :             : !! SOURCE
     164                 :             : 
     165                 :      410629 : subroutine init_matlu(natom,nspinor,nsppol,lpawu_natom,matlu,gpu_option,ndat)
     166                 :             : 
     167                 :             : !Arguments ------------------------------------
     168                 :             :  integer, intent(in) :: natom,nspinor,nsppol
     169                 :             :  integer, intent(in) :: lpawu_natom(natom)
     170                 :             :  integer, intent(in), optional :: gpu_option,ndat
     171                 :             :  type(matlu_type), target, intent(inout) :: matlu(natom)
     172                 :             : !Local variables ------------------------------------
     173                 :             :  integer :: iatom,lpawu,ndim,l_gpu_option,l_ndat
     174                 :             : !************************************************************************
     175                 :             : 
     176         [ +  + ]:      410629 :  l_gpu_option=ABI_GPU_DISABLED; if(present(gpu_option)) l_gpu_option=gpu_option
     177         [ -  + ]:      410629 :  l_ndat=1; if(present(ndat)) l_ndat=ndat
     178                 :             : ! matlu%mband       = mband
     179                 :             : ! matlu%dmftbandf   = dmftbandf
     180                 :             : ! matlu%dmftbandi   = dmftbandi
     181                 :             : ! matlu%nkpt        = nkpt
     182                 :             : ! matlu%mbandc  = 0
     183         [ +  + ]:     1226504 :  do iatom=1,natom
     184                 :             : 
     185                 :      815875 :    lpawu = lpawu_natom(iatom)
     186                 :      815875 :    matlu(iatom)%lpawu   = lpawu
     187                 :      815875 :    matlu(iatom)%nspinor = nspinor
     188                 :      815875 :    matlu(iatom)%nsppol  = nsppol
     189                 :      815875 :    matlu(iatom)%ndat  = l_ndat
     190                 :      815875 :    matlu(iatom)%gpu_option  = l_gpu_option
     191         [ +  + ]:      815875 :    if (lpawu == -1) cycle
     192                 :      517291 :    ndim = (2*lpawu+1) * nspinor
     193   [ -  +  +  -  :     2586455 :    ABI_MALLOC(matlu(iatom)%mat,(ndim,ndim,nsppol))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                +  -  + ]
     194         [ +  - ]:      927920 :    if(l_gpu_option==ABI_GPU_DISABLED) then
     195   [ +  +  +  +  :    52231398 :      matlu(iatom)%mat(:,:,:) = czero
                   +  + ]
     196         [ #  # ]:           0 :    else if(l_gpu_option==ABI_GPU_OPENMP) then
     197   [ #  #  #  #  :           0 :      matlu(iatom)%mat(:,:,:) = czero
                   #  # ]
     198                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     199                 :             :      call matlu_ompgpu_map_alloc(matlu(iatom)%mat)
     200                 :             : #endif
     201                 :           0 :      call gpu_set_to_zero_complex(matlu(iatom)%mat, int(nsppol,c_size_t)*ndim*ndim)
     202                 :             :    end if
     203                 :             : 
     204                 :             :  end do ! iatom
     205                 :             : 
     206                 :             : #if defined HAVE_OPENMP_OFFLOAD
     207                 :             :  contains
     208                 :             :    ! mat is located in an array of structs,
     209                 :             :    ! which syntax is loosely supported in OpenMP directives
     210                 :             :    subroutine matlu_ompgpu_map_alloc(mat)
     211                 :             :     complex(dp),intent(inout) :: mat(:,:,:)
     212                 :             :     !$OMP TARGET ENTER DATA MAP(alloc:mat)
     213                 :             :    end subroutine matlu_ompgpu_map_alloc
     214                 :             : #endif
     215                 :      410629 : end subroutine init_matlu
     216                 :             : !!***
     217                 :             : 
     218                 :             : !!****f* m_matlu/zero_matlu
     219                 :             : !! NAME
     220                 :             : !! zero_matlu
     221                 :             : !!
     222                 :             : !! FUNCTION
     223                 :             : !!  Set the elements of matlu to 0.
     224                 :             : !!
     225                 :             : !! INPUTS
     226                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
     227                 :             : !!  natom = number of atoms
     228                 :             : !!  onlynondiag = set all the off-diagonal elements to 0
     229                 :             : !!  onlyimag = set the imaginary part to 0
     230                 :             : !!
     231                 :             : !! OUTPUT
     232                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
     233                 :             : !!  err = maximal off-diagonal/imaginary element that is neglected
     234                 :             : !!
     235                 :             : !! SOURCE
     236                 :             : 
     237                 :       19015 : subroutine zero_matlu(matlu,natom,onlynondiag,onlyimag,err)
     238                 :             : 
     239                 :             : !Arguments ------------------------------------
     240                 :             :  integer, intent(in) :: natom
     241                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
     242                 :             :  integer, optional, intent(in) :: onlyimag,onlynondiag
     243                 :             :  real(dp), optional, intent(out) :: err
     244                 :             : !Local variables-------------------------------
     245                 :             :  integer :: iatom,im,im1,isppol
     246                 :             :  integer :: lpawu,ndim,nspinor,nsppol,tndim
     247                 :             :  real(dp) :: err_
     248                 :             : !*********************************************************************
     249                 :             : 
     250                 :       19015 :  nspinor = matlu(1)%nspinor
     251                 :       19015 :  nsppol  = matlu(1)%nsppol
     252                 :             : 
     253         [ -  + ]:       19015 :  if (present(err)) err = zero
     254                 :             : 
     255         [ +  + ]:       43149 :  do iatom=1,natom
     256                 :       24134 :    lpawu = matlu(iatom)%lpawu
     257         [ +  + ]:       24134 :    if (lpawu == -1) cycle
     258         [ +  + ]:       38302 :    if (present(onlynondiag)) then
     259                 :       17929 :      ndim  = 2*lpawu + 1
     260                 :       17929 :      tndim = nspinor * ndim
     261         [ +  + ]:       52527 :      do isppol=1,nsppol
     262         [ +  + ]:      225685 :        do im1=1,tndim
     263         [ +  + ]:     1084130 :          do im=1,tndim
     264         [ +  + ]:     1049532 :            if (im /= im1) then
     265         [ -  + ]:      703216 :              if (present(err)) then
     266                 :           0 :                err_ = abs(matlu(iatom)%mat(im,im1,isppol))
     267         [ #  # ]:           0 :                if (err_ > err) err = err_
     268                 :             :              end if
     269                 :      703216 :              matlu(iatom)%mat(im,im1,isppol) = czero
     270                 :             :            end if ! im/=im1
     271                 :             :          end do ! im
     272                 :             :        end do ! im1
     273                 :             :      end do ! isppol
     274         [ -  + ]:        1358 :    else if (present(onlyimag)) then
     275   [ #  #  #  #  :           0 :      if (present(err)) err = maxval(abs(aimag(matlu(iatom)%mat(:,:,:))))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
     276   [ #  #  #  #  :           0 :      matlu(iatom)%mat(:,:,:) = cmplx(dble(matlu(iatom)%mat(:,:,:)),zero,kind=dp)
                   #  # ]
     277                 :             :    else
     278   [ +  +  +  +  :       86835 :      matlu(iatom)%mat(:,:,:) = czero
                   +  + ]
     279                 :             :    end if ! onlynondiag
     280                 :             :  end do ! iatom
     281                 :             : 
     282                 :       19015 : end subroutine zero_matlu
     283                 :             : !!***
     284                 :             : 
     285                 :             : !!****f* m_matlu/destroy_matlu
     286                 :             : !! NAME
     287                 :             : !! destroy_matlu
     288                 :             : !!
     289                 :             : !! FUNCTION
     290                 :             : !!  Deallocate matlu
     291                 :             : !!
     292                 :             : !! INPUTS
     293                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
     294                 :             : !!  natom = number of atoms
     295                 :             : !!
     296                 :             : !! OUTPUT
     297                 :             : !!
     298                 :             : !! SOURCE
     299                 :             : 
     300                 :      410629 : subroutine destroy_matlu(matlu,natom)
     301                 :             : 
     302                 :             : !Arguments ------------------------------------
     303                 :             :  integer, intent(in) :: natom
     304                 :             :  type(matlu_type),target, intent(inout) :: matlu(natom)
     305                 :             : !Local variables-------------------------------
     306                 :             :  integer :: iatom
     307                 :             : ! *********************************************************************
     308                 :             : 
     309         [ +  + ]:     1226504 :  do iatom=1,natom
     310                 :             :    if(matlu(iatom)%gpu_option==ABI_GPU_OPENMP) then
     311                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     312                 :             :      call matlu_ompgpu_map_delete(matlu(iatom)%mat)
     313                 :             : #endif
     314                 :             :    end if
     315         [ +  + ]:     1226504 :    ABI_SFREE(matlu(iatom)%mat)
     316                 :             :  end do ! iatom
     317                 :             : 
     318                 :             : #if defined HAVE_OPENMP_OFFLOAD
     319                 :             :  contains
     320                 :             :    ! mat is located in an array of structs,
     321                 :             :    ! which syntax is loosely supported in OpenMP directives
     322                 :             :    subroutine matlu_ompgpu_map_delete(mat)
     323                 :             :     complex(dp),intent(inout) :: mat(:,:,:)
     324                 :             :     !$OMP TARGET EXIT DATA MAP(delete:mat)
     325                 :             :    end subroutine matlu_ompgpu_map_delete
     326                 :             : #endif
     327                 :      410629 : end subroutine destroy_matlu
     328                 :             : !!***
     329                 :             : 
     330                 :             : !!****f* m_matlu/copy_matlu
     331                 :             : !! NAME
     332                 :             : !! copy_matlu
     333                 :             : !!
     334                 :             : !! FUNCTION
     335                 :             : !!  Copy mat1 into mat2
     336                 :             : !!
     337                 :             : !! INPUTS
     338                 :             : !!  mat1 <type(matlu_type)>= density matrix nmat1 in the local orbital basis and related variables
     339                 :             : !!  natom = number of atoms
     340                 :             : !!  opt_diag = if present, only copy the diagonal elements (the off-diagonal elements are not set to 0)
     341                 :             : !!  opt_non_diag = if present, only copy the off-diagonal elements
     342                 :             : !!  opt_re = if present, only copy the real part
     343                 :             : !!
     344                 :             : !! OUTPUT
     345                 :             : !!  mat2 <type(matlu_type)>= density matrix nmat2 in the local orbital basis and related variables
     346                 :             : !!
     347                 :             : !! SOURCE
     348                 :             : 
     349                 :      194802 : subroutine copy_matlu(mat1,mat2,natom,opt_diag,opt_non_diag,opt_re)
     350                 :             : 
     351                 :             : !Arguments ------------------------------------
     352                 :             :  integer, intent(in) :: natom
     353                 :             :  type(matlu_type), intent(in) :: mat1(natom)
     354                 :             :  type(matlu_type), intent(inout) :: mat2(natom) !vz_i
     355                 :             :  integer, optional, intent(in) :: opt_diag,opt_non_diag,opt_re
     356                 :             : !Local variables-------------------------------
     357                 :             :  integer :: iatom,im,im1,isppol,lpawu,ndim,nspinor,nsppol
     358                 :             : ! *********************************************************************
     359                 :             : 
     360                 :      194802 :  nspinor = mat1(1)%nspinor
     361                 :      194802 :  nsppol  = mat1(1)%nsppol
     362                 :             : 
     363         [ +  + ]:      565621 :  do iatom=1,natom
     364                 :             : 
     365                 :      370819 :    lpawu = mat1(iatom)%lpawu
     366         [ +  + ]:      370819 :    if (lpawu == -1) cycle
     367                 :      248252 :    ndim = (2*lpawu+1) * nspinor
     368                 :             : 
     369                 :             :    !if both matrix are on GPU and no opt is provided, perform copy on GPU
     370                 :             :    !Other cases can be handled through OpenMP kernels on GPU but no use case exists.
     371                 :             :    if(mat1(iatom)%gpu_option==ABI_GPU_OPENMP .and. mat2(iatom)%gpu_option==ABI_GPU_OPENMP &
     372   [ -  +  -  -  :      248252 :    &    .and. .not. (present(opt_diag) .or. present(opt_non_diag) .or. present(opt_re))) then
             -  -  -  - ]
     373                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     374                 :             :      call gpu_copy_complex(mat2(iatom)%mat, mat1(iatom)%mat, int(nsppol, c_size_t)*ndim*ndim)
     375                 :             : #endif
     376                 :             :      cycle
     377                 :             :    end if
     378                 :             : 
     379                 :             : 
     380                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     381                 :             :    !$OMP TARGET UPDATE FROM(mat1(iatom)%mat) IF(mat1(iatom)%gpu_option==ABI_GPU_OPENMP)
     382                 :             :    !$OMP TARGET UPDATE FROM(mat2(iatom)%mat) IF(mat2(iatom)%gpu_option==ABI_GPU_OPENMP)
     383                 :             : #endif
     384         [ -  + ]:      443054 :    if (present(opt_diag)) then
     385         [ #  # ]:           0 :      do isppol=1,nsppol
     386         [ #  # ]:           0 :        do im=1,ndim
     387                 :           0 :          mat2(iatom)%mat(im,im,isppol) = mat1(iatom)%mat(im,im,isppol)
     388                 :             :        end do ! im
     389                 :             :      end do ! isppol
     390         [ -  + ]:      248252 :    else if (present(opt_non_diag)) then
     391         [ #  # ]:           0 :      do isppol=1,nsppol
     392         [ #  # ]:           0 :        do im1=1,ndim
     393         [ #  # ]:           0 :          do im=1,ndim
     394         [ #  # ]:           0 :            if (im /= im1) mat2(iatom)%mat(im,im1,isppol) = mat1(iatom)%mat(im,im1,isppol)
     395                 :             :          end do ! im
     396                 :             :        end do ! im1
     397                 :             :      end do ! isppol
     398         [ +  + ]:      248252 :    else if (present(opt_re)) then
     399   [ +  +  +  +  :     1787238 :      mat2(iatom)%mat(:,:,:) = cmplx(dble(mat1(iatom)%mat(:,:,:)),zero,kind=dp)
                   +  + ]
     400                 :             :    else
     401   [ +  +  +  +  :    24012946 :      mat2(iatom)%mat(:,:,:) = mat1(iatom)%mat(:,:,:)
                   +  + ]
     402                 :             :    end if ! opt
     403                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     404                 :             :    !$OMP TARGET UPDATE TO(mat2(iatom)%mat) IF(mat2(iatom)%gpu_option==ABI_GPU_OPENMP)
     405                 :             : #endif
     406                 :             : 
     407                 :             :  end do ! iatom
     408                 :             : 
     409                 :             : !   do iatom=1,natom
     410                 :             : !    lpawu=nmat1(iatom)%lpawu
     411                 :             : !    if(lpawu.ne.-1) then
     412                 :             : !     nmat2(iatom)%mat=nmat1(iatom)%mat
     413                 :             : !    endif
     414                 :             : !   enddo
     415                 :             : 
     416                 :      194802 : end subroutine copy_matlu
     417                 :             : !!***
     418                 :             : 
     419                 :             : !!****f* m_matlu/copy_matlu_from_ndat
     420                 :             : !! NAME
     421                 :             : !! copy_matlu_from_ndat
     422                 :             : !!
     423                 :             : !! FUNCTION
     424                 :             : !!  Copy matlu1 into matlu2
     425                 :             : !!
     426                 :             : !! INPUTS
     427                 :             : !!  maltu1 <type(matlu_type)>= density matrix matlu1 in the local orbital basis and related variables
     428                 :             : !!  natom = number of atoms
     429                 :             : !!
     430                 :             : !! OUTPUT
     431                 :             : !!  maltu2 <type(matlu_type)>= density matrix matlu2 in the local orbital basis and related variables
     432                 :             : !!
     433                 :             : !! SOURCE
     434                 :             : 
     435                 :           0 : subroutine copy_matlu_from_ndat(mat1,mat2,natom,ndat,idat,opt_diag,opt_non_diag,opt_re)
     436                 :             : 
     437                 :             : !Arguments ------------------------------------
     438                 :             : !type
     439                 :             :  integer, intent(in) :: natom,ndat,idat
     440                 :             :  type(matlu_type),intent(in) :: mat1(natom)
     441                 :             :  type(matlu_type),intent(inout) :: mat2(natom) !vz_i
     442                 :             :  integer, optional, intent(in) :: opt_diag,opt_non_diag,opt_re
     443                 :             : 
     444                 :             : !Local variables-------------------------------
     445                 :             :  integer :: iatom,isppol,im1,im,ndim,nsppol,nspinor,lpawu
     446                 :             : ! *********************************************************************
     447                 :             : 
     448         [ #  # ]:           0 :  ABI_CHECK(mat1(1)%nsppol==mat2(1)%nsppol*ndat, "bad ndat value")
     449                 :           0 :  nspinor = mat1(1)%nspinor
     450                 :           0 :  nsppol  = mat2(1)%nsppol
     451         [ #  # ]:           0 :  do iatom=1,natom
     452                 :           0 :    lpawu = mat1(iatom)%lpawu
     453         [ #  # ]:           0 :    if (lpawu == -1) cycle
     454                 :           0 :    ndim = (2*lpawu+1) * nspinor
     455                 :             : 
     456         [ #  # ]:           0 :    if (present(opt_diag)) then
     457         [ #  # ]:           0 :      do isppol=1,nsppol
     458         [ #  # ]:           0 :        do im=1,ndim
     459                 :           0 :          mat2(iatom)%mat(im,im,isppol) = mat1(iatom)%mat(im,im,(isppol-1)*ndat+idat)
     460                 :             :        end do ! im
     461                 :             :      end do ! isppol
     462         [ #  # ]:           0 :    else if (present(opt_non_diag)) then
     463         [ #  # ]:           0 :      do isppol=1,nsppol
     464         [ #  # ]:           0 :        do im1=1,ndim
     465         [ #  # ]:           0 :          do im=1,ndim
     466         [ #  # ]:           0 :            if (im /= im1) mat2(iatom)%mat(im,im1,isppol) = mat1(iatom)%mat(im,im1,(isppol-1)*ndat+idat)
     467                 :             :          end do ! im
     468                 :             :        end do ! im1
     469                 :             :      end do ! isppol
     470                 :             : 
     471         [ #  # ]:           0 :    else if (present(opt_re)) then
     472         [ #  # ]:           0 :      do isppol=1,nsppol
     473   [ #  #  #  # ]:           0 :        mat2(iatom)%mat(:,:,isppol) = cmplx(dble(mat1(iatom)%mat(:,:,(isppol-1)*ndat+idat)),zero,kind=dp)
     474                 :             :      end do ! isppol
     475                 :             :    else
     476         [ #  # ]:           0 :      do isppol=1,nsppol
     477   [ #  #  #  # ]:           0 :        mat2(iatom)%mat(:,:,isppol) = mat1(iatom)%mat(:,:,(isppol-1)*ndat+idat)
     478                 :             :      end do ! isppol
     479                 :             :    end if ! opt
     480                 :             :  enddo ! iatom
     481                 :             : 
     482                 :           0 : end subroutine copy_matlu_from_ndat
     483                 :             : !!***
     484                 :             : 
     485                 :             : !!****f* m_matlu/copy_matlu_to_ndat
     486                 :             : !! NAME
     487                 :             : !! copy_matlu_to_ndat
     488                 :             : !!
     489                 :             : !! FUNCTION
     490                 :             : !!  Copy matlu1 into matlu2
     491                 :             : !!
     492                 :             : !! INPUTS
     493                 :             : !!  maltu1 <type(matlu_type)>= density matrix matlu1 in the local orbital basis and related variables
     494                 :             : !!  natom = number of atoms
     495                 :             : !!
     496                 :             : !! OUTPUT
     497                 :             : !!  maltu2 <type(matlu_type)>= density matrix matlu2 in the local orbital basis and related variables
     498                 :             : !!
     499                 :             : !! SOURCE
     500                 :             : 
     501                 :           0 : subroutine copy_matlu_to_ndat(mat1,mat2,natom,ndat,idat,opt_diag,opt_non_diag,opt_re)
     502                 :             : 
     503                 :             : !Arguments ------------------------------------
     504                 :             : !type
     505                 :             :  integer, intent(in) :: natom,ndat,idat
     506                 :             :  type(matlu_type),intent(in) :: mat1(natom)
     507                 :             :  type(matlu_type),intent(inout) :: mat2(natom) !vz_i
     508                 :             :  integer, optional, intent(in) :: opt_diag,opt_non_diag,opt_re
     509                 :             : 
     510                 :             : !Local variables-------------------------------
     511                 :             :  integer :: iatom,isppol,im1,im,ndim,nsppol,nspinor,lpawu
     512                 :             : ! *********************************************************************
     513                 :             : 
     514                 :             : 
     515         [ #  # ]:           0 :  ABI_CHECK(mat1(1)%nsppol*ndat==mat2(1)%nsppol, "bad ndat value")
     516                 :           0 :  nspinor = mat1(1)%nspinor
     517                 :           0 :  nsppol  = mat1(1)%nsppol
     518         [ #  # ]:           0 :  do iatom=1,natom
     519                 :           0 :    lpawu = mat1(iatom)%lpawu
     520         [ #  # ]:           0 :    if (lpawu == -1) cycle
     521                 :           0 :    ndim = (2*lpawu+1) * nspinor
     522                 :             : 
     523         [ #  # ]:           0 :    if (present(opt_diag)) then
     524         [ #  # ]:           0 :      do isppol=1,nsppol
     525         [ #  # ]:           0 :        do im=1,ndim
     526                 :           0 :          mat2(iatom)%mat(im,im,(isppol-1)*ndat+idat) = mat1(iatom)%mat(im,im,isppol)
     527                 :             :        end do ! im
     528                 :             :      end do ! isppol
     529         [ #  # ]:           0 :    else if (present(opt_non_diag)) then
     530         [ #  # ]:           0 :      do isppol=1,nsppol
     531         [ #  # ]:           0 :        do im1=1,ndim
     532         [ #  # ]:           0 :          do im=1,ndim
     533         [ #  # ]:           0 :            if (im /= im1) mat2(iatom)%mat(im,im1,(isppol-1)*ndat+idat) = mat1(iatom)%mat(im,im1,isppol)
     534                 :             :          end do ! im
     535                 :             :        end do ! im1
     536                 :             :      end do ! isppol
     537                 :             : 
     538         [ #  # ]:           0 :    else if (present(opt_re)) then
     539         [ #  # ]:           0 :      do isppol=1,nsppol
     540   [ #  #  #  # ]:           0 :        mat2(iatom)%mat(:,:,(isppol-1)*ndat+idat) = cmplx(dble(mat1(iatom)%mat(:,:,isppol)),zero,kind=dp)
     541                 :             :      end do ! isppol
     542                 :             :    else
     543         [ #  # ]:           0 :      do isppol=1,nsppol
     544   [ #  #  #  # ]:           0 :        mat2(iatom)%mat(:,:,(isppol-1)*ndat+idat) = mat1(iatom)%mat(:,:,isppol)
     545                 :             :      end do ! isppol
     546                 :             :    end if ! opt
     547                 :             :  enddo ! iatom
     548                 :             : 
     549                 :           0 : end subroutine copy_matlu_to_ndat
     550                 :             : !!***
     551                 :             : 
     552                 :             : !!****f* m_matlu/print_matlu
     553                 :             : !! NAME
     554                 :             : !! print_matlu
     555                 :             : !!
     556                 :             : !! FUNCTION
     557                 :             : !!  Print matlu
     558                 :             : !!
     559                 :             : !! INPUTS
     560                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
     561                 :             : !!  natom= number of atoms
     562                 :             : !!  prtopt=   /=0   print matlu
     563                 :             : !!            >=5   print matlu in n,mx,my,mz representation
     564                 :             : !!  opt_diag=   0   print non diagonal matrix (real or complex according to nspinor)
     565                 :             : !!             -1   print non diagonal complex matrix
     566                 :             : !!            >=1   print diagonal matrix (real or complex according to nspinor)
     567                 :             : !!  opt_ab_out=  0  print matrix on std_out
     568                 :             : !!             /=0  print matrix on ab_out
     569                 :             : !!  opt_exp=        write in exponent format if present
     570                 :             : !!  argout=         output unit
     571                 :             : !!  compl=      1   print complex matrix
     572                 :             : !!            /=1   only print complex matrix if nspinor=2
     573                 :             : !!
     574                 :             : !! OUTPUT
     575                 :             : !!
     576                 :             : !! SOURCE
     577                 :             : 
     578                 :        5067 : subroutine print_matlu(matlu,natom,prtopt,opt_diag,opt_ab_out,opt_exp,argout,compl)
     579                 :             : 
     580                 :             : !Arguments ------------------------------------
     581                 :             :  integer, intent(in):: natom,prtopt
     582                 :             :  type(matlu_type), intent(in) :: matlu(natom)
     583                 :             :  integer, optional, intent(in) :: opt_diag,opt_ab_out,opt_exp,argout,compl
     584                 :             : !Local variables-------------------------------
     585                 :             :  integer :: arg_out,iatom,im,im1,ispinor,ispinor1,isppol,lpawu
     586                 :             :  integer :: ndim,nspinor,nsppol,optab_out,optdiag
     587                 :             :  logical :: testcmplx,testcmplx_
     588                 :        5067 :  complex(dp), allocatable :: mat_nmrep(:,:)
     589                 :             :  character(len=500) :: message
     590                 :             :  character(len=4) :: mode_paral,tag_at
     591                 :             :  character(len=9), parameter :: dspinm(2,2) = RESHAPE((/"n        ","mx       ","my       ","mz       "/),(/2,2/))
     592                 :             : ! *********************************************************************
     593                 :             : 
     594                 :        5067 :  arg_out    = ab_out
     595                 :        5067 :  mode_paral = 'COLL'
     596                 :        5067 :  optab_out  = 0
     597                 :        5067 :  optdiag    = 0
     598                 :             : 
     599         [ +  + ]:        5067 :  if (present(opt_diag)) optdiag = opt_diag
     600         [ +  + ]:        5067 :  if (present(opt_ab_out)) optab_out = opt_ab_out
     601         [ -  + ]:        5067 :  if (optab_out == 0) arg_out = std_out
     602                 :             : 
     603         [ -  + ]:        5067 :  if (present(argout)) then
     604                 :           0 :   arg_out    = argout
     605                 :           0 :   mode_paral = 'PERS'
     606                 :             :  end if
     607                 :             : 
     608                 :        5067 :  nspinor    = matlu(1)%nspinor
     609                 :        5067 :  nsppol     = matlu(1)%nsppol
     610                 :        5067 :  testcmplx_ = (nspinor == 2)
     611   [ +  +  +  +  :        5067 :  if (present(compl)) testcmplx_ = (nspinor == 2) .or. (compl == 1)
                   +  - ]
     612                 :             : 
     613         [ +  + ]:       21089 :  do iatom=1,natom
     614                 :             : 
     615                 :       16022 :    lpawu = matlu(iatom)%lpawu
     616         [ +  + ]:       16022 :    if (lpawu == -1) cycle
     617                 :        6191 :    ndim = 2*lpawu + 1
     618                 :             : 
     619                 :        6191 :    write(tag_at,'(i4)') iatom
     620                 :        6191 :    write(message,'(3a)') ch10,'   -------> For Correlated Atom ',adjustl(tag_at)
     621                 :        6191 :    call wrtout(arg_out,message,mode_paral)
     622                 :             : 
     623                 :        6191 :    testcmplx = testcmplx_
     624   [ +  +  +  +  :      403076 :    if (maxval(abs(aimag(matlu(iatom)%mat(:,:,:)))) > tol5) testcmplx = .true.
          +  +  +  +  +  
             -  +  -  +  
                      + ]
     625                 :             : 
     626                 :             :    !do isppol=1,nsppol
     627                 :             :    !  if (present(opt_ab_out) .and. nsppol == 2) then
     628                 :             :    !    noccspin = zero
     629                 :             :    !    do im=1,ndim
     630                 :             :    !      noccspin = noccspin + REAL(matlu(iatom)%mat(im,im,isppol))
     631                 :             :    !    end do
     632                 :             :        !write(message,fmt='(7x,a,i3,a,f10.5)') ". Occ. for lpawu and for spin",isppol," =",noccspin
     633                 :             :        !call wrtout(arg_out, message,mode_paral)
     634                 :             :    !  end if
     635                 :             :    !end do ! isppol
     636                 :             : 
     637         [ +  + ]:       20029 :    do isppol=1,nsppol
     638         [ +  + ]:        8771 :      if (nspinor == 1) then
     639                 :        7996 :        write(message,'(a,10x,a,1x,i1)') ch10,'-- polarization spin component',isppol
     640                 :        7996 :        call wrtout(arg_out,message,mode_paral)
     641                 :             :      end if ! nspinor=1
     642         [ +  + ]:       18317 :      do ispinor=1,nspinor
     643         [ +  + ]:       29413 :        do ispinor1=1,nspinor
     644         [ +  + ]:       11096 :          if (nspinor == 2) then
     645                 :        3100 :            write(message,'(a,10x,a,i1,1x,i1)') ch10,'-- spin components ',ispinor,ispinor1
     646                 :        3100 :            call wrtout(arg_out,message,mode_paral)
     647                 :             :          end if
     648         [ +  - ]:       20642 :          if (optdiag <= 0) then
     649         [ +  + ]:       70212 :            do im1=1,ndim
     650         [ +  + ]:       59116 :              if (optdiag == 0) then
     651   [ +  +  +  + ]:       52398 :                if ((.not. testcmplx) .and. (abs(prtopt) > 0)) then
     652         [ +  + ]:       21653 :                  if (present(opt_exp)) then
     653   [ +  -  +  + ]:        6328 :                    write(message,'(5x,20e24.14)') (dble(matlu(iatom)%mat(im1+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     654                 :             : !                  call wrtout(arg_out,  message,mode_paral)
     655                 :             : !                  write(message,'(5x,20e20.14)') (REAL(sqrt(matlu(iatom)%mat(m1,m,isppol,ispinor,ispinor1))),m=1,2*lpawu+1)
     656                 :             : !                  call wrtout(arg_out,  message,mode_paral)
     657                 :             : !                  write(message,'(5x,20e20.14)') (REAL(1.d0/sqrt(matlu(iatom)%mat(m,m,isppol,ispinor,ispinor1))),m=1,2*lpawu+1)
     658                 :             :                  else
     659   [ +  -  +  + ]:      122804 :                    write(message,'(5x,20f10.5)') (dble(matlu(iatom)%mat(im1+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     660                 :             :                  end if ! opt_exp
     661         [ +  - ]:       30673 :                else if (testcmplx .and. (abs(prtopt) > 0)) then
     662         [ +  + ]:       30673 :                  if (present(opt_exp)) then
     663         [ -  + ]:        2842 :                    if (opt_exp == 2) then
     664   [ #  #  #  # ]:           0 :                      write(message,'(5x,14(2e18.10,1x))') ((matlu(iatom)%mat(im1+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     665                 :             :                    else
     666   [ +  -  +  + ]:       18840 :                      write(message,'(5x,14(2e14.4,2x))') ((matlu(iatom)%mat(im1+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     667                 :             :                    end if ! opt_exp=2
     668                 :             :                  else
     669   [ +  -  +  + ]:      206500 :                    write(message,'(5x,14(2f9.5,2x))') ((matlu(iatom)%mat(im1+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     670                 :             :                  end if ! opt_exp
     671                 :             : !&               write(message,'(5x,14(2f15.11,2x))')((matlu(iatom)%mat(m1,m,isppol,ispinor,ispinor1)),m=1,2*lpawu+1)
     672                 :             :                end if ! testcmplx
     673         [ +  - ]:        6718 :              else if (optdiag == -1) then
     674   [ +  -  +  + ]:       44204 :                write(message,'(5x,14(2f10.5,2x))') ((matlu(iatom)%mat(im1+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     675                 :             :              end if ! optdiag
     676                 :       70212 :              call wrtout(arg_out,message,mode_paral)
     677                 :             :            end do ! im1
     678                 :             :          else if (optdiag >= 1) then
     679   [ #  #  #  # ]:           0 :            if ((.not. testcmplx) .and. (abs(prtopt) > 0)) write(message,'(5x,20f10.5)') &
     680   [ #  #  #  # ]:           0 :                & (dble(matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     681         [ #  # ]:           0 :            if (testcmplx .and. (abs(prtopt) > 0)) write(message,'(5x,14(2f9.5,2x))') &
     682   [ #  #  #  # ]:           0 :                & ((matlu(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor1-1)*ndim,isppol)),im=1,ndim)
     683                 :             : !            write(std_out,'(5x,14(2f9.5,2x))')((matlu(iatom)%mat(m1,m,isppol,ispinor,ispinor1)),m=1,2*lpawu+1)
     684                 :           0 :            call wrtout(arg_out,message,mode_paral)
     685                 :             :          end if ! optdiag
     686                 :             :        end do ! ispinor1
     687                 :             :      end do ! ispinor
     688   [ +  +  -  + ]:       24793 :      if (nspinor == 2 .and. prtopt >= 5) then
     689   [ #  #  #  #  :           0 :        ABI_MALLOC(mat_nmrep,(2*ndim,2*ndim)) ! Put matlu in n,mx,my,mz representation
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
     690         [ #  # ]:           0 :        do im=1,ndim
     691         [ #  # ]:           0 :          do im1=1,ndim
     692                 :           0 :            mat_nmrep(im1,im) = matlu(iatom)%mat(im1,im,isppol) + matlu(iatom)%mat(im1+ndim,im+ndim,isppol)  ! n
     693                 :           0 :            mat_nmrep(im1+ndim,im+ndim) = matlu(iatom)%mat(im1,im,isppol) - matlu(iatom)%mat(im1+ndim,im+ndim,isppol) ! mz
     694                 :           0 :            mat_nmrep(im1+ndim,im) = matlu(iatom)%mat(im1,im+ndim,isppol) + matlu(iatom)%mat(im1+ndim,im,isppol)  ! mx
     695                 :           0 :            mat_nmrep(im1,im+ndim) = (matlu(iatom)%mat(im1,im+ndim,isppol)-matlu(iatom)%mat(im+ndim,im,isppol)) * j_dpc ! my
     696                 :             :          end do ! im1
     697                 :             :        end do ! im
     698         [ #  # ]:           0 :        do ispinor=1,nspinor
     699         [ #  # ]:           0 :          do ispinor1=1,nspinor
     700                 :           0 :            write(message,'(a,10x,2a)') ch10,'-- spin components',dspinm(ispinor1,ispinor)
     701                 :           0 :            call wrtout(arg_out,message,mode_paral)
     702         [ #  # ]:           0 :            do im1=1,ndim
     703   [ #  #  #  # ]:           0 :              write(message,'(5x,14(2f9.5,2x))') ((mat_nmrep(im1+(ispinor1-1)*ndim,im+(ispinor-1)*ndim)),im=1,ndim)
     704                 :           0 :              call wrtout(arg_out,message,mode_paral)
     705                 :             :            end do ! im1
     706                 :             :          end do ! ispinor1
     707                 :             :        end do ! ispinor
     708         [ #  # ]:           0 :        ABI_FREE(mat_nmrep)
     709                 :             :      end if ! nspinor=2 and prtopt >=5
     710                 :             :    end do ! isppol
     711                 :             : !     if(nsppol==1.and.nspinor==1) then
     712                 :             : !       write(message,'(a,10x,a,i3,a)')  ch10,'-- polarization spin component',isppol+1,' is identical'
     713                 :             : !       call wrtout(arg_out,  message,mode_paral)
     714                 :             : !     endif
     715                 :             :  end do ! iatom
     716                 :             : 
     717                 :        5067 : end subroutine print_matlu
     718                 :             : !!***
     719                 :             : 
     720                 :             : !!****f* m_matlu/sym_matlu
     721                 :             : !! NAME
     722                 :             : !! sym_matlu
     723                 :             : !!
     724                 :             : !! FUNCTION
     725                 :             : !! Symmetrize local quantity.
     726                 :             : !!
     727                 :             : !! COPYRIGHT
     728                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
     729                 :             : !! This file is distributed under the terms of the
     730                 :             : !! GNU General Public License, see ~abinit/COPYING
     731                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
     732                 :             : !!
     733                 :             : !! INPUTS
     734                 :             : !!  gloc(natom) <type(matlu_type)>= density matrix in the local orbital basis and related variables
     735                 :             : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
     736                 :             : !!
     737                 :             : !! OUTPUT
     738                 :             : !!  gloc(natom) <type(matlu_type)>= density matrix symmetrized in the local orbital basis and related variables
     739                 :             : !!
     740                 :             : !! SIDE EFFECTS
     741                 :             : !!
     742                 :             : !! NOTES
     743                 :             : !! For nspinor==2, the density matrix is decomposed into the (n,mx,my,mz) representation
     744                 :             : !! by chg_repr_matlu. Under a symmetry operation R, the density component (mu=1) is invariant,
     745                 :             : !! while the magnetization components (mu=2..4) transform as an axial (pseudo-) vector:
     746                 :             : !! m -> det(R) * R_cart * m. The det(R) factor (computed from paw_dmft%symrec_cart, whose
     747                 :             : !! cartesian convention is identical to symrhoij_symcart of shared/libpaw/src/m_pawrhoij.F90,
     748                 :             : !! see pawrhoij_symrhoij) is folded into the local array symrot before symmetrization.
     749                 :             : !!
     750                 :             : !! SOURCE
     751                 :             : 
     752                 :       97522 :  subroutine sym_matlu(gloc,paw_dmft)
     753                 :             : 
     754                 :             : !Arguments ------------------------------------
     755                 :             :  type(paw_dmft_type), target, intent(in) :: paw_dmft
     756                 :             :  type(matlu_type), target, intent(inout) :: gloc(paw_dmft%natom)
     757                 :             : !Local variables-------------------------------
     758                 :             :  integer :: at_indx,iatom,irot,isppol,lpawu,m1,m2,mu,natom
     759                 :             :  integer :: ndim,ndim_max,nspinor,nsppol,nsym,nu,gpu_option
     760                 :       97522 :  complex(dp), target, allocatable :: gloc_tmp(:,:,:),gloc_tmp2(:,:,:)
     761                 :       97522 :  complex(dp), target, allocatable :: gloc_tmp3(:,:,:,:),gloc_tmp4(:,:,:,:)
     762                 :       97522 :  type(matlu_type), allocatable, target :: gloc_nmrep(:),glocsym(:)
     763                 :       97522 :  complex(dp), contiguous, pointer :: zarot(:,:,:,:),gloc_mat(:,:,:),glocsym_mat(:,:,:)
     764                 :       97522 :  real(dp), contiguous, pointer :: symrec_cart(:,:,:)
     765                 :             :  real(dp) :: det
     766                 :       97522 :  real(dp), allocatable :: symrot(:,:,:)
     767                 :             :  complex(dp) :: ratio
     768                 :             : 
     769                 :       97522 :  natom    = paw_dmft%natom
     770                 :       97522 :  ndim_max = 2*paw_dmft%maxlpawu + 1
     771                 :       97522 :  nspinor  = paw_dmft%nspinor
     772                 :       97522 :  nsppol   = gloc(1)%nsppol
     773                 :       97522 :  nsym     = paw_dmft%nsym
     774                 :       97522 :  gpu_option = gloc(1)%gpu_option
     775                 :       97522 :  zarot    => paw_dmft%zarot
     776                 :       97522 :  ratio = dcmplx(1.0_dp/nsym,0.0_dp)
     777                 :             : 
     778                 :             :  !zarot       => paw_dmft%zarot(:,1:ndim,irot,lpawu+1)
     779   [ +  -  +  -  :      471305 :  ABI_MALLOC(glocsym,(natom))
          +  -  -  +  -  
                +  +  + ]
     780                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     781                 :             :  !$OMP TARGET ENTER DATA MAP(alloc:zarot) IF(gpu_option==ABI_GPU_OPENMP)
     782                 :             :  !$OMP TARGET UPDATE TO(zarot) IF(gpu_option==ABI_GPU_OPENMP)
     783                 :             : #else
     784                 :             :   ABI_UNUSED((/m1,m2/))
     785                 :             : #endif
     786                 :             : 
     787                 :             : !=========  Case nspinor ==1 ========================
     788                 :             : 
     789         [ +  + ]:       97522 :  if (nspinor == 1) then
     790                 :             : 
     791   [ -  +  +  -  :      434015 :    ABI_MALLOC(gloc_tmp,(ndim_max,ndim_max*nsppol,nsym))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     792                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     793                 :             :    !$OMP TARGET ENTER DATA MAP(alloc:gloc_tmp) IF(gpu_option==ABI_GPU_OPENMP)
     794                 :             : #endif
     795                 :             : 
     796                 :       86803 :    call init_matlu(natom,nspinor,nsppol,paw_dmft%lpawu(:),glocsym(:),gpu_option=gpu_option)
     797                 :             : 
     798         [ +  + ]:      225153 :    do iatom=1,natom
     799                 :             : 
     800                 :      138350 :      lpawu = gloc(iatom)%lpawu
     801         [ +  + ]:      138350 :      if (lpawu == -1) cycle
     802                 :       88683 :      ndim = 2*lpawu + 1
     803                 :       88683 :      glocsym_mat => glocsym(iatom)%mat
     804                 :             : 
     805   [ -  +  +  -  :      443415 :      ABI_MALLOC(gloc_tmp2,(ndim,ndim*nsppol,nsym))
          -  +  +  -  -  
          +  +  -  +  -  
          +  -  -  +  -  
                      + ]
     806                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     807                 :             :      !$OMP TARGET ENTER DATA MAP(alloc:gloc_tmp2) IF(gpu_option==ABI_GPU_OPENMP)
     808                 :             : #endif
     809                 :             : 
     810                 :             : 
     811         [ +  - ]:       88683 :      if(gpu_option==ABI_GPU_DISABLED) then
     812                 :             : 
     813         [ +  + ]:     4241643 :        do irot=1,nsym
     814                 :     4152960 :          at_indx = paw_dmft%indsym(irot,iatom)
     815                 :     4152960 :          gloc_mat    => gloc(at_indx)%mat
     816                 :             : 
     817         [ +  + ]:    11637504 :          do isppol=1,nsppol
     818                 :             :            call abi_xgemm("n","n",ndim,ndim,ndim,cone,gloc_mat(:,:,isppol),ndim,&
     819                 :    11637504 :                         & zarot(:,1:ndim,irot,lpawu+1),ndim_max,czero,gloc_tmp(:,1+ndim*(isppol-1):ndim*isppol,irot),ndim_max)
     820                 :             :          end do ! isppol
     821                 :             : 
     822                 :             :          call abi_xgemm("t","n",ndim,ndim*nsppol,ndim,cone,zarot(:,1:ndim,irot,lpawu+1),ndim_max,&
     823                 :     4152960 :                       & gloc_tmp(:,:,irot),ndim_max,czero,gloc_tmp2(:,:,irot),ndim)
     824                 :             : 
     825         [ +  + ]:    11726187 :          do isppol=1,nsppol
     826   [ +  -  +  +  :   453796608 :            glocsym_mat(:,:,isppol) = glocsym_mat(:,:,isppol) + gloc_tmp2(:,1+ndim*(isppol-1):ndim*isppol,irot)
          +  +  +  +  +  
                      + ]
     827                 :             :          end do ! isppol
     828                 :             : 
     829                 :             :        end do ! irot
     830                 :             : 
     831   [ +  +  +  +  :     4984541 :        glocsym_mat(:,:,:) = glocsym_mat(:,:,:) / dble(nsym)
                   +  + ]
     832                 :             : 
     833                 :             :      else if(gpu_option==ABI_GPU_OPENMP) then
     834                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     835                 :             : 
     836                 :             :        do irot=1,nsym
     837                 :             :          at_indx = paw_dmft%indsym(irot,iatom)
     838                 :             :          gloc_mat    => gloc(at_indx)%mat
     839                 :             : 
     840                 :             :          !$OMP TARGET DATA USE_DEVICE_ADDR(gloc_tmp,zarot,gloc_mat)
     841                 :             :          call abi_gpu_xgemm_strided(2,"n","n",ndim,ndim,ndim,cone,&
     842                 :             :          &    c_loc(gloc_mat(:,:,:)),ndim,ndim*ndim,&
     843                 :             :          &    c_loc(zarot(:,1:ndim,irot,lpawu+1)),ndim_max,0,czero,&
     844                 :             :          &    c_loc(gloc_tmp(:,:,irot)),ndim_max,ndim*ndim,nsppol,async=.true.,stream_id=irot)
     845                 :             :          !$OMP END TARGET DATA
     846                 :             :        end do ! irot
     847                 :             :        call gpu_device_synchronize()
     848                 :             : 
     849                 :             :        !$OMP TARGET DATA USE_DEVICE_ADDR(gloc_tmp,zarot,gloc_tmp2)
     850                 :             :        call abi_gpu_xgemm_strided(2,"t","n",ndim,ndim*nsppol,ndim,cone,&
     851                 :             :        &    c_loc(zarot(:,:,:,lpawu+1)),ndim_max,ndim_max*ndim_max,&
     852                 :             :        &    c_loc(gloc_tmp(:,:,:)),ndim_max,ndim_max*ndim_max*nsppol,czero,&
     853                 :             :        &    c_loc(gloc_tmp2(:,:,:)),ndim,ndim*ndim*nsppol,nsym)
     854                 :             :        !$OMP END TARGET DATA
     855                 :             : 
     856                 :             :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:glocsym_mat,gloc_tmp2) PRIVATE(isppol)
     857                 :             :        do isppol=1,nsppol
     858                 :             :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(m1,m2,irot)
     859                 :             :          do m2=1,ndim
     860                 :             :            do m1=1,ndim
     861                 :             :              do irot=1,nsym
     862                 :             :                glocsym_mat(m1,m2,isppol) = glocsym_mat(m1,m2,isppol) + gloc_tmp2(m1,m2+ndim*(isppol-1),irot)
     863                 :             :              end do ! irot
     864                 :             :            end do ! m1
     865                 :             :          end do  ! m2
     866                 :             :        end do ! isppol
     867                 :             : 
     868                 :             :        call abi_xscal(ndim*ndim*nsppol, ratio, glocsym_mat, 1, gpu_option=gpu_option)
     869                 :             : 
     870                 :             : #endif
     871                 :             :      end if
     872                 :             : 
     873                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     874                 :             :      !$OMP TARGET EXIT DATA MAP(delete:gloc_tmp2) IF(gpu_option==ABI_GPU_OPENMP)
     875                 :             : #endif
     876         [ -  + ]:      225153 :      ABI_FREE(gloc_tmp2)
     877                 :             : 
     878                 :             :    end do ! iatom
     879                 :             : 
     880                 :             :    !==  Put glocsym into gloc
     881                 :       86803 :    call copy_matlu(glocsym(:),gloc(:),natom)
     882                 :             : 
     883                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     884                 :             :    !$OMP TARGET EXIT DATA MAP(delete:gloc_tmp) IF(gpu_option==ABI_GPU_OPENMP)
     885                 :             : #endif
     886         [ -  + ]:       86803 :    ABI_FREE(gloc_tmp)
     887                 :             : !=========  Case nspinor ==2 ========================
     888                 :             : 
     889                 :             :  else
     890                 :             : 
     891                 :       10719 :    symrec_cart => paw_dmft%symrec_cart(:,:,:)
     892                 :             : 
     893                 :             :    !== Fold the axial-vector det factor into the cartesian rotation matrices used
     894                 :             :    !== to symmetrize the magnetization: m -> det(R) * R_cart * m
     895   [ -  +  +  -  :       32157 :    ABI_MALLOC(symrot,(3,3,nsym))
          +  -  +  -  -  
                +  -  + ]
     896         [ +  + ]:      525231 :    do irot=1,nsym
     897                 :             :      det = symrec_cart(1,1,irot)*symrec_cart(2,2,irot)*symrec_cart(3,3,irot) &
     898                 :             :      &   + symrec_cart(2,1,irot)*symrec_cart(3,2,irot)*symrec_cart(1,3,irot) &
     899                 :             :      &   + symrec_cart(1,2,irot)*symrec_cart(2,3,irot)*symrec_cart(3,1,irot) &
     900                 :             :      &   - (symrec_cart(3,1,irot)*symrec_cart(2,2,irot)*symrec_cart(1,3,irot) &
     901                 :             :      &   +  symrec_cart(2,1,irot)*symrec_cart(1,2,irot)*symrec_cart(3,3,irot) &
     902                 :      514512 :      &   +  symrec_cart(3,2,irot)*symrec_cart(2,3,irot)*symrec_cart(1,1,irot))
     903   [ +  +  +  + ]:     6699375 :      symrot(:,:,irot) = dble(nint(det)) * symrec_cart(:,:,irot)
     904                 :             :    end do ! irot
     905                 :             : 
     906                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     907                 :             :    !$OMP TARGET ENTER DATA MAP(to:symrot) IF(gpu_option==ABI_GPU_OPENMP)
     908                 :             : #endif
     909                 :             :    !== Allocate temporary arrays
     910   [ -  +  +  -  :       61827 :    ABI_MALLOC(gloc_nmrep,(natom))
          -  +  -  +  +  
                      + ]
     911                 :       10719 :    call init_matlu(natom,1,4*nsppol,paw_dmft%lpawu(:),glocsym(:),gpu_option=gpu_option)
     912                 :       10719 :    call init_matlu(natom,1,4*nsppol,paw_dmft%lpawu(:),gloc_nmrep(:),gpu_option=gpu_option)
     913                 :             : 
     914                 :             :    ! Put gloc into gloc_nmrep (density and magnetization representation)
     915                 :             :    ! gloc_nmrep(iatom)%mat(:,:,i) = n,mx,my,mz for i=1,2,3,4 respectively
     916                 :       10719 :    call chg_repr_matlu(gloc(:),gloc_nmrep(:),natom,1,1)
     917                 :             : 
     918                 :             :   !==  Do the sum over symmetrized density matrix (in n,m repr)
     919         [ +  + ]:       51108 :    do iatom=1,natom
     920                 :             : 
     921                 :       40389 :      lpawu = gloc(iatom)%lpawu
     922         [ +  + ]:       40389 :      if (lpawu == -1) cycle
     923                 :       30499 :      ndim = 2*lpawu + 1
     924                 :       30499 :      glocsym_mat => glocsym(iatom)%mat
     925                 :             : 
     926                 :             : 
     927   [ -  +  +  -  :      213493 :      ABI_MALLOC(gloc_tmp3,(ndim,ndim,4*nsppol,nsym))
          -  +  +  -  +  
          -  -  +  +  -  
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     928   [ -  +  +  -  :      152495 :      ABI_MALLOC(gloc_tmp4,(ndim,ndim,4*nsppol,nsym))
          -  +  +  -  -  
          +  +  -  -  +  
          +  -  -  +  -  
                      + ]
     929                 :             : 
     930         [ +  - ]:       30499 :      if(gpu_option==ABI_GPU_DISABLED) then
     931         [ +  + ]:     1494451 :        do irot=1,nsym
     932                 :             : 
     933                 :     1463952 :          at_indx = paw_dmft%indsym(irot,iatom)
     934                 :     1463952 :          gloc_mat    => gloc_nmrep(at_indx)%mat
     935                 :             : 
     936         [ +  + ]:     2958403 :          do isppol=1,nsppol
     937         [ +  + ]:     8783712 :            do mu=1,4 ! Symmetrize density and magnetization
     938                 :             : 
     939                 :             :              call abi_xgemm("n","n",ndim,ndim,ndim,cone,gloc_mat(:,:,mu+(isppol-1)*4),ndim, &
     940                 :     7319760 :                           & zarot(:,1:ndim,irot,lpawu+1),ndim_max,czero,gloc_tmp3(:,:,mu+(isppol-1)*4,irot),ndim)
     941                 :             : 
     942                 :             :            end do ! mu
     943                 :             :          end do ! isppol
     944                 :             :        end do ! irot
     945                 :             : 
     946         [ +  + ]:     1494451 :        do irot=1,nsym
     947                 :             :          call abi_zgemm_2dd("t","n",ndim,ndim*4*nsppol,ndim,cone,zarot(:,1:ndim,irot,lpawu+1),ndim_max,&
     948                 :     1494451 :                       & gloc_tmp3(:,:,:,irot),ndim,czero,gloc_tmp4(:,:,:,irot),ndim)
     949                 :             : 
     950                 :             :        end do ! irot
     951                 :             : 
     952         [ +  + ]:     1494451 :        do irot=1,nsym
     953         [ +  + ]:     2958403 :          do isppol=1,nsppol
     954   [ +  -  +  +  :   166890528 :            glocsym_mat(:,:,1+(isppol-1)*4) = glocsym_mat(:,:,1+(isppol-1)*4) + gloc_tmp4(:,:,1+(isppol-1)*4,irot)
          +  +  +  +  +  
                      + ]
     955                 :             :          end do ! isppol
     956                 :             :        end do ! irot
     957                 :             : 
     958                 :             :          ! Symmetrize magnetization (axial vector: det factor folded in symrot)
     959                 :             : 
     960         [ +  + ]:     1494451 :        do irot=1,nsym
     961         [ +  + ]:     2958403 :          do isppol=1,nsppol
     962         [ +  + ]:     7319760 :            do nu=2,4
     963         [ +  + ]:    19031376 :              do mu=2,4
     964                 :             :                glocsym_mat(:,:,mu+(isppol-1)*4) = glocsym_mat(:,:,mu+(isppol-1)*4) + &
     965   [ +  -  +  +  :  1493231040 :                  &    symrot(mu-1,nu-1,irot)*gloc_tmp4(:,:,nu+(isppol-1)*4,irot)
          +  +  +  +  +  
                      + ]
     966                 :             :              end do ! mu
     967                 :             :            end do ! nu
     968                 :             :          end do ! isppol
     969                 :             :        end do ! irot
     970                 :             : 
     971                 :             :     !  ==  Normalize sum
     972   [ +  +  +  +  :     6984271 :        glocsym_mat(:,:,:) = glocsym_mat(:,:,:) / dble(nsym)
                   +  + ]
     973                 :             : 
     974                 :             :      else if(gpu_option==ABI_GPU_OPENMP) then
     975                 :             : #ifdef HAVE_OPENMP_OFFLOAD
     976                 :             :        !$OMP TARGET ENTER DATA MAP(alloc:gloc_tmp3,gloc_tmp4)
     977                 :             : 
     978                 :             :        do irot=1,nsym
     979                 :             : 
     980                 :             :          at_indx = paw_dmft%indsym(irot,iatom)
     981                 :             :          gloc_mat    => gloc_nmrep(at_indx)%mat
     982                 :             : 
     983                 :             :          !$OMP TARGET DATA USE_DEVICE_ADDR(gloc_tmp3,zarot,gloc_mat)
     984                 :             :          call abi_gpu_xgemm_strided(2,"n","n",ndim,ndim,ndim,cone,&
     985                 :             :          &    c_loc(gloc_mat(:,:,:)),ndim,ndim*ndim,&
     986                 :             :          &    c_loc(zarot(:,1:ndim,irot,lpawu+1)),ndim_max,0,czero,&
     987                 :             :          &    c_loc(gloc_tmp3(:,:,:,irot)),ndim,ndim*ndim,4*nsppol,async=.true.,stream_id=irot)
     988                 :             :          !$OMP END TARGET DATA
     989                 :             :        end do ! irot
     990                 :             :        call gpu_device_synchronize()
     991                 :             : 
     992                 :             : 
     993                 :             :        !$OMP TARGET DATA USE_DEVICE_ADDR(gloc_tmp3,zarot,gloc_tmp4)
     994                 :             :        call abi_gpu_xgemm_strided(2,"t","n",ndim,ndim*4*nsppol,ndim,cone,&
     995                 :             :        &    c_loc(zarot(:,:,:,lpawu+1)),ndim_max,ndim_max*ndim_max,&
     996                 :             :        &    c_loc(gloc_tmp3(:,:,:,:)),ndim,ndim*ndim*4*nsppol,czero,&
     997                 :             :        &    c_loc(gloc_tmp4(:,:,:,:)),ndim,ndim*ndim*4*nsppol,nsym)
     998                 :             :        !$OMP END TARGET DATA
     999                 :             : 
    1000                 :             : 
    1001                 :             :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:glocsym_mat,gloc_tmp4) PRIVATE(isppol)
    1002                 :             :        do isppol=1,nsppol
    1003                 :             :          !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(m1,m2,irot)
    1004                 :             :          do m2=1,ndim
    1005                 :             :            do m1=1,ndim
    1006                 :             :              do irot=1,nsym
    1007                 :             :                glocsym_mat(m1,m2,1+(isppol-1)*4) = glocsym_mat(m1,m2,1+(isppol-1)*4) + gloc_tmp4(m1,m2,1+(isppol-1)*4,irot)
    1008                 :             :              end do ! irot
    1009                 :             :            end do ! m1
    1010                 :             :          end do  ! m2
    1011                 :             :        end do ! isppol
    1012                 :             : 
    1013                 :             :          ! Symmetrize magnetization (axial vector: det factor folded in symrot)
    1014                 :             : 
    1015                 :             :        !$OMP TARGET TEAMS DISTRIBUTE MAP(to:glocsym_mat,gloc_tmp4,symrot) PRIVATE(isppol)
    1016                 :             :        do isppol=1,nsppol
    1017                 :             :          !$OMP PARALLEL DO COLLAPSE(3) PRIVATE(mu,m2,m1,irot,nu)
    1018                 :             :          do mu=2,4
    1019                 :             :            do m2=1,ndim
    1020                 :             :              do m1=1,ndim
    1021                 :             :                do irot=1,nsym
    1022                 :             :                  do nu=2,4
    1023                 :             :                    glocsym_mat(m1,m2,mu+(isppol-1)*4) = glocsym_mat(m1,m2,mu+(isppol-1)*4) + &
    1024                 :             :                    &    symrot(mu-1,nu-1,irot)*gloc_tmp4(m1,m2,nu+(isppol-1)*4,irot)
    1025                 :             :                  end do ! nu
    1026                 :             :                end do ! irot
    1027                 :             :              end do ! m1
    1028                 :             :            end do ! m2
    1029                 :             :          end do ! mu
    1030                 :             :        end do ! isppol
    1031                 :             : 
    1032                 :             :     !  ==  Normalize sum
    1033                 :             :        call abi_xscal(ndim*ndim*4*nsppol, ratio, glocsym_mat, 1, gpu_option=gpu_option)
    1034                 :             : 
    1035                 :             :        !$OMP TARGET EXIT DATA MAP(delete:gloc_tmp3,gloc_tmp4)
    1036                 :             : #endif
    1037                 :             :      end if ! gpu_option
    1038                 :             : 
    1039         [ -  + ]:       30499 :      ABI_FREE(gloc_tmp3)
    1040         [ -  + ]:       51108 :      ABI_FREE(gloc_tmp4)
    1041                 :             : 
    1042                 :             :    end do ! iatom
    1043                 :             : 
    1044                 :             : !==  Compute back density matrix in upup dndn updn dnup representation
    1045                 :       10719 :    call chg_repr_matlu(gloc(:),glocsym(:),natom,-1,1)
    1046                 :             : 
    1047                 :       10719 :    call destroy_matlu(gloc_nmrep(:),natom)
    1048   [ +  -  +  +  :       51108 :    ABI_FREE(gloc_nmrep)
             -  +  -  + ]
    1049                 :             : 
    1050                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1051                 :             :    !$OMP TARGET EXIT DATA MAP(delete:symrot) IF(gpu_option==ABI_GPU_OPENMP)
    1052                 :             : #endif
    1053         [ -  + ]:       10719 :    ABI_FREE(symrot)
    1054                 :             :   !==============end of nspinor=2 case ===========
    1055                 :             :  end if ! nspinor
    1056                 :             : 
    1057                 :       97522 :  call destroy_matlu(glocsym(:),natom)
    1058   [ +  -  +  +  :      276261 :  ABI_FREE(glocsym)
             -  +  -  + ]
    1059                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1060                 :             :  !$OMP TARGET EXIT DATA MAP(delete:zarot) IF(gpu_option==ABI_GPU_OPENMP)
    1061                 :             : #endif
    1062                 :             : 
    1063                 :             :  !mt2g(1)=1
    1064                 :             :  !mt2g(2)=2
    1065                 :             :  !mt2g(3)=4
    1066                 :             :  !mx2my2d=5
    1067                 :             :  !t2g=paw_dmft%dmftqmc_t2g
    1068                 :             :  !x2my2d=paw_dmft%dmftqmc_x2my2d
    1069                 :             : 
    1070                 :             : ! DBG_ENTER("COLL")
    1071                 :             : 
    1072                 :             :  !ci=cone
    1073                 :             :  !nspinor=gloc(1)%nspinor
    1074                 :             :  !nsppol=gloc(1)%nsppol
    1075                 :             :  !natom=cryst_struc%natom
    1076                 :             : 
    1077                 :             :  !ABI_MALLOC(glocnm,(natom))
    1078                 :             :  !ABI_MALLOC(glocnms,(natom))
    1079                 :             :  !ABI_MALLOC(glocsym,(natom))
    1080                 :             :  !ABI_MALLOC(lpawu_natom,(natom))
    1081                 :             :  !lpawu_natom(1:natom)=gloc(1:natom)%lpawu ! If gloc(1:natom)%lpawu is directly used in the next three lines, warnings are generated by some compilers.
    1082                 :             :  !call init_matlu(natom,nspinor,nsppol,lpawu_natom,glocnm)
    1083                 :             :  !call init_matlu(natom,nspinor,nsppol,lpawu_natom,glocnms)
    1084                 :             :  !call init_matlu(natom,nspinor,nsppol,lpawu_natom,glocsym)
    1085                 :             :  !ABI_FREE(lpawu_natom)
    1086                 :             : 
    1087                 :             : !=========  Case nspinor ==1 ========================
    1088                 :             : 
    1089                 :             :  !if (nspinor==1) then
    1090                 :             :  ! ispinor=1
    1091                 :             :  ! ispinor1=1
    1092                 :             :  ! do iatom=1,cryst_struc%natom
    1093                 :             :  !  do isppol=1,nsppol
    1094                 :             :  !   if(gloc(iatom)%lpawu/=-1) then
    1095                 :             :  !    lpawu=gloc(iatom)%lpawu
    1096                 :             :  !    do m1=1, 2*lpawu+1
    1097                 :             :  !     do m2=1, 2*lpawu+1
    1098                 :             :  !      do irot=1,cryst_struc%nsym
    1099                 :             :  !       at_indx=cryst_struc%indsym(4,irot,iatom)
    1100                 :             :  !       do m3=1, 2*lpawu+1
    1101                 :             :  !        do m4=1, 2*lpawu+1
    1102                 :             :  !         if(t2g==1) then
    1103                 :             :  !          m1s=mt2g(m1)
    1104                 :             :  !          m2s=mt2g(m2)
    1105                 :             :  !          m3s=mt2g(m3)
    1106                 :             :  !          m4s=mt2g(m4)
    1107                 :             :  !          lpawu_zarot=2
    1108                 :             :  !         else if (x2my2d==1) then
    1109                 :             :  !          m1s=mx2my2d
    1110                 :             :  !          m2s=mx2my2d
    1111                 :             :  !          m3s=mx2my2d
    1112                 :             :  !          m4s=mx2my2d
    1113                 :             :  !          lpawu_zarot=2
    1114                 :             :  !         else
    1115                 :             :  !          m1s=m1
    1116                 :             :  !          m2s=m2
    1117                 :             :  !          m3s=m3
    1118                 :             :  !          m4s=m4
    1119                 :             :  !          lpawu_zarot=lpawu
    1120                 :             :  !         endif
    1121                 :             :  !         zarot2=pawang%zarot(m3s,m1s,lpawu_zarot+1,irot)*pawang%zarot(m4s,m2s,lpawu_zarot+1,irot)
    1122                 :             :  !         glocsym(iatom)%mat(m1,m2,isppol,ispinor,ispinor1)=&
    1123                 :             : !&          glocsym(iatom)%mat(m1,m2,isppol,ispinor,ispinor1)&
    1124                 :             : !&          +gloc(at_indx)%mat(m3,m4,isppol,ispinor,ispinor1)*zarot2
    1125                 :             :  !        end do  ! m3
    1126                 :             :  !       end do  ! m4
    1127                 :             :  !      end do  ! irot
    1128                 :             :  !      glocsym(iatom)%mat(m1,m2,isppol,ispinor,ispinor1)=&
    1129                 :             : !&       glocsym(iatom)%mat(m1,m2,isppol,ispinor,ispinor1)/real(cryst_struc%nsym,kind=dp)
    1130                 :             : !      end do ! m2
    1131                 :             : !     end do ! m1
    1132                 :             : !    endif ! lpawu/=-1
    1133                 :             : !   end do ! isppol
    1134                 :             : !  end do ! iatom
    1135                 :             : !==  Put glocsym into gloc
    1136                 :             : !  do iatom=1,cryst_struc%natom
    1137                 :             : !    if(gloc(iatom)%lpawu/=-1) then
    1138                 :             : !      gloc(iatom)%mat=glocsym(iatom)%mat
    1139                 :             : !      gloc(iatom)%mat(:,:,1,:,:)=(glocsym(iatom)%mat(:,:,1,:,:) &
    1140                 :             : !&      + glocsym(iatom)%mat(:,:,2,:,:))/two
    1141                 :             : !      gloc(iatom)%mat(:,:,2,:,:)= gloc(iatom)%mat(:,:,1,:,:)
    1142                 :             : !      write(std_out,*) "WARNING: SYM non mag"
    1143                 :             : !      write(ab_out,*) "WARNING: SYM non mag"
    1144                 :             : !    endif
    1145                 :             : !  end do ! iatom
    1146                 :             : 
    1147                 :             : !=========  Case nspinor ==2 ========================
    1148                 :             : 
    1149                 :             : ! else if (nspinor==2) then
    1150                 :             : 
    1151                 :             : !== Allocate temporary arrays
    1152                 :             : !  do iatom=1,cryst_struc%natom
    1153                 :             : !   if(gloc(iatom)%lpawu/=-1) then
    1154                 :             : !    ndim=2*gloc(iatom)%lpawu+1
    1155                 :             : !    ABI_FREE(glocnm(iatom)%mat)
    1156                 :             : !    ABI_FREE(glocnms(iatom)%mat)
    1157                 :             : !    ABI_FREE(glocsym(iatom)%mat)
    1158                 :             : !    ABI_MALLOC(glocnm(iatom)%mat,(ndim,ndim,nsppol,4,1))
    1159                 :             : !    ABI_MALLOC(glocnms(iatom)%mat,(ndim,ndim,nsppol,4,1))
    1160                 :             : !    ABI_MALLOC(glocsym(iatom)%mat,(ndim,ndim,nsppol,2,2))
    1161                 :             : !   endif
    1162                 :             : !  enddo
    1163                 :             : !  ABI_MALLOC(symrec_cart,(3,3,cryst_struc%nsym))
    1164                 :             : 
    1165                 :             : !==  Compute symrec_cart
    1166                 :             : !  do irot=1,cryst_struc%nsym
    1167                 :             : !   call symredcart(cryst_struc%gprimd,cryst_struc%rprimd,symrec_cart(:,:,irot),cryst_struc%symrec(:,:,irot))
    1168                 :             : !  end do
    1169                 :             : 
    1170                 :             : !==  Compute density matrix in density and magnetization representation
    1171                 :             :  ! call chg_repr_matlu(gloc,glocnm,cryst_struc%natom,option=1,prtopt=1)
    1172                 :             : 
    1173                 :             : !==  Do the sum over symetrized density matrix (in n,m repr)
    1174                 :             : !  isppol=1
    1175                 :             : !  do iatom=1,cryst_struc%natom
    1176                 :             : !   if(gloc(iatom)%lpawu/=-1) then
    1177                 :             : !    lpawu=gloc(iatom)%lpawu
    1178                 :             : !    ndim=2*gloc(iatom)%lpawu+1
    1179                 :             : !    do m1=1, 2*lpawu+1
    1180                 :             : !     do m2=1, 2*lpawu+1
    1181                 :             : !      sumrho=czero
    1182                 :             : !      rotmag=czero
    1183                 :             : !      do irot=1,cryst_struc%nsym
    1184                 :             : !       summag=czero
    1185                 :             : !       at_indx=cryst_struc%indsym(4,irot,iatom)
    1186                 :             : !       do m3=1, 2*lpawu+1
    1187                 :             : !        do m4=1, 2*lpawu+1
    1188                 :             : !          if(t2g==1) then
    1189                 :             : !           m1s=mt2g(m1)
    1190                 :             : !           m2s=mt2g(m2)
    1191                 :             : !           m3s=mt2g(m3)
    1192                 :             : !           m4s=mt2g(m4)
    1193                 :             : !           lpawu_zarot=2
    1194                 :             : !!          else if (x2my2d==1) then
    1195                 :             : !           m1s=mx2my2d
    1196                 :             : !           m2s=mx2my2d
    1197                 :             : !           m3s=mx2my2d
    1198                 :             : !           m4s=mx2my2d
    1199                 :             : !           lpawu_zarot=2
    1200                 :             : !          else
    1201                 :             : !           m1s=m1
    1202                 :             : !           m2s=m2
    1203                 :             : !           m3s=m3
    1204                 :             : !           m4s=m4
    1205                 :             : !           lpawu_zarot=lpawu
    1206                 :             : !          endif
    1207                 :             : !         zarot2=pawang%zarot(m3s,m2s,lpawu_zarot+1,irot)*pawang%zarot(m4s,m1s,lpawu_zarot+1,irot)
    1208                 :             : !         sumrho=sumrho +  glocnm(at_indx)%mat(m4,m3,isppol,1,1)  * zarot2
    1209                 :             : !         do mu=1,3
    1210                 :             : !          summag(mu)=summag(mu) + glocnm(at_indx)%mat(m4,m3,isppol,mu+1,1) * zarot2
    1211                 :             : !         enddo
    1212                 :             : !        end do ! m3
    1213                 :             : !       end do !m4
    1214                 :             : 
    1215                 :             : !       ==  special case of magnetization
    1216                 :             :  !      do nu=1,3
    1217                 :             :  !       do mu=1,3
    1218                 :             :  !        rotmag(mu)=rotmag(mu)+symrec_cart(mu,nu,irot)*summag(nu)
    1219                 :             :  !       end do
    1220                 :             :  !      end do
    1221                 :             : !      write(std_out,'(a,3i4,2x,3(2f10.5,2x))') "rotmag",irot,m1,m2,(rotmag(mu),mu=1,3)
    1222                 :             :  !     end do ! irot
    1223                 :             : 
    1224                 :             : !       ==  Normalizes sum
    1225                 :             :  !     sumrho=sumrho/real(cryst_struc%nsym,kind=dp)
    1226                 :             : !        sumrho=glocnm(isppol,1,iatom,m1,m2) ! test without sym
    1227                 :             :  !     glocnms(iatom)%mat(m1,m2,isppol,1,1)=sumrho
    1228                 :             :  !     do mu=1,3
    1229                 :             :  !      rotmag(mu)=rotmag(mu)/real(cryst_struc%nsym,kind=dp)
    1230                 :             : !          rotmag(mu)=glocnm(isppol,mu+1,iatom,m1,m2) ! test without sym
    1231                 :             :  !      glocnms(iatom)%mat(m1,m2,isppol,mu+1,1)=rotmag(mu)
    1232                 :             :  !     enddo
    1233                 :             :  !    end do  ! m2
    1234                 :             :  !   end do ! m1
    1235                 :             :  !  endif ! lpawu/=-1
    1236                 :             :  ! end do ! iatom
    1237                 :             : 
    1238                 :             : !==  Compute back density matrix in upup dndn updn dnup representation
    1239                 :             :  ! call chg_repr_matlu(glocsym,glocnms,cryst_struc%natom,option=-1,prtopt=1)
    1240                 :             : 
    1241                 :             : !==  Put glocsym into gloc
    1242                 :             : !  do iatom=1,cryst_struc%natom
    1243                 :             : !    if(gloc(iatom)%lpawu/=-1) then
    1244                 :             : !      gloc(iatom)%mat=glocsym(iatom)%mat
    1245                 :             : !      gloc(iatom)%mat(:,:,1,:,:)=(glocsym(iatom)%mat(:,:,1,:,:) &
    1246                 :             : !&      + glocsym(iatom)%mat(:,:,2,:,:))/two
    1247                 :             : !      gloc(iatom)%mat(:,:,2,:,:)= gloc(iatom)%mat(:,:,1,:,:)
    1248                 :             : !      write(std_out,*) "WARNING: SYM non mag"
    1249                 :             : !      write(ab_out,*) "WARNING: SYM non mag"
    1250                 :             : !    endif
    1251                 :             : !  end do ! iatom
    1252                 :             : 
    1253                 :             : !  ABI_FREE(symrec_cart)
    1254                 :             : ! endif
    1255                 :             : 
    1256                 :             : ! call destroy_matlu(glocnm,cryst_struc%natom)
    1257                 :             : ! call destroy_matlu(glocnms,cryst_struc%natom)
    1258                 :             : ! call destroy_matlu(glocsym,cryst_struc%natom)
    1259                 :             : ! ABI_FREE(glocnm)
    1260                 :             : ! ABI_FREE(glocnms)
    1261                 :             : ! ABI_FREE(glocsym)
    1262                 :             : 
    1263         [ -  + ]:       97522 :  end subroutine sym_matlu
    1264                 :             : !!***
    1265                 :             : 
    1266                 :             : !!****f* m_matlu/inverse_matlu
    1267                 :             : !! NAME
    1268                 :             : !! inverse_matlu
    1269                 :             : !!
    1270                 :             : !! FUNCTION
    1271                 :             : !! Inverse local quantity.
    1272                 :             : !!
    1273                 :             : !! COPYRIGHT
    1274                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    1275                 :             : !! This file is distributed under the terms of the
    1276                 :             : !! GNU General Public License, see ~abinit/COPYING
    1277                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    1278                 :             : !!
    1279                 :             : !! INPUTS
    1280                 :             : !!  matlu(natom) :: input quantity to inverse
    1281                 :             : !!  natom=number of atoms in cell.
    1282                 :             : !!
    1283                 :             : !! OUTPUT
    1284                 :             : !!  matlu(natom) :: inverse of input matrix
    1285                 :             : !!
    1286                 :             : !! SIDE EFFECTS
    1287                 :             : !!
    1288                 :             : !! NOTES
    1289                 :             : !!
    1290                 :             : !! SOURCE
    1291                 :             : 
    1292                 :       53841 :  subroutine inverse_matlu(matlu,natom)
    1293                 :             : 
    1294                 :             : !Arguments ------------------------------------
    1295                 :             :  integer, intent(in) :: natom
    1296                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    1297                 :             : !Local variables-------------------------------
    1298                 :             :  integer :: iatom,isppol,lpawu,ndim,nspinor,nsppol
    1299                 :             :  !************************************************************************
    1300                 :             : 
    1301                 :       53841 :  nspinor = matlu(1)%nspinor
    1302                 :       53841 :  nsppol  = matlu(1)%nsppol
    1303                 :             : 
    1304         [ +  + ]:      152026 :  do iatom=1,natom
    1305                 :       98185 :    lpawu = matlu(iatom)%lpawu
    1306         [ +  + ]:       98185 :    if (lpawu == -1) cycle
    1307                 :       66177 :    ndim = nspinor * (2*lpawu+1)
    1308         [ +  + ]:      227856 :    do isppol=1,nsppol
    1309                 :      206023 :      call xginv(matlu(iatom)%mat(:,:,isppol),ndim)
    1310                 :             :    end do ! isppol
    1311                 :             :  end do ! iatom
    1312                 :             : 
    1313                 :             :  !if(prtopt>0) then
    1314                 :             :  !endif
    1315                 :             :  !ABI_MALLOC(gathermatlu,(natom))
    1316                 :             :  !do iatom=1,natom
    1317                 :             :  !  if(matlu(iatom)%lpawu.ne.-1) then
    1318                 :             :  !    tndim=nsppol*nspinor*(2*matlu(iatom)%lpawu+1)
    1319                 :             :  !    ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
    1320                 :             :  !    gathermatlu(iatom)%value=czero
    1321                 :             :  !  endif
    1322                 :             :  !enddo
    1323                 :             : 
    1324                 :             :  !call gather_matlu(matlu,gathermatlu,natom,option=1,prtopt=1)
    1325                 :             :  !do iatom=1,natom
    1326                 :             :  !  if(matlu(iatom)%lpawu.ne.-1) then
    1327                 :             :  !    tndim=nsppol*nspinor*(2*matlu(iatom)%lpawu+1)
    1328                 :             :      !call matcginv_dpc(gathermatlu(iatom)%value,tndim,tndim)
    1329                 :             :  !    call xginv(gathermatlu(iatom)%value,tndim)
    1330                 :             :  !  endif
    1331                 :             :  !enddo
    1332                 :             :  !call gather_matlu(matlu,gathermatlu,natom,option=-1,prtopt=1)
    1333                 :             : 
    1334                 :             :  !do iatom=1,natom
    1335                 :             :  !  if(matlu(iatom)%lpawu.ne.-1) then
    1336                 :             :  !    ABI_FREE(gathermatlu(iatom)%value)
    1337                 :             :  !  endif
    1338                 :             :  !enddo
    1339                 :             :  !ABI_FREE(gathermatlu)
    1340                 :             : 
    1341                 :       53841 :  end subroutine inverse_matlu
    1342                 :             : !!***
    1343                 :             : 
    1344                 :             : !!****f* m_matlu/diff_matlu
    1345                 :             : !! NAME
    1346                 :             : !! diff_matlu
    1347                 :             : !!
    1348                 :             : !! FUNCTION
    1349                 :             : !!
    1350                 :             : !! INPUTS
    1351                 :             : !!  char1 = character describing matlu1
    1352                 :             : !!  char2 = character describing matlu2
    1353                 :             : !!  matlu1(natom) <type(matlu_type)>= density matrix 1 in the local orbital basis and related variables
    1354                 :             : !!  matlu2(natom) <type(matlu_type)>= density matrix 2 in the local orbital basis and related variables
    1355                 :             : !!  natom = number of atoms
    1356                 :             : !!  option =1      if diff > toldiff , stop
    1357                 :             : !!          0      print diff and toldiff
    1358                 :             : !!          else   do not test and do not print
    1359                 :             : !!  toldiff = threshold for the difference between matlu1 and matlu2
    1360                 :             : !!  zero_or_one = useful when comparing the overlap of Wannier functions at one kpt with the identity
    1361                 :             : !!
    1362                 :             : !! OUTPUT
    1363                 :             : !!  ierr = 0 if diff < toldiff
    1364                 :             : !!       = -1 otherwise
    1365                 :             : !!
    1366                 :             : !! SOURCE
    1367                 :             : 
    1368                 :         966 : subroutine diff_matlu(char1,char2,matlu1,matlu2,natom,option,toldiff,ierr,zero_or_one)
    1369                 :             : 
    1370                 :             : !Arguments ------------------------------------
    1371                 :             :  integer, intent(in) :: natom,option
    1372                 :             :  type(matlu_type), intent(in) :: matlu1(natom),matlu2(natom)
    1373                 :             :  character(len=*), intent(in) :: char1,char2
    1374                 :             :  real(dp), intent(in) :: toldiff
    1375                 :             :  integer, optional, intent(out) :: ierr
    1376                 :             :  integer, optional, intent(in) :: zero_or_one
    1377                 :             : !Local variables-------------------------------
    1378                 :             :  integer  :: iatom,idiff,lpawu,nspinor,nsppol
    1379                 :             :  real(dp) :: matludiff
    1380                 :             :  character(len=500) :: message
    1381                 :             : ! *********************************************************************
    1382                 :             : 
    1383         [ +  + ]:         966 :  if (option /= 1 .and. option /= 0) return
    1384                 :             : 
    1385                 :         934 :  idiff     = 0
    1386                 :         934 :  matludiff = zero
    1387                 :         934 :  nspinor   = matlu1(1)%nspinor
    1388                 :         934 :  nsppol    = matlu1(1)%nsppol
    1389                 :             : 
    1390         [ +  + ]:        4064 :  do iatom=1,natom
    1391                 :        3130 :    lpawu = matlu1(iatom)%lpawu
    1392         [ +  + ]:        3130 :    if (lpawu == -1) cycle
    1393   [ +  +  +  +  :       55589 :    matludiff = matludiff + sum(abs(matlu1(iatom)%mat(:,:,:)-matlu2(iatom)%mat(:,:,:)))
                   +  + ]
    1394                 :        4064 :    idiff = idiff + (2*lpawu+1)**2
    1395                 :             :  end do ! iatom
    1396                 :         934 :  idiff = idiff * (nspinor**2) * nsppol
    1397                 :             : 
    1398         [ +  + ]:         934 :  if (.not. present(zero_or_one)) matludiff = matludiff / dble(idiff)
    1399                 :             : 
    1400         [ +  + ]:         934 :  if (matludiff < toldiff) then
    1401                 :         857 :    write(message,'(5a,6x,3a,4x,e12.4,a,e12.4)') ch10,'   ** Differences between ',trim(char1),' and ',&
    1402                 :        1714 :      & ch10,trim(char2),' are small enough:',ch10,matludiff,' is lower than',toldiff
    1403                 :         857 :    call wrtout(std_out,message,'COLL')
    1404         [ +  + ]:         857 :    if (present(ierr)) ierr = 0
    1405                 :             :  else
    1406                 :          77 :    write(message,'(5a,3x,3a,3x,e12.4,a,e12.4)') ch10,'Differences between ',trim(char1),' and ',&
    1407                 :         154 :      & ch10,trim(char2),' is too large:',ch10,matludiff,' is larger than',toldiff
    1408                 :          77 :    ABI_WARNING(message)
    1409                 :             : !    write(message,'(8a,4x,e12.4,a,e12.4)') ch10,"  Matrix for ",trim(char1)
    1410                 :          77 :    write(message,'(a,3x,a)') ch10,trim(char1)
    1411                 :          77 :    call wrtout(std_out,message,'COLL')
    1412                 :          77 :    call print_matlu(matlu1(:),natom,1,opt_diag=-1)
    1413                 :          77 :    write(message,'(a,3x,a)') ch10,trim(char2)
    1414                 :          77 :    call wrtout(std_out,message,'COLL')
    1415                 :          77 :    call print_matlu(matlu2(:),natom,1,opt_diag=-1)
    1416   [ -  +  -  - ]:          77 :    if (present(zero_or_one) .and. (mod(matludiff,one) < toldiff)) then
    1417                 :           0 :      write(message,'(a,3x,a)') ch10," The norm is not identity for this k-point &
    1418                 :           0 :         & but is compatible with a high symmetry point"
    1419                 :           0 :      call wrtout(std_out,message,'COLL')
    1420                 :             :    else if (present(zero_or_one)) then
    1421                 :           0 :      write(message,'(a,3x,a)') ch10," The norm is not identity for this k-point but might be compatible &
    1422                 :           0 :        & with a high symmetry point: it should be checked"
    1423                 :           0 :      call wrtout(std_out,message,'COLL')
    1424         [ -  + ]:          77 :    else if (option == 1) then
    1425                 :           0 :      call flush_unit(std_out)
    1426                 :           0 :      write(message,'(5a,6x,3a,4x,e12.4,a,e12.4)') ch10,'   ** Differences between ',trim(char1),' and ',&
    1427                 :           0 :        & ch10,trim(char2),' are too high:',ch10,matludiff,' is greater than',toldiff
    1428                 :           0 :      ABI_ERROR(message)
    1429                 :             :    end if ! zero_or_one
    1430         [ +  + ]:          77 :    if (present(ierr)) ierr = -1
    1431                 :             :  end if ! matludiff < toldiff
    1432                 :             : 
    1433                 :             : end subroutine diff_matlu
    1434                 :             : !!***
    1435                 :             : 
    1436                 :             : !!****f* m_matlu/add_matlu
    1437                 :             : !! NAME
    1438                 :             : !! add_matlu
    1439                 :             : !!
    1440                 :             : !! FUNCTION
    1441                 :             : !!
    1442                 :             : !! INPUTS
    1443                 :             : !!  matlu1 <type(matlu_type)>= density matrix matlu1 in the local orbital basis and related variables
    1444                 :             : !!  matlu2 <type(matlu_type)>= density matrix matlu2 in the local orbital basis and related variables
    1445                 :             : !!  natom = number of atoms
    1446                 :             : !!  sign_matlu2= 1 add matlu1 and matlu2
    1447                 :             : !!              -1 substract matlu2 to matlu1
    1448                 :             : !!
    1449                 :             : !! OUTPUT
    1450                 :             : !!  matlu3 <type(matlu_type)>= density matrix matlu3, sum/substract matlu1 and matlu2
    1451                 :             : !!
    1452                 :             : !! SOURCE
    1453                 :             : 
    1454                 :     1018099 : subroutine add_matlu(matlu1,matlu2,matlu3,natom,sign_matlu2,idat,ndat)
    1455                 :             : 
    1456                 :             : !Arguments ------------------------------------
    1457                 :             :  integer, intent(in) :: natom,sign_matlu2
    1458                 :             :  integer, optional,intent(in) :: idat,ndat
    1459                 :             :  type(matlu_type), intent(in) :: matlu1(natom),matlu2(natom)
    1460                 :             :  type(matlu_type), intent(inout) :: matlu3(natom) !vz_i
    1461                 :             : !Local variables-------------------------------
    1462                 :             :  integer :: iatom,lpawu,isppol
    1463                 :             : ! *********************************************************************
    1464                 :             : 
    1465         [ +  - ]:     1018099 :  if(present(idat) .and. present(ndat)) then
    1466         [ #  # ]:           0 :    do iatom=1,natom
    1467                 :           0 :      lpawu = matlu1(iatom)%lpawu
    1468         [ #  # ]:           0 :      if (lpawu == -1) cycle
    1469         [ #  # ]:           0 :      do isppol=1,matlu1(iatom)%nsppol
    1470         [ #  # ]:           0 :        if (sign_matlu2 == 1) then
    1471   [ #  #  #  # ]:           0 :          matlu3(iatom)%mat(:,:,(isppol-1)*ndat+idat) = matlu1(iatom)%mat(:,:,isppol) + matlu2(iatom)%mat(:,:,isppol)
    1472         [ #  # ]:           0 :        else if (sign_matlu2 == -1) then
    1473   [ #  #  #  # ]:           0 :          matlu3(iatom)%mat(:,:,(isppol-1)*ndat+idat) = matlu1(iatom)%mat(:,:,isppol) - matlu2(iatom)%mat(:,:,isppol)
    1474                 :             :        end if
    1475                 :             :      end do ! isppol
    1476                 :             :    end do ! iatom
    1477                 :             :  else
    1478         [ +  + ]:     3305648 :    do iatom=1,natom
    1479                 :     2287549 :      lpawu = matlu1(iatom)%lpawu
    1480         [ +  + ]:     2287549 :      if (lpawu == -1) cycle
    1481         [ +  + ]:     2144932 :      if (sign_matlu2 == 1) then
    1482   [ +  +  +  +  :     2712388 :        matlu3(iatom)%mat(:,:,:) = matlu1(iatom)%mat(:,:,:) + matlu2(iatom)%mat(:,:,:)
                   +  + ]
    1483         [ +  - ]:     1107932 :      else if (sign_matlu2 == -1) then
    1484   [ +  +  +  +  :    75876735 :        matlu3(iatom)%mat(:,:,:) = matlu1(iatom)%mat(:,:,:) - matlu2(iatom)%mat(:,:,:)
                   +  + ]
    1485                 :             :      end if
    1486                 :             :    end do ! iatom
    1487                 :             :  end if
    1488                 :             : 
    1489                 :     1018099 : end subroutine add_matlu
    1490                 :             : !!***
    1491                 :             : 
    1492                 :             : !!****f* m_matlu/chg_repr_matlu
    1493                 :             : !! NAME
    1494                 :             : !! chg_repr_matlu
    1495                 :             : !!
    1496                 :             : !! FUNCTION
    1497                 :             : !! Change representation of density matrix (useful for nspinor=2)
    1498                 :             : !!
    1499                 :             : !! COPYRIGHT
    1500                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    1501                 :             : !! This file is distributed under the terms of the
    1502                 :             : !! GNU General Public License, see ~abinit/COPYING
    1503                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    1504                 :             : !!
    1505                 :             : !! INPUTS
    1506                 :             : !!  glocspsp(natom) :: density matrix in the spin spin representation
    1507                 :             : !!  glocnm(natom) :: density matrix in the magnetization representation
    1508                 :             : !!  natom=number of atoms in cell.
    1509                 :             : !!  option=  1 glocspsp is input, glocnm is computed
    1510                 :             : !!        = -1 glocspsp is computed, glocnm is input
    1511                 :             : !!  prtopt= abs(prtopt) >= 3 : print in magnetization representation
    1512                 :             : !!
    1513                 :             : !! OUTPUT
    1514                 :             : !!  glocspsp(natom) :: density matrix in the spin spin representation
    1515                 :             : !!  glocnm(natom) :: density matrix in the magnetization representation
    1516                 :             : !!
    1517                 :             : !! SIDE EFFECTS
    1518                 :             : !!
    1519                 :             : !! NOTES
    1520                 :             : !!
    1521                 :             : !! SOURCE
    1522                 :             : 
    1523                 :       21438 :  subroutine chg_repr_matlu(glocspsp,glocnm,natom,option,prtopt)
    1524                 :             : 
    1525                 :             : !Arguments ------------------------------------
    1526                 :             :  integer, intent(in) :: natom,option,prtopt
    1527                 :             :  type(matlu_type), intent(inout), target :: glocnm(natom),glocspsp(natom)
    1528                 :             : !Local variables-------------------------------
    1529                 :             :  integer :: iatom,lpawu,m1,m2,mu,ndim,nsppol,isppol,gpu_option
    1530                 :       21438 :  complex(dp), contiguous, pointer :: glocnm_mat(:,:,:),glocspsp_mat(:,:,:)
    1531                 :             :  character(len=500) :: message
    1532                 :             : 
    1533                 :             : ! DBG_ENTER("COLL")
    1534                 :           0 :  ABI_CHECK(glocspsp(1)%nsppol*4==glocnm(1)%nsppol, "Mismatch in nsppol between glocspsp and glocnm")
    1535         [ -  + ]:       21438 :  ABI_CHECK(glocspsp(1)%gpu_option==glocnm(1)%gpu_option, "Mismatch in gpu_option between glocspsp and glocnm")
    1536                 :       21438 :  nsppol=glocspsp(1)%nsppol
    1537                 :       21438 :  gpu_option=glocspsp(1)%gpu_option
    1538                 :             : 
    1539                 :             : !==  Compute density matrix in density magnetization representation
    1540         [ +  + ]:       21438 :  if (option == 1) then
    1541         [ +  + ]:       51108 :    do iatom=1,natom
    1542                 :       40389 :      lpawu = glocspsp(iatom)%lpawu
    1543         [ +  + ]:       40389 :      if (lpawu == -1) cycle
    1544                 :       30499 :      ndim = 2*lpawu + 1
    1545                 :       30499 :      glocnm_mat => glocnm(iatom)%mat
    1546                 :       30499 :      glocspsp_mat => glocspsp(iatom)%mat
    1547                 :             : 
    1548                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1549                 :             :      !$OMP TARGET TEAMS DISTRIBUTE PRIVATE(isppol) MAP(to:glocnm_mat,glocspsp_mat) &
    1550                 :             :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1551                 :             : #endif
    1552         [ +  + ]:       60998 :      do isppol=1,nsppol
    1553                 :             :        !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(m1,m2)
    1554         [ +  + ]:      274491 :        do m2=1,ndim
    1555         [ +  + ]:     1738443 :          do m1=1,ndim
    1556                 :     1494451 :            glocnm_mat(m1,m2,1+(isppol-1)*4) = glocspsp_mat(m1,m2,     isppol)  + glocspsp_mat(m1+ndim,m2+ndim,isppol)
    1557                 :     1494451 :            glocnm_mat(m1,m2,4+(isppol-1)*4) = glocspsp_mat(m1,m2,     isppol)  - glocspsp_mat(m1+ndim,m2+ndim,isppol)
    1558                 :     1494451 :            glocnm_mat(m1,m2,2+(isppol-1)*4) = glocspsp_mat(m1,m2+ndim,isppol)  + glocspsp_mat(m1+ndim,m2,isppol)
    1559                 :     1707944 :            glocnm_mat(m1,m2,3+(isppol-1)*4) = (glocspsp_mat(m1,m2+ndim,isppol) - glocspsp_mat(m1+ndim,m2,isppol)) * j_dpc
    1560                 :             :          end do  ! m1
    1561                 :             :        end do ! m2
    1562                 :             :      end do ! isppol
    1563                 :             : 
    1564         [ -  + ]:       41218 :      if (abs(prtopt) >= 3) then
    1565                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1566                 :             :        !$OMP TARGET UPDATE FROM(glocnm) IF(gpu_option==ABI_GPU_OPENMP)
    1567                 :             : #endif
    1568                 :           0 :        write(message,'(a)') "        -- in n, m repr "
    1569                 :           0 :        call wrtout(std_out,message,'COLL')
    1570         [ #  # ]:           0 :        do mu=1,4
    1571         [ #  # ]:           0 :          do m1=1,ndim
    1572   [ #  #  #  # ]:           0 :            write(message,'(8x,(14(2f9.5,2x)))') (glocnm(iatom)%mat(m1,m2,isppol+mu-1),m2=1,ndim)
    1573                 :           0 :            call wrtout(std_out,message,'COLL')
    1574                 :             :          end do ! m1
    1575                 :           0 :          write(message,'(a)') ch10
    1576                 :           0 :          call wrtout(std_out,message,'COLL')
    1577                 :             :        end do ! mu
    1578                 :             :      end if ! prtopt >3
    1579                 :             :    end do ! iatom
    1580                 :             : 
    1581                 :             : !==  Compute back density matrix in upup dndn updn dnup representation
    1582         [ +  - ]:       10719 :  else if (option == -1) then
    1583                 :             : 
    1584         [ +  + ]:       51108 :    do iatom=1,natom
    1585                 :       40389 :      lpawu = glocnm(iatom)%lpawu
    1586         [ +  + ]:       40389 :      if (lpawu == -1) cycle
    1587                 :       30499 :      ndim = 2*lpawu + 1
    1588                 :       30499 :      glocnm_mat => glocnm(iatom)%mat
    1589                 :       30499 :      glocspsp_mat => glocspsp(iatom)%mat
    1590                 :             : 
    1591                 :             : #ifdef HAVE_OPENMP_OFFLOAD
    1592                 :             :      !$OMP TARGET TEAMS DISTRIBUTE PRIVATE(isppol) MAP(to:glocnm_mat,glocspsp_mat) &
    1593                 :             :      !$OMP& IF(gpu_option==ABI_GPU_OPENMP)
    1594                 :             : #endif
    1595         [ +  + ]:       71717 :      do isppol=1,nsppol
    1596                 :             :        !$OMP PARALLEL DO COLLAPSE(2) PRIVATE(m1,m2)
    1597         [ +  + ]:      284381 :        do m2=1,ndim
    1598         [ +  + ]:     1738443 :          do m1=1,ndim
    1599                 :             :            glocspsp_mat(m1,m2,isppol) = &
    1600                 :     1494451 :            &    half * (glocnm_mat(m1,m2,1+(isppol-1)*4)+glocnm_mat(m1,m2,4+(isppol-1)*4))
    1601                 :             :            glocspsp_mat(m1+ndim,m2+ndim,isppol) = &
    1602                 :     1494451 :            &    half * (glocnm_mat(m1,m2,1+(isppol-1)*4)-glocnm_mat(m1,m2,4+(isppol-1)*4))
    1603                 :             :            glocspsp_mat(m1,m2+ndim,isppol) = &
    1604                 :     1494451 :            &    half * (glocnm_mat(m1,m2,2+(isppol-1)*4)-j_dpc*glocnm_mat(m1,m2,3+(isppol-1)*4))
    1605                 :             :            glocspsp_mat(m1+ndim,m2,isppol) = &
    1606                 :     1707944 :            &    half * (glocnm_mat(m1,m2,2+(isppol-1)*4)+j_dpc*glocnm_mat(m1,m2,3+(isppol-1)*4))
    1607                 :             :          end do ! m1
    1608                 :             :        end do ! m2
    1609                 :             :      end do ! isppol
    1610                 :             :      !if (abs(prtopt) > 6) then
    1611                 :             :      !  write(message,'(a)') "        -- in spin spin repr "
    1612                 :             :      !  call wrtout(std_out,message,'COLL')
    1613                 :             :      !  do mu=1,4
    1614                 :             :      !    do m1=1,ndim
    1615                 :             :      !      write(message,'(8x,14(2f9.5,2x))') (glocspsp(iatom)%mat(m1,m2,isppol,mu,1),m2=1,ndim)
    1616                 :             :      !      call wrtout(std_out,  message,'COLL')
    1617                 :             :      !    end do ! m1
    1618                 :             :      !    write(message,'(a)') ch10
    1619                 :             :      !    call wrtout(std_out,message,'COLL')
    1620                 :             :      !  end do
    1621                 :             :      !end if ! prtopt>6
    1622                 :             :    end do ! iatom
    1623                 :             :  else
    1624                 :           0 :    message = "stop in chg_repr_matlu"
    1625                 :           0 :    ABI_ERROR(message)
    1626                 :             :  end if ! option
    1627                 :             : 
    1628                 :             : ! DBG_EXIT("COLL")
    1629                 :             : 
    1630         [ -  + ]:       21438 :  end subroutine chg_repr_matlu
    1631                 :             : !!***
    1632                 :             : 
    1633                 :             : !!****f* m_matlu/trace_matlu
    1634                 :             : !! NAME
    1635                 :             : !! trace_matlu
    1636                 :             : !!
    1637                 :             : !! FUNCTION
    1638                 :             : !!  Compute the trace of the matlu matrix
    1639                 :             : !!
    1640                 :             : !! INPUTS
    1641                 :             : !!  matlu(natom) <type(matlu_type)>= density matrix in the
    1642                 :             : !!               local orbital basis and related variables
    1643                 :             : !!  natom = number of atoms
    1644                 :             : !!  itau = flag for print
    1645                 :             : !!      not present (default) : occupations from G(iw)
    1646                 :             : !!       = 1  : occupations from G(tau)
    1647                 :             : !!       = -1 : occupations from G0(tau)
    1648                 :             : !!       = 4  : trace of matlu
    1649                 :             : !!
    1650                 :             : !! OUTPUT
    1651                 :             : !!  trace_loc(nsppol+1,natom)= trace for each atom and each polarization,
    1652                 :             : !!                             trace_loc(iatom,nsppol+1) is
    1653                 :             : !!                             the full trace over all polarizations
    1654                 :             : !!  trace= trace over all correlated atoms
    1655                 :             : !!
    1656                 :             : !! SOURCE
    1657                 :             : 
    1658                 :         811 :  subroutine trace_matlu(matlu,natom,trace_loc,itau,trace)
    1659                 :             : 
    1660                 :             : !Arguments ------------------------------------
    1661                 :             :  integer, intent(in) :: natom
    1662                 :             :  type(matlu_type), intent(in) :: matlu(natom)
    1663                 :             :  real(dp), target, optional, intent(inout) :: trace_loc(matlu(1)%nsppol+1,natom)
    1664                 :             :  integer, optional, intent(in) :: itau
    1665                 :             :  complex(dp), optional, intent(out) :: trace
    1666                 :             : !Local variables-------------------------------
    1667                 :             :  integer :: iatom,im,isppol,lpawu,ndim,nspinor,nsppol
    1668                 :             :  complex(dp) :: trace_tmp,trace_tmp2
    1669                 :             :  real(dp), contiguous, pointer :: traceloc(:,:) => null()
    1670                 :             :  character(len=4) :: tag
    1671                 :             :  character(len=12) :: tag_nb_elec
    1672                 :             :  character(len=500) :: message
    1673                 :             : ! *********************************************************************
    1674                 :             : 
    1675                 :         812 :  nspinor = matlu(1)%nspinor
    1676                 :         812 :  nsppol  = matlu(1)%nsppol
    1677                 :             : 
    1678         [ +  + ]:         812 :  if (present(trace_loc)) then
    1679                 :         811 :    traceloc => trace_loc(:,:)
    1680                 :             :  else
    1681   [ +  -  -  +  :           4 :    ABI_MALLOC(traceloc,(nsppol+1,natom))
          +  -  -  +  +  
          -  +  -  +  -  
             -  +  -  + ]
    1682                 :             :  end if
    1683                 :             : 
    1684                 :         812 :  trace_tmp = czero
    1685   [ +  +  +  + ]:       10309 :  traceloc(:,:) = zero
    1686                 :             : 
    1687         [ +  + ]:        3649 :  do iatom=1,natom
    1688                 :             : 
    1689                 :        2837 :    lpawu = matlu(iatom)%lpawu
    1690         [ +  + ]:        2837 :    if (lpawu == -1) cycle
    1691                 :             : 
    1692                 :        1008 :    ndim = nspinor * (2*lpawu+1)
    1693                 :        1008 :    write(tag,'(i4)') iatom
    1694                 :        1008 :    write(message,'(3a)') ch10,'   -------> For Correlated Atom ',adjustl(tag)
    1695         [ +  + ]:        1008 :    if (.not. present(itau)) then
    1696                 :        1007 :      call wrtout(std_out,message,'COLL')
    1697                 :             :    end if
    1698                 :             : 
    1699                 :             :    if (present(itau)) then
    1700         [ -  + ]:           1 :      if (itau > 0) then
    1701                 :           1 :        call wrtout(std_out,message,'COLL')
    1702                 :             :      end if
    1703                 :             :    end if ! present(itau)
    1704                 :             : 
    1705         [ +  + ]:        2485 :    do isppol=1,nsppol
    1706                 :             :      trace_tmp2 = czero
    1707         [ +  + ]:        9249 :      do im=1,ndim
    1708                 :        9249 :        trace_tmp2 = trace_tmp2 + matlu(iatom)%mat(im,im,isppol)
    1709                 :             :      end do ! im
    1710                 :        1477 :      trace_tmp = trace_tmp + trace_tmp2
    1711                 :        1477 :      traceloc(isppol,iatom) = dble(trace_tmp2)
    1712                 :        2485 :      traceloc(nsppol+1,iatom) = traceloc(nsppol+1,iatom) + traceloc(isppol,iatom)
    1713                 :             :    end do ! isppol
    1714         [ +  + ]:        1008 :    if (nsppol == 1 .and. nspinor == 1) traceloc(nsppol+1,iatom) = traceloc(nsppol+1,iatom) * two
    1715                 :        1008 :    write(tag_nb_elec,'(f12.6)') traceloc(nsppol+1,iatom)
    1716                 :        1008 :    tag_nb_elec = adjustl(tag_nb_elec)
    1717         [ +  + ]:        1008 :    if (.not. present(itau)) then
    1718                 :        1007 :      write(message,'(8x,2a)') 'Nb of Corr. elec. from G(iw) is: ',tag_nb_elec
    1719                 :        1007 :      call wrtout(std_out,message,'COLL')
    1720                 :             :    end if ! not present(itau)
    1721                 :         812 :    if (present(itau)) then
    1722         [ +  - ]:           1 :      if (itau == 1) then
    1723                 :           1 :        write(message,'(8x,2a)') 'Nb of Corr. elec. from G(tau=0-) is: ',tag_nb_elec
    1724                 :           1 :        call wrtout(std_out,message,'COLL')
    1725         [ #  # ]:           0 :      else if (itau == -1) then
    1726                 :           0 :        write(message,'(8x,2a)') 'Nb: Sum of the values of G0(tau=0-) is: ',tag_nb_elec
    1727                 :           0 :        call wrtout(std_out,message,'COLL')
    1728         [ #  # ]:           0 :      else if (itau == 4) then
    1729                 :           0 :        write(message,'(8x,2a)') 'Trace of matlu matrix is: ',tag_nb_elec
    1730                 :           0 :        call wrtout(std_out,message,'COLL')
    1731                 :             :      end if ! itau
    1732                 :             :    end if ! present(itau)
    1733                 :             :  end do ! iatom
    1734                 :             : 
    1735         [ -  + ]:         812 :  if (present(trace)) then
    1736         [ #  # ]:           0 :    if (nsppol == 1 .and. nspinor == 1) trace_tmp = trace_tmp * two
    1737                 :           0 :    trace = trace_tmp
    1738                 :             :  end if ! present(trace)
    1739                 :             : 
    1740         [ +  + ]:         812 :  if (nsppol > 1 .and. (.not. present(trace))) then
    1741         [ +  + ]:        1323 :    do iatom=1,natom
    1742                 :         986 :      lpawu = matlu(iatom)%lpawu
    1743         [ +  + ]:         986 :      if (lpawu == -1) cycle
    1744                 :             :      !! MAG
    1745                 :             :     ! if(nsppol>1.and.present(itau)) then
    1746                 :             :     !   if(itau==1) then
    1747                 :         469 :      write(tag_nb_elec,'(f12.6)') traceloc(2,iatom) - traceloc(1,iatom)
    1748                 :         469 :      write(message,'(8x,2a)') 'DMFT Corr. Elec. Mag.: ',adjustl(tag_nb_elec)
    1749                 :        1323 :      call wrtout(std_out,message,'COLL')
    1750                 :             :     !   endif
    1751                 :             :    end do ! iatom
    1752                 :             :  end if ! nsppol>1
    1753                 :             : 
    1754         [ +  + ]:         812 :  if (.not. present(trace_loc)) then
    1755         [ -  + ]:           1 :    ABI_FREE(traceloc)
    1756                 :             :  end if
    1757                 :         812 :  traceloc => null()
    1758                 :             : 
    1759         [ +  + ]:         812 :  end subroutine trace_matlu
    1760                 :             : !!***
    1761                 :             : 
    1762                 :             : !!****f* m_matlu/gather_matlu
    1763                 :             : !! NAME
    1764                 :             : !! gather_matlu
    1765                 :             : !!
    1766                 :             : !! FUNCTION
    1767                 :             : !! Create new array from matlu
    1768                 :             : !!
    1769                 :             : !! COPYRIGHT
    1770                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    1771                 :             : !! This file is distributed under the terms of the
    1772                 :             : !! GNU General Public License, see ~abinit/COPYING
    1773                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    1774                 :             : !!
    1775                 :             : !! INPUTS
    1776                 :             : !!  gloc(natom) <type(matlu_type)>        = density matrix in the spin spin representation
    1777                 :             : !!  gatherloc(natom) <type(coeff2c_type)> = density matrix where spin and angular momentum are gathered in the same index
    1778                 :             : !!  natom=number of atoms in cell.
    1779                 :             : !!  option= 1 go from gloc to gathergloc
    1780                 :             : !!  option= -1 go from gathergloc to gloc
    1781                 :             : !!  prtopt= option to define level of printing
    1782                 :             : !!
    1783                 :             : !! OUTPUT
    1784                 :             : !!  gloc(natom) <type(matlu_type)>        = density matrix in the spin spin representation
    1785                 :             : !!  gatherloc(natom) <type(coeff2c_type)> = density matrix where spin and angular momentum are gathered in the same index
    1786                 :             : !!
    1787                 :             : !! SIDE EFFECTS
    1788                 :             : !!
    1789                 :             : !! SOURCE
    1790                 :         216 :  subroutine gather_matlu(gloc,gathergloc,natom,option,prtopt)
    1791                 :             : 
    1792                 :             :  use defs_wvltypes
    1793                 :             :  use m_crystal, only : crystal_t
    1794                 :             : 
    1795                 :             : ! type  matlus_type
    1796                 :             : !  SEQUENCE
    1797                 :             : !  complex(dp), pointer :: mat(:,:)
    1798                 :             : ! end type matlus_type
    1799                 :             : 
    1800                 :             : !Arguments ------------------------------------
    1801                 :             : !scalars
    1802                 :             :  integer,intent(in) :: natom,option,prtopt
    1803                 :             :  type(coeff2c_type), intent(inout) :: gathergloc(natom)
    1804                 :             :  type(matlu_type),intent(inout) :: gloc(natom)
    1805                 :             : !Local variables-------------------------------
    1806                 :             : !scalars
    1807                 :             :  integer :: iatom,im1,im2,ispinor,ispinor1,isppol,isppol1
    1808                 :             :  integer :: jc1,jc2,ml1,ml2,ndim,nspinor,nsppol,tndim
    1809                 :             :  character(len=500) :: message
    1810                 :             : 
    1811                 :             : ! DBG_ENTER("COLL")
    1812                 :         108 :  nsppol=gloc(1)%nsppol
    1813                 :         108 :  nspinor=gloc(1)%nspinor
    1814                 :             : 
    1815         [ +  + ]:         540 :  do iatom=1,natom
    1816         [ +  + ]:         540 :    if(gloc(iatom)%lpawu.ne.-1) then
    1817                 :             : !==-------------------------------------
    1818                 :             : 
    1819                 :         324 :      ndim=2*gloc(iatom)%lpawu+1
    1820                 :         324 :      tndim=nsppol*nspinor*ndim
    1821                 :             : 
    1822                 :             : !== Put norm into array "gathergloc"
    1823                 :         324 :      jc1=0
    1824         [ +  + ]:         648 :      do isppol=1,nsppol
    1825         [ +  + ]:        1296 :        do ispinor=1,nspinor
    1826         [ +  + ]:        5508 :          do ml1=1,ndim
    1827                 :        4536 :            jc1=jc1+1
    1828                 :        4536 :            jc2=0
    1829         [ +  + ]:        9720 :            do isppol1=1,nsppol
    1830         [ +  + ]:       18144 :              do ispinor1=1,nspinor
    1831         [ +  + ]:       77112 :                do ml2=1,ndim
    1832                 :       63504 :                  jc2=jc2+1
    1833         [ +  - ]:       72576 :                  if(option==1) then
    1834         [ +  - ]:       63504 :                    if(isppol==isppol1) then
    1835                 :       63504 :                      gathergloc(iatom)%value(jc1,jc2)=gloc(iatom)%mat(ml1+(ispinor-1)*ndim,ml2+(ispinor1-1)*ndim,isppol)
    1836                 :             :                    endif
    1837         [ #  # ]:           0 :                  else if(option==-1) then
    1838         [ #  # ]:           0 :                    if(isppol==isppol1) then
    1839                 :           0 :                      gloc(iatom)%mat(ml1+(ispinor-1)*ndim,ml2+(ispinor1-1)*ndim,isppol)=gathergloc(iatom)%value(jc1,jc2)
    1840                 :             :                    endif
    1841                 :             :                  endif
    1842                 :             :                enddo
    1843                 :             :              enddo ! ispinor1
    1844                 :             :            enddo ! isppol1
    1845                 :             :          enddo
    1846                 :             :        enddo !ispinor
    1847                 :             :      enddo ! isppol
    1848                 :             :    endif
    1849                 :             :  enddo ! iatom
    1850   [ +  -  -  + ]:         108 :  if(option==1.and.prtopt==3) then
    1851         [ #  # ]:           0 :    do iatom=1,natom
    1852         [ #  # ]:           0 :      if(gloc(iatom)%lpawu.ne.-1) then
    1853                 :           0 :        tndim=nsppol*nspinor*(2*gloc(iatom)%lpawu+1)
    1854                 :           0 :        write(message,'(2a,i5)') ch10,' (gathermatlu:) For atom', iatom
    1855                 :           0 :        call wrtout(std_out,message,'COLL')
    1856         [ #  # ]:           0 :        do im1=1,tndim
    1857                 :             :          write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))')&
    1858   [ #  #  #  # ]:           0 : &         (gathergloc(iatom)%value(im1,im2),im2=1,tndim)
    1859                 :           0 :          call wrtout(std_out,message,'COLL')
    1860                 :             :        end do
    1861                 :             :      endif
    1862                 :             :    enddo ! iatom
    1863   [ -  +  -  - ]:         108 :  else if(option==-1.and.prtopt==3) then
    1864                 :           0 :    call print_matlu(gloc,natom,prtopt)
    1865                 :             :  endif
    1866                 :             : 
    1867                 :             : 
    1868                 :             : 
    1869                 :             : ! DBG_EXIT("COLL")
    1870                 :             : 
    1871                 :         108 :  end subroutine gather_matlu
    1872                 :             : !!***
    1873                 :             : 
    1874                 :             : !!****f* m_matlu/diag_matlu
    1875                 :             : !! NAME
    1876                 :             : !! diag_matlu
    1877                 :             : !!
    1878                 :             : !! FUNCTION
    1879                 :             : !! Diagonalize hermitian matlu matrix
    1880                 :             : !!
    1881                 :             : !! COPYRIGHT
    1882                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    1883                 :             : !! This file is distributed under the terms of the
    1884                 :             : !! GNU General Public License, see ~abinit/COPYING
    1885                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    1886                 :             : !!
    1887                 :             : !! INPUTS
    1888                 :             : !!  matlu(natom) :: input quantity to diagonalize (careful, matlu must be hermitian)
    1889                 :             : !!  natom=number of atoms
    1890                 :             : !!  prtopt: >=3 : print eigenvectors
    1891                 :             : !!          >=4 : print matlu before diagonalization
    1892                 :             : !!  nsppol_imp= if 1, one can diagonalize with the same matrix the Up
    1893                 :             : !!   and Dn matlu matrix. It is convenient because one can thus have the
    1894                 :             : !!   same interaction matrix for up and dn spins. Default is nsppol.
    1895                 :             : !!  checkstop= if true (default), print the matrix for spin down in the diagonalization basis of spin up
    1896                 :             : !!             (useful when nsppol=2 and nsppol_imp=1)
    1897                 :             : !!  optreal= diagonalize the real matrix if max(imag(matlu)) < 1e-6
    1898                 :             : !!  test= if 8 or 10, use the block diagonalization algorithm (8 for real and 10 for complex)
    1899                 :             : !!
    1900                 :             : !! OUTPUT
    1901                 :             : !!  matlu_diag(natom) :: diagonalized density matrix
    1902                 :             : !!  eigvectmatlu(natom) = Eigenvectors corresponding to the diagonalization
    1903                 :             : !!
    1904                 :             : !! SIDE EFFECTS
    1905                 :             : !!
    1906                 :             : !! NOTES
    1907                 :             : !!
    1908                 :             : !! SOURCE
    1909                 :             : 
    1910                 :         197 :  subroutine diag_matlu(matlu,matlu_diag,natom,prtopt,eigvectmatlu,nsppol_imp,checkstop,opt_real,test)
    1911                 :             : 
    1912                 :             : !Arguments ------------------------------------
    1913                 :             :  integer, intent(in) :: natom,prtopt
    1914                 :             :  type(matlu_type), intent(in) :: matlu(natom)
    1915                 :             :  type(matlu_type), intent(inout) :: eigvectmatlu(natom),matlu_diag(natom) !vz_i
    1916                 :             :  integer, optional, intent(in) :: nsppol_imp,opt_real,test
    1917                 :             :  logical, optional, intent(in) :: checkstop
    1918                 :             : !Local variables-------------------------------
    1919                 :             :  integer :: iatom,im1,im2,info,isppol,lpawu,lwork,lworkr
    1920                 :             :  integer :: nspinor,nsppol,nsppolimp,optreal,tndim
    1921                 :             :  logical :: blockdiag,blockdiagc,checkstop_in,print_temp_mat2
    1922                 :             :  character(len=4) :: tag
    1923                 :             :  character(len=500) :: message
    1924                 :         197 :  real(dp), allocatable :: eig(:),rwork(:),valuer(:,:),work(:)!,valuer2(:,:)
    1925                 :             :  !real(dp),allocatable :: valuer3(:,:),valuer4(:,:)
    1926                 :             : ! real(dp),allocatable :: eigvec(:,:)
    1927                 :         197 :  complex(dp), allocatable :: temp_mat(:,:),zwork(:)
    1928                 :             : !debug complex(dp),allocatable :: temp_mat3(:,:)
    1929                 :             : !************************************************************************
    1930                 :             : 
    1931                 :         197 :  blockdiag    = .false.
    1932                 :         197 :  blockdiagc   = .false.
    1933                 :         197 :  checkstop_in = .true.
    1934                 :         197 :  nspinor      = matlu(1)%nspinor
    1935                 :         197 :  nsppol       = matlu(1)%nsppol
    1936                 :         197 :  nsppolimp    = nsppol
    1937                 :         197 :  optreal      = 0
    1938                 :             : 
    1939         [ +  + ]:         197 :  if (present(nsppol_imp)) nsppolimp = nsppol_imp
    1940         [ +  + ]:         197 :  if (present(checkstop)) checkstop_in = checkstop
    1941         [ +  + ]:         197 :  if (present(test)) blockdiag = (test == 8 )
    1942                 :         183 :  if (present(test)) blockdiagc = ( test == 10)
    1943         [ +  + ]:         197 :  if (present(opt_real)) optreal = opt_real
    1944                 :             : 
    1945                 :         197 :  call zero_matlu(matlu_diag(:),natom)
    1946                 :         197 :  call copy_matlu(matlu(:),eigvectmatlu(:),natom)
    1947                 :             : 
    1948                 :             :  !donotdiag=.true.
    1949                 :             :  !donotdiag=.false.
    1950                 :             : ! ===========================
    1951                 :             : ! Check is diagonalization is necessary and how
    1952                 :             : ! ===========================
    1953                 :             :  !do isppol=1,matlu(1)%nsppol
    1954                 :             :  !  do iatom=1,natom
    1955                 :             :  !     if(matlu(iatom)%lpawu.ne.-1) then
    1956                 :             :  !      tndim=(2*matlu(iatom)%lpawu+1)
    1957                 :             :  !       do im1=1,tndim
    1958                 :             :  !         do im2=1,tndim
    1959                 :             :  !           do ispinor=1,nspinor
    1960                 :             :  !             do ispinor1=1,nspinor
    1961                 :             :  !               if(abs(matlu(iatom)%mat(im1,im2,isppol,ispinor,ispinor1))>tol8.and.&
    1962                 :             : !&                 (im1/=im2.or.ispinor/=ispinor1)) then
    1963                 :             : !                 if matrix is diagonal: do not diagonalize
    1964                 :             :  !                 donotdiag=.false.
    1965                 :             :  !                 exit
    1966                 :             :  !               endif
    1967                 :             :  !             enddo
    1968                 :             :  !           enddo
    1969                 :             :  !         enddo
    1970                 :             :  !       enddo
    1971                 :             :  !     endif
    1972                 :             :  !  enddo
    1973                 :             :  !enddo
    1974                 :             : 
    1975                 :             :  !if(donotdiag) then
    1976                 :             :  !  do isppol=1,matlu(1)%nsppol
    1977                 :             :  !    do iatom=1,natom
    1978                 :             :  !       if(matlu(iatom)%lpawu.ne.-1) then
    1979                 :             :  !         tndim=(2*matlu(iatom)%lpawu+1)
    1980                 :             :  !         eigvectmatlu(iatom,isppol)%value(:,:)=czero
    1981                 :             :  !         do im1=1,tndim
    1982                 :             :  !           eigvectmatlu(iatom,isppol)%value(im1,im1)=cone
    1983                 :             :  !         enddo
    1984                 :             :  !       endif
    1985                 :             :  !    enddo
    1986                 :             :  !  enddo
    1987                 :             :  !  call copy_matlu(matlu,matlu_diag,natom)
    1988                 :             :  !  write(message,'(a)')  "   Diagonalisation of matlu will not be performed"
    1989                 :             :  !  call wrtout(std_out,message,'COLL')
    1990                 :             :  !  return
    1991                 :             :  !endif
    1992                 :             : 
    1993                 :             : ! For nsppol=2, and if nsppolimp=1, the eigenvectors are computed for isppol=1, and applied through
    1994                 :             : ! rotate_matlu to isppol=2. It is the reason why the sum below is only from 1 to nsppolimp !
    1995                 :             : 
    1996         [ +  + ]:         915 :  do iatom=1,natom
    1997                 :             : 
    1998                 :         718 :    lpawu = matlu(iatom)%lpawu
    1999         [ +  + ]:         718 :    if (lpawu == -1) cycle
    2000                 :         261 :    write(tag,'(i4)') iatom
    2001                 :         261 :    tndim = nspinor * (2*lpawu+1)
    2002                 :         261 :    lwork = 2*tndim - 1
    2003                 :         261 :    lworkr = tndim * (tndim+2) * 2
    2004   [ -  +  +  -  :         783 :    ABI_MALLOC(eig,(tndim))
          +  -  +  -  -  
                +  -  + ]
    2005                 :             : 
    2006                 :             : ! ===========================
    2007                 :             : ! Define gathermatlu
    2008                 :             : ! ===========================
    2009                 :             :    !ABI_MALLOC(gathermatlu,(natom))
    2010                 :             :    !do iatom=1,natom
    2011                 :             :    !  if(matlu(iatom)%lpawu.ne.-1) then
    2012                 :             :    !    tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2013                 :             :    !    ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
    2014                 :             :    !    gathermatlu(iatom)%value=czero
    2015                 :             :    !  endif
    2016                 :             :    !enddo
    2017                 :             :    !if(nsppol==1.and.nspinor==2) then
    2018                 :             :    !  call gather_matlu(matlu,gathermatlu,natom,option=1,prtopt=1)
    2019                 :             :    !else if((nsppol==2.or.nsppol==1).and.nspinor==1) then
    2020                 :             :    !  do iatom=1,natom
    2021                 :             :    !    if(matlu(iatom)%lpawu.ne.-1) then
    2022                 :             :    !      tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2023                 :             :    !      do im1=1,tndim
    2024                 :             :    !        do im2=1,tndim
    2025                 :             :    !          gathermatlu(iatom)%value(im1,im2)=matlu(iatom)%mat(im1,im2,isppol,1,1)
    2026                 :             :    !        enddo
    2027                 :             :    !      enddo
    2028                 :             :    !    endif
    2029                 :             :    !  enddo
    2030                 :             :    !endif
    2031                 :             : 
    2032                 :             :    ! ===========================
    2033                 :             :    ! Diagonalize
    2034                 :             :    ! ===========================
    2035         [ +  + ]:         647 :    do isppol=1,nsppolimp
    2036                 :             : !debug       allocate(temp_mat2(tndim,tndim))
    2037                 :             : !debug       temp_mat2=zero
    2038                 :             : !         ABI_MALLOC(valuer2,(tndim,tndim))
    2039                 :             : !         ABI_MALLOC(valuer3,(tndim,tndim))
    2040                 :             : !         ABI_MALLOC(valuer4,(tndim,tndim))
    2041                 :             : !         valuer2=zero
    2042                 :             : !         valuer3=zero
    2043                 :             : !         valuer4=zero
    2044         [ +  + ]:         386 :      if (prtopt >= 4) then
    2045                 :          14 :        write(message,'(a,i4,a,i4)') "       BEFORE DIAGONALIZATION for atom",iatom,"  and isppol",isppol
    2046                 :          14 :        call wrtout(std_out,message,'COLL')
    2047         [ +  + ]:         112 :        do im1=1,tndim
    2048   [ +  -  +  + ]:         784 :          write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))') (matlu(iatom)%mat(im1,im2,isppol),im2=1,tndim)
    2049                 :         112 :          call wrtout(std_out,message,'COLL')
    2050                 :             :        end do ! im1
    2051                 :             :      end if ! prtopt>=4
    2052                 :             : !debug       temp_mat2(:,:)=gathermatlu(iatom)%value(:,:)
    2053                 :             : !           write(std_out,*)"diag"
    2054                 :             : 
    2055   [ +  +  +  +  :       16250 :      if (optreal == 1 .and. maxval(abs(aimag(matlu(iatom)%mat(:,:,isppol)))) < tol6 ) then
          +  +  +  -  -  
          +  -  -  +  +  
                   +  + ]
    2056                 :         154 :        write(message,'(a,2x,a,e9.3,a)') ch10,"Imaginary part of Local Hamiltonian is lower than ",&
    2057                 :         308 :          & tol6,": the real matrix is used"
    2058                 :         154 :        call wrtout(std_out,message,'COLL')
    2059   [ -  +  +  -  :         616 :        ABI_MALLOC(valuer,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    2060   [ +  +  +  + ]:        6318 :        valuer(:,:) = dble(matlu(iatom)%mat(:,:,isppol))
    2061                 :             : !           write(message,'(a)') ch10
    2062                 :             : !           call wrtout(std_out,message,'COLL')
    2063                 :             : !           write(message,'(a,i4,a,i4)')  "BEFORE valuer for atom",iatom,"  and isppol",isppol
    2064                 :             : !           call wrtout(std_out,message,'COLL')
    2065                 :             : !           do im1=1,tndim
    2066                 :             : !             write(message,'(2(1x,18(1x,"(",f20.15,",",f20.15,")")))')&
    2067                 :             : !&             (valuer(im1,im2),im2=1,tndim)
    2068                 :             : !             call wrtout(std_out,message,'COLL')
    2069                 :             : !           end do
    2070                 :             : !           do im1=1,tndim
    2071                 :             : !             valuer(im1,im1)=real(im1,kind=dp)*0.00000000001_dp+valuer(im1,im1)
    2072                 :             : !           enddo
    2073                 :             : !           write(message,'(a)') ch10
    2074                 :             : !           call wrtout(std_out,message,'COLL')
    2075                 :             : !           write(message,'(a,i4,a,i4)')  "BEFORE valuer for atom",iatom,"  and isppol",isppol
    2076                 :             : !           call wrtout(std_out,message,'COLL')
    2077                 :             : !           do im1=1,tndim
    2078                 :             : !             write(message,'(2(1x,18(1x,f20.15,f20.15)))')&
    2079                 :             : !&             (valuer(im1,im2),im2=1,tndim)
    2080                 :             : !             call wrtout(std_out,message,'COLL')
    2081                 :             : !           end do
    2082                 :             :            !call dsyev('v','u',tndim,valuer,tndim,eig,work,lworkr,info)
    2083         [ +  + ]:         154 :        if (blockdiag .or. blockdiagc) then
    2084                 :          12 :          call blockdiago_fordsyev(valuer(:,:),tndim,eig(:))
    2085                 :             :        else
    2086   [ -  +  +  -  :         426 :          ABI_MALLOC(work,(lworkr))
          +  -  +  -  -  
                +  -  + ]
    2087                 :         142 :          call dsyev('v','u',tndim,valuer(:,:),tndim,eig(:),work(:),lworkr,info)
    2088         [ -  + ]:         142 :          ABI_FREE(work)
    2089                 :             :        end if ! blockdiag
    2090                 :             : !!       For reproductibility
    2091                 :             : !           ! valuer2: eigenvector for the perturb matrix
    2092                 :             : !           valuer2=real(gathermatlu(iatom)%value,kind=dp)
    2093                 :             : !           do im1=1,tndim
    2094                 :             : !             valuer2(im1,im1)=float(im1)*0.00000000001+valuer2(im1,im1)
    2095                 :             : !           enddo
    2096                 :             : !           call dsyev('v','u',tndim,valuer2,tndim,eig,work,lworkr,info)
    2097                 :             : !           write(message,'(a)') ch10
    2098                 :             : !           call wrtout(std_out,message,'COLL')
    2099                 :             : !           write(message,'(a,i4,a,i4)')  "       valuer2 for atom",iatom,"  and isppol",isppol
    2100                 :             : !           call wrtout(std_out,message,'COLL')
    2101                 :             : !           do im1=1,tndim
    2102                 :             : !             write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))')&
    2103                 :             : !&             (valuer2(im1,im2),im2=1,tndim)
    2104                 :             : !             call wrtout(std_out,message,'COLL')
    2105                 :             : !           end do
    2106                 :             : !           call dgemm('n','n',tndim,tndim,tndim,cone,valuer,tndim,&
    2107                 :             : !&            valuer2,tndim,czero,valuer3                ,tndim)
    2108                 :             : !           call dgemm('c','n',tndim,tndim,tndim,cone,valuer2,tndim,&
    2109                 :             : !&            valuer3                   ,tndim,czero,valuer4,tndim)
    2110                 :             : !           ! valuer4: compute unpert matrix in the basis of the
    2111                 :             : !           ! perturb basis
    2112                 :             : !           write(message,'(a)') ch10
    2113                 :             : !           call wrtout(std_out,message,'COLL')
    2114                 :             : !           write(message,'(a,i4,a,i4)')  "BEFORE valuer4 for atom",iatom,"  and isppol",isppol
    2115                 :             : !           call wrtout(std_out,message,'COLL')
    2116                 :             : !           do im1=1,tndim
    2117                 :             : !             write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))')&
    2118                 :             : !&             (valuer4(im1,im2),im2=1,tndim)
    2119                 :             : !             call wrtout(std_out,message,'COLL')
    2120                 :             : !           end do
    2121                 :             : !           call dsyev('v','u',tndim,valuer4,tndim,eig,work,lworkr,info)
    2122                 :             : !           ! valuer4: Diago valuer4 (nearly diag)
    2123                 :             : !           write(message,'(a)') ch10
    2124                 :             : !           call wrtout(std_out,message,'COLL')
    2125                 :             : !           write(message,'(a,i4,a,i4)')  "AFTER  valuer4 for atom",iatom,"  and isppol",isppol
    2126                 :             : !           call wrtout(std_out,message,'COLL')
    2127                 :             : !           do im1=1,tndim
    2128                 :             : !             write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))')&
    2129                 :             : !&             (valuer4(im1,im2),im2=1,tndim)
    2130                 :             : !             call wrtout(std_out,message,'COLL')
    2131                 :             : !           end do
    2132                 :             : !           call dgemm('n','n',tndim,tndim,tndim,cone,valuer2,tndim,&
    2133                 :             : !&            valuer4,tndim,czero,valuer                ,tndim)
    2134                 :             :            !write(6,*) "INFO",info
    2135   [ +  +  +  + ]:        6318 :        eigvectmatlu(iatom)%mat(:,:,isppol) = cmplx(valuer(:,:),zero,kind=dp)
    2136         [ -  + ]:         154 :        ABI_FREE(valuer)
    2137                 :             : !           write(message,'(a,i4,a,i4)')  "AFTER valuer for atom",iatom,"  and isppol",isppol
    2138                 :             : !           call wrtout(std_out,message,'COLL')
    2139                 :             : !           do im1=1,tndim
    2140                 :             : !             write(message,'(2(1x,18(1x,"(",f20.15,",",f20.15,")")))')&
    2141                 :             : !&             (valuer(im1,im2),im2=1,tndim)
    2142                 :             : !             call wrtout(std_out,message,'COLL')
    2143                 :             : !           end do
    2144                 :             :      else
    2145                 :             : 
    2146         [ +  + ]:         232 :        if (blockdiagc) then
    2147                 :          12 :         write(message,'(a,a,a)') ch10, "   == The local Hamiltonian in Ylm basis is complex.&
    2148                 :          24 :           & The complex matrix is used for the diagonalisation. Printing real and imaginary part of rotation matrix:  "
    2149                 :          12 :         call wrtout(std_out,message,'COLL')
    2150                 :             : 
    2151   [ +  +  +  + ]:        2532 :         eigvectmatlu(iatom)%mat(:,:,isppol) = matlu(iatom)%mat(:,:,isppol)
    2152                 :             : 
    2153                 :          12 :         call blockdiago_forzheev(eigvectmatlu(iatom)%mat(:,:,isppol),tndim,eig(:))
    2154                 :             : 
    2155                 :             :         !ABI_MALLOC(zwork,(lwork))
    2156                 :             :         !ABI_MALLOC(rwork,(3*tndim-2))
    2157                 :             :         !call zheev('v','u',tndim,eigvectmatlu(iatom)%mat(:,:,isppol),tndim,eig(:),zwork(:),lwork,rwork(:),info)
    2158                 :             :         !ABI_FREE(zwork)
    2159                 :             :         !ABI_FREE(rwork)
    2160                 :             :        else
    2161   [ +  +  +  +  :        7400 :           if (optreal == 1 .and. maxval(abs(aimag(matlu(iatom)%mat(:,:,isppol)))) > tol8 ) then
          +  +  +  -  -  
          +  -  -  +  +  
                   +  - ]
    2162                 :           2 :             write(message,'(a)') " Local hamiltonian in correlated basis is complex"
    2163                 :           2 :             ABI_COMMENT(message)
    2164                 :             :           end if
    2165                 :             :          !eigvectmatlu(iatom)%mat(:,:,isppol) = matlu(iatom)%mat(:,:,isppol)
    2166   [ -  +  +  -  :         660 :          ABI_MALLOC(zwork,(lwork))
          +  -  +  -  -  
                +  -  + ]
    2167   [ +  -  -  +  :         660 :          ABI_MALLOC(rwork,(3*tndim-2))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
    2168                 :         220 :          call zheev('v','u',tndim,eigvectmatlu(iatom)%mat(:,:,isppol),tndim,eig(:),zwork(:),lwork,rwork(:),info)
    2169         [ -  + ]:         220 :          ABI_FREE(zwork)
    2170         [ -  + ]:         220 :          ABI_FREE(rwork)
    2171                 :             :        endif !blockdiag
    2172                 :             :      end if ! present(optreal)
    2173         [ +  + ]:         386 :      if (prtopt >= 3) then
    2174         [ +  - ]:          68 :        write(message,'(3a,i1)') "       EIGENVECTORS for atom ",trim(adjustl(tag))," and isppol ",isppol
    2175                 :          68 :        call wrtout(std_out,message,'COLL')
    2176         [ +  + ]:         482 :        do im1=1,tndim
    2177                 :             :          !write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))') (eigvectmatlu(iatom)%mat(im1,im2,isppol),im2=1,tndim)
    2178   [ +  -  +  + ]:        4204 :          write(message,'(12(1x,18(1x,f6.3,1x,f6.3)))') (eigvectmatlu(iatom)%mat(im1,im2,isppol),im2=1,tndim)
    2179                 :         482 :          call wrtout(std_out,message,'COLL')
    2180                 :             :        end do ! im1
    2181                 :             :           ! do im1=1,tndim
    2182                 :             :           !   xcheck=czero
    2183                 :             :           !   do im3=1,tndim
    2184                 :             :           !     do im2=1,tndim
    2185                 :             :           !       xcheck=xcheck+gathermatlu(iatom)%value(im1,im2)*conjg(gathermatlu(iatom)%value(im2,im3))
    2186                 :             :           !     end do
    2187                 :             :           !   end do
    2188                 :             :           !   write(6,*) "check",im3,im1,xcheck
    2189                 :             :           ! end do
    2190                 :             :      end if ! prtopt>=3
    2191                 :             : !       write(std_out,*) "eig",eig
    2192                 :             : ! ===========================
    2193                 :             : ! Put eigenvalue in matlu_diag
    2194                 :             : ! ===========================
    2195         [ +  + ]:        2452 :      do im1=1,tndim
    2196                 :        2452 :        matlu_diag(iatom)%mat(im1,im1,isppol) = cmplx(eig(im1),zero,kind=dp)
    2197                 :             :      end do ! im1
    2198                 :             :          !if(prtopt>=2) then
    2199                 :             : !            write(message,'(a,12(1x,18(1x,"(",f9.3,",",f9.3,")")))')&
    2200                 :             : !&            ch10,(eig(im1),im1=1,tndim)
    2201                 :             : !             call wrtout(std_out,message,'COLL')
    2202                 :             :            !call wrtout(std_out,message,'COLL')
    2203                 :             :             !write(std_out,*) "EIG", eig
    2204                 :             :          !endif
    2205                 :             : !         ABI_FREE(valuer2)
    2206                 :             : !         ABI_FREE(valuer3)
    2207                 :             : !         ABI_FREE(valuer4)
    2208                 :             : !     endif
    2209                 :             : !   enddo
    2210                 :             : ! ===========================
    2211                 :             : ! Keep eigenvectors gathermatlu
    2212                 :             : ! ===========================
    2213                 :             :          !if (present(eigvectmatlu)) then
    2214                 :             :          !  tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2215                 :             :          !  eigvectmatlu(iatom,isppol)%value(:,:)=gathermatlu(iatom)%value(:,:)
    2216                 :             : !           write(std_out,*) "eigvect in diag_matlu"
    2217                 :             : !           do im1=1,tndim
    2218                 :             : !             write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))')&
    2219                 :             : !&             (gathermatlu(iatom)%value(im1,im2),im2=1,tndim)
    2220                 :             : !             call wrtout(std_out,message,'COLL')
    2221                 :             : !           end do
    2222                 :             :          !endif
    2223                 :             : 
    2224         [ -  + ]:         647 :      if (nsppolimp == 1 .and. nsppol == 2) then
    2225                 :             : ! ==================================================================
    2226                 :             : ! If necessary rotate levels for this other spin, assuming the same
    2227                 :             : ! rotation matrix: it has to be checked afterwards that the matrix is
    2228                 :             : ! diagonal
    2229                 :             : ! ===================================================================
    2230                 :             : 
    2231                 :             : !        input matrix: gathermatlu
    2232                 :             : !        rotation matrix: eigvectmatlu
    2233                 :             : !        intermediate matrix: temp_mat
    2234                 :             : !        result matrix: temp_mat2
    2235                 :             :          !do im1=1,tndim
    2236                 :             :          !  do im2=1,tndim
    2237                 :             :          !    gathermatlu(iatom)%value(im1,im2)=matlu(iatom)%mat(im1,im2,2,1,1)
    2238                 :             :          !  enddo
    2239                 :             :          !enddo
    2240                 :             : 
    2241         [ #  # ]:           0 :        if (prtopt >= 3) then
    2242                 :           0 :          write(message,'(a,i4,a,i4)') "       MATLU for atom",iatom," inside if nsppolimp==1"
    2243                 :           0 :          call wrtout(std_out,message,'COLL')
    2244         [ #  # ]:           0 :          do im1=1,tndim
    2245   [ #  #  #  # ]:           0 :            write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))') (matlu(iatom)%mat(im1,im2,2),im2=1,tndim)
    2246                 :           0 :            call wrtout(std_out,message,'COLL')
    2247                 :             :          end do ! im1
    2248                 :             :        end if ! prtopt>=3
    2249                 :             : 
    2250   [ #  #  #  #  :           0 :        ABI_MALLOC(temp_mat,(tndim,tndim))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    2251                 :             : 
    2252                 :             :        call abi_xgemm('n','n',tndim,tndim,tndim,cone,matlu(iatom)%mat(:,:,2),tndim,&
    2253                 :           0 :                     & eigvectmatlu(iatom)%mat(:,:,1),tndim,czero,temp_mat(:,:),tndim)
    2254                 :             : 
    2255                 :             :        call abi_xgemm('c','n',tndim,tndim,tndim,cone,eigvectmatlu(iatom)%mat(:,:,1),tndim,&
    2256                 :           0 :                     & temp_mat(:,:),tndim,czero,matlu_diag(iatom)%mat(:,:,2),tndim)
    2257                 :             : 
    2258         [ #  # ]:           0 :        ABI_FREE(temp_mat)
    2259                 :             : 
    2260   [ #  #  #  # ]:           0 :        eigvectmatlu(iatom)%mat(:,:,2) = eigvectmatlu(iatom)%mat(:,:,1)
    2261                 :             :        print_temp_mat2 = .false.
    2262         [ #  # ]:           0 :        do im2=1,tndim
    2263         [ #  # ]:           0 :          do im1=1,tndim
    2264   [ #  #  #  # ]:           0 :            if (im1 /= im2 .and. abs(matlu_diag(iatom)%mat(im1,im2,2)) > tol5) then
    2265                 :           0 :              write(message,'(3a,i4,2f16.4)') ch10,'diag_matlu= Matrix for spin number 2 obtained with', &
    2266                 :           0 :               & ' eigenvectors from diagonalization for spin nb 1 is non diagonal for atom:',iatom,&
    2267                 :           0 :               & abs(matlu_diag(iatom)%mat(im1,im2,2)),tol5
    2268                 :           0 :              call wrtout(std_out,message,'COLL')
    2269   [ #  #  #  # ]:           0 :              if (abs(matlu_diag(iatom)%mat(im1,im2,2)) > tol1 .or. checkstop_in) print_temp_mat2 = .true.
    2270                 :             :            end if
    2271                 :             :          end do ! im1
    2272                 :             :        end do ! im2
    2273                 :             : 
    2274   [ #  #  #  # ]:           0 :        if (print_temp_mat2 .and. prtopt >= 3) then
    2275                 :           0 :          write(message,'(a)') "       temp_mat2"
    2276                 :           0 :          call wrtout(std_out,message,'COLL')
    2277         [ #  # ]:           0 :          do im1=1,tndim
    2278   [ #  #  #  # ]:           0 :            write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))') (matlu_diag(iatom)%mat(im1,im2,2),im2=1,tndim)
    2279                 :           0 :            call wrtout(std_out,message,'COLL')
    2280                 :             :          end do ! im1
    2281         [ #  # ]:           0 :          if (iatom == 2) ABI_ERROR("iatom==2")
    2282                 :             :        end if ! print_temp_mat2
    2283                 :             :      end if ! nsppol_imp=1 and nsppol=2
    2284                 :             :    end do ! isppol
    2285                 :             : 
    2286         [ -  + ]:         915 :    ABI_FREE(eig)
    2287                 :             : 
    2288                 :             : !!  for check only
    2289                 :             : !debug     if(matlu(iatom)%lpawu.ne.-1) then
    2290                 :             : !debug       allocate(temp_mat(tndim,tndim))
    2291                 :             : !debug       allocate(temp_mat3(tndim,tndim))
    2292                 :             : !debug           do im1=1,tndim
    2293                 :             : !debug             do im2=1,tndim
    2294                 :             : !debug!               rot_mat(iatom,isppol)%value(im1,im2)=rot_mat_orig(iatom,isppol)%value(im1,im2)
    2295                 :             : !debug               temp_mat3(im1,im2)=conjg(gathermatlu(iatom)%value(im2,im1))
    2296                 :             : !debug             enddo
    2297                 :             : !debug           enddo
    2298                 :             : !debug       temp_mat(:,:)=czero
    2299                 :             : !debug!      input matrix: temp_mat2
    2300                 :             : !debug!      rotation matrix: gathermatlu
    2301                 :             : !debug!      intermediate matrix: temp_mat
    2302                 :             : !debug!      result matrix: temp_mat2
    2303                 :             : !debug       call zgemm('n','c',tndim,tndim,tndim,cone,temp_mat2   ,tndim,&
    2304                 :             : !debug&        temp_mat3,tndim,czero,temp_mat                ,tndim)
    2305                 :             : !debug       call zgemm('n','n',tndim,tndim,tndim,cone,temp_mat3,tndim,&
    2306                 :             : !debug&        temp_mat                   ,tndim,czero,temp_mat2,tndim)
    2307                 :             : !debug!       call zgemm('n','c',tndim,tndim,tndim,cone,temp_mat2   ,tndim,&
    2308                 :             : !debug!&        gathermatlu(iatom)%value,tndim,czero,temp_mat                ,tndim)
    2309                 :             : !debug!       call zgemm('n','n',tndim,tndim,tndim,cone,gathermatlu(iatom)%value,tndim,&
    2310                 :             : !debug!&        temp_mat                   ,tndim,czero,temp_mat2,tndim)
    2311                 :             : !debug         write(std_out,*) "result"
    2312                 :             : !debug         do im1=1,tndim
    2313                 :             : !debug           write(message,'(12(1x,18(1x,"(",f9.3,",",f9.3,")")))')&
    2314                 :             : !debug&           (temp_mat2(im1,im2),im2=1,tndim)
    2315                 :             : !debug           call wrtout(std_out,message,'COLL')
    2316                 :             : !debug         end do
    2317                 :             : !debug       deallocate(temp_mat)
    2318                 :             : !debug       deallocate(temp_mat3)
    2319                 :             : !debug     endif ! lpawu
    2320                 :             : 
    2321                 :             :  end do  ! iatom
    2322                 :             : ! End loop over atoms
    2323                 :             : ! ===========================
    2324                 :             : 
    2325                 :         108 :  end subroutine diag_matlu
    2326                 :             : !!***
    2327                 :             : 
    2328                 :             : !!****f* m_matlu/rotate_matlu
    2329                 :             : !! NAME
    2330                 :             : !! rotate_matlu
    2331                 :             : !!
    2332                 :             : !! FUNCTION
    2333                 :             : !! Rotate matlu matrix
    2334                 :             : !!
    2335                 :             : !! COPYRIGHT
    2336                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2337                 :             : !! This file is distributed under the terms of the
    2338                 :             : !! GNU General Public License, see ~abinit/COPYING
    2339                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2340                 :             : !!
    2341                 :             : !! INPUTS
    2342                 :             : !!  matlu_inp(natom) :: input quantity to rotate
    2343                 :             : !!  rot_mat(natom) :: Rotation matrix (usually from diag_matlu)
    2344                 :             : !!  natom=number of atoms in cell.
    2345                 :             : !!  inverse=   1: rot_mat^H * matlu * rot_mat (from original basis to diagonal basis)
    2346                 :             : !!           /=1: rot_mat * matlu * rot_mat^H (from diagonal basis to original basis)
    2347                 :             : !!
    2348                 :             : !! OUTPUT
    2349                 :             : !!
    2350                 :             : !! SIDE EFFECTS
    2351                 :             : !!
    2352                 :             : !! NOTES
    2353                 :             : !!
    2354                 :             : !! SOURCE
    2355                 :             : 
    2356                 :       35082 :  subroutine rotate_matlu(matlu_inp,rot_mat,natom,inverse)
    2357                 :             : 
    2358                 :             : !Arguments ------------------------------------
    2359                 :             :  integer, intent(in) :: inverse,natom
    2360                 :             :  type(matlu_type), intent(inout) :: matlu_inp(natom)
    2361                 :             :  type(matlu_type), intent(in) :: rot_mat(natom)
    2362                 :             : !Local variables-------------------------------
    2363                 :             :  integer :: iatom,isppol,lpawu,nspinor,nsppol,tndim
    2364                 :       35082 :  complex(dp), allocatable :: temp_mat(:,:)
    2365                 :             :  character(len=1) :: c1,c2
    2366                 :             : !************************************************************************
    2367                 :             : 
    2368                 :       35082 :  nspinor = matlu_inp(1)%nspinor
    2369                 :       35082 :  nsppol  = matlu_inp(1)%nsppol
    2370                 :             : 
    2371         [ +  + ]:       35082 :  if (inverse == 1) then
    2372                 :       16880 :    c1 = "n" ; c2 = "c"
    2373                 :             :  else
    2374                 :       18202 :    c1 = "c" ; c2 = "n"
    2375                 :             :  end if ! inverse
    2376                 :             : 
    2377         [ +  + ]:      135741 :  do iatom=1,natom
    2378                 :      100659 :    lpawu = matlu_inp(iatom)%lpawu
    2379         [ +  + ]:      100659 :    if (lpawu == -1) cycle
    2380                 :       62640 :    tndim = nspinor * (2*lpawu+1)
    2381   [ -  +  +  -  :      250560 :    ABI_MALLOC(temp_mat,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
                   +  - ]
    2382         [ +  + ]:      133408 :    do isppol=1,nsppol
    2383                 :             :      call abi_xgemm('n',c1,tndim,tndim,tndim,cone,matlu_inp(iatom)%mat(:,:,isppol),tndim,&
    2384                 :       70768 :                   & rot_mat(iatom)%mat(:,:,isppol),tndim,czero,temp_mat(:,:),tndim)
    2385                 :             :      call abi_xgemm(c2,'n',tndim,tndim,tndim,cone,rot_mat(iatom)%mat(:,:,isppol),tndim,&
    2386                 :      133408 :                   & temp_mat(:,:),tndim,czero,matlu_inp(iatom)%mat(:,:,isppol),tndim)
    2387                 :             :    end do ! isppol
    2388         [ -  + ]:      135741 :    ABI_FREE(temp_mat)
    2389                 :             :  end do ! iatom
    2390                 :             : 
    2391                 :             :  !do isppol=1,nsppol
    2392                 :             : 
    2393                 :             : ! ===========================
    2394                 :             : ! Define gathermatlu and rot_mat_orig and allocate
    2395                 :             : ! ===========================
    2396                 :             :    !ABI_MALLOC(rot_mat_orig,(natom))
    2397                 :             :    !ABI_MALLOC(gathermatlu,(natom))
    2398                 :             :    !do iatom=1,natom
    2399                 :             :    !  if(matlu(iatom)%lpawu.ne.-1) then
    2400                 :             :    !    tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2401                 :             :    !    ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
    2402                 :             :    !    gathermatlu(iatom)%value=czero
    2403                 :             : !       ABI_MALLOC(rot_mat_orig(iatom,isppol)%value,(tndim,tndim))
    2404                 :             : !       rot_mat_orig(iatom,isppol)%value(:,:)=rot_mat(iatom,isppol)%value(:,:)
    2405                 :             :    !    ABI_MALLOC(rot_mat_orig(iatom)%value,(tndim,tndim))
    2406                 :             :    !    rot_mat_orig(iatom)%value(:,:)=rot_mat(iatom,isppol)%value(:,:)
    2407                 :             :    !  endif
    2408                 :             :    !enddo
    2409                 :             :    !if(nsppol==1.and.nspinor==2) then
    2410                 :             :    !  call gather_matlu(matlu,gathermatlu,natom,option=1,prtopt=1)
    2411                 :             :    !else if((nsppol==2.or.nsppol==1).and.nspinor==1) then
    2412                 :             :    !  do iatom=1,natom
    2413                 :             :    !    if(matlu(iatom)%lpawu.ne.-1) then
    2414                 :             :    !      tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2415                 :             :    !      do im1=1,tndim
    2416                 :             :    !        do im2=1,tndim
    2417                 :             :    !          gathermatlu(iatom)%value(im1,im2)=matlu(iatom)%mat(im1,im2,isppol,1,1)
    2418                 :             :    !        enddo
    2419                 :             :    !      enddo
    2420                 :             :    !    endif
    2421                 :             :    !  enddo
    2422                 :             :    !endif
    2423                 :             :         ! write(std_out,*) "gathermatlu in rotate matlu"
    2424                 :             :         ! do im1=1,tndim
    2425                 :             :         !   write(message,'(12(1x,18(1x,"(",e17.10,",",e17.10,")")))')&
    2426                 :             :         !    (gathermatlu(1)%value(im1,im2),im2=1,tndim)
    2427                 :             :         !   call wrtout(std_out,message,'COLL')
    2428                 :             :         ! end do
    2429                 :             : 
    2430                 :             : ! ===========================
    2431                 :             : ! If necessary, invert rot_mat
    2432                 :             : ! ===========================
    2433                 :             :    !if(inverse==1) then
    2434                 :             :    !  do iatom=1,natom
    2435                 :             :    !    if(matlu(iatom)%lpawu.ne.-1) then
    2436                 :             :    !      tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2437                 :             :    !        do im1=1,tndim
    2438                 :             :    !          do im2=1,tndim
    2439                 :             : !               rot_mat(iatom,isppol)%value(im1,im2)=conjg(rot_mat_orig(iatom,isppol)%value(im2,im1))
    2440                 :             :    !            rot_mat(iatom,isppol)%value(im1,im2)=conjg(rot_mat_orig(iatom)%value(im2,im1))
    2441                 :             :    !          enddo
    2442                 :             :    !        enddo
    2443                 :             :    !    endif ! lpawu
    2444                 :             :    !  enddo ! iatom
    2445                 :             :    !endif
    2446                 :             :         ! write(std_out,*) "rot_mat_orig "
    2447                 :             :         ! do im1=1,tndim
    2448                 :             :         !   write(message,'(12(1x,18(1x,"(",e18.10,",",e18.10,")")))')&
    2449                 :             :         ! &   (rot_mat_orig(1)%value(im1,im2),im2=1,tndim)
    2450                 :             :         !   call wrtout(std_out,message,'COLL')
    2451                 :             :         ! end do
    2452                 :             :         ! write(std_out,*) "rot_mat "
    2453                 :             :         ! do im1=1,tndim
    2454                 :             :         !   write(message,'(12(1x,18(1x,"(",e18.10,",",e18.10,")")))')&
    2455                 :             :         ! &   (rot_mat(1,1)%value(im1,im2),im2=1,tndim)
    2456                 :             :         !   call wrtout(std_out,message,'COLL')
    2457                 :             :         ! end do
    2458                 :             : 
    2459                 :             : ! ===========================
    2460                 :             : ! Rotate
    2461                 :             : ! ===========================
    2462                 :             :    !ABI_MALLOC(temp_mat,(tndim,tndim))
    2463                 :             :    !do iatom=1,natom
    2464                 :             :    !  if(matlu(iatom)%lpawu.ne.-1) then
    2465                 :             :    !    tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2466                 :             :    !    temp_mat(:,:)=czero
    2467                 :             : !      input matrix: gathermatlu
    2468                 :             : !      rotation matrix: rot_mat
    2469                 :             : !      intermediate matrix: temp_mat
    2470                 :             : !      result matrix: gathermatlu
    2471                 :             :        ! temp_mat = gathermatlu * conjg(rot_mat)
    2472                 :             :    !    call zgemm('n','c',tndim,tndim,tndim,cone,gathermatlu(iatom)%value
    2473                 :             :    !    ,tndim,&
    2474                 :             : !&        rot_mat(iatom,isppol)%value,tndim,czero,temp_mat
    2475                 :             : !,tndim)
    2476                 :             :        ! gathermatlu = rot_mat * temp_mat = rot_mat * gathermatlu *
    2477                 :             :        ! conjg(rot_mat)
    2478                 :             :    !    call
    2479                 :             :    !    zgemm('n','n',tndim,tndim,tndim,cone,rot_mat(iatom,isppol)%value,tndim,&
    2480                 :             : !&        temp_mat
    2481                 :             : !,tndim,czero,gathermatlu(iatom)%value,tndim)
    2482                 :             :   !   endif ! lpawu
    2483                 :             :   ! enddo ! iatom
    2484                 :             :    !do iatom=1,natom
    2485                 :             :    !  if(matlu(iatom)%lpawu.ne.-1) then
    2486                 :             :    !    write(std_out,*) "temp_mat in rotate_matlu 2"
    2487                 :             :    !    do im1=1,tndim
    2488                 :             :    !      write(message,'(12(1x,18(1x,"(",f17.10,",",f17.10,")")))')&
    2489                 :             :    !&       (temp_mat(im1,im2),im2=1,tndim)
    2490                 :             :    !      call wrtout(std_out,message,'COLL')
    2491                 :             :    !    end do
    2492                 :             :    !  endif
    2493                 :             :    !enddo
    2494                 :             :    !do iatom=1,natom
    2495                 :             :    !  if(matlu(iatom)%lpawu.ne.-1) then
    2496                 :             :    !    write(std_out,*) "gathermatlu in rotate_matlu 2"
    2497                 :             :    !    do im1=1,tndim
    2498                 :             :    !      write(message,'(12(1x,18(1x,"(",f17.10,",",f17.10,")")))')&
    2499                 :             :    !&       (gathermatlu(iatom)%value(im1,im2),im2=1,tndim)
    2500                 :             :    !      call wrtout(std_out,message,'COLL')
    2501                 :             :    !    end do
    2502                 :             :    !  endif
    2503                 :             :    !enddo
    2504                 :             :   ! ABI_FREE(temp_mat)
    2505                 :             :      !ABI_ERROR("Aborting now")
    2506                 :             : 
    2507                 :             : ! Choose inverse rotation: reconstruct correct rot_mat from rot_mat_orig
    2508                 :             : ! ========================================================================
    2509                 :             :    !if(inverse==1) then
    2510                 :             :    !  do iatom=1,natom
    2511                 :             :    !    if(matlu(iatom)%lpawu.ne.-1) then
    2512                 :             :    !      tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2513                 :             :    !        do im1=1,tndim
    2514                 :             :    !          do im2=1,tndim
    2515                 :             : !  !
    2516                 :             : !  rot_mat(iatom,isppol)%value(im1,im2)=rot_mat_orig(iatom,isppol)%value(im1,im2)
    2517                 :             :    !            rot_mat(iatom,isppol)%value(im1,im2)=rot_mat_orig(iatom)%value(im1,im2)
    2518                 :             :    !          enddo
    2519                 :             :    !        enddo
    2520                 :             :    !    endif ! lpawu
    2521                 :             :    !  enddo ! iatom
    2522                 :             :    !endif
    2523                 :             : 
    2524                 :             : ! ===========================
    2525                 :             : ! Put data into matlu(iatom)
    2526                 :             : ! ===========================
    2527                 :             :    !if(nsppol==1.and.nspinor==2) then
    2528                 :             :    !  call gather_matlu(matlu,gathermatlu,natom,option=-1,prtopt=1)
    2529                 :             :    !else if((nsppol==2.or.nsppol==1).and.nspinor==1) then
    2530                 :             :    !  do iatom=1,natom
    2531                 :             :    !    if(matlu(iatom)%lpawu.ne.-1) then
    2532                 :             :    !      tndim=nspinor*(2*matlu(iatom)%lpawu+1)
    2533                 :             :    !      do im1=1,tndim
    2534                 :             :    !        do im2=1,tndim
    2535                 :             :    !          matlu(iatom)%mat(im1,im2,isppol,1,1)=
    2536                 :             :    !          gathermatlu(iatom)%value(im1,im2)
    2537                 :             :    !        enddo
    2538                 :             :    !      enddo
    2539                 :             :    !    endif
    2540                 :             :    !  enddo
    2541                 :             :    !endif ! test nsppol/nspinor
    2542                 :             : ! ===========================
    2543                 :             : ! Deallocations
    2544                 :             : ! ===========================
    2545                 :             :    !do iatom=1,natom
    2546                 :             :    !  if(matlu(iatom)%lpawu.ne.-1) then
    2547                 :             :    !    ABI_FREE(gathermatlu(iatom)%value)
    2548                 :             : !       ABI_FREE(rot_mat_orig(iatom,isppol)%value)
    2549                 :             :    !    ABI_FREE(rot_mat_orig(iatom)%value)
    2550                 :             :    !  endif
    2551                 :             :    !enddo
    2552                 :             :    !ABI_FREE(gathermatlu)
    2553                 :             :    !ABI_FREE(rot_mat_orig)
    2554                 :             :  !enddo ! isppol
    2555                 :             : 
    2556                 :       35082 :  end subroutine rotate_matlu
    2557                 :             : !!***
    2558                 :             : 
    2559                 :             : !!****f* m_matlu/shift_matlu
    2560                 :             : !! NAME
    2561                 :             : !! shift_matlu
    2562                 :             : !!
    2563                 :             : !! FUNCTION
    2564                 :             : !! Add/subtract a scalar to the diagonal part
    2565                 :             : !!
    2566                 :             : !! COPYRIGHT
    2567                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2568                 :             : !! This file is distributed under the terms of the
    2569                 :             : !! GNU General Public License, see ~abinit/COPYING
    2570                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2571                 :             : !!
    2572                 :             : !! INPUTS
    2573                 :             : !!  matlu(natom) :: input quantity to shift
    2574                 :             : !!  natom=number of atoms in cell.
    2575                 :             : !!  shift= shift of the diagonal part.
    2576                 :             : !!  signe= 1 (default) : the shift is substracted
    2577                 :             : !!       = -1 : the shift is added
    2578                 :             : !!
    2579                 :             : !! OUTPUT
    2580                 :             : !!  matlu(natom) :: shifted matrix
    2581                 :             : !!
    2582                 :             : !! SIDE EFFECTS
    2583                 :             : !!
    2584                 :             : !! NOTES
    2585                 :             : !!
    2586                 :             : !! SOURCE
    2587                 :             : 
    2588                 :       21511 :  subroutine shift_matlu(matlu,natom,shift,signe)
    2589                 :             : 
    2590                 :             : !Arguments ------------------------------------
    2591                 :             :  integer, intent(in) :: natom
    2592                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    2593                 :             :  complex(dp), intent(in) :: shift(natom)
    2594                 :             :  integer, optional, intent(in) :: signe
    2595                 :             : !Local variables-------------------------------
    2596                 :             :  integer :: iatom,im,lpawu,ndim,nspinor,nsppol,signe_used
    2597                 :             : ! character(len=500) :: message
    2598                 :             : !************************************************************************
    2599                 :             : 
    2600                 :       21511 :  nspinor    = matlu(1)%nspinor
    2601                 :       21511 :  nsppol     = matlu(1)%nsppol
    2602                 :       21511 :  signe_used = 1
    2603                 :             : 
    2604         [ +  + ]:       21511 :  if (present(signe)) then
    2605         [ -  + ]:         710 :    if (signe == -1) signe_used = -1
    2606                 :             :  end if ! present(signe)
    2607                 :             : 
    2608         [ +  + ]:       55622 :  do iatom=1,natom
    2609                 :       34111 :    lpawu = matlu(iatom)%lpawu
    2610         [ +  + ]:       34111 :    if (lpawu == -1) cycle
    2611                 :       27295 :    ndim = nspinor * (2*lpawu+1)
    2612         [ +  + ]:      262773 :    do im=1,ndim
    2613   [ +  +  +  + ]:      551228 :      matlu(iatom)%mat(im,im,:) = matlu(iatom)%mat(im,im,:) + merge(-shift(iatom),shift(iatom),signe_used==1)
    2614                 :             :    end do ! im
    2615                 :             :  end do ! iatom
    2616                 :             : 
    2617                 :       21511 :  end subroutine shift_matlu
    2618                 :             : !!***
    2619                 :             : 
    2620                 :             : !!****f* m_matlu/checkreal_matlu
    2621                 :             : !! NAME
    2622                 :             : !! checkreal_matlu
    2623                 :             : !!
    2624                 :             : !! FUNCTION
    2625                 :             : !! Check that matlu is real and diagonal with given precision
    2626                 :             : !!
    2627                 :             : !! COPYRIGHT
    2628                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2629                 :             : !! This file is distributed under the terms of the
    2630                 :             : !! GNU General Public License, see ~abinit/COPYING
    2631                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2632                 :             : !!
    2633                 :             : !! INPUTS
    2634                 :             : !!  dmft_solv :: impurity solver
    2635                 :             : !!  matlu(natom) :: input quantity to check
    2636                 :             : !!  natom=number of atoms in cell.
    2637                 :             : !!  tol : threshold. Print a warning if max(abs(imag(off diagonal elements))) > tol or
    2638                 :             : !!        max(abs(off diagonal elements)) > tol, and throws an error if max(abs(imag(diagonal elements))) > tol
    2639                 :             : !!
    2640                 :             : !! SIDE EFFECTS
    2641                 :             : !!
    2642                 :             : !! NOTES
    2643                 :             : !!
    2644                 :             : !! SOURCE
    2645                 :             : 
    2646                 :           0 :  subroutine checkreal_matlu(matlu,natom,tol)
    2647                 :             : 
    2648                 :             : !Arguments ------------------------------------
    2649                 :             :  real(dp), intent(in) :: tol
    2650                 :             :  integer, intent(in)  :: natom
    2651                 :             :  type(matlu_type), intent(in) :: matlu(natom)
    2652                 :             : !Local variables-------------------------------
    2653                 :             :  integer :: iatom,im,im1,isppol,lpawu,ndim,nspinor,nsppol
    2654                 :             :  character(len=500) :: message
    2655                 :             :  real(dp) :: elem,maximag,maximagdiag,maxoffdiag
    2656                 :             : !************************************************************************
    2657                 :             : 
    2658                 :           0 :  maximag     = zero
    2659                 :           0 :  maximagdiag = zero
    2660                 :           0 :  maxoffdiag  = zero
    2661                 :           0 :  nspinor     = matlu(1)%nspinor
    2662                 :           0 :  nsppol      = matlu(1)%nsppol
    2663                 :             : 
    2664         [ #  # ]:           0 :  do iatom=1,natom
    2665                 :           0 :    lpawu = matlu(iatom)%lpawu
    2666         [ #  # ]:           0 :    if (lpawu == -1) cycle
    2667                 :           0 :    ndim = nspinor * (2*lpawu+1)
    2668         [ #  # ]:           0 :    do isppol=1,nsppol
    2669         [ #  # ]:           0 :      do im1=1,ndim
    2670         [ #  # ]:           0 :        do im=1,ndim
    2671                 :           0 :          elem = abs(aimag(matlu(iatom)%mat(im,im1,isppol)))
    2672         [ #  # ]:           0 :          if (elem > maximag) maximag = elem
    2673         [ #  # ]:           0 :          if (im == im1) then
    2674         [ #  # ]:           0 :            if (elem > maximagdiag) maximagdiag = elem
    2675                 :             :          else
    2676                 :           0 :            elem = abs(matlu(iatom)%mat(im,im1,isppol))
    2677         [ #  # ]:           0 :            if (elem > maxoffdiag) maxoffdiag = elem
    2678                 :             :          end if ! im/=im1
    2679                 :             :        end do ! im
    2680                 :             :      end do ! im1
    2681                 :             :    end do ! isppol
    2682                 :             :  end do ! iatom
    2683                 :             : 
    2684         [ #  # ]:           0 :  if (maximagdiag > tol) then
    2685                 :           0 :    write(message,'(3x,2a,e12.4,a,e12.4,2a)') ch10,&
    2686                 :           0 :      & ' Diagonal part of the occupation matrix is complex: the imaginary part ',&
    2687                 :           0 :      & maximagdiag,' is larger than',tol,ch10,  &
    2688                 :           0 :      & "The calculation cannot handle it : check that your calculation is meaningful"
    2689                 :           0 :    ABI_ERROR(message)
    2690                 :             :  end if ! maximagdiag > tol
    2691         [ #  # ]:           0 :  if (maximag > tol) then
    2692                 :           0 :    write(message,'(3x,2a,e12.4,a,e12.4,2a)') ch10,&
    2693                 :           0 :      & ' The off diagonal occupation matrix is complex: the imaginary part ',maximag,' is larger than',tol,ch10,&
    2694                 :           0 :      & "Check that your calculation is meaningful"
    2695                 :           0 :    ABI_WARNING(message)
    2696                 :             :  end if ! maximag > tol
    2697         [ #  # ]:           0 :  if (maxoffdiag > tol) then
    2698                 :           0 :    write(message,'(3x,2a,e12.4,a,e12.4,6a)') ch10,&
    2699                 :           0 :         & ' Occupation matrix is non diagonal : the maximum off-diag part ',maxoffdiag,' is larger than',tol,ch10,&
    2700                 :           0 :         & "The corresponding non diagonal elements will be neglected in the Weiss/Hybridization functions",ch10,&
    2701                 :           0 :         & "(Except if dmft_solv=8,9 where these elements are taken into account)",ch10,"This is an approximation."
    2702                 :           0 :    ABI_WARNING(message)
    2703                 :             :  else
    2704                 :           0 :    write(message,'(3x,2a,e12.4,a,e12.4,2a)') ch10,' Occupation matrix is diagonal : the off-diag part ',&
    2705                 :           0 :      & maxoffdiag,' is lower than',tol
    2706                 :           0 :    ABI_COMMENT(message)
    2707                 :             :  end if ! maxoffdiag > tol
    2708                 :             : 
    2709                 :           0 :  end subroutine checkreal_matlu
    2710                 :             : !!***
    2711                 :             : 
    2712                 :             : !!****f* m_matlu/checkdiag_matlu
    2713                 :             : !! NAME
    2714                 :             : !! checkdiag_matlu
    2715                 :             : !!
    2716                 :             : !! FUNCTION
    2717                 :             : !! Check that matlu is diagonal in the orbital index with given precision
    2718                 :             : !!
    2719                 :             : !! COPYRIGHT
    2720                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2721                 :             : !! This file is distributed under the terms of the
    2722                 :             : !! GNU General Public License, see ~abinit/COPYING
    2723                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2724                 :             : !!
    2725                 :             : !! INPUTS
    2726                 :             : !!  matlu(natom) :: input quantity to check
    2727                 :             : !!  natom=number of atoms in cell.
    2728                 :             : !!  tol : precision
    2729                 :             : !!
    2730                 :             : !! OUTPUT
    2731                 :             : !!  nondiag= true if max(abs(off diagonal elements)) > tol
    2732                 :             : !!
    2733                 :             : !! SIDE EFFECTS
    2734                 :             : !!
    2735                 :             : !! NOTES
    2736                 :             : !!
    2737                 :             : !! SOURCE
    2738                 :             : 
    2739                 :         148 :  subroutine checkdiag_matlu(matlu,natom,tol,nondiag)
    2740                 :             : 
    2741                 :             : !Arguments ------------------------------------
    2742                 :             :  real(dp), intent(in) :: tol
    2743                 :             :  integer, intent(in)  :: natom
    2744                 :             :  logical, intent(out) :: nondiag
    2745                 :             :  type(matlu_type), intent(in) :: matlu(natom)
    2746                 :             : !Local variables-------------------------------
    2747                 :             :  integer :: iatom,im,im1,isppol,lpawu,ndim,nsppol,nspinor
    2748                 :             : !************************************************************************
    2749                 :             : 
    2750                 :         148 :  nondiag = .false.
    2751                 :         148 :  nspinor = matlu(1)%nspinor
    2752                 :         148 :  nsppol  = matlu(1)%nsppol
    2753                 :             : 
    2754         [ +  + ]:         612 :  do iatom=1,natom
    2755                 :         464 :    lpawu = matlu(iatom)%lpawu
    2756         [ +  + ]:         464 :    if (lpawu == -1) cycle
    2757                 :         188 :    ndim = nspinor * (2*lpawu+1)
    2758         [ +  + ]:         618 :    do isppol=1,nsppol
    2759         [ +  + ]:        2318 :      do im1=1,ndim
    2760         [ +  + ]:       13030 :        do im=1,ndim
    2761                 :             : !              if(im/=im1) write(std_out,*) "im,im1",im,im1,matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor)
    2762                 :             :  !            if(present(nondiag).eqv..false.) then
    2763                 :             :  !              if(im/=im1.and.(abs(matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor))>tol))  then
    2764                 :             :  !                write(message,'(5i5)') im,im1,isppol,ispinor,ispinor
    2765                 :             :  !                call wrtout(std_out,message,'COLL')
    2766                 :             :  !                write(message,'(a,3e16.5)')" checkdiag_matlu: Warning ",matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor),tol
    2767                 :             :  !                call wrtout(std_out,message,'COLL')
    2768                 :             :  !                if(.not.present(opt)) ABI_ERROR("not present(opt)")
    2769                 :             :  !                if(matlu(1)%nspinor==1) ABI_ERROR("matlu%nspinor==1")
    2770                 :             :  !              endif
    2771                 :             : !             endif
    2772                 :             :  !              if(present(nondiag)) then
    2773   [ +  +  +  + ]:       12748 :          if ((im /= im1) .and. abs(dble(matlu(iatom)%mat(im,im1,isppol))) > tol) nondiag = .true.
    2774                 :             :                   ! write(6,*) "NONDIAG", matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1)
    2775                 :             :                !if(ispinor/=ispinor1.and.(abs(matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1))>tol))  then
    2776                 :             :                !  write(message,'(a,3e16.5)')" checkdiag_matlu :i Warning ",matlu(iatom)%mat(im,im1,isppol,ispinor,ispinor1),tol
    2777                 :             :                !  call wrtout(std_out,message,'COLL')
    2778                 :             :                !  write(message,'(5i5)') im,im1,isppol,ispinor,ispinor
    2779                 :             :                !  call wrtout(std_out,message,'COLL')
    2780                 :             :                !  if(matlu(1)%nspinor==1) ABI_ERROR("matlu%nspinor==1")
    2781                 :             :                !endif
    2782                 :             :        end do ! im
    2783                 :             :      end do ! im1
    2784                 :             :    end do ! isppol
    2785                 :             :  end do ! iatom
    2786                 :             : 
    2787                 :         148 :  end subroutine checkdiag_matlu
    2788                 :             : !!***
    2789                 :             : 
    2790                 :             : !!****f* m_matlu/prod_matlu
    2791                 :             : !! NAME
    2792                 :             : !! prod_matlu
    2793                 :             : !!
    2794                 :             : !! FUNCTION
    2795                 :             : !! Matrix product of two matlus
    2796                 :             : !!
    2797                 :             : !! COPYRIGHT
    2798                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2799                 :             : !! This file is distributed under the terms of the
    2800                 :             : !! GNU General Public License, see ~abinit/COPYING
    2801                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2802                 :             : !!
    2803                 :             : !! INPUTS
    2804                 :             : !!  matlu1(natom) :: input quantity
    2805                 :             : !!  matlu2(natom) :: input quantity
    2806                 :             : !!
    2807                 :             : !! OUTPUT
    2808                 :             : !!  matlu3(natom) :: output quantity
    2809                 :             : !!
    2810                 :             : !! SIDE EFFECTS
    2811                 :             : !!
    2812                 :             : !! NOTES
    2813                 :             : !!
    2814                 :             : !! SOURCE
    2815                 :             : 
    2816                 :          72 :  subroutine prod_matlu(matlu1,matlu2,matlu3,natom)
    2817                 :             : 
    2818                 :             : !Arguments ------------------------------------
    2819                 :             :  integer, intent(in) :: natom
    2820                 :             :  type(matlu_type), intent(in) :: matlu1(natom),matlu2(natom)
    2821                 :             :  type(matlu_type), intent(inout) :: matlu3(natom)
    2822                 :             : !Local variables-------------------------------
    2823                 :             :  integer :: iatom,isppol,lpawu,ndim,nspinor,nsppol
    2824                 :             : !************************************************************************
    2825                 :             : 
    2826                 :          72 :  nspinor = matlu1(1)%nspinor
    2827                 :          72 :  nsppol  = matlu1(1)%nsppol
    2828                 :             : 
    2829         [ +  + ]:         212 :  do iatom=1,natom
    2830                 :         140 :    lpawu = matlu1(iatom)%lpawu
    2831         [ +  + ]:         140 :    if (lpawu == -1) cycle
    2832                 :          80 :    ndim = nspinor * (2*lpawu+1)
    2833         [ +  + ]:         272 :    do isppol=1,nsppol
    2834                 :             :      call abi_xgemm("n","n",ndim,ndim,ndim,cone,matlu1(iatom)%mat(:,:,isppol),ndim,&
    2835                 :         260 :                   & matlu2(iatom)%mat(:,:,isppol),ndim,czero,matlu3(iatom)%mat(:,:,isppol),ndim)
    2836                 :             :    end do ! isppol
    2837                 :             :  end do ! iatom
    2838                 :             : 
    2839                 :             :   !call zero_matlu(matlu3,natom)
    2840                 :             :  !do iatom=1,natom
    2841                 :             :  !  lpawu=matlu1(iatom)%lpawu
    2842                 :             :  !  if(lpawu.ne.-1) then
    2843                 :             :  !    do isppol=1,matlu1(1)%nsppol
    2844                 :             :  !      do ispinor1=1,matlu1(1)%nspinor
    2845                 :             :  !        do ispinor2=1,matlu1(1)%nspinor
    2846                 :             :  !          do ispinor3=1,matlu1(1)%nspinor
    2847                 :             :  !            do im1=1,2*lpawu+1
    2848                 :             :  !              do im2=1,2*lpawu+1
    2849                 :             :  !                do im3=1,2*lpawu+1
    2850                 :             :  !                  matlu3(iatom)%mat(im1,im2,isppol,ispinor1,ispinor2)= &
    2851                 :             : !&                    matlu3(iatom)%mat(im1,im2,isppol,ispinor1,ispinor2)+ &
    2852                 :             : !&                    matlu1(iatom)%mat(im1,im3,isppol,ispinor1,ispinor3)*&
    2853                 :             : !&                    matlu2(iatom)%mat(im3,im2,isppol,ispinor3,ispinor2)
    2854                 :             :  !                enddo ! im3
    2855                 :             :  !              enddo ! im2
    2856                 :             :  !            enddo ! im1
    2857                 :             :  !          enddo ! ispinor3
    2858                 :             :  !        enddo ! ispinor2
    2859                 :             :  !      enddo ! ispinor1
    2860                 :             :  !    enddo ! isppol
    2861                 :             :  !  endif ! lpawu
    2862                 :             :  !enddo ! iatom
    2863                 :             : 
    2864                 :          72 :  end subroutine prod_matlu
    2865                 :             : !!***
    2866                 :             : 
    2867                 :             : !!****f* m_matlu/conjg_matlu
    2868                 :             : !! NAME
    2869                 :             : !! conjg_matlu
    2870                 :             : !!
    2871                 :             : !! FUNCTION
    2872                 :             : !! conjugate of input matlu
    2873                 :             : !!
    2874                 :             : !! COPYRIGHT
    2875                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2876                 :             : !! This file is distributed under the terms of the
    2877                 :             : !! GNU General Public License, see ~abinit/COPYING
    2878                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2879                 :             : !!
    2880                 :             : !! INPUTS
    2881                 :             : !!  matlu1(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: input quantity
    2882                 :             : !!
    2883                 :             : !! SIDE EFFECTS
    2884                 :             : !!
    2885                 :             : !! NOTES
    2886                 :             : !!
    2887                 :             : !! SOURCE
    2888                 :           0 :  subroutine conjg_matlu(matlu1,natom)
    2889                 :             :  use defs_wvltypes
    2890                 :             : 
    2891                 :             : !Arguments ------------------------------------
    2892                 :             : !scalars
    2893                 :             :  integer, intent(in) :: natom
    2894                 :             : !arrays
    2895                 :             :  type(matlu_type), intent(inout) :: matlu1(natom)
    2896                 :             : !Local variables-------------------------------
    2897                 :             : !scalars
    2898                 :             :  integer :: iatom,im1,im2,ispinor2,ispinor1,isppol
    2899                 :             :  integer :: lpawu,ndim
    2900                 :             : !arrays
    2901                 :             : !************************************************************************
    2902         [ #  # ]:           0 :  do iatom=1,natom
    2903                 :           0 :    lpawu=matlu1(iatom)%lpawu
    2904         [ #  # ]:           0 :    if(lpawu.ne.-1) then
    2905                 :           0 :      ndim=2*lpawu+1
    2906         [ #  # ]:           0 :      do isppol=1,matlu1(1)%nsppol
    2907         [ #  # ]:           0 :        do ispinor1=1,matlu1(1)%nspinor
    2908         [ #  # ]:           0 :          do ispinor2=1,matlu1(1)%nspinor
    2909         [ #  # ]:           0 :            do im1=1,2*lpawu+1
    2910         [ #  # ]:           0 :              do im2=1,2*lpawu+1
    2911                 :             :                matlu1(iatom)%mat(im1+(ispinor1-1)*ndim,im2+(ispinor2-1)*ndim,isppol)= &
    2912                 :           0 : &               conjg(matlu1(iatom)%mat(im1+(ispinor1-1)*ndim,im2+(ispinor2-1)*ndim,isppol))
    2913                 :             :              enddo ! im2
    2914                 :             :            enddo ! im1
    2915                 :             :          enddo ! ispinor2
    2916                 :             :        enddo ! ispinor1
    2917                 :             :      enddo ! isppol
    2918                 :             :    endif ! lpawu
    2919                 :             :  enddo ! iatom
    2920                 :             : 
    2921                 :           0 :  end subroutine conjg_matlu
    2922                 :             : !!***
    2923                 :             : 
    2924                 :             : !!****f* m_matlu/ln_matlu
    2925                 :             : !! NAME
    2926                 :             : !! ln_matlu
    2927                 :             : !!
    2928                 :             : !! FUNCTION
    2929                 :             : !! Compute the logarithm of matlu (only if diagonal for the moment)
    2930                 :             : !!
    2931                 :             : !! COPYRIGHT
    2932                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2933                 :             : !! This file is distributed under the terms of the
    2934                 :             : !! GNU General Public License, see ~abinit/COPYING
    2935                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2936                 :             : !!
    2937                 :             : !! INPUTS
    2938                 :             : !!  matlu1(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: input quantity
    2939                 :             : 
    2940                 :             : !! SIDE EFFECTS
    2941                 :             : !!
    2942                 :             : !! NOTES
    2943                 :             : !!
    2944                 :             : !! SOURCE
    2945                 :           0 :  subroutine ln_matlu(matlu1,natom)
    2946                 :             :  use defs_wvltypes
    2947                 :             : 
    2948                 :             : !Arguments ------------------------------------
    2949                 :             : !scalars
    2950                 :             :  integer, intent(in) :: natom
    2951                 :             : !arrays
    2952                 :             :  type(matlu_type), intent(inout) :: matlu1(natom)
    2953                 :             : !Local variables-------------------------------
    2954                 :             : !scalars
    2955                 :             :  integer :: iatom,im,ispinor,isppol
    2956                 :             :  integer :: lpawu,ndim
    2957                 :             :  character(len=500) :: message
    2958                 :             : !arrays
    2959                 :             : !************************************************************************
    2960                 :             :  !call checkdiag_matlu(matlu1,natom,tol8)
    2961         [ #  # ]:           0 :  do iatom=1,natom
    2962                 :           0 :    lpawu=matlu1(iatom)%lpawu
    2963         [ #  # ]:           0 :    if(lpawu.ne.-1) then
    2964                 :           0 :      ndim=2*lpawu+1
    2965         [ #  # ]:           0 :      do isppol=1,matlu1(1)%nsppol
    2966         [ #  # ]:           0 :        do ispinor=1,matlu1(1)%nspinor
    2967         [ #  # ]:           0 :          do im=1,2*lpawu+1
    2968         [ #  # ]:           0 :            if( real(matlu1(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol))<zero) then
    2969                 :           0 :              write(message,'(2a,2es13.5,a)') ch10," ln_matlu: PROBLEM " &
    2970                 :           0 : &             , matlu1(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)
    2971                 :           0 :              ABI_ERROR(message)
    2972                 :             :            endif
    2973                 :             :            matlu1(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol)= &
    2974                 :           0 : &           log(matlu1(iatom)%mat(im+(ispinor-1)*ndim,im+(ispinor-1)*ndim,isppol))
    2975                 :             :          enddo ! im
    2976                 :             :        enddo ! ispinor
    2977                 :             :      enddo ! isppol
    2978                 :             :    endif ! lpawu
    2979                 :             :  enddo ! iatom
    2980                 :             : 
    2981                 :           0 :  end subroutine ln_matlu
    2982                 :             : !!***
    2983                 :             : 
    2984                 :             : !!****f* m_matlu/slm2ylm_matlu
    2985                 :             : !! NAME
    2986                 :             : !! slm2ylm_matlu
    2987                 :             : !!
    2988                 :             : !! FUNCTION
    2989                 :             : !! Transform mat from Slm to Ylm basis or vice versa
    2990                 :             : !!
    2991                 :             : !! COPYRIGHT
    2992                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    2993                 :             : !! This file is distributed under the terms of the
    2994                 :             : !! GNU General Public License, see ~abinit/COPYING
    2995                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    2996                 :             : !!
    2997                 :             : !! INPUTS
    2998                 :             : !!  matlu1(natom) :: input quantity
    2999                 :             : !!  natom :: number of atoms
    3000                 :             : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    3001                 :             : !!  option=1 go from Slm to Ylm basis
    3002                 :             : !!  option=2 go from Ylm to Slm basis
    3003                 :             : !! SIDE EFFECTS
    3004                 :             : !!
    3005                 :             : !! NOTES
    3006                 :             : !!
    3007                 :             : !! SOURCE
    3008                 :             : 
    3009                 :       12400 :  subroutine slm2ylm_matlu(matlu,natom,paw_dmft,option,optprt)
    3010                 :             : 
    3011                 :             : !Arguments ------------------------------------
    3012                 :             :  integer, intent(in) :: natom,option,optprt
    3013                 :             :  type(matlu_type), target, intent(inout) :: matlu(natom)
    3014                 :             :  type(paw_dmft_type), target, intent(in) :: paw_dmft
    3015                 :             : !Local variables-------------------------------
    3016                 :             :  integer :: iatom,im1,im2,ispin,ispinor1,ispinor2,isppol
    3017                 :             :  integer :: lpawu,ndim,ndim_max,nspin,nspinor,nsppol
    3018                 :             :  complex(dp), pointer :: mat_out(:,:) => null(), slm2ylm(:,:) => null()
    3019                 :       12400 :  complex(dp), allocatable :: mat_inp(:,:),mat_tmp(:,:)
    3020                 :       12400 :  complex(dp), target, allocatable :: mat_tmp2(:,:)
    3021                 :             :  character(len=1) :: c1,c2
    3022                 :             :  character(len=500) :: message
    3023                 :             : !************************************************************************
    3024                 :             : 
    3025                 :       12400 :  ndim_max = 2*paw_dmft%maxlpawu + 1
    3026                 :       12400 :  nspinor  = paw_dmft%nspinor
    3027                 :       12400 :  nsppol   = paw_dmft%nsppol
    3028                 :       12400 :  nspin    = nsppol * (nspinor**2)
    3029                 :             : 
    3030         [ +  + ]:       12400 :  if (option == 1) then
    3031                 :        5604 :    c1 = "n" ; c2 = "c"
    3032         [ +  - ]:        6796 :  else if (option == 2) then
    3033                 :        6796 :    c1 = "c" ; c2 = "n"
    3034                 :             :  end if
    3035                 :             : 
    3036         [ +  + ]:       62000 :  do iatom=1,natom
    3037                 :             : 
    3038                 :       49600 :    lpawu = paw_dmft%lpawu(iatom)
    3039         [ +  + ]:       49600 :    if (lpawu == -1) cycle
    3040                 :       37200 :    ndim = 2*lpawu + 1
    3041                 :       37200 :    slm2ylm => paw_dmft%slm2ylm(:,:,lpawu+1)
    3042                 :             : 
    3043         [ -  + ]:       37200 :    if (optprt > 2) then
    3044                 :           0 :      write(message,'(2a)') ch10,"SLM2YLM matrix"
    3045                 :           0 :      call wrtout(std_out,message,'COLL')
    3046         [ #  # ]:           0 :      do im1=1,ndim
    3047                 :           0 :        write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))') (slm2ylm(im1,im2),im2=1,ndim)
    3048                 :           0 :        call wrtout(std_out,message,'COLL')
    3049                 :             :      end do ! im1
    3050                 :             :    end if ! optprt>2
    3051                 :             : 
    3052   [ -  +  +  -  :      148800 :    ABI_MALLOC(mat_inp,(ndim,ndim))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    3053   [ -  +  +  -  :      148800 :    ABI_MALLOC(mat_tmp,(ndim,nspin*ndim))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    3054   [ -  +  +  -  :      111600 :    ABI_MALLOC(mat_tmp2,(ndim,nspin*ndim))
          -  +  +  -  -  
                +  -  + ]
    3055                 :             : 
    3056                 :       37200 :    ispin = 0
    3057                 :             : 
    3058         [ +  + ]:       74400 :    do isppol=1,nsppol
    3059         [ +  + ]:      148800 :      do ispinor2=1,nspinor
    3060         [ +  + ]:      260400 :        do ispinor1=1,nspinor
    3061                 :             : 
    3062                 :      148800 :          ispin = ispin + 1
    3063                 :             : 
    3064                 :             :          ! Make copy here instead of creating a temporary when calling zgemm in order to please -fcheck
    3065   [ +  +  +  + ]:     8481600 :          mat_inp(:,:) = matlu(iatom)%mat(1+(ispinor1-1)*ndim:ndim*ispinor1,1+(ispinor2-1)*ndim:ispinor2*ndim,isppol)
    3066                 :             : 
    3067         [ -  + ]:      148800 :          if (optprt > 2) then
    3068                 :           0 :            write(message,'(2a,i2,a,i2,a,i2)') ch10,"SLM input matrix,&
    3069                 :           0 :              & isppol=",isppol,", ispinor1=",ispinor1,", ispinor2=",ispinor2
    3070                 :           0 :            call wrtout(std_out,message,'COLL')
    3071         [ #  # ]:           0 :            do im1=1,ndim
    3072                 :             :              write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))') &
    3073                 :           0 :                & (mat_inp(im1,im2),im2=1,ndim)
    3074                 :           0 :              call wrtout(std_out,message,'COLL')
    3075                 :             :            end do ! im1
    3076                 :             :          end if ! optprt>2
    3077                 :             : 
    3078                 :             :          call abi_xgemm("n",c2,ndim,ndim,ndim,cone,mat_inp(:,:),ndim,slm2ylm(:,1:ndim), &
    3079         [ -  + ]:      223200 :                       & ndim_max,czero,mat_tmp(:,1+(ispin-1)*ndim:ndim*ispin),ndim)
    3080                 :             : 
    3081                 :             :        end do ! ispinor2
    3082                 :             :      end do ! ispinor1
    3083                 :             :    end do ! isppol
    3084                 :             : 
    3085                 :             :    call abi_xgemm(c1,"n",ndim,ndim*nspin,ndim,cone,slm2ylm(:,1:ndim),ndim_max,mat_tmp(:,:),ndim, &
    3086         [ -  + ]:       37200 :                 & czero,mat_tmp2(:,:),ndim)
    3087                 :             : 
    3088                 :       37200 :    ispin = 0
    3089                 :             : 
    3090         [ +  + ]:       74400 :    do isppol=1,nsppol
    3091         [ +  + ]:      148800 :      do ispinor2=1,nspinor
    3092         [ +  + ]:      260400 :        do ispinor1=1,nspinor
    3093                 :             : 
    3094                 :      148800 :          ispin = ispin + 1
    3095                 :             : 
    3096                 :      148800 :          mat_out => mat_tmp2(:,1+(ispin-1)*ndim:ndim*ispin)
    3097                 :             : 
    3098   [ +  -  +  +  :    16963200 :          matlu(iatom)%mat(1+(ispinor1-1)*ndim:ndim*ispinor1,1+(ispinor2-1)*ndim:ispinor2*ndim,isppol) = mat_out(:,:)
          +  +  +  +  +  
                      + ]
    3099                 :             : 
    3100         [ -  + ]:      223200 :          if (optprt > 2) then
    3101                 :           0 :            write(message,'(2a,i2,a,i2,a,i2)') ch10,"YLM output matrix, isppol=",isppol,", ispinor=",ispinor1,&
    3102                 :           0 :               & ", ispinor2=",ispinor2
    3103                 :           0 :            call wrtout(std_out,message,'COLL')
    3104         [ #  # ]:           0 :            do im1=1,ndim
    3105                 :           0 :              write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))') (mat_out(im1,im2),im2=1,ndim)
    3106                 :           0 :              call wrtout(std_out,message,'COLL')
    3107                 :             :            end do ! im1
    3108                 :             :          end if ! optprt>2
    3109                 :             : 
    3110                 :             :        end do ! ispinor1
    3111                 :             :      end do ! ispinor2
    3112                 :             :    end do ! isppol
    3113                 :             : 
    3114         [ -  + ]:       37200 :    ABI_FREE(mat_inp)
    3115         [ -  + ]:       37200 :    ABI_FREE(mat_tmp)
    3116         [ -  + ]:       62000 :    ABI_FREE(mat_tmp2)
    3117                 :             : 
    3118                 :             :  end do ! iatom
    3119                 :             : 
    3120                 :       12400 :  mat_out => null()
    3121                 :       12400 :  slm2ylm => null()
    3122                 :             : 
    3123                 :             :  !do iatom=1,natom
    3124                 :             :  !  lpawu=matlu(iatom)%lpawu
    3125                 :             :  !  if(lpawu.ne.-1) then
    3126                 :             :  !    ndim=2*lpawu+1
    3127                 :             :  !    ll=lpawu
    3128                 :             :  !    ABI_MALLOC(slm2ylm,(2*ll+1,2*ll+1))
    3129                 :             :  !    slm2ylm=czero
    3130                 :             :  !    do im=1,2*ll+1
    3131                 :             :  !      mm=im-ll-1;jm=-mm+ll+1
    3132                 :             :  !      onem=dble((-1)**mm)
    3133                 :             :  !      if (mm> 0) then
    3134                 :             :  !        slm2ylm(im,im)= cmplx(onem*invsqrt2,zero,kind=dp)
    3135                 :             :  !        slm2ylm(jm,im)= cmplx(invsqrt2,     zero,kind=dp)
    3136                 :             :  !      end if
    3137                 :             :  !      if (mm==0) then
    3138                 :             :  !        slm2ylm(im,im)=cone
    3139                 :             :  !      end if
    3140                 :             :  !      if (mm< 0) then
    3141                 :             :  !        slm2ylm(im,im)= cmplx(zero,     invsqrt2,kind=dp)
    3142                 :             :  !        slm2ylm(jm,im)=-cmplx(zero,onem*invsqrt2,kind=dp)
    3143                 :             :  !      end if
    3144                 :             :  !    end do
    3145                 :             :  !    if(optprt>2) then
    3146                 :             :  !      write(message,'(2a)') ch10,"SLM2YLM matrix"
    3147                 :             :  !      call wrtout(std_out,message,'COLL')
    3148                 :             :  !      do im1=1,ll*2+1
    3149                 :             :  !        write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3150                 :             : !&         (slm2ylm(im1,im2),im2=1,ll*2+1)
    3151                 :             :  !        call wrtout(std_out,message,'COLL')
    3152                 :             :  !      end do
    3153                 :             :  !    endif
    3154                 :             :  !    do isppol=1,matlu(1)%nsppol
    3155                 :             :  !      do ispinor=1,matlu(1)%nspinor
    3156                 :             :  !        do ispinor2=1,matlu(1)%nspinor
    3157                 :             :  !          ABI_MALLOC(mat_out_c,(2*ll+1,2*ll+1))
    3158                 :             :  !          ABI_MALLOC(mat_inp_c,(2*ll+1,2*ll+1))
    3159                 :             :  !          mat_inp_c(:,:) = matlu(iatom)%mat(1+(ispinor-1)*ndim:ndim+(ispinor-1)*ndim,1+(ispinor2-1)*ndim:ndim+(ispinor2-1)*ndim,isppol)
    3160                 :             :  !          mat_out_c=czero
    3161                 :             : 
    3162                 :             :  !          if(optprt>2) then
    3163                 :             :  !            write(message,'(2a, i2, a, i2, a, i2)') ch10,"SLM input matrix, isppol=", isppol, ", ispinor=", ispinor,&
    3164                 :             : !&             ", ispinor2=", ispinor2
    3165                 :             :  !            call wrtout(std_out,message,'COLL')
    3166                 :             :  !            do im1=1,ll*2+1
    3167                 :             :  !              write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3168                 :             : !&               (mat_inp_c(im1,im2),im2=1,ll*2+1)
    3169                 :             :  !              call wrtout(std_out,message,'COLL')
    3170                 :             :  !            end do
    3171                 :             :  !          endif
    3172                 :             : 
    3173                 :             :   !         do jm=1,2*ll+1
    3174                 :             :   !           do im=1,2*ll+1
    3175                 :             :   !             tmp2=czero
    3176                 :             :   !             do ii=1,2*ll+1
    3177                 :             :   !               do jj=1,2*ll+1
    3178                 :             :   !                 if(option==1) then
    3179                 :             :   !                   tmp2=tmp2+mat_inp_c(ii,jj)*(slm2ylm(im,ii))*CONJG(slm2ylm(jm,jj))
    3180                 :             :   !                 else if(option==2) then
    3181                 :             :   !                   tmp2=tmp2+mat_inp_c(ii,jj)*CONJG(slm2ylm(ii,im))*(slm2ylm(jj,jm))
    3182                 :             :   !                 end if
    3183                 :             :   !               end do
    3184                 :             :   !             end do
    3185                 :             :   !             mat_out_c(im,jm)=tmp2
    3186                 :             :   !           end do
    3187                 :             :   !         end do
    3188                 :             : 
    3189                 :             :   !         if(optprt>2) then
    3190                 :             :   !           write(message,'(2a, i2, a, i2, a, i2)') ch10,"YLM output matrix, isppol=", isppol, ", ispinor=", ispinor,&
    3191                 :             : !&             ", ispinor2=", ispinor2
    3192                 :             :   !           call wrtout(std_out,message,'COLL')
    3193                 :             :   !           do im1=1,ll*2+1
    3194                 :             :   !             write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3195                 :             :   !    &         (mat_out_c(im1,im2),im2=1,ll*2+1)
    3196                 :             :   !             call wrtout(std_out,message,'COLL')
    3197                 :             :   !           end do
    3198                 :             :   !         endif
    3199                 :             : 
    3200                 :             :   !         matlu(iatom)%mat(1+(ispinor-1)*ndim:ndim+(ispinor-1)*ndim,1+(ispinor2-1)*ndim:ndim+(ispinor2-1)*ndim,isppol)=mat_out_c(:,:)
    3201                 :             :   !         ABI_FREE(mat_out_c)
    3202                 :             :   !         ABI_FREE(mat_inp_c)
    3203                 :             :   !      enddo ! im
    3204                 :             :  !      enddo ! ispinor
    3205                 :             :  !    enddo ! isppol
    3206                 :             :  !    ABI_FREE(slm2ylm)
    3207                 :             :  !  endif ! lpawu
    3208                 :             :  !enddo ! iatom
    3209                 :             : 
    3210                 :       12400 :  end subroutine slm2ylm_matlu
    3211                 :             : !!***
    3212                 :             : 
    3213                 :             : !!****f* m_matlu/fac_matlu
    3214                 :             : !! NAME
    3215                 :             : !! fac_matlu
    3216                 :             : !!
    3217                 :             : !! FUNCTION
    3218                 :             : !! Multiply matlu by a scalar
    3219                 :             : !!
    3220                 :             : !! COPYRIGHT
    3221                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    3222                 :             : !! This file is distributed under the terms of the
    3223                 :             : !! GNU General Public License, see ~abinit/COPYING
    3224                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    3225                 :             : !!
    3226                 :             : !! INPUTS
    3227                 :             : !!  matlu(natom) :: input quantity
    3228                 :             : !!  natom=number of atoms in cell.
    3229                 :             : !!  fac= factor
    3230                 :             : !!
    3231                 :             : !! OUTPUT
    3232                 :             : !!  matlu(natom) :: fac * matlu
    3233                 :             : !!
    3234                 :             : !! SIDE EFFECTS
    3235                 :             : !!
    3236                 :             : !! NOTES
    3237                 :             : !!
    3238                 :             : !! SOURCE
    3239                 :             : 
    3240                 :       33157 :  subroutine fac_matlu(matlu,natom,fac)
    3241                 :             : 
    3242                 :             : !Arguments ------------------------------------
    3243                 :             :  integer, intent(in) :: natom
    3244                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    3245                 :             :  complex(dp), intent(in) :: fac
    3246                 :             : !Local variables-------------------------------
    3247                 :             :  integer :: iatom,lpawu
    3248                 :             : ! character(len=500) :: message
    3249                 :             : !************************************************************************
    3250                 :             : 
    3251         [ +  + ]:      110606 :  do iatom=1,natom
    3252                 :       77449 :    lpawu = matlu(iatom)%lpawu
    3253         [ +  + ]:       77449 :    if (lpawu == -1) cycle
    3254   [ +  +  +  +  :    10082764 :    matlu(iatom)%mat(:,:,:) = fac * matlu(iatom)%mat(:,:,:)
                   +  + ]
    3255                 :             :  end do ! iatom
    3256                 :             : 
    3257                 :       33157 :  end subroutine fac_matlu
    3258                 :             : !!***
    3259                 :             : 
    3260                 :             : !!****f* m_matlu/printplot_matlu
    3261                 :             : !! NAME
    3262                 :             : !! printplot_matlu
    3263                 :             : !!
    3264                 :             : !! FUNCTION
    3265                 :             : !! Write matlu for a given frequency
    3266                 :             : !!
    3267                 :             : !! COPYRIGHT
    3268                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    3269                 :             : !! This file is distributed under the terms of the
    3270                 :             : !! GNU General Public License, see ~abinit/COPYING
    3271                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    3272                 :             : !!
    3273                 :             : !! INPUTS
    3274                 :             : !!  matlu(natom) :: input quantity to write
    3275                 :             : !!  natom=number of atoms in cell.
    3276                 :             : !!  freq :: frequency
    3277                 :             : !!  char1 :: name of the file on which to write
    3278                 :             : !!  units :: unit of the file
    3279                 :             : !!  imre :: if present, write real and imaginary parts in two different files
    3280                 :             : !!
    3281                 :             : !! OUTPUT
    3282                 :             : !!
    3283                 :             : !! SIDE EFFECTS
    3284                 :             : !!
    3285                 :             : !! NOTES
    3286                 :             : !!
    3287                 :             : !! SOURCE
    3288                 :             : 
    3289                 :           0 :  subroutine printplot_matlu(matlu,natom,freq,char1,units,imre)
    3290                 :             : 
    3291                 :             : !Arguments ------------------------------------
    3292                 :             : !scalars
    3293                 :             :  integer, intent(in) :: natom,units
    3294                 :             :  integer, optional, intent(in) :: imre
    3295                 :             :  real(dp), intent(in) :: freq
    3296                 :             : !arrays
    3297                 :             :  type(matlu_type), intent(in) :: matlu(natom)
    3298                 :             :  character(len=*), intent(in) :: char1
    3299                 :             : !Local variables-------------------------------
    3300                 :             : !scalars
    3301                 :             :  integer :: iatom,im,im1,ispinor,ispinor1,isppol
    3302                 :             :  integer :: lpawu,ndim,nspinor,nsppol,unitnb
    3303                 :             :  character(len=4) :: tag_at
    3304                 :             :  character(len=fnlen) :: tmpfil,tmpfilim,tmpfilre
    3305                 :             : ! character(len=500) :: message
    3306                 :             : !arrays
    3307                 :             : !************************************************************************
    3308                 :             : 
    3309                 :           0 :  nspinor = matlu(1)%nspinor
    3310                 :           0 :  nsppol  = matlu(1)%nsppol
    3311                 :             : 
    3312                 :             :  ! not yet tested and used
    3313         [ #  # ]:           0 :  do iatom=1,natom
    3314                 :           0 :    lpawu = matlu(iatom)%lpawu
    3315         [ #  # ]:           0 :    if (lpawu == -1) cycle
    3316                 :           0 :    ndim   = 2*lpawu + 1
    3317                 :           0 :    unitnb = units + iatom
    3318                 :           0 :    call int2char4(iatom,tag_at)
    3319         [ #  # ]:           0 :    if (present(imre)) then
    3320         [ #  # ]:           0 :      tmpfilre = trim(char1)//tag_at//"re"
    3321         [ #  # ]:           0 :      tmpfilim = trim(char1)//tag_at//"im"
    3322                 :           0 :      open(unit=unitnb+10,file=trim(tmpfilre),status='unknown',form='formatted')
    3323                 :           0 :      open(unit=unitnb+20,file=trim(tmpfilim),status='unknown',form='formatted')
    3324                 :           0 :      write(unitnb+10,'(400e26.16)') freq,(((((dble(matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
    3325   [ #  #  #  #  :           0 :       & im=1,ndim),ispinor=1,nspinor),im1=1,ndim),ispinor1=1,nspinor),isppol=1,nsppol)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    3326                 :           0 :      write(unitnb+20,'(400e26.16)') freq,(((((aimag(matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol)),&
    3327   [ #  #  #  #  :           0 :       & im=1,ndim),ispinor=1,nspinor),im1=1,ndim),ispinor1=1,nspinor),isppol=1,nsppol)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    3328                 :             :    else
    3329         [ #  # ]:           0 :      tmpfil = trim(char1)//tag_at
    3330                 :           0 :      open(unit=unitnb,file=trim(tmpfil),status='unknown',form='formatted')
    3331                 :           0 :      write(unitnb,'(400e26.16)') freq,(((((matlu(iatom)%mat(im+(ispinor-1)*ndim,im1+(ispinor1-1)*ndim,isppol),&
    3332   [ #  #  #  #  :           0 :       & im=1,ndim),ispinor=1,nspinor),im1=1,ndim),ispinor1=1,nspinor),isppol=1,nsppol)
          #  #  #  #  #  
          #  #  #  #  #  
          #  #  #  #  #  
                      # ]
    3333                 :             :    end if ! present(imre)
    3334                 :             :  end do ! iatom
    3335                 :             : 
    3336                 :           0 :  end subroutine printplot_matlu
    3337                 :             : !!***
    3338                 :             : 
    3339                 :             : !!****f* m_matlu/identity_matlu
    3340                 :             : !! NAME
    3341                 :             : !! identity_matlu
    3342                 :             : !!
    3343                 :             : !! FUNCTION
    3344                 :             : !!  Set the diagonal elements to 1 (the off-diagonal are not set to 0)
    3345                 :             : !!
    3346                 :             : !! COPYRIGHT
    3347                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    3348                 :             : !! This file is distributed under the terms of the
    3349                 :             : !! GNU General Public License, see ~abinit/COPYING
    3350                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    3351                 :             : !!
    3352                 :             : !! INPUTS
    3353                 :             : !!  matlu(natom) :: input quantity
    3354                 :             : !!  natom=number of atoms in cell.
    3355                 :             : !!
    3356                 :             : !! OUTPUT
    3357                 :             : !!
    3358                 :             : !! SIDE EFFECTS
    3359                 :             : !!
    3360                 :             : !! NOTES
    3361                 :             : !!
    3362                 :             : !! SOURCE
    3363                 :             : 
    3364                 :         275 :  subroutine identity_matlu(matlu,natom)
    3365                 :             : 
    3366                 :             : !Arguments ------------------------------------
    3367                 :             :  integer, intent(in) :: natom
    3368                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    3369                 :             : !Local variables-------------------------------
    3370                 :             :  integer :: iatom,im,lpawu,ndim,nspinor
    3371                 :             : ! character(len=500) :: message
    3372                 :             : !arrays
    3373                 :             : !************************************************************************
    3374                 :             : 
    3375                 :         275 :  nspinor = matlu(1)%nspinor
    3376                 :             : 
    3377         [ +  + ]:        1255 :  do iatom=1,natom
    3378                 :         980 :    lpawu = matlu(iatom)%lpawu
    3379         [ +  + ]:         980 :    if (lpawu == -1) cycle
    3380                 :         327 :    ndim = nspinor * (2*lpawu+1)
    3381         [ +  + ]:        2294 :    do im=1,ndim
    3382         [ +  + ]:        5004 :      matlu(iatom)%mat(im,im,:) = cone
    3383                 :             :    end do ! im
    3384                 :             :  end do ! iatom
    3385                 :             : 
    3386                 :         275 :  end subroutine identity_matlu
    3387                 :             : !!***
    3388                 :             : 
    3389                 :             : !!***
    3390                 :             : !!****f* m_matlu/magmomforb_matlu
    3391                 :             : !! NAME
    3392                 :             : !! magmomforb_matlu
    3393                 :             : !!
    3394                 :             : !! FUNCTION
    3395                 :             : !! return the product of occupation matrix of dimension [(2*ll+1)]**4 in the Ylm basis
    3396                 :             : !! with the matrix of orbital angular momentum element for the x,y and z direction.
    3397                 :             : !! Option gives the direction of the magnetic moment x==1, y==2 and z==3.
    3398                 :             : !!
    3399                 :             : !!
    3400                 :             : !! COPYRIGHT
    3401                 :             : !! Copyright (C) 2005-2026 ABINIT group (FGendron)
    3402                 :             : !! This file is distributed under the terms of the
    3403                 :             : !! GNU General Public License, see ~abinit/COPYING
    3404                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    3405                 :             : !!
    3406                 :             : !! INPUTS
    3407                 :             : !! matlu1(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: input quantity in Ylm basis
    3408                 :             : !! natom :: number of atoms
    3409                 :             : !! option = 1 :: x axis
    3410                 :             : !!        = 2 :: y axis
    3411                 :             : !!        = 3 :: z axis
    3412                 :             : !! optptr > 2 :: print orbital angular matrix elements and resulting product
    3413                 :             : !!
    3414                 :             : !! OUTPUT
    3415                 :             : !!  matlu(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: product
    3416                 :             : !!
    3417                 :             : !! SIDE EFFECTS
    3418                 :             : !!
    3419                 :             : !! NOTES
    3420                 :             : !!
    3421                 :             : !! SOURCE
    3422                 :          36 :  subroutine magmomforb_matlu(matlu,mu,natom,option,optprt)
    3423                 :             :  use defs_wvltypes
    3424                 :             : 
    3425                 :             : !Arguments ------------------------------------
    3426                 :             : !scalars
    3427                 :             :  integer, intent(in) :: natom,option,optprt
    3428                 :             :  complex(dp), allocatable, intent(inout) :: mu(:)
    3429                 :             : !arrays
    3430                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    3431                 :             : !Local variables-------------------------------
    3432                 :             : !scalars
    3433                 :             :  integer :: iatom,im,ispinor,isppol,ispinor2
    3434                 :             :  integer :: lpawu,ll,jm,ml1,jc1,ms1,lcor,im1,im2,tndim,ndim
    3435                 :             :  character(len=500) :: message
    3436                 :             :  real(dp) :: xj
    3437                 :             : !arrays
    3438                 :          36 :  complex(dp),allocatable :: mat_out_c(:,:)
    3439                 :             : ! integer, allocatable :: ind_msml(:,:)
    3440                 :          36 :  complex(dp), allocatable :: temp_mat(:,:)
    3441                 :          36 :  type(coeff2c_type), allocatable :: gathermatlu(:)
    3442                 :          36 :  type(coeff2c_type), allocatable :: muorb(:)
    3443                 :             : !************************************************************************
    3444                 :             : 
    3445                 :             :  !=====================================
    3446                 :             :  ! Allocate matrices
    3447                 :             :  !=====================================
    3448                 :             : 
    3449   [ -  +  +  -  :         252 :  ABI_MALLOC(gathermatlu,(natom))
          +  -  +  -  -  
             +  -  +  +  
                      + ]
    3450   [ -  +  +  -  :         216 :  ABI_MALLOC(muorb,(natom))
          -  +  -  +  +  
                      + ]
    3451         [ +  + ]:         180 :  do iatom=1,natom
    3452         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    3453                 :         108 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    3454   [ -  +  +  -  :         432 :      ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3455   [ +  +  +  + ]:       22788 :      gathermatlu(iatom)%value=czero
    3456   [ -  +  +  -  :         324 :      ABI_MALLOC(muorb(iatom)%value,(tndim,tndim))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    3457   [ +  +  +  + ]:       22788 :      muorb(iatom)%value=czero
    3458                 :             :    end if
    3459                 :             :  end do
    3460                 :             : 
    3461         [ +  + ]:         180 :  do iatom=1,natom
    3462                 :         144 :    lpawu=matlu(iatom)%lpawu
    3463         [ +  + ]:         180 :    if(lpawu.ne.-1) then
    3464                 :             : 
    3465                 :         108 :      ll=lpawu
    3466                 :         108 :      lcor=lpawu
    3467                 :             :      !=====================================
    3468                 :             :      !build orbital angular momentum matrix along x axis
    3469                 :             :      !=====================================
    3470         [ +  + ]:         108 :      if(option==1) then
    3471                 :             : 
    3472                 :             :        jc1=0
    3473         [ +  + ]:         144 :        do ms1 =-1,1
    3474                 :         108 :          xj=float(ms1)+half
    3475         [ +  + ]:         900 :          do ml1 = -ll,ll
    3476                 :         756 :             jc1=jc1+1
    3477         [ +  + ]:         756 :             if(jc1 == 1) then
    3478                 :          36 :                muorb(iatom)%value(jc1,jc1+1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5
    3479                 :             :             endif
    3480   [ +  +  +  + ]:         864 :             if(jc1 > 1 .and. jc1 < 2*(2*ll+1)) then
    3481                 :         432 :                muorb(iatom)%value(jc1,jc1+1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5
    3482                 :         432 :                muorb(iatom)%value(jc1,jc1-1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5
    3483         [ +  + ]:         324 :             else if(jc1== 2*(2*ll+1)) then
    3484                 :          36 :                muorb(iatom)%value(jc1,jc1-1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5
    3485                 :             :             end if
    3486                 :             :           end do
    3487                 :             :         end do
    3488                 :             : 
    3489                 :             :      !=====================================
    3490                 :             :      !build orbital angular momentum matrix along y axis
    3491                 :             :      !=====================================
    3492         [ +  + ]:          72 :      else if(option==2) then
    3493                 :             : 
    3494                 :             :        jc1=0
    3495         [ +  + ]:         144 :        do ms1 =-1,1
    3496                 :         108 :          xj=float(ms1)+half
    3497         [ +  + ]:         900 :          do ml1 = -ll,ll
    3498                 :         756 :             jc1=jc1+1
    3499         [ +  + ]:         756 :             if(jc1 == 1) then
    3500                 :          36 :                muorb(iatom)%value(jc1,jc1+1) = cmplx(zero,sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5,kind=dp)
    3501                 :             :             endif
    3502   [ +  +  +  + ]:         864 :             if(jc1 > 1 .and. jc1 < 2*(2*ll+1)) then
    3503                 :         432 :                muorb(iatom)%value(jc1,jc1+1) = cmplx(zero,sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5,kind=dp)
    3504                 :         432 :                muorb(iatom)%value(jc1,jc1-1) = cmplx(zero,-sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5,kind=dp)
    3505         [ +  + ]:         324 :             else if(jc1 == 2*(2*ll+1)) then
    3506                 :          36 :                muorb(iatom)%value(jc1,jc1-1) = cmplx(zero,-sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5,kind=dp)
    3507                 :             :             end if
    3508                 :             :           end do
    3509                 :             :         end do
    3510                 :             : 
    3511                 :             :      !=====================================
    3512                 :             :      !build orbital angular momentum matrix along z axis
    3513                 :             :      !=====================================
    3514         [ +  - ]:          36 :      else if(option==3) then
    3515                 :             :        jc1=0
    3516         [ +  + ]:         144 :        do ms1=-1,1
    3517         [ +  + ]:         900 :          do ml1=-ll,ll
    3518                 :         756 :             jc1=jc1+1
    3519         [ +  + ]:         864 :             if(jc1 < tndim+1) then
    3520                 :         504 :               muorb(iatom)%value(jc1,jc1) = ml1
    3521                 :             :             endif
    3522                 :             :           end do
    3523                 :             :         end do
    3524                 :             :      end if
    3525                 :             : 
    3526         [ -  + ]:         108 :      if(optprt>2) then
    3527                 :           0 :         write(message,'(a,i4)') "Orbital angular momentum matrix elements in |m_l,m_s> basis for axis=", option
    3528                 :           0 :         call wrtout(std_out,message,"COLL")
    3529         [ #  # ]:           0 :         do im=1,2*(ll*2+1)
    3530   [ #  #  #  # ]:           0 :           write(message,'(6(1x,9(1x,f4.1,",",f4.1)))') (muorb(iatom)%value(im,jm),jm=1,2*(ll*2+1))
    3531                 :           0 :           call wrtout(std_out,message,"COLL")
    3532                 :             :         end do
    3533                 :             :      end if
    3534                 :             : 
    3535                 :             :    end if !lpawu
    3536                 :             :  end do !atom
    3537                 :             : 
    3538                 :             :      !=====================================
    3539                 :             :      ! Reshape input Ylm matlu in one 14x14 matrix
    3540                 :             :      !=====================================
    3541                 :             : 
    3542                 :          36 :  call gather_matlu(matlu,gathermatlu,natom,option=1,prtopt=1)
    3543                 :             : 
    3544                 :             : !!printing for debug
    3545                 :             : ! write(std_out,*) "gathermatlu in magmomforb"
    3546                 :             : ! do im1=1,tndim
    3547                 :             : !   write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3548                 :             : !        (gathermatlu(1)%value(im1,im2),im2=1,tndim)
    3549                 :             : !   call wrtout(std_out,message,'COLL')
    3550                 :             : ! end do
    3551                 :             : 
    3552                 :             :      !=====================================
    3553                 :             :      ! Matrix product of Occ and muorb
    3554                 :             :      !=====================================
    3555         [ +  + ]:         180 :  do iatom=1,natom
    3556         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    3557                 :         108 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    3558   [ -  +  +  -  :         432 :      ABI_MALLOC(temp_mat,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    3559                 :             : 
    3560                 :             :      call abi_zgemm('n','n',tndim,tndim,tndim,cone,&
    3561                 :             :      &    gathermatlu(iatom)%value,tndim,&
    3562                 :             :      &    muorb(iatom)%value,tndim,czero,&
    3563                 :         108 :      &    temp_mat,tndim)
    3564                 :             : 
    3565   [ +  -  +  -  :       22896 :      gathermatlu(iatom)%value=temp_mat
          -  +  -  -  +  
                +  +  + ]
    3566         [ -  + ]:         108 :      ABI_FREE(temp_mat)
    3567                 :             : 
    3568                 :             :      !=====================================
    3569                 :             :      ! Trace of matrix product
    3570                 :             :      !=====================================
    3571                 :             : 
    3572         [ +  + ]:        1620 :    do im1=1,tndim
    3573         [ +  + ]:       22788 :      do im2=1,tndim
    3574         [ +  + ]:       22680 :        if(im1==im2) then
    3575                 :        1512 :          mu(iatom) = mu(iatom) + gathermatlu(iatom)%value(im1,im2)
    3576                 :             :        end if
    3577                 :             :      end do
    3578                 :             :    end do
    3579                 :             : 
    3580                 :             : 
    3581                 :             :      !=====================================
    3582                 :             :      ! Reshape product matrix into matlu format
    3583                 :             :      !=====================================
    3584                 :             : 
    3585                 :             :  !call gather_matlu(matlu,gathermatlu,natom,option=-1,prtopt=1)
    3586                 :             : 
    3587                 :             : 
    3588         [ -  + ]:         108 :      if(optprt>2) then
    3589   [ #  #  #  #  :           0 :        ABI_MALLOC(mat_out_c,(2*ll+1,2*ll+1))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    3590                 :           0 :        ndim = 2*ll+1
    3591         [ #  # ]:           0 :        do isppol=1,matlu(1)%nsppol
    3592         [ #  # ]:           0 :          do ispinor=1,matlu(1)%nspinor
    3593         [ #  # ]:           0 :            do ispinor2=1,matlu(1)%nspinor
    3594   [ #  #  #  # ]:           0 :              mat_out_c(:,:) = matlu(iatom)%mat(1+(ispinor-1)*ndim:ndim+(ispinor-1)*ndim,1+(ispinor2-1)*ndim:ndim+(ispinor2-1)*ndim,isppol)
    3595                 :             : 
    3596                 :           0 :              write(message,'(2a, i2, a, i2, a, i2)') ch10,"Orbital angular momentum matrix, isppol=", isppol, ", ispinor=",&
    3597                 :           0 : &            ispinor,", ispinor2=", ispinor2
    3598                 :           0 :              call wrtout(std_out,message,'COLL')
    3599         [ #  # ]:           0 :              do im1=1,ll*2+1
    3600                 :             :                write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3601                 :           0 :       &         (mat_out_c(im1,im2),im2=1,ll*2+1)
    3602                 :           0 :                call wrtout(std_out,message,'COLL')
    3603                 :             :              end do
    3604                 :             : 
    3605                 :             :            end do ! ispinor2
    3606                 :             :          end do ! ispinor
    3607                 :             :        end do ! isppol
    3608         [ #  # ]:           0 :        ABI_FREE(mat_out_c)
    3609                 :             :      endif
    3610                 :             : 
    3611                 :             :    end if !lpawu
    3612                 :             :  end do !atom
    3613                 :             : 
    3614                 :             :      !=====================================
    3615                 :             :      ! Deallocate gathermatlu
    3616                 :             :      !=====================================
    3617                 :             : 
    3618         [ +  + ]:         180 :  do iatom=1,natom
    3619         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    3620         [ -  + ]:         108 :      ABI_FREE(gathermatlu(iatom)%value)
    3621         [ -  + ]:         108 :      ABI_FREE(muorb(iatom)%value)
    3622                 :             :    end if
    3623                 :             :  end do
    3624   [ +  -  +  +  :         180 :  ABI_FREE(gathermatlu)
             -  +  -  + ]
    3625   [ +  -  +  +  :         180 :  ABI_FREE(muorb)
             -  +  -  + ]
    3626                 :             : 
    3627                 :          36 :  end subroutine magmomforb_matlu
    3628                 :             : 
    3629                 :             : !!***
    3630                 :             : 
    3631                 :             : 
    3632                 :             : !!***
    3633                 :             : !!****f* m_matlu/magmomfspin_matlu
    3634                 :             : !! NAME
    3635                 :             : !! magmomfspin_matlu
    3636                 :             : !!
    3637                 :             : !! FUNCTION
    3638                 :             : !! return the product of occupation matrix of dimension [(2*ll+1)]**4 in the Ylm basis
    3639                 :             : !! with the matrix of spin angular momentum element for the x,y and z direction.
    3640                 :             : !! Option gives the direction of the magnetic moment x==1, y==2 and z==3.
    3641                 :             : !!
    3642                 :             : !!
    3643                 :             : !! COPYRIGHT
    3644                 :             : !! Copyright (C) 2005-2026 ABINIT group (FGendron)
    3645                 :             : !! This file is distributed under the terms of the
    3646                 :             : !! GNU General Public License, see ~abinit/COPYING
    3647                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    3648                 :             : !!
    3649                 :             : !! INPUTS
    3650                 :             : !! matlu1(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: input quantity in Ylm basis
    3651                 :             : !! natom :: number of atoms
    3652                 :             : !! option = 1 :: x axis
    3653                 :             : !!        = 2 :: y axis
    3654                 :             : !!        = 3 :: z axis
    3655                 :             : !! optptr > 2 :: print spin angular matrix elements and resulting product
    3656                 :             : !!
    3657                 :             : !! OUTPUT
    3658                 :             : !!  matlu(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: product
    3659                 :             : !!
    3660                 :             : !! SIDE EFFECTS
    3661                 :             : !!
    3662                 :             : !! NOTES
    3663                 :             : !!
    3664                 :             : !! SOURCE
    3665                 :          36 :  subroutine magmomfspin_matlu(matlu,mu,natom,option,optprt)
    3666                 :             :  use defs_wvltypes
    3667                 :             : 
    3668                 :             : !Arguments ------------------------------------
    3669                 :             : !scalars
    3670                 :             :  integer, intent(in) :: natom,option,optprt
    3671                 :             :  complex(dp), allocatable, intent(inout) :: mu(:)
    3672                 :             : !arrays
    3673                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    3674                 :             : !Local variables-------------------------------
    3675                 :             : !scalars
    3676                 :             :  integer :: iatom,im,ispinor,isppol,ispinor2
    3677                 :             :  integer :: lpawu,ll,jm,ml1,jc1,ms1,lcor,im1,im2,tndim,ndim
    3678                 :             :  character(len=500) :: message
    3679                 :             :  real(dp) :: xj
    3680                 :             : !arrays
    3681                 :          36 :  complex(dp),allocatable :: mat_out_c(:,:)
    3682                 :          36 :  integer, allocatable :: ind_msml(:,:)
    3683                 :          36 :  complex(dp), allocatable :: temp_mat(:,:)
    3684                 :          36 :  type(coeff2c_type), allocatable :: gathermatlu(:)
    3685                 :          36 :  type(coeff2c_type), allocatable :: muspin(:)
    3686                 :             : !************************************************************************
    3687                 :             : 
    3688                 :             :  !=====================================
    3689                 :             :  ! Allocate matrices
    3690                 :             :  !=====================================
    3691                 :             : 
    3692   [ -  +  +  -  :         252 :  ABI_MALLOC(gathermatlu,(natom))
          +  -  +  -  -  
             +  -  +  +  
                      + ]
    3693   [ -  +  +  -  :         216 :  ABI_MALLOC(muspin,(natom))
          -  +  -  +  +  
                      + ]
    3694         [ +  + ]:         180 :  do iatom=1,natom
    3695         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    3696                 :         108 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    3697   [ -  +  +  -  :         432 :      ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3698   [ +  +  +  + ]:       22788 :      gathermatlu(iatom)%value=czero
    3699   [ -  +  +  -  :         324 :      ABI_MALLOC(muspin(iatom)%value,(tndim,tndim))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    3700   [ +  +  +  + ]:       22788 :      muspin(iatom)%value=czero
    3701                 :             :    end if
    3702                 :             :  end do
    3703                 :             : 
    3704         [ +  + ]:         180 :  do iatom=1,natom
    3705                 :         144 :    lpawu=matlu(iatom)%lpawu
    3706         [ +  + ]:         180 :    if(lpawu.ne.-1) then
    3707                 :         108 :      ll=lpawu
    3708                 :         108 :      lcor=lpawu
    3709   [ -  +  +  -  :         324 :      ABI_MALLOC(ind_msml,(2,-ll:ll))
          +  -  +  -  -  
                +  +  - ]
    3710   [ +  +  +  + ]:        2376 :      ind_msml=czero
    3711                 :             :      !=====================================
    3712                 :             :      !build spin angular momentum matrix along x axis
    3713                 :             :      !=====================================
    3714         [ +  + ]:         108 :      if(option==1) then
    3715                 :             :        jc1=0
    3716         [ +  + ]:         108 :        do ms1=1,2
    3717         [ +  + ]:         612 :          do ml1=-ll,ll
    3718                 :         504 :           jc1=jc1+1
    3719                 :         576 :           ind_msml(ms1,ml1)=jc1
    3720                 :             :          end do
    3721                 :             :        end do
    3722                 :             : 
    3723                 :             :        jc1=0
    3724         [ +  + ]:         144 :        do ms1 =-1,1
    3725                 :         108 :          xj=float(ms1)+half
    3726         [ +  + ]:         900 :          do ml1 = -ll,ll
    3727                 :         756 :             jc1=jc1+1
    3728         [ +  + ]:         864 :             if(xj < 0.0 ) then
    3729                 :         252 :                muspin(iatom)%value(ind_msml(2,ml1),jc1) = 0.5
    3730         [ +  - ]:         504 :             else if(xj > 0.0) then
    3731                 :         504 :                muspin(iatom)%value(ind_msml(1,ml1),ind_msml(2,ml1)) = 0.5
    3732                 :             :             end if
    3733                 :             :           end do
    3734                 :             :         end do
    3735                 :             : 
    3736                 :             :      !=====================================
    3737                 :             :      !build spin angular momentum matrix along y axis
    3738                 :             :      !up spin is first
    3739                 :             :      !=====================================
    3740         [ +  + ]:          72 :      else if(option==2) then
    3741                 :             :         jc1=0
    3742         [ +  + ]:         108 :        do ms1=1,2
    3743         [ +  + ]:         612 :          do ml1=-ll,ll
    3744                 :         504 :           jc1=jc1+1
    3745                 :         576 :           ind_msml(ms1,ml1)=jc1
    3746                 :             :          end do
    3747                 :             :        end do
    3748                 :             : 
    3749                 :             :        jc1=0
    3750         [ +  + ]:         144 :        do ms1 =-1,1
    3751                 :         108 :          xj=float(ms1)+half
    3752         [ +  + ]:         900 :          do ml1 = -ll,ll
    3753                 :         756 :             jc1=jc1+1
    3754         [ +  + ]:         864 :             if(xj < 0.0 ) then
    3755                 :         252 :                muspin(iatom)%value(ind_msml(2,ml1),jc1) = cmplx(zero,0.5,kind=dp)
    3756         [ +  - ]:         504 :             else if(xj > 0.0) then
    3757                 :         504 :                muspin(iatom)%value(ind_msml(1,ml1),ind_msml(2,ml1)) = cmplx(zero,-0.5,kind=dp)
    3758                 :             :             end if
    3759                 :             :           end do
    3760                 :             :         end do
    3761                 :             : 
    3762                 :             :      !=====================================
    3763                 :             :      !build spin angular momentum matrix along z axis
    3764                 :             :      !up spin is first
    3765                 :             :      !=====================================
    3766         [ +  - ]:          36 :      else if(option==3) then
    3767                 :             :        jc1=0
    3768         [ +  + ]:         144 :        do ms1=-1,1
    3769                 :         108 :          xj=float(ms1)+half
    3770         [ +  + ]:         900 :          do ml1=-ll,ll
    3771                 :         756 :             jc1=jc1+1
    3772         [ +  + ]:         864 :             if(jc1 < tndim+1) then
    3773         [ +  + ]:         504 :               if(xj < 0.0 ) then
    3774                 :         252 :                  muspin(iatom)%value(jc1,jc1) = -xj
    3775         [ +  - ]:         252 :               else if(xj > 0.0) then
    3776                 :         252 :                  muspin(iatom)%value(jc1,jc1) = -xj
    3777                 :             :               end if
    3778                 :             :             endif
    3779                 :             :          end do
    3780                 :             :        end do
    3781                 :             :      end if
    3782                 :             : 
    3783         [ -  + ]:         108 :      if(optprt>2) then
    3784                 :           0 :         write(message,'(a,i4)') "Spin angular momentum matrix elements in |m_l,m_s> basis for axis", option
    3785                 :           0 :         call wrtout(std_out,message,"COLL")
    3786         [ #  # ]:           0 :         do im=1,2*(ll*2+1)
    3787   [ #  #  #  # ]:           0 :           write(message,'(6(1x,9(1x,f4.1,",",f4.1)))') (muspin(iatom)%value(im,jm),jm=1,2*(ll*2+1))
    3788                 :           0 :           call wrtout(std_out,message,"COLL")
    3789                 :             :         end do
    3790                 :             :      end if
    3791                 :             : 
    3792         [ -  + ]:         108 :    ABI_FREE(ind_msml)
    3793                 :             :    end if !lpawu
    3794                 :             :  end do !atom
    3795                 :             : 
    3796                 :             :      !=====================================
    3797                 :             :      ! Reshape input Ylm matlu in one 14x14 matrix
    3798                 :             :      !=====================================
    3799                 :             : 
    3800                 :          36 :  call gather_matlu(matlu,gathermatlu,natom,option=1,prtopt=1)
    3801                 :             : 
    3802                 :             : !!printing for debug
    3803                 :             : !! write(std_out,*) "gathermatlu in magmomfspin"
    3804                 :             : !! do im1=1,tndim
    3805                 :             : !!   write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3806                 :             : !!        (gathermatlu(1)%value(im1,im2),im2=1,tndim)
    3807                 :             : !!   call wrtout(std_out,message,'coll')
    3808                 :             : !! end do
    3809                 :             : 
    3810                 :             :      !=====================================
    3811                 :             :      ! Matrix product of Occ and muspin
    3812                 :             :      !=====================================
    3813         [ +  + ]:         180 :  do iatom=1,natom
    3814         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    3815                 :         108 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    3816   [ -  +  +  -  :         432 :      ABI_MALLOC(temp_mat,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    3817                 :             : 
    3818                 :             :      call zgemm('n','n',tndim,tndim,tndim,cone,&
    3819                 :             :      &    gathermatlu(iatom)%value,tndim,&
    3820                 :             :      &    muspin(iatom)%value,tndim,czero,&
    3821                 :         108 :      &    temp_mat,tndim)
    3822                 :             : 
    3823   [ +  -  +  -  :       22896 :      gathermatlu(iatom)%value=temp_mat
          -  +  -  -  +  
                +  +  + ]
    3824         [ -  + ]:         108 :      ABI_FREE(temp_mat)
    3825                 :             : 
    3826                 :             :      !!printing for debug
    3827                 :             :      !!write(std_out,*) "gathermatlu in magmomfspin after product"
    3828                 :             :      !!do im1=1,tndim
    3829                 :             :      !!   write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3830                 :             :      !!        (gathermatlu(1)%value(im1,im2),im2=1,tndim)
    3831                 :             :      !!   call wrtout(std_out,message,'coll')
    3832                 :             :      !!end do
    3833                 :             : 
    3834                 :             :      !=====================================
    3835                 :             :      ! Trace of matrix product
    3836                 :             :      !=====================================
    3837                 :             : 
    3838         [ +  + ]:        1620 :    do im1=1,tndim
    3839         [ +  + ]:       22788 :      do im2=1,tndim
    3840         [ +  + ]:       22680 :        if(im1==im2) then
    3841                 :        1512 :          mu(iatom) = mu(iatom) + gathermatlu(iatom)%value(im1,im2)
    3842                 :             :        end if
    3843                 :             :      end do
    3844                 :             :    end do
    3845                 :             : 
    3846                 :             :      !=====================================
    3847                 :             :      ! Reshape product matrix into matlu format
    3848                 :             :      !=====================================
    3849                 :             : 
    3850                 :             :     !call gather_matlu(matlu,gathermatlu,natom,option=-1,prtopt=1)
    3851                 :             : 
    3852                 :             : 
    3853                 :             :      !=====================================
    3854                 :             :      ! Print matlu
    3855                 :             :      !=====================================
    3856         [ -  + ]:         108 :      if(optprt>2) then
    3857   [ #  #  #  #  :           0 :        ABI_MALLOC(mat_out_c,(2*ll+1,2*ll+1))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    3858                 :           0 :        ndim = 2*ll+1
    3859         [ #  # ]:           0 :        do isppol=1,matlu(1)%nsppol
    3860         [ #  # ]:           0 :          do ispinor=1,matlu(1)%nspinor
    3861         [ #  # ]:           0 :            do ispinor2=1,matlu(1)%nspinor
    3862   [ #  #  #  # ]:           0 :              mat_out_c(:,:) = matlu(iatom)%mat(1+(ispinor-1)*ndim:ndim+(ispinor-1)*ndim,1+(ispinor2-1)*ndim:ndim+(ispinor2-1)*ndim,isppol)
    3863                 :             : 
    3864                 :           0 :              write(message,'(2a, i2, a, i2, a, i2)') ch10,"Spin angular momentum matrix, isppol=", isppol, ", ispinor=", ispinor,&
    3865                 :           0 : &             ", ispinor2=", ispinor2
    3866                 :           0 :              call wrtout(std_out,message,'COLL')
    3867         [ #  # ]:           0 :              do im1=1,ll*2+1
    3868                 :             :                write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    3869                 :           0 :       &         (mat_out_c(im1,im2),im2=1,ll*2+1)
    3870                 :           0 :                call wrtout(std_out,message,'COLL')
    3871                 :             :              end do
    3872                 :             : 
    3873                 :             :            end do ! im
    3874                 :             :          end do ! ispinor
    3875                 :             :        end do ! isppol
    3876         [ #  # ]:           0 :        ABI_FREE(mat_out_c)
    3877                 :             :      endif
    3878                 :             : 
    3879                 :             :    end if !lpawu
    3880                 :             :  end do !atom
    3881                 :             : 
    3882                 :             :      !=====================================
    3883                 :             :      ! Deallocate gathermatlu
    3884                 :             :      !=====================================
    3885                 :             : 
    3886         [ +  + ]:         180 :  do iatom=1,natom
    3887         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    3888         [ -  + ]:         108 :      ABI_FREE(gathermatlu(iatom)%value)
    3889         [ -  + ]:         108 :      ABI_FREE(muspin(iatom)%value)
    3890                 :             :    end if
    3891                 :             :  end do
    3892   [ +  -  +  +  :         180 :  ABI_FREE(gathermatlu)
             -  +  -  + ]
    3893   [ +  -  +  +  :         180 :  ABI_FREE(muspin)
             -  +  -  + ]
    3894                 :             : 
    3895                 :          36 :  end subroutine magmomfspin_matlu
    3896                 :             : 
    3897                 :             : !!***
    3898                 :             : 
    3899                 :             : 
    3900                 :             : !!***
    3901                 :             : !!****f* m_matlu/magmomfzeeman_matlu
    3902                 :             : !! NAME
    3903                 :             : !! magmomfspin_matlu
    3904                 :             : !!
    3905                 :             : !! FUNCTION
    3906                 :             : !! return the product of occupation matrix of dimension [(2*ll+1)]**4 in the Ylm basis
    3907                 :             : !! with the matrix of Zeeman angular momentum element (L_u + 2*S_u) for the x,y and z direction.
    3908                 :             : !! Option gives the direction of the magnetic moment x==1, y==2 and z==3.
    3909                 :             : !!
    3910                 :             : !!
    3911                 :             : !! COPYRIGHT
    3912                 :             : !! Copyright (C) 2005-2026 ABINIT group (FGendron)
    3913                 :             : !! This file is distributed under the terms of the
    3914                 :             : !! GNU General Public License, see ~abinit/COPYING
    3915                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    3916                 :             : !!
    3917                 :             : !! INPUTS
    3918                 :             : !! matlu1(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: input quantity in Ylm basis
    3919                 :             : !! natom :: number of atoms
    3920                 :             : !! option = 1 :: x axis
    3921                 :             : !!        = 2 :: y axis
    3922                 :             : !!        = 3 :: z axis
    3923                 :             : !! optptr > 2 :: print Zeeman angular matrix elements and resulting product
    3924                 :             : !!
    3925                 :             : !! OUTPUT
    3926                 :             : !!  matlu(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: product
    3927                 :             : !!
    3928                 :             : !! SIDE EFFECTS
    3929                 :             : !!
    3930                 :             : !! NOTES
    3931                 :             : !!
    3932                 :             : !! SOURCE
    3933                 :          36 :  subroutine magmomfzeeman_matlu(matlu,mu,natom,option,optprt)
    3934                 :             :  use defs_wvltypes
    3935                 :             : 
    3936                 :             : !Arguments ------------------------------------
    3937                 :             : !scalars
    3938                 :             :  integer, intent(in) :: natom,option,optprt
    3939                 :             :  complex(dp), allocatable, intent(inout) :: mu(:)
    3940                 :             : !arrays
    3941                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    3942                 :             : !Local variables-------------------------------
    3943                 :             : !scalars
    3944                 :             :  integer :: iatom,im,ispinor,isppol,ispinor2
    3945                 :             :  integer :: lpawu,ll,jm,ml1,jc1,ms1,lcor,im1,im2,tndim,ndim
    3946                 :             :  character(len=500) :: message
    3947                 :             :  real(dp) :: xj
    3948                 :             : !arrays
    3949                 :          36 :  complex(dp),allocatable :: mat_out_c(:,:)
    3950                 :          36 :  integer, allocatable :: ind_msml(:,:)
    3951                 :          36 :  complex(dp), allocatable :: temp_mat(:,:)
    3952                 :          36 :  type(coeff2c_type), allocatable :: gathermatlu(:)
    3953                 :          36 :  type(coeff2c_type), allocatable :: muzeeman(:)
    3954                 :             : !************************************************************************
    3955                 :             : 
    3956                 :             :  !=====================================
    3957                 :             :  ! Allocate matrices
    3958                 :             :  !=====================================
    3959                 :             : 
    3960   [ -  +  +  -  :         252 :  ABI_MALLOC(gathermatlu,(natom))
          +  -  +  -  -  
             +  -  +  +  
                      + ]
    3961   [ -  +  +  -  :         216 :  ABI_MALLOC(muzeeman,(natom))
          -  +  -  +  +  
                      + ]
    3962         [ +  + ]:         180 :  do iatom=1,natom
    3963         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    3964                 :         108 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    3965   [ -  +  +  -  :         432 :      ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    3966   [ +  +  +  + ]:       22788 :      gathermatlu(iatom)%value=czero
    3967   [ -  +  +  -  :         324 :      ABI_MALLOC(muzeeman(iatom)%value,(tndim,tndim))
          -  +  +  -  -  
             +  -  +  -  
                      + ]
    3968   [ +  +  +  + ]:       22788 :      muzeeman(iatom)%value=czero
    3969                 :             :    end if
    3970                 :             :  end do
    3971                 :             : 
    3972         [ +  + ]:         180 :  do iatom=1,natom
    3973                 :         144 :    lpawu=matlu(iatom)%lpawu
    3974         [ +  + ]:         180 :    if(lpawu.ne.-1) then
    3975                 :         108 :      ll=lpawu
    3976                 :         108 :      lcor=lpawu
    3977   [ -  +  +  -  :         324 :      ABI_MALLOC(ind_msml,(2,-ll:ll))
          +  -  +  -  -  
                +  -  + ]
    3978   [ +  +  +  + ]:        2376 :      ind_msml=czero
    3979                 :             :      !=====================================
    3980                 :             :      !build Zeeman angular momentum matrix along x axis
    3981                 :             :      !=====================================
    3982         [ +  + ]:         108 :      if(option==1) then
    3983                 :             :        jc1=0
    3984         [ +  + ]:         108 :        do ms1=1,2
    3985         [ +  + ]:         612 :          do ml1=-ll,ll
    3986                 :         504 :           jc1=jc1+1
    3987                 :         576 :           ind_msml(ms1,ml1)=jc1
    3988                 :             :          end do
    3989                 :             :        end do
    3990                 :             : 
    3991                 :             :        jc1=0
    3992         [ +  + ]:         144 :        do ms1 =-1,1
    3993                 :         108 :          xj=float(ms1)+half
    3994         [ +  + ]:         900 :          do ml1 = -ll,ll
    3995                 :         756 :             jc1=jc1+1
    3996         [ +  + ]:         756 :             if(xj < 0.0 ) then
    3997                 :         252 :                muzeeman(iatom)%value(ind_msml(2,ml1),jc1) = 2*0.5
    3998         [ +  - ]:         504 :             else if(xj > 0.0) then
    3999                 :         504 :                muzeeman(iatom)%value(ind_msml(1,ml1),ind_msml(2,ml1)) = 2*0.5
    4000                 :             :             end if
    4001         [ +  + ]:         756 :             if(jc1 == 1) then
    4002                 :          36 :                muzeeman(iatom)%value(jc1,jc1+1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5
    4003                 :             :             endif
    4004   [ +  +  +  + ]:         864 :             if(jc1 > 1 .and.jc1 < 2*(2*ll+1)) then
    4005                 :         432 :                muzeeman(iatom)%value(jc1,jc1+1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5
    4006                 :         432 :                muzeeman(iatom)%value(jc1,jc1-1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5
    4007         [ +  + ]:         324 :             else if(jc1 == 2*(2*ll+1)) then
    4008                 :          36 :                muzeeman(iatom)%value(jc1,jc1-1) = sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5
    4009                 :             :             end if
    4010                 :             :           end do
    4011                 :             :         end do
    4012                 :             : 
    4013                 :             :      !=====================================
    4014                 :             :      !build Zeeman angular momentum matrix along y axis
    4015                 :             :      !up spin is first
    4016                 :             :      !=====================================
    4017         [ +  + ]:          72 :      else if(option==2) then
    4018                 :             :         jc1=0
    4019         [ +  + ]:         108 :        do ms1=1,2
    4020         [ +  + ]:         612 :          do ml1=-ll,ll
    4021                 :         504 :           jc1=jc1+1
    4022                 :         576 :           ind_msml(ms1,ml1)=jc1
    4023                 :             :          end do
    4024                 :             :        end do
    4025                 :             : 
    4026                 :             :        jc1=0
    4027         [ +  + ]:         144 :        do ms1 =-1,1
    4028                 :         108 :          xj=float(ms1)+half
    4029         [ +  + ]:         900 :          do ml1 = -ll,ll
    4030                 :         756 :             jc1=jc1+1
    4031         [ +  + ]:         756 :             if(xj < 0.0 ) then
    4032                 :         252 :                muzeeman(iatom)%value(ind_msml(2,ml1),jc1) = 2*cmplx(zero,0.5,kind=dp)
    4033         [ +  - ]:         504 :             else if(xj > 0.0) then
    4034                 :         504 :                muzeeman(iatom)%value(ind_msml(1,ml1),ind_msml(2,ml1)) = 2*cmplx(zero,-0.5,kind=dp)
    4035                 :             :             end if
    4036         [ +  + ]:         756 :             if(jc1 == 1) then
    4037                 :          36 :                muzeeman(iatom)%value(jc1,jc1+1) = cmplx(zero,sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5,kind=dp)
    4038                 :             :             endif
    4039   [ +  +  +  + ]:         864 :             if(jc1 > 1 .and. jc1 < 2*(2*ll+1)) then
    4040                 :         432 :                muzeeman(iatom)%value(jc1,jc1+1) = cmplx(zero,sqrt(float((lcor*(lcor+1)) - ml1*(ml1 + 1)))*0.5,kind=dp)
    4041                 :         432 :                muzeeman(iatom)%value(jc1,jc1-1) = cmplx(zero,-sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5,kind=dp)
    4042         [ +  + ]:         324 :             else if(jc1== 2*(2*ll+1)) then
    4043                 :          36 :                muzeeman(iatom)%value(jc1,jc1-1) = cmplx(zero,-sqrt(float((lcor*(lcor+1)) - ml1*(ml1 - 1)))*0.5,kind=dp)
    4044                 :             :             end if
    4045                 :             :           end do
    4046                 :             :         end do
    4047                 :             : 
    4048                 :             : 
    4049                 :             :      !=====================================
    4050                 :             :      !build Zeeman angular momentum matrix along z axis
    4051                 :             :      !up spin is first
    4052                 :             :      !=====================================
    4053         [ +  - ]:          36 :      else if(option==3) then
    4054                 :             :        jc1=0
    4055         [ +  + ]:         144 :        do ms1=-1,1
    4056                 :         108 :          xj=float(ms1)+half
    4057         [ +  + ]:         900 :          do ml1=-ll,ll
    4058                 :         756 :             jc1=jc1+1
    4059         [ +  + ]:         864 :             if(jc1 < tndim+1) then
    4060         [ +  + ]:         504 :               if(xj < 0.0 ) then
    4061                 :         252 :                  muzeeman(iatom)%value(jc1,jc1) = ml1-2*xj
    4062         [ +  - ]:         252 :               else if(xj > 0.0) then
    4063                 :         252 :                  muzeeman(iatom)%value(jc1,jc1) = ml1-2*xj
    4064                 :             :               end if
    4065                 :             :             endif
    4066                 :             :          end do
    4067                 :             :        end do
    4068                 :             :      end if
    4069                 :             : 
    4070                 :             : 
    4071         [ -  + ]:         108 :      if(optprt>2) then
    4072                 :           0 :         write(message,'(a,i4)') "Zeeman angular momentum matrix elements in |m_l,m_s> basis for axis", option
    4073                 :           0 :         call wrtout(std_out,message,"COLL")
    4074         [ #  # ]:           0 :         do im=1,2*(ll*2+1)
    4075   [ #  #  #  # ]:           0 :           write(message,'(6(1x,9(1x,f4.1,",",f4.1)))') (muzeeman(iatom)%value(im,jm),jm=1,2*(ll*2+1))
    4076                 :           0 :           call wrtout(std_out,message,"COLL")
    4077                 :             :         end do
    4078                 :             :      end if
    4079                 :             : 
    4080         [ -  + ]:         108 :    ABI_FREE(ind_msml)
    4081                 :             :    end if !lpawu
    4082                 :             :  end do !atom
    4083                 :             : 
    4084                 :             :      !=====================================
    4085                 :             :      ! Reshape input Ylm matlu in one 14x14 matrix
    4086                 :             :      !=====================================
    4087                 :             : 
    4088                 :             :  !ABI_MALLOC(gathermatlu,(natom))
    4089                 :             :  !do iatom=1,natom
    4090                 :             :  !  if(matlu(iatom)%lpawu.ne.-1) then
    4091                 :             :  !    tndim=2*(2*matlu(iatom)%lpawu+1)
    4092                 :             :  !    ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
    4093                 :             :  !    gathermatlu(iatom)%value=czero
    4094                 :             :  !  end if
    4095                 :             :  !end do
    4096                 :             : 
    4097                 :          36 :  call gather_matlu(matlu,gathermatlu,natom,option=1,prtopt=1)
    4098                 :             : 
    4099                 :             : !!printing for debug
    4100                 :             : !! write(std_out,*) "gathermatlu in magmomfspin"
    4101                 :             : !! do im1=1,tndim
    4102                 :             : !!   write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    4103                 :             : !!        (gathermatlu(1)%value(im1,im2),im2=1,tndim)
    4104                 :             : !!   call wrtout(std_out,message,'coll')
    4105                 :             : !! end do
    4106                 :             : 
    4107                 :             :      !=====================================
    4108                 :             :      ! Matrix product of Occ and muzeeman
    4109                 :             :      !=====================================
    4110         [ +  + ]:         180 :  do iatom=1,natom
    4111         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    4112                 :         108 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    4113   [ -  +  +  -  :         432 :      ABI_MALLOC(temp_mat,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
    4114                 :             : 
    4115                 :             :      call abi_zgemm('n','n',tndim,tndim,tndim,cone,&
    4116                 :             :      &    gathermatlu(iatom)%value,tndim,&
    4117                 :             :      &    muzeeman(iatom)%value,tndim,czero,&
    4118                 :         108 :      &    temp_mat,tndim)
    4119                 :             : 
    4120   [ +  -  +  -  :       22896 :      gathermatlu(iatom)%value=temp_mat
          -  +  -  -  +  
                +  +  + ]
    4121         [ -  + ]:         108 :      ABI_FREE(temp_mat)
    4122                 :             : 
    4123                 :             :      !!printing for debug
    4124                 :             :      !!write(std_out,*) "gathermatlu in magmomfspin after product"
    4125                 :             :      !!do im1=1,tndim
    4126                 :             :      !!   write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    4127                 :             :      !!        (gathermatlu(1)%value(im1,im2),im2=1,tndim)
    4128                 :             :      !!   call wrtout(std_out,message,'coll')
    4129                 :             :      !!end do
    4130                 :             : 
    4131                 :             :      !=====================================
    4132                 :             :      ! Trace of matrix product
    4133                 :             :      !=====================================
    4134                 :             : 
    4135         [ +  + ]:        1620 :    do im1=1,tndim
    4136         [ +  + ]:       22788 :      do im2=1,tndim
    4137         [ +  + ]:       22680 :        if(im1==im2) then
    4138                 :        1512 :          mu(iatom) = mu(iatom) + gathermatlu(iatom)%value(im1,im2)
    4139                 :             :        end if
    4140                 :             :      end do
    4141                 :             :    end do
    4142                 :             : 
    4143                 :             :      !=====================================
    4144                 :             :      ! Reshape product matrix into matlu format
    4145                 :             :      !=====================================
    4146                 :             : 
    4147                 :             :     !call gather_matlu(matlu,gathermatlu,natom,option=-1,prtopt=1)
    4148                 :             : 
    4149                 :             : 
    4150                 :             :      !=====================================
    4151                 :             :      ! Print matlu
    4152                 :             :      !=====================================
    4153         [ -  + ]:         108 :      if(optprt>2) then
    4154   [ #  #  #  #  :           0 :        ABI_MALLOC(mat_out_c,(2*ll+1,2*ll+1))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    4155                 :           0 :        ndim = 2*ll+1
    4156         [ #  # ]:           0 :        do isppol=1,matlu(1)%nsppol
    4157         [ #  # ]:           0 :          do ispinor=1,matlu(1)%nspinor
    4158         [ #  # ]:           0 :            do ispinor2=1,matlu(1)%nspinor
    4159   [ #  #  #  # ]:           0 :              mat_out_c(:,:) = matlu(iatom)%mat(1+(ispinor-1)*ndim:ndim+(ispinor-1)*ndim,1+(ispinor2-1)*ndim:ndim+(ispinor2-1)*ndim,isppol)
    4160                 :             : 
    4161                 :           0 :              write(message,'(2a, i2, a, i2, a, i2)') ch10,"Zeeman angular momentum matrix, isppol=", isppol, ", ispinor=",&
    4162                 :           0 : &            ispinor,", ispinor2=", ispinor2
    4163                 :           0 :              call wrtout(std_out,message,'COLL')
    4164         [ #  # ]:           0 :              do im1=1,ll*2+1
    4165                 :             :                write(message,'(12(1x,9(1x,"(",f9.5,",",f9.5,")")))')&
    4166                 :           0 :       &         (mat_out_c(im1,im2),im2=1,ll*2+1)
    4167                 :           0 :                call wrtout(std_out,message,'COLL')
    4168                 :             :              end do
    4169                 :             : 
    4170                 :             :            end do ! im
    4171                 :             :          end do ! ispinor
    4172                 :             :        end do ! isppol
    4173         [ #  # ]:           0 :        ABI_FREE(mat_out_c)
    4174                 :             :      endif ! optprt
    4175                 :             : 
    4176                 :             :    end if !lpawu
    4177                 :             :  end do !atom
    4178                 :             : 
    4179                 :             :      !=====================================
    4180                 :             :      ! Deallocate gathermatlu
    4181                 :             :      !=====================================
    4182                 :             : 
    4183         [ +  + ]:         180 :  do iatom=1,natom
    4184         [ +  + ]:         180 :    if(matlu(iatom)%lpawu.ne.-1) then
    4185         [ -  + ]:         108 :      ABI_FREE(gathermatlu(iatom)%value)
    4186         [ -  + ]:         108 :      ABI_FREE(muzeeman(iatom)%value)
    4187                 :             :    end if
    4188                 :             :  end do
    4189   [ +  -  +  +  :         180 :  ABI_FREE(gathermatlu)
             -  +  -  + ]
    4190   [ +  -  +  +  :         180 :  ABI_FREE(muzeeman)
             -  +  -  + ]
    4191                 :          36 :  end subroutine magmomfzeeman_matlu
    4192                 :             : 
    4193                 :             : !!***
    4194                 :             : 
    4195                 :             : !!***
    4196                 :             : !!****f* m_matlu/chi_matlu
    4197                 :             : !! NAME
    4198                 :             : !! chi_matlu
    4199                 :             : !!
    4200                 :             : !! FUNCTION
    4201                 :             : !! return the matrix of dimension [(2*ll+1)]**4 in the Ylm basis
    4202                 :             : !! with the matrix elements of the orbital (option=1), spin (option=2) and
    4203                 :             : !! total (option=3) angular momentum for z direction. It is used by the
    4204                 :             : !! QMC for the correlation function of the magnetic moment
    4205                 :             : !!
    4206                 :             : !!
    4207                 :             : !! COPYRIGHT
    4208                 :             : !! Copyright (C) 2005-2026 ABINIT group (FGendron)
    4209                 :             : !! This file is distributed under the terms of the
    4210                 :             : !! GNU General Public License, see ~abinit/COPYING
    4211                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    4212                 :             : !!
    4213                 :             : !! INPUTS
    4214                 :             : !! matlu1(natom)%(nsppol,nspinor,nspinor,ndim,ndim) ::
    4215                 :             : !! natom :: number of atoms
    4216                 :             : !! option = 1 :: Orbital angular momentum along z axis
    4217                 :             : !!        = 2 :: 2*Spin angluar momentum alonf z axis
    4218                 :             : !!        = 3 :: total angular momentum along z axis
    4219                 :             : !! optptr > 2 :: print angular matrix elements
    4220                 :             : !!
    4221                 :             : !! OUTPUT
    4222                 :             : !!  matlu(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: quantity in Ylm basis
    4223                 :             : !!
    4224                 :             : !! SIDE EFFECTS
    4225                 :             : !!
    4226                 :             : !! NOTES
    4227                 :             : !!
    4228                 :             : !! SOURCE
    4229                 :           0 :  subroutine chi_matlu(matlu,natom,option,optprt)
    4230                 :             :  use defs_wvltypes
    4231                 :             : 
    4232                 :             : !Arguments ------------------------------------
    4233                 :             : !scalars
    4234                 :             :  integer, intent(in) :: natom,option,optprt
    4235                 :             : !arrays
    4236                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    4237                 :             : !Local variables-------------------------------
    4238                 :             : !scalars
    4239                 :             :  integer :: iatom,im
    4240                 :             :  integer :: lpawu,ll,jm,ml1,jc1,ms1,lcor,tndim
    4241                 :             :  character(len=500) :: message
    4242                 :             :  real(dp) :: xj
    4243                 :             : !arrays
    4244                 :           0 :  integer, allocatable :: ind_msml(:,:)
    4245                 :             : ! type(coeff2c_type), allocatable :: gathermatlu(:)
    4246                 :           0 :  type(coeff2c_type), allocatable :: muchi(:)
    4247                 :             : !************************************************************************
    4248                 :             : 
    4249                 :             :  !=====================================
    4250                 :             :  ! Allocate matrices
    4251                 :             :  !=====================================
    4252                 :             : 
    4253   [ #  #  #  #  :           0 :  ABI_MALLOC(muchi,(natom))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    4254         [ #  # ]:           0 :  do iatom=1,natom
    4255                 :             :    !if(matlu(iatom)%lpawu.ne.-1) then
    4256                 :           0 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    4257   [ #  #  #  #  :           0 :      ABI_MALLOC(muchi(iatom)%value,(tndim,tndim))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    4258   [ #  #  #  # ]:           0 :      muchi(iatom)%value=czero
    4259                 :             :    !end if
    4260                 :             :  end do
    4261                 :             : 
    4262         [ #  # ]:           0 :  do iatom=1,natom
    4263                 :           0 :    lpawu=matlu(iatom)%lpawu
    4264         [ #  # ]:           0 :    if(lpawu.ne.-1) then
    4265                 :           0 :      ll=lpawu
    4266                 :           0 :      lcor=lpawu
    4267   [ #  #  #  #  :           0 :      ABI_MALLOC(ind_msml,(2,-ll:ll))
          #  #  #  #  #  
                #  #  # ]
    4268   [ #  #  #  # ]:           0 :      ind_msml=czero
    4269                 :             :      !=====================================
    4270                 :             :      !Orbital angular momentum matrix along z axis
    4271                 :             :      !=====================================
    4272         [ #  # ]:           0 :      if(option==1) then
    4273                 :             :        jc1=0
    4274         [ #  # ]:           0 :        do ms1=1,2
    4275         [ #  # ]:           0 :          do ml1=-ll,ll
    4276                 :           0 :           jc1=jc1+1
    4277                 :           0 :           ind_msml(ms1,ml1)=jc1
    4278                 :             :          end do
    4279                 :             :        end do
    4280                 :             : 
    4281                 :             :        jc1=0
    4282         [ #  # ]:           0 :        do ms1=-1,1
    4283         [ #  # ]:           0 :          do ml1=-ll,ll
    4284                 :           0 :             jc1=jc1+1
    4285         [ #  # ]:           0 :             if(jc1 <tndim+1) then
    4286                 :           0 :                 muchi(iatom)%value(jc1,jc1) = ml1
    4287                 :             :             endif
    4288                 :             :           end do
    4289                 :             :         end do
    4290                 :             : 
    4291                 :             :      !=====================================
    4292                 :             :      !Spin angular momentum matrix along z axis
    4293                 :             :      !up spin is first
    4294                 :             :      !=====================================
    4295         [ #  # ]:           0 :      else if(option==2) then
    4296                 :             :         jc1=0
    4297         [ #  # ]:           0 :        do ms1=1,2
    4298         [ #  # ]:           0 :          do ml1=-ll,ll
    4299                 :           0 :           jc1=jc1+1
    4300                 :           0 :           ind_msml(ms1,ml1)=jc1
    4301                 :             :          end do
    4302                 :             :        end do
    4303                 :             : 
    4304                 :             :        jc1=0
    4305         [ #  # ]:           0 :        do ms1=-1,1
    4306                 :           0 :          xj=float(ms1)+half
    4307         [ #  # ]:           0 :          do ml1=-ll,ll
    4308                 :           0 :             jc1=jc1+1
    4309         [ #  # ]:           0 :             if(jc1<tndim+1) then
    4310         [ #  # ]:           0 :                 if(xj < 0.0 ) then
    4311                 :           0 :                         muchi(iatom)%value(jc1,jc1) = -2*xj
    4312         [ #  # ]:           0 :                 else if(xj > 0.0) then
    4313                 :           0 :                         muchi(iatom)%value(jc1,jc1) = -2*xj
    4314                 :             : 
    4315                 :             :                 end if
    4316                 :             :              endif
    4317                 :             :          end do
    4318                 :             :        end do
    4319                 :             : 
    4320                 :             :      !=====================================
    4321                 :             :      !Total angular momentum matrix along z axis
    4322                 :             :      !up spin is first
    4323                 :             :      !=====================================
    4324         [ #  # ]:           0 :      else if(option==3) then
    4325                 :             :        jc1=0
    4326         [ #  # ]:           0 :        do ms1=-1,1
    4327                 :           0 :          xj=float(ms1)+half
    4328         [ #  # ]:           0 :          do ml1=-ll,ll
    4329                 :           0 :             jc1=jc1+1
    4330         [ #  # ]:           0 :             if(jc1<tndim+1) then
    4331         [ #  # ]:           0 :                 if(xj < 0.0 ) then
    4332                 :           0 :                         muchi(iatom)%value(jc1,jc1) = ml1-2*xj
    4333         [ #  # ]:           0 :                 else if(xj > 0.0) then
    4334                 :           0 :                         muchi(iatom)%value(jc1,jc1) = ml1-2*xj
    4335                 :             :                 end if
    4336                 :             :             endif
    4337                 :             :          end do
    4338                 :             :        end do
    4339                 :             :      end if
    4340                 :             : 
    4341         [ #  # ]:           0 :      if(optprt>2) then
    4342         [ #  # ]:           0 :         if(option==1) then
    4343                 :           0 :           write(message,'(a)') "Orbital angular momentum matrix elements in |m_l,m_s> basis"
    4344         [ #  # ]:           0 :         else if(option==2) then
    4345                 :           0 :           write(message,'(a)') "Spin angular momentum matrix elements in |m_l,m_s> basis"
    4346         [ #  # ]:           0 :         else if(option==3) then
    4347                 :           0 :           write(message,'(a)') "Zeeman angular momentum matrix elements in |m_l,m_s> basis"
    4348                 :             :         end if
    4349                 :           0 :         call wrtout(std_out,message,"COLL")
    4350         [ #  # ]:           0 :         do im=1,2*(ll*2+1)
    4351   [ #  #  #  # ]:           0 :           write(message,'(6(1x,9(1x,f4.1,",",f4.1)))') (muchi(iatom)%value(im,jm),jm=1,2*(ll*2+1))
    4352                 :           0 :           call wrtout(std_out,message,"COLL")
    4353                 :             :         end do
    4354                 :             :      end if
    4355                 :             : 
    4356         [ #  # ]:           0 :    ABI_FREE(ind_msml)
    4357                 :             : 
    4358                 :             :      !=====================================
    4359                 :             :      ! Reshape matrix into matlu format
    4360                 :             :      !=====================================
    4361                 :             : 
    4362                 :             :    ! call gather_matlu(matlu,muchi(iatom),natom=1,option=-1,prtopt=1)
    4363                 :             : 
    4364                 :             : 
    4365                 :             :    end if !lpawu
    4366                 :             :  end do !atom
    4367                 :             : 
    4368                 :             :   !=====================================
    4369                 :             :   ! Reshape matrix into matlu format
    4370                 :             :   !=====================================
    4371                 :             : 
    4372                 :           0 :   call gather_matlu(matlu,muchi,natom,option=-1,prtopt=1)
    4373                 :             : 
    4374                 :             :      !=====================================
    4375                 :             :      ! Deallocate gathermatlu
    4376                 :             :      !=====================================
    4377                 :             : 
    4378         [ #  # ]:           0 :  do iatom=1,natom
    4379         [ #  # ]:           0 :    if(matlu(iatom)%lpawu.ne.-1) then
    4380         [ #  # ]:           0 :      ABI_FREE(muchi(iatom)%value)
    4381                 :             :    end if
    4382                 :             :  end do
    4383   [ #  #  #  #  :           0 :  ABI_FREE(muchi)
             #  #  #  # ]
    4384                 :             : 
    4385                 :           0 :  end subroutine chi_matlu
    4386                 :             : 
    4387                 :             : !!***
    4388                 :             : 
    4389                 :             : !!****f* m_matlu/trace_prod_matlu
    4390                 :             : !! NAME
    4391                 :             : !! trace_prod_matlu
    4392                 :             : !!
    4393                 :             : !! FUNCTION
    4394                 :             : !! Computes Tr(matlu1*matlu2) for each atom. It is NOT assumed
    4395                 :             : !! that either matlu1 or matlu2 is symmetric, so this routine is
    4396                 :             : !! suboptimal if this is the case.
    4397                 :             : !!
    4398                 :             : !! COPYRIGHT
    4399                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    4400                 :             : !! This file is distributed under the terms of the
    4401                 :             : !! GNU General Public License, see ~abinit/COPYING
    4402                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    4403                 :             : !!
    4404                 :             : !! INPUTS
    4405                 :             : !!  matlu1(natom),matlu2(natom) :: input quantity
    4406                 :             : !!  natom=number of atoms in cell.
    4407                 :             : !!  opt_add = if present, add the result to trace
    4408                 :             : !!  trace_tot = if present, computes the trace over all atoms
    4409                 :             : !!  iatom = if present, only computes the contribution of iatom
    4410                 :             : !!          if <=0, add all contributions as usual
    4411                 :             : !!
    4412                 :             : !! OUTPUT
    4413                 :             : !!  trace(natom) :: Tr(matlu1*matlu2) for each atom
    4414                 :             : !!
    4415                 :             : !! SIDE EFFECTS
    4416                 :             : !!
    4417                 :             : !! NOTES
    4418                 :             : !!
    4419                 :             : !! SOURCE
    4420                 :             : 
    4421                 :        8841 :  subroutine trace_prod_matlu(matlu1,matlu2,natom,trace,trace_tot,iatom)
    4422                 :             : 
    4423                 :             : !Arguments ------------------------------------
    4424                 :             :  integer, intent(in) :: natom
    4425                 :             :  type(matlu_type), intent(in) :: matlu1(natom),matlu2(natom)
    4426                 :             :  complex(dp), intent(inout) :: trace(natom)
    4427                 :             :  complex(dp), optional, intent(out) :: trace_tot
    4428                 :             :  integer, optional, intent(in) :: iatom
    4429                 :             : !Local variables-------------------------------
    4430                 :             :  integer :: ia1,ia2,iatom_,isppol,lpawu,nspinor,nsppol
    4431                 :             : !************************************************************************
    4432                 :             : 
    4433                 :        8841 :  nspinor = matlu1(1)%nspinor
    4434                 :        8841 :  nsppol  = matlu1(1)%nsppol
    4435                 :             : 
    4436         [ +  + ]:       27687 :  trace(:)  = czero
    4437                 :             : 
    4438                 :        8841 :  ia1 = 1 ; ia2 = natom
    4439         [ +  + ]:        8841 :  if (present(iatom)) then
    4440         [ +  - ]:        8731 :    if (iatom > 0) then
    4441                 :        8841 :      ia1 = iatom ; ia2 = iatom
    4442                 :             :    end if
    4443                 :             :  end if ! present(iatom)
    4444                 :             : 
    4445         [ +  + ]:       27687 :  do iatom_=ia1,ia2
    4446                 :       18846 :    lpawu = matlu1(iatom_)%lpawu
    4447         [ +  + ]:       18846 :    if (lpawu == -1) cycle
    4448         [ +  + ]:       27880 :    do isppol=1,nsppol
    4449   [ +  +  +  + ]:      942986 :      trace(iatom_) = trace(iatom_) + sum(matlu1(iatom_)%mat(:,:,isppol)*transpose(matlu2(iatom_)%mat(:,:,isppol)))
    4450                 :             :    end do ! isppol
    4451         [ +  + ]:       19496 :    if (nsppol == 1 .and. nspinor == 1) trace(iatom_) = trace(iatom_) * two
    4452                 :             :  end do ! iatom
    4453                 :             : 
    4454   [ -  +  -  - ]:        8841 :  if (present(trace_tot)) trace_tot = sum(trace(:))
    4455                 :             : 
    4456                 :        8841 :  end subroutine trace_prod_matlu
    4457                 :             : !!***
    4458                 :             : 
    4459                 :             : !!****f* m_matlu/xmpi_matlu
    4460                 :             : !! NAME
    4461                 :             : !! xmpi_sum_matlu
    4462                 :             : !!
    4463                 :             : !! FUNCTION
    4464                 :             : !!  Put matlu into a buffer and perform the required MPI operation
    4465                 :             : !!  (xmpi_sum or xmpi_bcast) on the input communicator.
    4466                 :             : !!
    4467                 :             : !! INPUTS
    4468                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
    4469                 :             : !!  natom = number of atoms
    4470                 :             : !!  comm = communicator on which to perform the required communication
    4471                 :             : !!  master = master node (only used in the case of xmpi_bcast, default is 0)
    4472                 :             : !!  option = 1 (default) : xmpi_sum
    4473                 :             : !!         = 2 : xmpi_bcast
    4474                 :             : !!
    4475                 :             : !! OUTPUT
    4476                 :             : !!
    4477                 :             : !! SOURCE
    4478                 :             : 
    4479                 :        2218 :  subroutine xmpi_matlu(matlu,natom,comm,master,option)
    4480                 :             : 
    4481                 :             : !Arguments ------------------------------------
    4482                 :             :  integer, intent(in) :: comm,natom
    4483                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    4484                 :             :  integer, optional, intent(in) :: master,option
    4485                 :             : !Local variables-------------------------------
    4486                 :             :  integer :: iatom,ibuf,im1,ierr,isppol,lpawu
    4487                 :             :  integer :: master_node,ndim,nspinor,nsppol,opt,siz_buf
    4488                 :        2218 :  complex(dp), allocatable :: buffer(:)
    4489                 :             : !************************************************************************
    4490                 :             : 
    4491                 :        2218 :  nspinor = matlu(1)%nspinor
    4492                 :        2218 :  nsppol  = matlu(1)%nsppol
    4493                 :        2218 :  opt = 1
    4494         [ +  + ]:        2218 :  if (present(option)) opt = option
    4495                 :        2218 :  master_node = 0
    4496         [ +  + ]:        2218 :  if (present(master)) master_node = master
    4497                 :             : 
    4498                 :        2218 :  siz_buf = 0
    4499         [ +  + ]:        9969 :  do iatom=1,natom
    4500                 :        7751 :    lpawu = matlu(iatom)%lpawu
    4501         [ +  + ]:        7751 :    if (lpawu == -1) cycle
    4502                 :        9969 :    siz_buf = siz_buf + (2*lpawu+1)**2
    4503                 :             :  end do ! iatom
    4504                 :             : 
    4505                 :        2218 :  siz_buf = siz_buf * (nspinor**2) * nsppol
    4506                 :             : 
    4507   [ -  +  +  -  :        6654 :  ABI_MALLOC(buffer,(siz_buf))
          +  -  +  -  -  
                +  -  + ]
    4508                 :             : 
    4509                 :        2218 :  ibuf = 0
    4510         [ +  + ]:        9969 :  do iatom=1,natom
    4511                 :        7751 :    lpawu = matlu(iatom)%lpawu
    4512         [ +  + ]:        7751 :    if (lpawu == -1) cycle
    4513                 :        2734 :    ndim = nspinor * (2*lpawu+1)
    4514         [ +  + ]:        8933 :    do isppol=1,nsppol
    4515         [ +  + ]:       32582 :      do im1=1,ndim
    4516         [ +  + ]:      159034 :        buffer(ibuf+1:ibuf+ndim) = matlu(iatom)%mat(:,im1,isppol)
    4517                 :       24831 :        ibuf = ibuf + ndim
    4518                 :             :      end do ! im1
    4519                 :             :    end do ! isppol
    4520                 :             :  end do ! iatom
    4521                 :             : 
    4522         [ +  + ]:        2218 :  if (opt == 1) then
    4523                 :        2176 :    call xmpi_sum(buffer(:),comm,ierr)
    4524         [ +  - ]:          42 :  else if (opt == 2) then
    4525                 :          42 :    call xmpi_bcast(buffer(:),master_node,comm,ierr)
    4526                 :             :  end if ! opt
    4527                 :             : 
    4528                 :             :  ibuf = 0
    4529         [ +  + ]:        9969 :  do iatom=1,natom
    4530                 :        7751 :    lpawu = matlu(iatom)%lpawu
    4531         [ +  + ]:        7751 :    if (lpawu == -1) cycle
    4532                 :        2734 :    ndim = nspinor * (2*lpawu+1)
    4533         [ +  + ]:        8933 :    do isppol=1,nsppol
    4534         [ +  + ]:       32582 :      do im1=1,ndim
    4535         [ +  + ]:      159034 :        matlu(iatom)%mat(:,im1,isppol) = buffer(ibuf+1:ibuf+ndim)
    4536                 :       24831 :        ibuf = ibuf + ndim
    4537                 :             :      end do ! im1
    4538                 :             :    end do ! isppol
    4539                 :             :  end do ! iatom
    4540                 :             : 
    4541         [ -  + ]:        2218 :  ABI_FREE(buffer)
    4542                 :             : 
    4543                 :        2218 :  end subroutine xmpi_matlu
    4544                 :             : !!***
    4545                 :             : 
    4546                 :             : !!****f* m_matlu/symmetrize_matlu
    4547                 :             : !! NAME
    4548                 :             : !! symmetrize_matlu
    4549                 :             : !!
    4550                 :             : !! FUNCTION
    4551                 :             : !!  Symmetrizes matlu (A = (A+A^T)/2
    4552                 :             : !!
    4553                 :             : !! INPUTS
    4554                 :             : !!  matlu <type(matlu_type)>= density matrix in the local orbital basis and related variables
    4555                 :             : !!  natom = number of atoms
    4556                 :             : !!
    4557                 :             : !! OUTPUT
    4558                 :             : !!  err = difference between A and symmetrized A
    4559                 :             : !!
    4560                 :             : !! SOURCE
    4561                 :             : 
    4562                 :           0 :  subroutine symmetrize_matlu(matlu,natom,err)
    4563                 :             : 
    4564                 :             : !Arguments ------------------------------------
    4565                 :             :  integer, intent(in) :: natom
    4566                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    4567                 :             :  real(dp), optional, intent(out) :: err
    4568                 :             : !Local variables-------------------------------
    4569                 :             :  integer :: iatom,isppol,lpawu,nspinor,nsppol,tndim
    4570                 :             :  real(dp) :: err_
    4571                 :           0 :  complex(dp), allocatable :: mat_tmp(:,:)
    4572                 :             : !************************************************************************
    4573                 :             : 
    4574                 :           0 :  nspinor = matlu(1)%nspinor
    4575                 :           0 :  nsppol  = matlu(1)%nsppol
    4576                 :             : 
    4577         [ #  # ]:           0 :  if (present(err)) err = zero
    4578                 :             : 
    4579         [ #  # ]:           0 :  do iatom=1,natom
    4580                 :           0 :    lpawu = matlu(iatom)%lpawu
    4581         [ #  # ]:           0 :    if (lpawu == -1) cycle
    4582                 :           0 :    tndim = nspinor * (2*lpawu+1)
    4583   [ #  #  #  #  :           0 :    ABI_MALLOC(mat_tmp,(tndim,tndim))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4584         [ #  # ]:           0 :    do isppol=1,nsppol
    4585                 :             :      mat_tmp(:,:) = half * (matlu(iatom)%mat(:,:,isppol)+ &
    4586   [ #  #  #  # ]:           0 :                   & transpose(matlu(iatom)%mat(:,:,isppol)))
    4587         [ #  # ]:           0 :      if (present(err)) then
    4588   [ #  #  #  # ]:           0 :        err_ = sum(abs(mat_tmp(:,:)-matlu(iatom)%mat(:,:,isppol)))
    4589         [ #  # ]:           0 :        if (err_ > err) err = err_
    4590                 :             :      end if ! present(err)
    4591   [ #  #  #  # ]:           0 :      matlu(iatom)%mat(:,:,isppol) = mat_tmp(:,:)
    4592                 :             :    end do ! isppol
    4593         [ #  # ]:           0 :    ABI_FREE(mat_tmp)
    4594                 :             :  end do ! iatom
    4595                 :             : 
    4596                 :           0 :  end subroutine symmetrize_matlu
    4597                 :             : !!***
    4598                 :             : 
    4599                 :             : !!****f* m_matlu/ylm2jmj_matlu
    4600                 :             : !! NAME
    4601                 :             : !! ylm2jmj_matlu
    4602                 :             : !!
    4603                 :             : !! FUNCTION
    4604                 :             : !! Transform mat from Ylm to JmJ basis or vice versa
    4605                 :             : !!
    4606                 :             : !! COPYRIGHT
    4607                 :             : !! Copyright (C) 2005-2026 ABINIT group (BAmadon)
    4608                 :             : !! This file is distributed under the terms of the
    4609                 :             : !! GNU General Public License, see ~abinit/COPYING
    4610                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    4611                 :             : !!
    4612                 :             : !! INPUTS
    4613                 :             : !!  matlu(natom) :: input quantity
    4614                 :             : !!  natom :: number of atoms
    4615                 :             : !!  option=1 go from Ylm to JmJ basis
    4616                 :             : !!  option=2 go from JmJ to Ylm basis
    4617                 :             : !!  paw_dmft  <type(paw_dmft_type)>= paw+dmft related data
    4618                 :             : !! SIDE EFFECTS
    4619                 :             : !!
    4620                 :             : !! NOTES
    4621                 :             : !!
    4622                 :             : !! SOURCE
    4623                 :             : 
    4624                 :           0 :  subroutine ylm2jmj_matlu(matlu,natom,option,paw_dmft)
    4625                 :             : 
    4626                 :             : !Arguments ------------------------------------
    4627                 :             :  integer, intent(in) :: natom,option
    4628                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    4629                 :             :  type(paw_dmft_type), intent(in) :: paw_dmft
    4630                 :             : !Local variables-------------------------------
    4631                 :             :  integer :: iatom,lpawu,nspinor,tndim,tndim_max
    4632                 :           0 :  complex(dp), allocatable :: mat_tmp(:,:)
    4633                 :             :  character(len=1) :: c1,c2
    4634                 :             : !************************************************************************
    4635                 :             : 
    4636                 :           0 :  nspinor = paw_dmft%nspinor
    4637         [ #  # ]:           0 :  if (nspinor == 1) ABI_BUG("nspinor should be equal to 2")
    4638                 :             : 
    4639                 :           0 :  tndim_max = nspinor * (2*paw_dmft%maxlpawu+1)
    4640                 :             : 
    4641         [ #  # ]:           0 :  if (option == 1) then
    4642                 :           0 :    c1 = "c" ; c2 = "n"
    4643                 :             :  else
    4644                 :           0 :    c1 = "n" ; c2 = "c"
    4645                 :             :  end if
    4646                 :             : 
    4647   [ #  #  #  #  :           0 :  ABI_MALLOC(mat_tmp,(tndim_max,tndim_max))
          #  #  #  #  #  
          #  #  #  #  #  
                   #  # ]
    4648                 :             : 
    4649         [ #  # ]:           0 :  do iatom=1,natom
    4650                 :           0 :    lpawu = paw_dmft%lpawu(iatom)
    4651         [ #  # ]:           0 :    if (lpawu == -1) cycle
    4652         [ #  # ]:           0 :    if (lpawu == 0) ABI_BUG("l should not be equal to 0")
    4653                 :           0 :    tndim = nspinor * (2*lpawu+1)
    4654                 :             : 
    4655                 :             :    call abi_xgemm("n",c2,tndim,tndim,tndim,cone,matlu(iatom)%mat(:,:,1),tndim, &
    4656                 :           0 :                 & paw_dmft%jmj2ylm(:,1:tndim,lpawu+1),tndim_max,czero,mat_tmp(:,1:tndim),tndim_max)
    4657                 :             : 
    4658                 :             :    call abi_xgemm(c1,"n",tndim,tndim,tndim,cone,paw_dmft%jmj2ylm(:,1:tndim,lpawu+1), &
    4659                 :           0 :                 & tndim_max,mat_tmp(:,1:tndim),tndim_max,czero,matlu(iatom)%mat(:,:,1),tndim)
    4660                 :             : 
    4661                 :             :  end do ! iatom
    4662                 :             : 
    4663         [ #  # ]:           0 :  ABI_FREE(mat_tmp)
    4664                 :             : 
    4665                 :           0 :  end subroutine ylm2jmj_matlu
    4666                 :             : !!***
    4667                 :             : 
    4668                 :             : !!***
    4669                 :             : !!****f* m_matlu/magnfield_matlu
    4670                 :             : !! NAME
    4671                 :             : !! magnfield_matlu
    4672                 :             : !!
    4673                 :             : !! FUNCTION
    4674                 :             : !! return the matrix of magnetic moment mz times Bz
    4675                 :             : !!
    4676                 :             : !!
    4677                 :             : !! COPYRIGHT
    4678                 :             : !! Copyright (C) 2005-2026 ABINIT group (FGendron)
    4679                 :             : !! This file is distributed under the terms of the
    4680                 :             : !! GNU General Public License, see ~abinit/COPYING
    4681                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    4682                 :             : !!
    4683                 :             : !! INPUTS
    4684                 :             : !! matlu1(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: input quantity in Ylm basis
    4685                 :             : !! natom :: number of atoms
    4686                 :             : !! bfield :: value of magnetic field in Tesla
    4687                 :             : !! option = 1 :: scalar spin angular momentum along z axis
    4688                 :             : !! option = 2 :: SOC total angular momentum (L+2S) along z axis
    4689                 :             : !!
    4690                 :             : !! OUTPUT
    4691                 :             : !!  matlu(natom)%(nsppol,nspinor,nspinor,ndim,ndim) :: product
    4692                 :             : !!
    4693                 :             : !! SIDE EFFECTS
    4694                 :             : !!
    4695                 :             : !! NOTES
    4696                 :             : !!
    4697                 :             : !! SOURCE
    4698                 :           8 :  subroutine magnfield_matlu(matlu,natom,bfield,option)
    4699                 :             :  use defs_basis
    4700                 :             :  use defs_wvltypes
    4701                 :             :  implicit none
    4702                 :             : 
    4703                 :             : !Arguments ------------------------------------
    4704                 :             : !scalars
    4705                 :             :  integer, intent(in) :: natom,option
    4706                 :             :  real(dp) :: bfield
    4707                 :             : !arrays
    4708                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    4709                 :             : !Local variables-------------------------------
    4710                 :             : !scalars
    4711                 :             :  integer :: iatom,im,ndim,isppol
    4712                 :             :  integer :: ll,ml1,jc1,ms1,tndim
    4713                 :             :  real(dp) :: xj
    4714                 :             : !arrays
    4715                 :           8 :  type(coeff2c_type), allocatable :: magnmatb(:)
    4716                 :             : !************************************************************************
    4717                 :             : 
    4718                 :             :  !================================
    4719                 :             :  ! Allocate matrices
    4720                 :             :  !================================
    4721                 :             : 
    4722   [ -  +  +  -  :          32 :  ABI_MALLOC(magnmatb,(natom))
          +  -  +  -  -  
             +  -  +  +  
                      + ]
    4723         [ +  + ]:          16 :  do iatom=1,natom
    4724         [ +  - ]:          16 :    if(matlu(iatom)%lpawu .ne. -1) then
    4725                 :           8 :      tndim=2*(2*matlu(iatom)%lpawu+1)
    4726   [ -  +  +  -  :          32 :      ABI_MALLOC(magnmatb(iatom)%value,(tndim,tndim))
          -  +  +  -  +  
          -  +  -  -  +  
             -  +  -  + ]
    4727   [ +  +  +  + ]:         888 :      magnmatb(iatom)%value=czero
    4728                 :             :    endif
    4729                 :             :  enddo
    4730                 :             : 
    4731         [ +  - ]:           8 :  if(option .eq. 1) then
    4732                 :             : 
    4733                 :             :  !================================
    4734                 :             :  ! Scalar magnetism (Spin only case)
    4735                 :             :  ! H = mu_B*g_e*S_Z*B_z
    4736                 :             :  !================================
    4737                 :             : 
    4738         [ +  + ]:          16 :    do iatom=1,natom
    4739         [ +  - ]:          16 :      if(matlu(iatom)%lpawu .ne. -1) then
    4740                 :           8 :        ndim=2*matlu(iatom)%lpawu+1
    4741         [ +  + ]:          24 :        do isppol=1,matlu(iatom)%nsppol
    4742         [ +  + ]:         104 :          do im=1,ndim
    4743         [ +  + ]:          96 :            if (isppol .eq. 1) then
    4744                 :          40 :              matlu(iatom)%mat(im,im,isppol) = half*bfield
    4745                 :             :            else
    4746                 :          40 :              matlu(iatom)%mat(im,im,isppol) = -half*bfield
    4747                 :             :            endif
    4748                 :             :          enddo ! im
    4749                 :             :        enddo ! isppol
    4750                 :             :      endif ! lpawu
    4751                 :             :    enddo ! natom
    4752                 :             : 
    4753                 :             : 
    4754         [ #  # ]:           0 :  elseif(option .eq. 2) then
    4755                 :             : 
    4756                 :             :  !================================
    4757                 :             :  ! Spin-orbit magnetism
    4758                 :             :  ! H = mu_B*(L_z+g_e*S_Z)*B_z
    4759                 :             :  !================================
    4760                 :             : 
    4761         [ #  # ]:           0 :    do iatom=1,natom
    4762         [ #  # ]:           0 :      if(matlu(iatom)%lpawu .ne. -1) then
    4763                 :           0 :        tndim=2*(2*matlu(iatom)%lpawu+1)
    4764                 :           0 :        ll=matlu(iatom)%lpawu
    4765                 :             : 
    4766                 :           0 :        jc1=0
    4767         [ #  # ]:           0 :        do ms1=-1,1
    4768                 :           0 :          xj=float(ms1)+half
    4769         [ #  # ]:           0 :          do ml1=-ll,ll
    4770                 :           0 :            jc1=jc1+1
    4771         [ #  # ]:           0 :            if(jc1 < tndim+1) then
    4772         [ #  # ]:           0 :              if (xj < 0.0) then
    4773                 :           0 :                magnmatb(iatom)%value(jc1,jc1) = half*(ml1-2*xj)*bfield
    4774         [ #  # ]:           0 :              elseif(xj > 0.0) then
    4775                 :           0 :                magnmatb(iatom)%value(jc1,jc1) = half*(ml1-2*xj)*bfield
    4776                 :             :              endif
    4777                 :             :            endif
    4778                 :             :          enddo !ml1
    4779                 :             :        enddo ! ms1
    4780                 :             :      endif !lpawu
    4781                 :             :    enddo !natom
    4782                 :             :  endif !option
    4783                 :             : 
    4784                 :             :  !=======================
    4785                 :             :  ! reshape matrix
    4786                 :             :  !=======================
    4787                 :             : 
    4788         [ -  + ]:           8 :  if(option .eq. 2) then
    4789                 :           0 :    call gather_matlu(matlu,magnmatb(natom),natom,option=-1,prtopt=1)
    4790                 :             :  endif
    4791                 :             : 
    4792                 :             :  !================================
    4793                 :             :  ! Deallocate matrices
    4794                 :             :  !================================
    4795                 :             : 
    4796         [ +  + ]:          16 :  do iatom=1,natom
    4797         [ +  - ]:          16 :    if(matlu(iatom)%lpawu .ne. -1) then
    4798         [ -  + ]:           8 :      ABI_FREE(magnmatb(iatom)%value)
    4799                 :             :    endif
    4800                 :             :  enddo
    4801                 :             : 
    4802   [ +  -  +  +  :          16 :  ABI_FREE(magnmatb)
             -  +  -  + ]
    4803                 :             : 
    4804                 :           8 :  end subroutine magnfield_matlu
    4805                 :             : !!***
    4806                 :             : 
    4807                 :             : 
    4808                 :             : !!****f* m_matlu/magmomjmj_matlu
    4809                 :             : !! NAME
    4810                 :             : !! magmomjmj_matlu
    4811                 :             : !!
    4812                 :             : !! FUNCTION
    4813                 :             : !! return the matrix of magnetic moments in the Jmj basis
    4814                 :             : !!
    4815                 :             : !!
    4816                 :             : !! COPYRIGHT
    4817                 :             : !! Copyright (C) 2005-2026 ABINIT group (FGendron)
    4818                 :             : !! This file is distributed under the terms of the
    4819                 :             : !! GNU General Public License, see ~abinit/COPYING
    4820                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
    4821                 :             : !!
    4822                 :             : !! INPUTS
    4823                 :             : !!
    4824                 :             : !! OUTPUT
    4825                 :             : !!
    4826                 :             : !! SIDE EFFECTS
    4827                 :             : !!
    4828                 :             : !! NOTES
    4829                 :             : !!
    4830                 :             : !! SOURCE
    4831                 :           0 :  subroutine magmomjmj_matlu(matlu,natom)
    4832                 :             :  use defs_basis
    4833                 :             :  use defs_wvltypes
    4834                 :             :  implicit none
    4835                 :             : 
    4836                 :             : !Arguments ------------------------------------
    4837                 :             : !scalars
    4838                 :             :  integer, intent(in) :: natom
    4839                 :             : !arrays
    4840                 :             :  type(matlu_type), intent(inout) :: matlu(natom)
    4841                 :             : !Local variables-------------------------------
    4842                 :             : !scalars
    4843                 :             :  integer :: iatom,lpawu,ll,ml1,ms1,jm,jc1,tndim,jj
    4844                 :             :  real(dp) :: xj,xmj
    4845                 :             : !arrays
    4846                 :           0 :  integer, allocatable :: ind_msml(:,:)
    4847                 :           0 :  type(coeff2c_type), allocatable :: gathermatlu(:)
    4848                 :           0 :  complex(dpc),allocatable :: mlms2jmj(:,:)
    4849                 :             : !************************************************************************
    4850                 :             : 
    4851                 :             :  !=====================================
    4852                 :             :  ! Allocate Matrices
    4853                 :             :  !=====================================
    4854                 :             : 
    4855   [ #  #  #  #  :           0 :  ABI_MALLOC(gathermatlu,(natom))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    4856                 :             : 
    4857         [ #  # ]:           0 :  do iatom=1,natom
    4858                 :           0 :    lpawu=matlu(iatom)%lpawu
    4859         [ #  # ]:           0 :    if(lpawu.ne.-1) then
    4860                 :           0 :      ll=lpawu
    4861                 :           0 :      tndim=2*(2*ll+1)
    4862                 :             : 
    4863   [ #  #  #  #  :           0 :      ABI_MALLOC(gathermatlu(iatom)%value,(tndim,tndim))
          #  #  #  #  #  
          #  #  #  #  #  
             #  #  #  # ]
    4864   [ #  #  #  # ]:           0 :      gathermatlu(iatom)%value=czero
    4865   [ #  #  #  #  :           0 :      ABI_MALLOC(mlms2jmj,(tndim,tndim))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    4866   [ #  #  #  # ]:           0 :      mlms2jmj=czero
    4867   [ #  #  #  #  :           0 :      ABI_MALLOC(ind_msml,(2,-ll:ll))
          #  #  #  #  #  
             #  #  #  #  
                      # ]
    4868   [ #  #  #  # ]:           0 :      mlms2jmj=czero
    4869                 :             : 
    4870                 :             :  !=====================================
    4871                 :             :  ! Build J,M_J matrix
    4872                 :             :  !=====================================
    4873                 :             : 
    4874                 :             :     jc1=0
    4875         [ #  # ]:           0 :     do ms1=1,2
    4876         [ #  # ]:           0 :       do ml1=-ll,ll
    4877                 :           0 :         jc1=jc1+1
    4878                 :           0 :         ind_msml(ms1,ml1)=jc1
    4879                 :             :       end do
    4880                 :             :     end do
    4881                 :             : 
    4882                 :           0 :     jc1=0
    4883         [ #  # ]:           0 :     do jj=ll,ll+1
    4884                 :           0 :       xj=float(jj)-half !  xj is in {ll-0.5, ll+0.5}
    4885         [ #  # ]:           0 :       do jm=-jj,jj-1
    4886                 :           0 :         xmj=float(jm)+half  ! xmj is in {-xj,xj}
    4887                 :           0 :         jc1=jc1+1           ! Global index for JMJ
    4888         [ #  # ]:           0 :         if(nint(xj+0.5)==ll+1) then  ! if xj=ll+0.5
    4889                 :           0 :           mlms2jmj(jc1,jc1)=xmj   !  J=L+0.5 and m_J=L+0.5
    4890         [ #  # ]:           0 :         else if(nint(xj-0.5)==ll-1) then
    4891                 :           0 :           mlms2jmj(jc1,jc1)=xmj   !  J=L+0.5 and m_J=-L-0.5
    4892                 :             :         end if
    4893                 :             :       end do
    4894                 :             :     end do
    4895                 :             : 
    4896                 :             :     !print to debug
    4897                 :             :     !write(message,'(3a)') ch10,"JMJ Matrix"
    4898                 :             :     !call wrtout(std_out,message,"COLL")
    4899                 :             :     !do im=1,2*(ll*2+1)
    4900                 :             :     !  write(message,'(12(1x,18(1x,f5.2,f5.2)))') (mlms2jmj(im,jm),jm=1,2*(ll*2+1))
    4901                 :             :     !  call wrtout(std_out,message,"COLL")
    4902                 :             :     !end do
    4903                 :             : 
    4904                 :             :   !=====================================
    4905                 :             :   ! Put back into matlu format
    4906                 :             :   !=====================================
    4907                 :             : 
    4908   [ #  #  #  #  :           0 :    gathermatlu(iatom)%value=mlms2jmj
          #  #  #  #  #  
                #  #  # ]
    4909                 :             : 
    4910                 :           0 :    call gather_matlu(matlu,gathermatlu(iatom),natom=1,option=-1,prtopt=0)
    4911                 :             : 
    4912                 :             :   !=====================================
    4913                 :             :   ! Deallocate Matrices
    4914                 :             :   !=====================================
    4915                 :             : 
    4916         [ #  # ]:           0 :    ABI_FREE(gathermatlu(iatom)%value)
    4917                 :             :     end if !lpawu
    4918                 :             :   end do !natom
    4919                 :             : 
    4920         [ #  # ]:           0 : ABI_FREE(mlms2jmj)
    4921         [ #  # ]:           0 : ABI_FREE(ind_msml)
    4922   [ #  #  #  #  :           0 : ABI_FREE(gathermatlu)
             #  #  #  # ]
    4923                 :             : 
    4924                 :           0 : end subroutine magmomjmj_matlu
    4925                 :             : 
    4926                 :             : 
    4927   [ #  #  #  #  :           0 : END MODULE m_matlu
          #  #  #  #  #  
                #  #  # ]
    4928                 :             : !!***
        

Generated by: LCOV version 2.3-1