LCOV - code coverage report
Current view: top level - src/44_abitools - m_wfutils.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 97.2 % 108 105
Test Date: 2026-09-21 22:40:37 Functions: 100.0 % 3 3

            Line data    Source code
       1              : !!****m* ABINIT/m_wfutils
       2              : !! NAME
       3              : !!  m_wfutils
       4              : !!
       5              : !! FUNCTION
       6              : !!  parameters and function for wave functions copy
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2001-2026 ABINIT group (CS,GZ,FB)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~ABINIT/Infos/copyright
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_wfutils
      23              : 
      24              :  use defs_basis
      25              :  use m_abicore
      26              :  use m_errors
      27              : 
      28              :  use m_time,     only : timab
      29              : 
      30              :  implicit none
      31              : 
      32              :  private
      33              : 
      34              :  public :: setWFParameter ! Definition of wave functions parameters for copy functions.
      35              :  public :: wfcopy         ! Copy of wave functions arrays.
      36              : 
      37              : ! Global variables
      38              :  integer,save,public ABI_PROTECTED :: x_cplx   ! fortran data type for wave functions arrays real or complex.
      39              :  integer,save,public ABI_PROTECTED :: x_me_g0  ! processor number
      40              :  integer,save,public ABI_PROTECTED :: x_npw_k  ! number of plane waves at this k point
      41              :  integer,save,public ABI_PROTECTED :: x_nspinor! number of spinorial components of the wavefunctions on current proc
      42              :  integer,save,public ABI_PROTECTED :: x_icg    ! shift to be applied on the location of data in the array cg
      43              :  integer,save,public ABI_PROTECTED :: x_igsc   ! shift to be applied on the location of data in the array gsc
      44              :  integer,save,public ABI_PROTECTED :: x_blocksize
      45              : 
      46              : contains
      47              : !!***
      48              : 
      49              : !!****f* m_wfutils/setWFParameter
      50              : !! NAME
      51              : !!
      52              : !! setWFParameter
      53              : !!
      54              : !! FUNCTION
      55              : !! Initialize wave functions parameters for copy functions
      56              : !!
      57              : !! INPUTS
      58              : !!  cplx=fortran data type for wave functions arrays real or complex
      59              : !!  me_g0=1 if this node treats G=0.
      60              : !!  npw_k=number of plane waves at this k point
      61              : !!  nspinor=number of spinorial components of the wavefunctions on current proc
      62              : !!  icg=shift to be applied on the location of data in the array cg
      63              : !!  igsc=shift to be applied on the location of data in the array gsc
      64              : !!  blocksize=size of blocks
      65              : !!
      66              : !! SOURCE
      67              : !!
      68         5636 : subroutine setWFParameter(cplx,me_g0,npw_k,nspinor,icg,igsc,blocksize)
      69              : 
      70              : !Arguments ------------------------------------
      71              :  integer, intent(in) :: cplx,me_g0,npw_k,nspinor
      72              :  integer, intent(in) :: icg,igsc,blocksize
      73              : 
      74              : ! *********************************************************************
      75              : 
      76              :  ! Copy values in global variables
      77         5636 :  x_cplx=cplx
      78         5636 :  x_me_g0=me_g0
      79         5636 :  x_npw_k=npw_k
      80         5636 :  x_nspinor=nspinor
      81         5636 :  x_icg=icg
      82         5636 :  x_igsc=igsc
      83         5636 :  x_blocksize=blocksize
      84              : 
      85         5636 : end subroutine setWFParameter
      86              : !!***
      87              : 
      88              : ! correspondence with abinit. here for real wf
      89              : ! this is the index of a given band in cg array
      90         8343 : integer function x_cgindex(iblocksize)
      91              : 
      92              :  integer, intent(in) :: iblocksize
      93              : 
      94         8343 :  x_cgindex=x_npw_k*x_nspinor*(iblocksize-1)+x_icg+1
      95              : 
      96              : end function x_cgindex
      97              : 
      98              : ! correspondence with abinit. here for real wf
      99              : ! this is the index of a given band in gsc array
     100         2525 : integer function x_gscindex(iblocksize)
     101              : 
     102              :  integer, intent(in) :: iblocksize
     103              : 
     104         2525 :  x_gscindex=x_npw_k*x_nspinor*(iblocksize-1)+x_igsc+1
     105              : 
     106              : end function x_gscindex
     107              : 
     108        86506 : integer function x_windex(iblocksize)
     109              : 
     110              :  integer, intent(in) :: iblocksize
     111              : 
     112        86506 :  x_windex=x_npw_k*x_nspinor*(iblocksize-1)+1
     113              : 
     114              : end function x_windex
     115              : 
     116        97374 : integer function wfindex(iblocksize,indtype)
     117              : 
     118              :  integer, intent(in) :: iblocksize
     119              :  character(len=1), intent(in) :: indtype
     120              : 
     121         8343 :  select case(indtype)
     122              :  case ('C')
     123         8343 :    wfindex=x_cgindex(iblocksize)
     124              :  case ('S')
     125         2525 :    wfindex=x_gscindex(iblocksize)
     126              :  case ('W')
     127        86506 :    wfindex=x_windex(iblocksize)
     128              :  case default
     129        97374 :    ABI_ERROR("Wrong indtype: "//trim(indtype))
     130              :  end select
     131              : 
     132        97374 : end function wfindex
     133              : 
     134              : !!****f* m_wfutils/wfcopy
     135              : !! NAME
     136              : !!
     137              : !! wfcopy
     138              : !!
     139              : !! FUNCTION
     140              : !! copy of wave functions arrays.
     141              : !! called from lobpcg in REAL or COMPLEX wave functions.
     142              : !!
     143              : !! INPUTS
     144              : !!   direction=copy direction
     145              : !!                'D' direct (global array to local)
     146              : !!                'I' indirect (local to global)
     147              : !!   size=number of elements
     148              : !!   tsrc=source array
     149              : !!   incsrc=size increment for tsrc array
     150              : !!   tdest=destination array
     151              : !!   incdest=increment for tdest array
     152              : !!   blockiter=number of block iteration in case REAL
     153              : !!   iblock=block index
     154              : !!   indtype=indexation type in array
     155              : !!   withbbloc=apply block on band for each block
     156              : !!
     157              : !! TODO
     158              : !!  Split the two cases so that we can avoid the array descriptors.
     159              : !!
     160              : !! SOURCE
     161              : !!
     162       126373 : subroutine wfcopy(direction,size,tsrc,incsrc,tdest,incdest,blockiter,iblock,indtype,&
     163              : &                withbbloc,timopt,tim_wfcopy) ! optional arguments
     164              : 
     165              : !Arguments ------------------------------------
     166              :  character(len=1), intent(in) :: direction
     167              :  integer, intent(in) :: size,incsrc,incdest
     168              :  integer, intent(in) :: blockiter,iblock
     169              :  character(len=1), intent(in) :: indtype
     170              :  logical, optional, intent(in) :: withbbloc
     171              :  integer, intent(in), optional :: timopt,tim_wfcopy
     172              : !arrays
     173              :  real(dp), DEV_CONTARRD intent(in) :: tsrc(:,:)
     174              :  real(dp), DEV_CONTARRD intent(inout) :: tdest(:,:)
     175              : 
     176              : !Local variables ------------------------------------
     177              :  integer,parameter :: ndat1=1
     178              :  logical :: bblock=.false.
     179              :  integer :: lig,g1,g2,vectsize,rvectsize
     180              :  integer :: blocksize,bblocksize,iblocksize,iband
     181              :  real(dp) :: factor
     182              :  real(dp) :: tsec(2)
     183              : 
     184              : ! *********************************************************************
     185              : 
     186       126373 :  if (present(tim_wfcopy).and.present(timopt)) then
     187       126373 :    if(abs(timopt)==3) then
     188            0 :      call timab(tim_wfcopy,1,tsec)
     189              :    end if
     190              :  end if
     191              : 
     192       126373 :  if (present(withbbloc)) bblock=withbbloc
     193              : 
     194       126373 :  if (indtype == 'C') then
     195        14658 :    lig=x_icg
     196       111715 :  else if (indtype == 'S') then
     197         8062 :    lig=x_igsc
     198              :  else
     199              :    lig=0
     200              :  endif
     201              : 
     202       126373 :  rvectsize=x_npw_k*x_nspinor
     203       126373 :  if (x_me_g0 == 1) then
     204        47413 :    vectsize=2*rvectsize-1
     205              :  else
     206        78960 :    vectsize=2*rvectsize
     207              :  endif
     208       126373 :  if (x_cplx == 2) vectsize=x_npw_k*x_nspinor
     209              : 
     210       126373 :  blocksize  = x_blocksize
     211       126373 :  bblocksize=(iblock-1)*blocksize
     212              : 
     213       126373 :  if (direction == 'D') then
     214              : 
     215        81382 :    if (x_cplx == 1) then
     216              :      ! Pack real and imag part.
     217         4555 :      factor=sqrt(two)
     218        28641 :      do iblocksize=1,blockiter
     219        24086 :        iband=iblocksize
     220        24086 :        if (bblock) then
     221         1422 :          iband=iblocksize+bblocksize
     222              :        endif
     223        28641 :        if (x_me_g0 == 1) then
     224        10862 :          tdest(1 ,iblocksize)=tsrc(1,wfindex(iband,indtype))
     225        10862 :          g1 = wfindex(iband,  indtype)+1
     226        10862 :          g2 = wfindex(iband+1,indtype)-1
     227       815782 :          call dcopy(rvectsize-1,tsrc(1,g1:g2),1,tdest(2:rvectsize,iblocksize),1)
     228       413322 :          tdest(2:rvectsize,iblocksize) = factor * tdest(2:rvectsize,iblocksize)
     229              : 
     230       815782 :          call dcopy(rvectsize-1,tsrc(2,g1:g2),1,tdest(rvectsize+1:vectsize,iblocksize),1)
     231       413322 :          tdest(rvectsize+1:vectsize,iblocksize) = factor * tdest(rvectsize+1:vectsize,iblocksize)
     232              :          ! MG FIXME: Here gfortran4.9 allocates temporary arrays due to factor.
     233              :        else
     234        13224 :          g1 = wfindex(iband,  indtype)
     235        13224 :          g2 = wfindex(iband+1,indtype)-1
     236       462840 :          call dcopy(rvectsize,tsrc(1,g1:g2),1,tdest(1:rvectsize,iblocksize),1)
     237       238032 :          tdest(1:rvectsize,iblocksize) = factor * tdest(1:rvectsize,iblocksize)
     238              : 
     239       462840 :          call dcopy(rvectsize,tsrc(2,g1:g2),1,tdest(rvectsize+1:vectsize,iblocksize),1)
     240       238032 :          tdest(rvectsize+1:vectsize,iblocksize) = factor * tdest(rvectsize+1:vectsize,iblocksize)
     241              :        end if
     242              :      end do
     243              :    else
     244        76827 :      if (indtype == 'C') then
     245         8670 :        if (bblock) then
     246         5369 :          g1 = vectsize*((iblock-1)*blocksize)+lig+1
     247         5369 :          g2 = vectsize*(iblock*blocksize)+lig
     248         5369 :          call zcopy(size,tsrc(:,g1:g2),incsrc,tdest(:,1:blocksize),incdest)
     249              :        else
     250         3301 :          g1 = lig+1
     251         3301 :          g2 = vectsize*((iblock-1)*blocksize)+lig
     252         3301 :          call zcopy(size,tsrc(:,g1:g2),incsrc,tdest(:,1:bblocksize),incdest)
     253              :        end if
     254        68157 :      else if (indtype == 'S') then
     255         3213 :        g1 = lig+1
     256         3213 :        g2 = vectsize*((iblock-1)*blocksize)+lig
     257         3213 :        call zcopy(size,tsrc(:,g1:g2),incsrc,tdest(:,1:bblocksize),incdest)
     258              :      else
     259        64944 :        call zcopy(size,tsrc,incsrc,tdest,incdest)
     260              :      endif
     261              :    end if
     262              : 
     263        44991 :  else if (direction == 'I') then
     264        44991 :    if (x_cplx == 1) then
     265              :      ! Unpack real and imag blocks.
     266         2485 :      factor=one/sqrt(two)
     267        15778 :      do iblocksize=1,blockiter
     268        13293 :        iband=iblocksize
     269        13293 :        if ( bblock ) then
     270         2156 :          iband=iblocksize+(iblock-1)*blocksize
     271              :        end if
     272        15778 :        if (x_me_g0 == 1) then
     273         5877 :          tdest(1,wfindex(iband,indtype))=tsrc(1,iblocksize)
     274         5877 :          tdest(2,wfindex(iband,indtype))=zero
     275              : 
     276         5877 :          g1 = wfindex(iband,indtype)+1
     277         5877 :          g2 = wfindex(iband+1,indtype)-1
     278       451377 :          call dcopy(rvectsize-1,tsrc(2:rvectsize,iblocksize),1,tdest(1,g1:g2),1)
     279       228627 :          tdest(1,g1:g2) = factor * tdest(1,g1:g2)
     280              : 
     281       451377 :          call dcopy(rvectsize-1,tsrc(rvectsize+1:vectsize,iblocksize),1,tdest(2,g1:g2),1)
     282       228627 :          tdest(2,g1:g2) = factor * tdest(2,g1:g2)
     283              :        else
     284         7416 :          g1 = wfindex(iband,indtype)
     285         7416 :          g2 = wfindex(iband+1,indtype)-1
     286       259560 :          call dcopy(rvectsize,tsrc(1:rvectsize,iblocksize),1,tdest(1,g1:g2),1)
     287       133488 :          tdest(1,g1:g2) = factor * tdest(1,g1:g2)
     288       259560 :          call dcopy(rvectsize,tsrc(rvectsize+1:vectsize,iblocksize),1,tdest(2,g1:g2),1)
     289       133488 :          tdest(2,g1:g2) = factor * tdest(2,g1:g2)
     290              :        end if
     291              :      end do
     292              :    else
     293        42506 :      if (indtype == 'C') then
     294         5369 :        g1 = vectsize*((iblock-1)*blocksize)+lig+1
     295         5369 :        g2 = vectsize*(iblock*blocksize)+lig
     296         5369 :        call zcopy(size,tsrc,1,tdest(:,g1:g2),1)
     297        37137 :      else if ( indtype == 'S' ) then
     298         4665 :        g1 = vectsize*((iblock-1)*blocksize)+lig+1
     299         4665 :        g2 = vectsize*(iblock*blocksize)+lig
     300         4665 :        call zcopy(size,tsrc,1,tdest(:,g1:g2),1)
     301              :      else
     302        32472 :        call zcopy(size,tsrc,1,tdest,1)
     303              :      end if
     304              :    end if
     305              :  else
     306            0 :    ABI_ERROR("Wrong direction: "//trim(direction))
     307              :  endif
     308              : 
     309       126373 :  if (present(tim_wfcopy).and.present(timopt)) then
     310       126373 :    if(abs(timopt)==3) then
     311            0 :      call timab(tim_wfcopy,2,tsec)
     312              :    end if
     313              :  end if
     314              : 
     315       126373 : end subroutine wfcopy
     316              : !!***
     317              : 
     318              : end module m_wfutils
     319              : !!***
        

Generated by: LCOV version 2.3-1