LCOV - code coverage report
Current view: top level - src/65_paw - m_fourier_interpol.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 73.0 % 204 149
Test Date: 2026-11-10 13:31:01 Functions: 100.0 % 3 3
Branches: 45.7 % 674 308

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_fourier_interpol
       2                 :             : !! NAME
       3                 :             : !!  m_fourier_interpol
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module contains routines used to perform a Fourier interpolation.
       7                 :             : !!  Mainly used in PAW to interpol data from/to the coarse FFT grid from/to the fine FFT grid.
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !! Copyright (C) 2018-2026 ABINIT group (FJ, MT, MG)
      11                 :             : !! This file is distributed under the terms of the
      12                 :             : !! GNU General Public License, see ~abinit/COPYING
      13                 :             : !! or http://www.gnu.org/copyleft/gpl.txt .
      14                 :             : !!
      15                 :             : !! SOURCE
      16                 :             : 
      17                 :             : #if defined HAVE_CONFIG_H
      18                 :             : #include "config.h"
      19                 :             : #endif
      20                 :             : 
      21                 :             : #include "abi_common.h"
      22                 :             : 
      23                 :             : MODULE m_fourier_interpol
      24                 :             : 
      25                 :             :  use defs_basis
      26                 :             :  use m_abicore
      27                 :             :  use m_errors
      28                 :             : 
      29                 :             :  use defs_abitypes, only : MPI_type
      30                 :             :  use m_fft,         only : zerosym, indirect_parallel_Fourier, fourdp
      31                 :             :  use m_pawfgr,      only : pawfgr_type,pawfgr_destroy,indgrid
      32                 :             :  use m_mpinfo,      only : destroy_mpi_enreg, initmpi_seq
      33                 :             : 
      34                 :             :  implicit none
      35                 :             : 
      36                 :             :  private
      37                 :             : 
      38                 :             : !public procedures.
      39                 :             :  public :: transgrid            ! Convert a density/potential from the coarse to the fine grid and vice versa
      40                 :             :  public :: fourier_interpol     ! Fourier interpolation. Just a wrapper for transgrid.
      41                 :             :  public :: fourier_interpol_seq ! Fourier interpolation without MPI-FFT.
      42                 :             : 
      43                 :             : CONTAINS  !========================================================================================
      44                 :             : !!***
      45                 :             : 
      46                 :             : !----------------------------------------------------------------------
      47                 :             : 
      48                 :             : !!****f* m_fourier_interpol/transgrid
      49                 :             : !! NAME
      50                 :             : !! transgrid
      51                 :             : !!
      52                 :             : !! FUNCTION
      53                 :             : !! Convert a given density (or potential) from the coarse to the fine rectangular grid and vice versa
      54                 :             : !! Used in PAW calculations
      55                 :             : !!
      56                 :             : !! INPUTS
      57                 :             : !!  cplex=1 if rhor[f] is real, 2 if rhor[f] is complex
      58                 :             : !!  mpi_enreg=information about MPI parallelization
      59                 :             : !!  nspden=number of spin-density components
      60                 :             : !!  optgrid=+1 to go from the coarse grid towards the fine grid
      61                 :             : !!          -1 to go from the fine grid towards the coarse grid
      62                 :             : !!  optin= 0: input density/potential is taken from rhor(:,nspden)
      63                 :             : !!         1: input density/potential is taken from rhog(:)     (ispden=1)
      64                 :             : !!                                              and rhor(:,2:4) (ispden=2,3,4)
      65                 :             : !!  optout= 0: output density/potential is given in r space in rhor(:,nspden)
      66                 :             : !!          1: output density/potential is given in r space in rhor(:,nspden)
      67                 :             : !!                                           and in g space in rhog(:)
      68                 :             : !!  pawfgr <type(paw_fgr_type)>=fine rectangular grid parameters
      69                 :             : !!    %nfftc=number of points in the coarse FFT box
      70                 :             : !!    %nfft =number of points in the fine FFT box
      71                 :             : !!    %ngfftc(18)=all needed information about 3D FFT, for the coarse grid
      72                 :             : !!    %ngfft(18) =all needed information about 3D FFT, for the fine grid
      73                 :             : !!    %coatofin(nfftc)=Index of the points of the coarse grid on the fine grid
      74                 :             : !!    %fintocoa(nfft) =Index of the points of the fine grid on the coarse grid
      75                 :             : !!    %usefinegrid= 1 if a fine FFT grid is used (0 otherwise)
      76                 :             : !!  if optgrid=+1 and optin=1:
      77                 :             : !!    rhog(2,nfftc)=Fourier transform of input density/potential on the coarse grid
      78                 :             : !!  if optgrid=-1 and optin=1:
      79                 :             : !!    rhogf(2,nfftf)=Fourier transform of input density/potential on the fine grid
      80                 :             : !!  if optgrid=+1
      81                 :             : !!    rhor(cplex*nfftc,nspden)=input density/potential in r space on the coarse grid
      82                 :             : !!  if optgrid=-1:
      83                 :             : !!    rhorf(cplex*nfftf,nspden)=input density/potential in r space on the fine grid
      84                 :             : !!
      85                 :             : !! OUTPUT
      86                 :             : !!  if optgrid=-1 and optout=1:
      87                 :             : !!    rhog(2,nfftc)=Fourier transform of output density/potential on the coarse grid
      88                 :             : !!  if optgrid=+1 and optout=1:
      89                 :             : !!    rhogf(2,nfftf)=Fourier transform of output density/potential on the fine grid
      90                 :             : !!  if optgrid=-1
      91                 :             : !!    rhor(cplex*nfftc,nspden)=output density/potential in r space on the coarse grid
      92                 :             : !!  if optgrid=+1:
      93                 :             : !!    rhorf(cplex*nfftf,nspden)=output density/potential in r space on the fine grid
      94                 :             : !!
      95                 :             : !! SOURCE
      96                 :             : 
      97                 :       55171 : subroutine transgrid(cplex,mpi_enreg,nspden,optgrid,optin,optout,paral_kgb,pawfgr,rhog,rhogf,rhor,rhorf)
      98                 :             : 
      99                 :             : !Arguments ---------------------------------------------
     100                 :             : !scalars
     101                 :             :  integer,intent(in) :: cplex,nspden,optgrid,optin,optout,paral_kgb
     102                 :             :  type(MPI_type),intent(in) :: mpi_enreg
     103                 :             :  type(pawfgr_type),intent(in) :: pawfgr
     104                 :             : !arrays
     105                 :             :  real(dp),intent(inout) :: rhog(2,pawfgr%nfftc),rhogf(2,pawfgr%nfft)
     106                 :             :  real(dp),intent(inout) :: rhor(cplex*pawfgr%nfftc,nspden),rhorf(cplex*pawfgr%nfft,nspden)
     107                 :             : 
     108                 :             : !Local variables ---------------------------------------
     109                 :             : !scalars
     110                 :             :  integer :: i1,ispden,nfftc,nfftctot,nfftf,nfftftot
     111                 :             :  character(len=500) :: msg
     112                 :             : !arrays
     113                 :             :  integer :: ngfftc(18),ngfftf(18)
     114                 :       55171 :  real(dp),allocatable :: vectg(:,:),work(:,:),workfft(:)
     115                 :             : 
     116                 :             : ! *************************************************************************
     117                 :             : 
     118                 :             :  DBG_ENTER("COLL")
     119                 :             : 
     120                 :             : !Tests
     121         [ -  + ]:       55171 :  if(pawfgr%nfft<pawfgr%nfftc) then
     122                 :           0 :    write(msg,'(a,2(i0,1x))')' nfft (fine grid) must be >= nfft (coarse grid) while: ',pawfgr%nfft, pawfgr%nfftc
     123                 :           0 :    ABI_ERROR(msg)
     124                 :             :  end if
     125                 :             : 
     126                 :             : !Store FFT dimensions
     127         [ +  + ]:     1048249 :  nfftc=pawfgr%nfftc;ngfftc(:)=pawfgr%ngfftc(:);nfftctot=ngfftc(1)*ngfftc(2)*ngfftc(3)
     128         [ +  + ]:     1048249 :  nfftf=pawfgr%nfft ;ngfftf(:)=pawfgr%ngfft (:);nfftftot=ngfftf(1)*ngfftf(2)*ngfftf(3)
     129                 :             : 
     130                 :             : !If no fine FFT grid is used, this is only a simple transfer
     131         [ +  + ]:       55171 :  if (pawfgr%usefinegrid==0) then
     132         [ +  - ]:        4052 :    if (optgrid==1) then
     133   [ +  +  +  + ]:    43212698 :      rhorf=rhor
     134   [ +  +  +  -  :     1213748 :      if (optout==1.and.optin==1) rhogf=rhog
             +  +  +  + ]
     135   [ +  +  -  + ]:        4052 :      if (optout==1.and.optin/=1) then
     136   [ #  #  #  #  :           0 :        ABI_MALLOC(workfft,(cplex*nfftc))
          #  #  #  #  #  
                #  #  # ]
     137         [ #  # ]:           0 :        workfft(:)=rhor(:,1)
     138                 :           0 :        call fourdp(cplex,rhogf,workfft,-1,mpi_enreg,nfftc,1,ngfftc,0)
     139         [ #  # ]:           0 :        ABI_FREE(workfft)
     140                 :             :      end if
     141                 :             :    end if
     142         [ -  + ]:        4052 :    if (optgrid==-1) then
     143   [ #  #  #  # ]:           0 :      rhor=rhorf
     144   [ #  #  #  #  :           0 :      if (optout==1.and.optin==1) rhog=rhogf
             #  #  #  # ]
     145   [ #  #  #  # ]:           0 :      if (optout==1.and.optin/=1) then
     146   [ #  #  #  #  :           0 :        ABI_MALLOC(workfft,(cplex*nfftc))
          #  #  #  #  #  
                #  #  # ]
     147         [ #  # ]:           0 :        workfft(:)=rhorf(:,1)
     148                 :           0 :        call fourdp(cplex,rhog,workfft,-1,mpi_enreg,nfftc,1,ngfftc,0)
     149         [ #  # ]:           0 :        ABI_FREE(workfft)
     150                 :             :      end if
     151                 :             :    end if
     152                 :             :    return
     153                 :             :  end if
     154                 :             : 
     155                 :             : !====== FROM THE COARSE GRID TOWARDS THE FINE GRID =============
     156                 :             : !===============================================================
     157                 :             : !Calculate the FT of rhor to have it in the g space on the coarse grid
     158                 :             : !Transfer the FT of rhor on the coarse grid towards the fine grid
     159                 :             : !Then calculate the FT back to get rhorf on the fine grid
     160         [ +  + ]:       51119 :  if (optgrid==1) then
     161                 :             : 
     162   [ -  +  +  -  :       58899 :    ABI_MALLOC(work,(2,nfftc))
          +  -  +  -  -  
                +  -  + ]
     163                 :             : 
     164                 :             : !  First spin component
     165                 :             : !  --------------------------------------------------------------
     166         [ +  + ]:       19633 :    if (optout==0) then
     167                 :             : !    if optout=0, rhog on the fine grid is temporary (in vectg)
     168   [ -  +  +  -  :       56835 :      ABI_MALLOC(vectg,(2,nfftf))
          +  -  +  -  -  
                +  -  + ]
     169   [ +  +  +  + ]:  2395552236 :      vectg(:,:)=zero
     170         [ +  + ]:       18945 :      if (optin==1) then
     171                 :             :        call zerosym(rhog,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     172                 :       18748 : &       comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     173   [ +  +  -  + ]:       18748 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     174                 :             :          call indirect_parallel_Fourier&
     175   [ +  -  -  -  :        1280 : &         (pawfgr%coatofin,vectg,mpi_enreg,ngfftf,ngfftc,nfftf,nfftc,paral_kgb,rhog,nfftctot)
             -  -  -  + ]
     176                 :             :        else
     177         [ +  + ]:   235836195 :          do i1=1,nfftc
     178         [ +  + ]:   707473649 :            vectg(:,pawfgr%coatofin(i1))=rhog(:,i1)
     179                 :             :          end do
     180                 :             :        end if
     181                 :             :      else
     182   [ -  +  +  -  :         591 :        ABI_MALLOC(workfft,(cplex*nfftc))
          +  -  +  -  -  
                +  -  + ]
     183         [ +  + ]:        5516 :        workfft(:)=rhor(:,1)
     184                 :         197 :        call fourdp(cplex,work,workfft,-1,mpi_enreg,nfftc,1,ngfftc,0)
     185         [ -  + ]:         197 :        ABI_FREE(workfft)
     186                 :             :        call zerosym(work,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     187                 :         197 : &       comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     188   [ -  +  -  - ]:         197 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     189                 :             :          call indirect_parallel_Fourier&
     190   [ #  #  #  #  :           0 : &         (pawfgr%coatofin,vectg,mpi_enreg,ngfftf,ngfftc,nfftf,nfftc,paral_kgb,work,nfftctot)
             #  #  #  # ]
     191                 :             :        else
     192         [ +  + ]:        5516 :          do i1=1,nfftc
     193         [ +  + ]:       16154 :            vectg(:,pawfgr%coatofin(i1))=work(:,i1)
     194                 :             :          end do
     195                 :             :        end if
     196                 :             :      end if
     197                 :             : !    call zerosym(vectg,2,ngfftf(1),ngfftf(2),ngfftf(3),&
     198                 :             : !    &        comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     199   [ -  +  +  -  :       56835 :      ABI_MALLOC(workfft,(cplex*nfftf))
          +  -  +  -  -  
                +  -  + ]
     200                 :       18945 :      call fourdp(cplex,vectg,workfft,1,mpi_enreg,nfftf,1,ngfftf,0)
     201         [ +  + ]:   806287034 :      rhorf(:,1)=workfft(:)
     202         [ -  + ]:       18945 :      ABI_FREE(workfft)
     203         [ -  + ]:       18945 :      ABI_FREE(vectg)
     204                 :             :    else
     205                 :             : !    if optout=1, rhog on the fine grid is saved
     206                 :             :      call zerosym(rhog,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     207                 :         688 : &     comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     208   [ +  +  +  + ]:    96501448 :      rhogf(:,:)=zero
     209         [ +  - ]:         688 :      if (optin==1) then
     210   [ +  +  -  + ]:         688 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     211                 :             :          call indirect_parallel_Fourier&
     212   [ +  -  -  -  :          12 : &         (pawfgr%coatofin,rhogf,mpi_enreg,ngfftf,ngfftc,nfftf,nfftc,paral_kgb,rhog,nfftctot)
             -  -  -  + ]
     213                 :             :        else
     214         [ +  + ]:    12298156 :          do i1=1,nfftc
     215         [ +  + ]:    36893116 :            rhogf(:,pawfgr%coatofin(i1))=rhog(:,i1)
     216                 :             :          end do
     217                 :             :        end if
     218                 :             :      else
     219   [ #  #  #  #  :           0 :        ABI_MALLOC(workfft,(cplex*nfftc))
          #  #  #  #  #  
                #  #  # ]
     220         [ #  # ]:           0 :        workfft(:)=rhor(:,1)
     221                 :           0 :        call fourdp(cplex,work,workfft,-1,mpi_enreg,nfftc,1,ngfftc,0)
     222         [ #  # ]:           0 :        ABI_FREE(workfft)
     223                 :             :        call zerosym(work,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     224                 :           0 : &       comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     225   [ #  #  #  # ]:           0 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     226                 :             :          call indirect_parallel_Fourier&
     227   [ #  #  #  #  :           0 : &         (pawfgr%coatofin,rhogf,mpi_enreg,ngfftf,ngfftc,nfftf,nfftc,paral_kgb,work,nfftctot)
             #  #  #  # ]
     228                 :             :        else
     229         [ #  # ]:           0 :          do i1=1,nfftc
     230         [ #  # ]:           0 :            rhogf(:,pawfgr%coatofin(i1))=work(:,i1)
     231                 :             :          end do
     232                 :             :        end if
     233                 :             :      end if
     234                 :             : !    call zerosym(rhogf,2,ngfftf(1),ngfftf(2),ngfftf(3),&
     235                 :             : !    &        comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     236   [ -  +  +  -  :        2064 :      ABI_MALLOC(workfft,(cplex*nfftf))
          +  -  +  -  -  
                +  -  + ]
     237                 :         688 :      call fourdp(cplex,rhogf,workfft,1,mpi_enreg,nfftf,1,ngfftf,0)
     238         [ +  + ]:    32167608 :      rhorf(:,1)=workfft(:)
     239         [ -  + ]:         688 :      ABI_FREE(workfft)
     240                 :             :    end if
     241                 :             : 
     242                 :             : !  Additional spin components
     243                 :             : !  ----------------------------------------------------
     244         [ +  + ]:       19633 :    if (nspden>=2) then
     245   [ -  +  +  -  :       11178 :      ABI_MALLOC(vectg,(2,nfftf))
          +  -  +  -  -  
                +  -  + ]
     246         [ +  + ]:        9632 :      do ispden=2,nspden
     247   [ +  +  +  + ]:   412329947 :        vectg(:,:)=zero
     248   [ -  +  +  -  :       17718 :        ABI_MALLOC(workfft,(cplex*nfftc))
          +  -  +  -  -  
                +  -  + ]
     249         [ +  + ]:    39602380 :        workfft(:)=rhor(:,ispden)
     250                 :        5906 :        call fourdp(cplex,work,workfft,-1,mpi_enreg,nfftc,1,ngfftc,0)
     251         [ -  + ]:        5906 :        ABI_FREE(workfft)
     252                 :             :        call zerosym(work,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     253                 :        5906 : &       comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     254   [ +  +  -  + ]:        5906 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     255                 :             :          call indirect_parallel_Fourier&
     256   [ +  -  -  -  :         212 : &         (pawfgr%coatofin,vectg,mpi_enreg,ngfftf,ngfftc,nfftf,nfftc,paral_kgb,work,nfftctot)
             -  -  -  + ]
     257                 :             :        else
     258         [ +  + ]:    39038384 :          do i1=1,nfftc
     259         [ +  + ]:   117103764 :            vectg(:,pawfgr%coatofin(i1))=work(:,i1)
     260                 :             :          end do
     261                 :             :        end if
     262                 :             : !      call zerosym(vectg,2,ngfftf(1),ngfftf(2),ngfftf(3),&
     263                 :             : !      &          comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     264   [ -  +  +  -  :       17718 :        ABI_MALLOC(workfft,(cplex*nfftf))
          +  -  +  -  -  
                +  -  + ]
     265                 :        5906 :        call fourdp(cplex,vectg,workfft,1,mpi_enreg,nfftf,1,ngfftf,0)
     266         [ +  + ]:   137587221 :        rhorf(:,ispden)=workfft(:)
     267         [ -  + ]:        9632 :        ABI_FREE(workfft)
     268                 :             :      end do
     269         [ -  + ]:        3726 :      ABI_FREE(vectg)
     270                 :             :    end if
     271                 :             : 
     272         [ -  + ]:       19633 :    ABI_FREE(work)
     273                 :             : 
     274                 :             : 
     275                 :             : !  ====== FROM THE FINE GRID TOWARDS THE COARSE GRID =============
     276                 :             : !  ==============================================================
     277                 :             : !  Calculate the FT of rhorf to have it in the g space on the fine grid
     278                 :             : !  Transfer the FT of rhorf on the fine grid towards the coarse grid
     279                 :             : !  Then calculate the FT back to get rhor on the coarse grid
     280         [ +  - ]:       31486 :  else if (optgrid==-1) then
     281                 :             : 
     282   [ -  +  +  -  :       94458 :    ABI_MALLOC(work,(2,nfftf))
          +  -  +  -  -  
                +  -  + ]
     283                 :             : 
     284                 :             : !  First spin component
     285                 :             : !  --------------------------------------------------------------
     286         [ +  - ]:       31486 :    if (optout==0) then
     287                 :             : !    if optout=0, rhog on the fine grid is temporary (in vectg)
     288   [ -  +  +  -  :       94458 :      ABI_MALLOC(vectg,(2,nfftc))
          +  -  +  -  -  
                +  -  + ]
     289   [ +  +  +  + ]:  2113129939 :      vectg(:,:)=zero
     290         [ -  + ]:       31486 :      if (optin==1) then
     291         [ #  # ]:           0 :        do i1=1,nfftf
     292   [ #  #  #  # ]:           0 :          if (pawfgr%fintocoa(i1)/=0) vectg(:,pawfgr%fintocoa(i1))=rhogf(:,i1)
     293                 :             :        end do
     294                 :             :      else
     295   [ -  +  +  -  :       94458 :        ABI_MALLOC(workfft,(cplex*nfftf))
          +  -  +  -  -  
                +  -  + ]
     296         [ +  + ]:  2050491976 :        workfft(:)=rhorf(:,1)
     297                 :       31486 :        call fourdp(cplex,work,workfft,-1,mpi_enreg,nfftf,1,ngfftf,0)
     298         [ -  + ]:       31486 :        ABI_FREE(workfft)
     299   [ +  +  -  + ]:       31486 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     300                 :             :          call indirect_parallel_Fourier&
     301   [ +  -  -  -  :        1636 : &         (pawfgr%fintocoa,vectg,mpi_enreg,ngfftc,ngfftf,nfftc,nfftf,paral_kgb,work,nfftftot)
             -  -  -  + ]
     302                 :             :        else
     303         [ +  + ]:  1765026148 :          do i1=1,nfftf
     304   [ +  +  +  + ]:  3016383826 :            if (pawfgr%fintocoa(i1)/=0) vectg(:,pawfgr%fintocoa(i1))=work(:,i1)
     305                 :             :          end do
     306                 :             :        end if
     307                 :             :      end if
     308                 :             :      call zerosym(vectg,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     309                 :       31486 : &     comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     310   [ -  +  +  -  :       94458 :      ABI_MALLOC(workfft,(cplex*nfftc))
          +  -  +  -  -  
                +  -  + ]
     311                 :       31486 :      call fourdp(cplex,vectg,workfft,1,mpi_enreg,nfftc,1,ngfftc,0)
     312         [ +  + ]:   713574054 :      rhor(:,1)=workfft(:)
     313         [ -  + ]:       31486 :      ABI_FREE(workfft)
     314         [ -  + ]:       31486 :      ABI_FREE(vectg)
     315                 :             :    else
     316                 :             : !    if optout=1, rhog on the fine grid is saved
     317   [ #  #  #  # ]:           0 :      rhog(:,:)=zero
     318         [ #  # ]:           0 :      if (optin==1) then
     319         [ #  # ]:           0 :        do i1=1,nfftf
     320   [ #  #  #  # ]:           0 :          if (pawfgr%fintocoa(i1)/=0) rhog(:,pawfgr%fintocoa(i1))=rhogf(:,i1)
     321                 :             :        end do
     322                 :             :      else
     323   [ #  #  #  #  :           0 :        ABI_MALLOC(workfft,(cplex*nfftf))
          #  #  #  #  #  
                #  #  # ]
     324         [ #  # ]:           0 :        workfft(:)=rhorf(:,1)
     325                 :           0 :        call fourdp(cplex,work,workfft,-1,mpi_enreg,nfftf,1,ngfftf,0)
     326         [ #  # ]:           0 :        ABI_FREE(workfft)
     327   [ #  #  #  # ]:           0 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     328                 :             :          call indirect_parallel_Fourier&
     329   [ #  #  #  #  :           0 : &         (pawfgr%fintocoa,rhog,mpi_enreg,ngfftc,ngfftf,nfftc,nfftf,paral_kgb,work,nfftftot)
             #  #  #  # ]
     330                 :             :        else
     331         [ #  # ]:           0 :          do i1=1,nfftf
     332   [ #  #  #  # ]:           0 :            if (pawfgr%fintocoa(i1)/=0) rhog(:,pawfgr%fintocoa(i1))=work(:,i1)
     333                 :             :          end do
     334                 :             :        end if
     335                 :             :      end if
     336                 :             :      call zerosym(rhog,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     337                 :           0 : &     comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     338   [ #  #  #  #  :           0 :      ABI_MALLOC(workfft,(cplex*nfftc))
          #  #  #  #  #  
                #  #  # ]
     339                 :           0 :      call fourdp(cplex,rhog,workfft,1,mpi_enreg,nfftc,1,ngfftc,0)
     340         [ #  # ]:           0 :      rhor(:,1)=workfft(:)
     341         [ #  # ]:           0 :      ABI_FREE(workfft)
     342                 :             :    end if
     343                 :             : 
     344                 :             : !  Additional spin components
     345                 :             : !  ----------------------------------------------------
     346         [ +  + ]:       31486 :    if (nspden>=2) then
     347   [ -  +  +  -  :       24438 :      ABI_MALLOC(vectg,(2,nfftc))
          +  -  +  -  -  
                +  -  + ]
     348         [ +  + ]:       18456 :      do ispden=2,nspden
     349   [ +  +  +  + ]:   211348778 :        vectg(:,:)=zero
     350   [ -  +  +  -  :       30930 :        ABI_MALLOC(workfft,(cplex*nfftf))
          +  -  +  -  -  
                +  -  + ]
     351         [ +  + ]:   238847431 :        workfft(:)=rhorf(:,ispden)
     352                 :       10310 :        call fourdp(cplex,work,workfft,-1,mpi_enreg,nfftf,1,ngfftf,0)
     353         [ -  + ]:       10310 :        ABI_FREE(workfft)
     354   [ +  +  -  + ]:       10310 :        if(mpi_enreg%nproc_fft > 1 .and. mpi_enreg%paral_kgb==1) then
     355                 :             :          call indirect_parallel_Fourier&
     356   [ +  -  -  -  :         256 : &         (pawfgr%fintocoa,vectg,mpi_enreg,ngfftc,ngfftf,nfftc,nfftf,paral_kgb,work,nfftftot)
             -  -  -  + ]
     357                 :             :        else
     358         [ +  + ]:   235099143 :          do i1=1,nfftf
     359   [ +  +  +  + ]:   374748447 :            if (pawfgr%fintocoa(i1)/=0) vectg(:,pawfgr%fintocoa(i1))=work(:,i1)
     360                 :             :          end do
     361                 :             :        end if
     362                 :             :        call zerosym(vectg,2,ngfftc(1),ngfftc(2),ngfftc(3),&
     363                 :       10310 : &       comm_fft=mpi_enreg%comm_fft,distribfft=mpi_enreg%distribfft)
     364   [ -  +  +  -  :       30930 :        ABI_MALLOC(workfft,(cplex*nfftc))
          +  -  +  -  -  
                +  -  + ]
     365                 :       10310 :        call fourdp(cplex,vectg,workfft,1,mpi_enreg,nfftc,1,ngfftc,0)
     366         [ +  + ]:    70537466 :        rhor(:,ispden)=workfft(:)
     367         [ -  + ]:       18456 :        ABI_FREE(workfft)
     368                 :             :      end do
     369         [ -  + ]:        8146 :      ABI_FREE(vectg)
     370                 :             :    end if
     371                 :             : 
     372         [ -  + ]:       31486 :    ABI_FREE(work)
     373                 :             : 
     374                 :             :  end if
     375                 :             : 
     376                 :             :  DBG_EXIT("COLL")
     377                 :             : 
     378                 :             : end subroutine transgrid
     379                 :             : !!***
     380                 :             : 
     381                 :             : !----------------------------------------------------------------------
     382                 :             : 
     383                 :             : !!****f* m_fourier_interpol/fourier_interpol
     384                 :             : !! NAME
     385                 :             : !! fourier_interpol
     386                 :             : !!
     387                 :             : !! FUNCTION
     388                 :             : !!  Perform a Fourier interpolation. Just a wrapper for transgrid, the table giving the correspondence
     389                 :             : !!  between the coarse and the mesh FFT grids are constructed inside the routine. This allows to specify an
     390                 :             : !!  arbitrary FFT mesh to be used for the interpolation. Besides the routine works also in
     391                 :             : !!  case of NC calculations since it does not require Pawfgr.
     392                 :             : !!
     393                 :             : !! INPUTS
     394                 :             : !! cplex=1 if rhor[f] is real, 2 if rhor[f] is complex
     395                 :             : !! MPI_enreg<MPI_type>=Information about MPI parallelization
     396                 :             : !! nspden=number of spin-density components
     397                 :             : !! nfft_in =number of points in the input FFT box (WARNING no FFT parallelism)
     398                 :             : !! nfft_out=number of points in the output FFT box
     399                 :             : !! ngfft_in(18)=all needed information about 3D FFT, for the input grid
     400                 :             : !! ngfft_out(18) =all needed information about 3D FFT, for the output grid
     401                 :             : !! optin= 0: input density/potential is taken from rhor_in(:,nspden)
     402                 :             : !!        1: input density/potential is taken from rhog_in(:)     (ispden=1)
     403                 :             : !!                                             and rhor_in(:,2:4) (ispden=2,3,4)
     404                 :             : !! optout= 0: output density/potential is given in r space in rhor_out(:,nspden)
     405                 :             : !!         1: output density/potential is given in r space in rhor_out(:,nspden)
     406                 :             : !!                                          and in g space in rhog_out(:)
     407                 :             : !! ngfft_asked(18)=All info on the required FFT mesh.
     408                 :             : !!
     409                 :             : !! OUTPUT
     410                 :             : !!  rhor_out(cplex*nfft_out,nspden)=output density/potential in r space on the required FFT mesh.
     411                 :             : !!  if optout=1:
     412                 :             : !!   rhog_out(2,nfftc)=Fourier transform of output density/potential on the coarse grid
     413                 :             : !!
     414                 :             : !! SOURCE
     415                 :             : 
     416                 :        1732 : subroutine fourier_interpol(cplex,nspden,optin,optout,nfft_in,ngfft_in,nfft_out,ngfft_out,&
     417                 :        1732 :                            MPI_enreg,rhor_in,rhor_out,rhog_in,rhog_out)
     418                 :             : 
     419                 :             : !Arguments ------------------------------------
     420                 :             : !scalars
     421                 :             :  integer,intent(in) :: cplex,nspden,optin,optout
     422                 :             :  integer,intent(in) :: nfft_in,nfft_out
     423                 :             :  type(MPI_type),intent(in) :: MPI_enreg
     424                 :             : !arrays
     425                 :             :  integer,intent(in) :: ngfft_in(18),ngfft_out(18)
     426                 :             :  real(dp),intent(inout) :: rhor_in(cplex*nfft_in,nspden)
     427                 :             :  real(dp),intent(inout) :: rhog_in(2,nfft_in)
     428                 :             :  real(dp),intent(out) :: rhor_out(cplex*nfft_out,nspden)
     429                 :             :  real(dp),intent(out) :: rhog_out(2,nfft_out)
     430                 :             : 
     431                 :             : !Local variables ---------------------------------------
     432                 :             : !scalars
     433                 :             :  integer :: nfftf,nfftc,nfftc_tot,nfftf_tot,optgrid
     434                 :             :  logical :: ltest
     435                 :             :  type(Pawfgr_type) :: Pawfgr
     436                 :             : !arrays
     437                 :             :  integer :: ngfftc(18),ngfftf(18)
     438                 :             : 
     439                 :             : ! *************************************************************************
     440                 :             : 
     441   [ +  +  +  - ]:       22516 :  ltest= ALL(ngfft_in(7:) == ngfft_out(7:) )
     442         [ -  + ]:        1732 :  ABI_CHECK(ltest,'ngfftf_in(7:18)/=ngfftf_out(7:18)')
     443                 :             : 
     444                 :             :  !================================
     445                 :             :  !=== Which one is the coarse? ===
     446                 :             :  !================================
     447         [ -  + ]:        1732 :  if (nfft_out>=nfft_in) then
     448                 :             :    ! From coarse to fine grid. If meshes are equivalent, call transgrid anyway because of optout, optin.
     449                 :           0 :    nfftf    =nfft_out
     450                 :           0 :    ngfftf(:)=ngfft_out(:)
     451         [ #  # ]:           0 :    nfftf_tot =PRODUCT(ngfft_out(1:3))
     452                 :             : 
     453                 :           0 :    nfftc    =nfft_in
     454                 :           0 :    ngfftc(:)=ngfft_in(:)
     455         [ #  # ]:           0 :    nfftc_tot =PRODUCT(ngfft_in (1:3))
     456                 :             : 
     457                 :           0 :    Pawfgr%usefinegrid=1
     458   [ #  #  #  #  :           0 :    if (ALL(ngfft_in(1:3)==ngfft_out(1:3))) Pawfgr%usefinegrid=0
                   #  # ]
     459                 :           0 :    optgrid=1
     460                 :             : 
     461                 :             :  else
     462                 :             :    ! From fine towards coarse.
     463                 :        1732 :    nfftf    =nfft_in
     464                 :        1732 :    ngfftf(:)=ngfft_in(:)
     465         [ +  + ]:        6928 :    nfftf_tot =PRODUCT(ngfft_in(1:3))
     466                 :             : 
     467                 :        1732 :    nfftc    =nfft_out
     468                 :        1732 :    ngfftc(:)=ngfft_out(:)
     469         [ +  + ]:        6928 :    nfftc_tot =PRODUCT(ngfft_out (1:3))
     470                 :        1732 :    Pawfgr%usefinegrid=1
     471                 :        1732 :    optgrid=-1
     472                 :             :  end if
     473                 :             : 
     474   [ -  +  +  -  :        5196 :  ABI_MALLOC(Pawfgr%coatofin,(nfftc_tot))
          +  -  +  -  -  
                +  -  + ]
     475   [ -  +  +  -  :        5196 :  ABI_MALLOC(Pawfgr%fintocoa,(nfftf_tot))
          +  -  +  -  -  
                +  -  + ]
     476                 :             : 
     477                 :        1732 :  call indgrid(Pawfgr%coatofin,Pawfgr%fintocoa,nfftc_tot,nfftf_tot,ngfftc,ngfftf)
     478                 :             : 
     479         [ +  + ]:        6928 :  Pawfgr%mgfft =MAXVAL (ngfftf(1:3))
     480         [ +  + ]:        6928 :  Pawfgr%nfft  =PRODUCT(ngfftf(1:3)) ! no FFT parallelism!
     481         [ +  + ]:       32908 :  Pawfgr%ngfft =ngfftf
     482                 :             : 
     483         [ +  + ]:        6928 :  Pawfgr%mgfftc =MAXVAL (ngfftc(1:3))
     484         [ +  + ]:        6928 :  Pawfgr%nfftc  =PRODUCT(ngfftc(1:3)) ! no FFT parallelism!
     485         [ +  + ]:       32908 :  Pawfgr%ngfftc =ngfftc
     486                 :             : 
     487         [ -  + ]:        1732 :  if (optgrid==1) then
     488                 :           0 :    call transgrid(cplex,MPI_enreg,nspden,optgrid,optin,optout,MPI_enreg%paral_kgb,Pawfgr,rhog_in ,rhog_out,rhor_in ,rhor_out)
     489                 :             :  else
     490                 :        1732 :    call transgrid(cplex,MPI_enreg,nspden,optgrid,optin,optout,MPI_enreg%paral_kgb,Pawfgr,rhog_out,rhog_in ,rhor_out,rhor_in)
     491                 :             :  end if
     492                 :             : 
     493                 :        1732 :  call pawfgr_destroy(Pawfgr)
     494                 :             : 
     495                 :        1732 : end subroutine fourier_interpol
     496                 :             : !!***
     497                 :             : 
     498                 :             : !----------------------------------------------------------------------
     499                 :             : 
     500                 :             : !!****f* m_fourier_interpol/fourier_interpol_seq
     501                 :             : !! NAME
     502                 :             : !! fourier_interpol_seq
     503                 :             : !!
     504                 :             : !! FUNCTION
     505                 :             : !!  Perform a Fourier interpolation in sequential i.e. without MPI-FFT.
     506                 :             : !!
     507                 :             : !! INPUTS
     508                 :             : !! cplex=1 if rhor is real, 2 if rhor is complex
     509                 :             : !! nspden=number of spin-density components
     510                 :             : !! from_nfft =number of points in the input FFT box (WARNING no FFT parallelism)
     511                 :             : !! from_ngfft_(18)=all needed information about 3D FFT, for the input grid
     512                 :             : !! to_nfft=number of points in the output FFT box
     513                 :             : !! to_ngfft_out=all needed information about 3D FFT, for the output grid
     514                 :             : !! from_rhor=Input density
     515                 :             : !!
     516                 :             : !! OUTPUT
     517                 :             : !! to_rhor=Output density in r-space
     518                 :             : !! [to_rhog]=Output density in g-space.
     519                 :             : !!
     520                 :             : !! SOURCE
     521                 :             : 
     522                 :        1732 : subroutine fourier_interpol_seq(cplex, nspden, from_nfft, from_ngfft, to_nfft, to_ngfft, from_rhor, to_rhor, &
     523                 :           0 :                                 to_rhog) ! optional
     524                 :             : 
     525                 :             : !Arguments ------------------------------------
     526                 :             : !scalars
     527                 :             :  integer,intent(in) :: cplex, nspden, from_nfft, to_nfft
     528                 :             : !arrays
     529                 :             :  integer,intent(in) :: from_ngfft(18), to_ngfft(18)
     530                 :             :  real(dp),intent(inout) :: from_rhor(cplex*from_nfft, nspden)
     531                 :             :  real(dp),intent(out) :: to_rhor(cplex*to_nfft, nspden)
     532                 :             :  real(dp),optional,intent(out) :: to_rhog(2, to_nfft)
     533                 :             : 
     534                 :             : !Local variables ---------------------------------------
     535                 :             : !scalars
     536                 :        1732 :  type(MPI_type) :: MPI_enreg_seq
     537                 :             : !arrays
     538                 :             :  integer :: ngfft_in(18),ngfft_out(18)
     539                 :        1732 :  real(dp),allocatable :: from_rhog(:,:), to_rhog__(:,:)
     540                 :             : ! *************************************************************************
     541                 :             : 
     542                 :        1732 :  ngfft_in = from_ngfft; ngfft_out = to_ngfft
     543   [ +  +  +  + ]:       13856 :  ngfft_in(4:6) = ngfft_in(1:3); ngfft_out(4:6) = ngfft_out(1:3)
     544                 :             :  ! No MPI-FFT here.
     545   [ +  +  +  + ]:       38104 :  ngfft_in(9:18) = 0; ngfft_out(9:18) = 0
     546                 :        1732 :  ngfft_in(10) = 1; ngfft_out(10) = 1
     547                 :             : 
     548                 :        1732 :  call initmpi_seq(MPI_enreg_seq)
     549                 :             : 
     550                 :             :  ! Which one is coarse? Note that this part is not very robust and can fail!
     551         [ -  + ]:        1732 :  if (ngfft_in(2) * ngfft_in(3) < ngfft_out(2) * ngfft_out(3)) then
     552                 :           0 :    call MPI_enreg_seq%distribfft%init_seq('c', ngfft_in(2), ngfft_in(3), 'all')
     553                 :           0 :    call MPI_enreg_seq%distribfft%init_seq('f', ngfft_out(2), ngfft_out(3), 'all')
     554                 :             :  else
     555                 :        1732 :    call MPI_enreg_seq%distribfft%init_seq('f', ngfft_in(2), ngfft_in(3), 'all')
     556                 :        1732 :    call MPI_enreg_seq%distribfft%init_seq('c', ngfft_out(2), ngfft_out(3), 'all')
     557                 :             :  end if
     558                 :             : 
     559   [ -  +  +  -  :        5196 :  ABI_MALLOC(from_rhog,  (2, from_nfft))
          +  -  +  -  -  
                +  -  + ]
     560   [ -  +  +  -  :        5196 :  ABI_MALLOC(to_rhog__, (2, to_nfft))
          +  -  +  -  -  
                +  -  + ]
     561                 :             : 
     562                 :             :  call fourier_interpol(cplex, nspden, 0, 0, from_nfft, ngfft_in, to_nfft, ngfft_out, &
     563                 :        1732 :                        MPI_enreg_seq, from_rhor, to_rhor, from_rhog, to_rhog__)
     564                 :             : 
     565   [ -  +  -  -  :        1732 :  if (present(to_rhog)) to_rhog = to_rhog__
                   -  - ]
     566                 :             : 
     567         [ -  + ]:        1732 :  ABI_FREE(from_rhog)
     568         [ -  + ]:        1732 :  ABI_FREE(to_rhog__)
     569                 :        1732 :  call destroy_mpi_enreg(MPI_enreg_seq)
     570                 :             : 
     571   [ -  +  -  +  :        3464 : end subroutine fourier_interpol_seq
          -  +  -  +  -  
          +  -  +  -  +  
          -  +  -  +  -  
             +  -  +  -  
                      + ]
     572                 :             : !!***
     573                 :             : 
     574                 :             : !----------------------------------------------------------------------
     575                 :             : 
     576                 :             : END MODULE m_fourier_interpol
     577                 :             : !!***
        

Generated by: LCOV version 2.3-1