LCOV - code coverage report
Current view: top level - src/72_response - m_paral_pert.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 92.5 % 213 197
Test Date: 2026-11-10 15:53:16 Functions: 100.0 % 6 6
Branches: 56.4 % 392 221

             Branch data     Line data    Source code
       1                 :             : !!****m* ABINIT/m_paral_pert
       2                 :             : !! NAME
       3                 :             : !!  m_paral_pert
       4                 :             : !!
       5                 :             : !! FUNCTION
       6                 :             : !!  This module provides routines to manage the parallelisation/distribution
       7                 :             : !!  over perturbations
       8                 :             : !!
       9                 :             : !! COPYRIGHT
      10                 :             : !! Copyright (C) 2013-2026 ABINIT group (MT,FJ,MD)
      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                 :             : !! For the initials of contributors, see ~abinit/doc/developers/contributors.txt.
      15                 :             : !!
      16                 :             : !! SOURCE
      17                 :             : 
      18                 :             : #if defined HAVE_CONFIG_H
      19                 :             : #include "config.h"
      20                 :             : #endif
      21                 :             : 
      22                 :             : #include "abi_common.h"
      23                 :             : 
      24                 :             : MODULE m_paral_pert
      25                 :             : 
      26                 :             :  use defs_basis
      27                 :             :  use m_abicore
      28                 :             :  use m_errors
      29                 :             :  use m_xmpi
      30                 :             :  use m_dtset
      31                 :             : 
      32                 :             :  use defs_abitypes, only : MPI_type
      33                 :             :  use m_time,      only : timab
      34                 :             :  use m_copy,      only : deep_copy
      35                 :             :  use m_paw_an,    only : paw_an_type, paw_an_free, paw_an_redistribute
      36                 :             :  use m_paw_ij,    only : paw_ij_type, paw_ij_free, paw_ij_redistribute
      37                 :             :  use m_pawfgrtab, only : pawfgrtab_type, pawfgrtab_free, pawfgrtab_redistribute
      38                 :             :  use m_pawrhoij,  only : pawrhoij_type, pawrhoij_free, pawrhoij_redistribute
      39                 :             :  use m_paral_atom,only : get_atm_proc
      40                 :             :  use m_mpinfo,    only : initmpi_atom
      41                 :             : 
      42                 :             :  implicit none
      43                 :             : 
      44                 :             :  private
      45                 :             : 
      46                 :             : !public procedures.
      47                 :             :  public :: set_pert_comm
      48                 :             :  public :: unset_pert_comm
      49                 :             :  public :: set_pert_paw
      50                 :             :  public :: unset_pert_paw
      51                 :             : 
      52                 :             : !private procedures.
      53                 :             :  private :: get_exchatom_list
      54                 :             :  private :: get_exchatom_list1
      55                 :             : !!***
      56                 :             : 
      57                 :             : CONTAINS
      58                 :             : !!***
      59                 :             : 
      60                 :             : !----------------------------------------------------------------------
      61                 :             : 
      62                 :             : !!****f* m_paral_pert/set_pert_comm
      63                 :             : !! NAME
      64                 :             : !! set_pert_comm
      65                 :             : !!
      66                 :             : !! FUNCTION
      67                 :             : !! Set the MPI communicators over the perturbed cell
      68                 :             : !!
      69                 :             : !! INPUTS
      70                 :             : !!  nppert=number of processes for the parallelization over perturbations
      71                 :             : !!
      72                 :             : !! SIDE EFFECTS
      73                 :             : !!  mpi_enreg=information about MPI parallelization
      74                 :             : !!
      75                 :             : !! SOURCE
      76                 :             : 
      77                 :         721 : subroutine set_pert_comm(mpi_enreg,nppert)
      78                 :             : 
      79                 :             : !Arguments ---------------------------------------------
      80                 :             : !scalars
      81                 :             :  integer,intent(in) :: nppert
      82                 :             :  type(MPI_type), intent(inout) :: mpi_enreg
      83                 :             : 
      84                 :             : ! *************************************************************************
      85                 :             : 
      86         [ +  + ]:         721 :  if (mpi_enreg%paral_pert==0) return
      87                 :             : 
      88                 :             : !New communicators for the perturbed cell
      89                 :          26 :  mpi_enreg%comm_cell =mpi_enreg%comm_cell_pert
      90                 :          26 :  mpi_enreg%me_cell   =xmpi_comm_rank(mpi_enreg%comm_cell)
      91                 :          26 :  mpi_enreg%nproc_cell=mpi_enreg%nproc/nppert
      92                 :             : 
      93                 :             : !Adjust other communicators
      94                 :          26 :  mpi_enreg%comm_kpt    =mpi_enreg%comm_cell
      95                 :          26 :  mpi_enreg%me_kpt      =mpi_enreg%me_cell
      96                 :          26 :  mpi_enreg%comm_kptband=mpi_enreg%comm_cell
      97                 :          26 :  mpi_enreg%comm_wvl    =mpi_enreg%comm_cell
      98                 :             : 
      99                 :             : end subroutine set_pert_comm
     100                 :             : !!***
     101                 :             : 
     102                 :             : !----------------------------------------------------------------------
     103                 :             : 
     104                 :             : !!****f* m_paral_pert/unset_pert_comm
     105                 :             : !! NAME
     106                 :             : !! unset_pert_comm
     107                 :             : !!
     108                 :             : !! FUNCTION
     109                 :             : !! Unset the MPI communicators over the perturbed cell; restore the global communicators.
     110                 :             : !!
     111                 :             : !! SIDE EFFECTS
     112                 :             : !!  mpi_enreg=information about MPI parallelization
     113                 :             : !!
     114                 :             : !! SOURCE
     115                 :             : 
     116                 :         721 : subroutine unset_pert_comm(mpi_enreg)
     117                 :             : 
     118                 :             : !Arguments ---------------------------------------------
     119                 :             : !scalars
     120                 :             :  type(MPI_type), intent(inout) :: mpi_enreg
     121                 :             : 
     122                 :             : ! *************************************************************************
     123                 :             : 
     124         [ +  + ]:         721 :  if (mpi_enreg%paral_pert==0) return
     125                 :             : 
     126                 :             : !New communicators for the cell
     127                 :          26 :  mpi_enreg%comm_cell =mpi_enreg%comm_world
     128                 :          26 :  mpi_enreg%nproc_cell=mpi_enreg%nproc
     129                 :          26 :  mpi_enreg%me_cell   =mpi_enreg%me
     130                 :             : 
     131                 :             : !Adjust other communicators
     132                 :          26 :  mpi_enreg%comm_kpt    =mpi_enreg%comm_cell
     133                 :          26 :  mpi_enreg%me_kpt      =mpi_enreg%me_cell
     134                 :          26 :  mpi_enreg%comm_kptband=mpi_enreg%comm_cell
     135                 :          26 :  mpi_enreg%comm_wvl    =mpi_enreg%comm_cell
     136                 :             : 
     137                 :             : end  subroutine unset_pert_comm
     138                 :             : !!***
     139                 :             : 
     140                 :             : !----------------------------------------------------------------------
     141                 :             : 
     142                 :             : !!****f* m_paral_pert/set_pert_paw
     143                 :             : !! NAME
     144                 :             : !! set_pert_paw
     145                 :             : !!
     146                 :             : !! FUNCTION
     147                 :             : !! Set PAW data for the parallelization over perturbations:
     148                 :             : !!  Set MPI communicator over atomic sites
     149                 :             : !!  Redistribute PAW on-site data
     150                 :             : !!
     151                 :             : !! INPUTS
     152                 :             : !!  dtset <type(dataset_type)>=all input variables for this dataset
     153                 :             : !!
     154                 :             : !! OUTPUT
     155                 :             : !!  paw_an_out(my_natom)<type(paw_an_type)>= --optional--
     156                 :             : !!              redistributed PAW arrays given on angular mesh
     157                 :             : !!              if not present, paw_an is redistributed "in-place"
     158                 :             : !!  paw__ij_out(my_natom)<type(paw_ij_type)>= --optional--
     159                 :             : !!              redistributed PAW arrays given on (i,j) channels
     160                 :             : !!              if not present, paw_ij is redistributed "in-place"
     161                 :             : !!  pawfgrtab_out(my_natom)<type(pawfgrtab_type)>= --optional--
     162                 :             : !!              redistributed PAW atomic data given on fine grid
     163                 :             : !!              if not present, pawfgrtab is redistributed "in-place"
     164                 :             : !!  pawrhoij_out(my_natom)<type(pawrhoij_type)>= --optional--
     165                 :             : !!              redistributed PAW rhoij occupancies
     166                 :             : !!              if not present, pawrhoij is redistributed "in-place"
     167                 :             : !!  old_atmtab=save the indexes of the atoms treated by current proc
     168                 :             : !!  old_comm_atom=save the identifier of the MPI communicator
     169                 :             : !!
     170                 :             : !! SIDE EFFECTS
     171                 :             : !!  mpi_enreg=information about MPI parallelization
     172                 :             : !!  my_natom=number of atoms treated by current processor
     173                 :             : !!  paw_an(my_natom)<type(paw_an_type)>=PAW arrays given on angular mesh
     174                 :             : !!  paw_ij(my_natom)<type(paw_ij_type)>=PAW arrays given on (i,j) channels
     175                 :             : !!  pawfgrtab(my_natom)<type(pawfgrtab_type)>=PAW atomic data given on fine grid
     176                 :             : !!  pawrhoij(my_natom)<type(pawrhoij_type)>=PAW rhoij occupancies
     177                 :             : !!
     178                 :             : !! SOURCE
     179                 :             : 
     180                 :         721 : subroutine set_pert_paw(dtset,mpi_enreg,my_natom,old_atmtab,old_comm_atom,&
     181                 :             : &                       paw_an,paw_ij,pawfgrtab,pawrhoij,&
     182                 :             : &                       paw_an_out,paw_ij_out,pawfgrtab_out,pawrhoij_out)
     183                 :             : 
     184                 :             : !Arguments ---------------------------------------------
     185                 :             : !scalars
     186                 :             :  integer,intent(inout) :: my_natom
     187                 :             :  integer,intent(inout) :: old_comm_atom
     188                 :             :  type(dataset_type), intent(in) :: dtset
     189                 :             :  type(MPI_type), intent(inout) :: mpi_enreg
     190                 :             : !arrays
     191                 :             :  integer,pointer,intent(out) :: old_atmtab(:)
     192                 :             :  type(paw_ij_type),allocatable,target,intent(inout) :: paw_ij(:)
     193                 :             :  type(paw_ij_type),optional,pointer,intent(inout) :: paw_ij_out(:)
     194                 :             :  type(paw_an_type),allocatable,target,intent(inout) :: paw_an(:)
     195                 :             :  type(paw_an_type),optional,pointer,intent(inout) :: paw_an_out(:)
     196                 :             :  type(pawfgrtab_type),allocatable,target,intent(inout) :: pawfgrtab(:)
     197                 :             :  type(pawfgrtab_type),optional,pointer,intent(inout) :: pawfgrtab_out(:)
     198                 :             :  type(pawrhoij_type),allocatable,target,intent(inout) :: pawrhoij(:)
     199                 :             :  type(pawrhoij_type),optional,pointer,intent(inout) :: pawrhoij_out(:)
     200                 :             : 
     201                 :             : !Local variables ---------------------------------------
     202                 :             : !scalars
     203                 :             : !Type of algo used for communications: 1-brute force, 2-asynchronous
     204                 :             :  integer,parameter :: algo_option=2
     205                 :             :  logical :: paral_atom
     206                 :             : !arrays
     207                 :         721 :  integer,allocatable :: SendAtomProc(:), SendAtomList(:)
     208                 :         721 :  integer,allocatable :: RecvAtomProc(:), RecvAtomList(:)
     209                 :             :  real(dp) :: tsec(2)
     210                 :             : 
     211                 :             : ! *************************************************************************
     212                 :             : 
     213                 :         721 :  call timab(593,1,tsec)
     214                 :             : 
     215                 :         721 :  paral_atom=(dtset%natom/=my_natom)
     216                 :             : 
     217                 :             : !Default value when parallelization over atomic sites is not activated
     218   [ +  +  +  +  :         721 :  if ((mpi_enreg%paral_pert==0).or.(.not.paral_atom).or.(dtset%usepaw==0)) then
                   -  + ]
     219                 :         701 :    old_comm_atom=mpi_enreg%comm_atom
     220                 :         701 :    call deep_copy(mpi_enreg%my_atmtab,old_atmtab)
     221         [ -  + ]:         701 :    if (present(pawrhoij_out))  pawrhoij_out=>pawrhoij
     222         [ -  + ]:         701 :    if (present(paw_ij_out))    paw_ij_out=>paw_ij
     223         [ -  + ]:         701 :    if (present(paw_an_out))    paw_an_out=>paw_an
     224         [ -  + ]:         701 :    if (present(pawfgrtab_out)) pawfgrtab_out=>pawfgrtab
     225                 :             :    return
     226                 :             :  end if
     227                 :             : 
     228                 :             : !Redefine communicator for atoms and store old communicator
     229                 :             : 
     230                 :          20 :  old_comm_atom=mpi_enreg%comm_atom
     231                 :          20 :  call deep_copy(mpi_enreg%my_atmtab,old_atmtab)
     232                 :          20 :  call initmpi_atom(dtset,mpi_enreg)
     233                 :          20 :  my_natom=mpi_enreg%my_natom
     234                 :             : 
     235                 :             : !If "asynchronous algo", determine lists of atoms to be exchanged
     236                 :             : !  between me and other processes
     237                 :             :  if (algo_option==2) then
     238                 :          20 :    call timab(594,1,tsec)
     239                 :             :    call get_exchatom_list(old_comm_atom,mpi_enreg%comm_atom,old_atmtab,&
     240                 :             : &       mpi_enreg%my_atmtab,dtset%natom,SendAtomProc,&
     241                 :          20 : &       SendAtomList,RecvAtomProc,RecvAtomList)
     242                 :          20 :    call timab(594,2,tsec)
     243                 :             :  end if
     244                 :             : 
     245                 :             : !Redistribute PAW on-site data
     246                 :             : 
     247                 :             : !pawrhoij datastructure
     248                 :          20 :  call timab(595,1,tsec)
     249         [ -  + ]:          20 :  if (present(pawrhoij_out)) then
     250                 :           0 :    nullify(pawrhoij_out)
     251                 :             :    if (algo_option==1) then
     252                 :             :      call pawrhoij_redistribute(pawrhoij,old_comm_atom,mpi_enreg%comm_atom,&
     253                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     254                 :             : &         natom=dtset%natom,pawrhoij_out=pawrhoij_out)
     255                 :             :    else if (algo_option==2) then
     256                 :             :      call pawrhoij_redistribute(pawrhoij,old_comm_atom,mpi_enreg%comm_atom,&
     257                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     258                 :             : &         natom=dtset%natom,pawrhoij_out=pawrhoij_out, &
     259                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     260                 :           0 : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     261                 :             :    end if
     262                 :             :  else
     263                 :             :    if (algo_option==1) then
     264                 :             :      call pawrhoij_redistribute(pawrhoij,old_comm_atom,mpi_enreg%comm_atom,&
     265                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     266                 :             : &         natom=dtset%natom)
     267                 :          20 :    else if (algo_option==2) then
     268                 :             :      call pawrhoij_redistribute(pawrhoij,old_comm_atom,mpi_enreg%comm_atom,&
     269                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     270                 :             : &         natom=dtset%natom,&
     271                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     272                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     273                 :             :    end if
     274                 :             :  end if
     275                 :          20 :  call timab(595,2,tsec)
     276                 :             : 
     277                 :             : !paw_ij datastructure
     278                 :          20 :  call timab(596,1,tsec)
     279         [ -  + ]:          20 :  if (present(paw_ij_out)) then
     280                 :           0 :    nullify(paw_ij_out)
     281                 :             :    if (algo_option==1) then
     282                 :             :      call paw_ij_redistribute(paw_ij,old_comm_atom,mpi_enreg%comm_atom,&
     283                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     284                 :             : &         natom=dtset%natom,paw_ij_out=paw_ij_out)
     285                 :             :    else if (algo_option==2) then
     286                 :             :      call paw_ij_redistribute(paw_ij,old_comm_atom,mpi_enreg%comm_atom,&
     287                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     288                 :             : &         natom=dtset%natom,paw_ij_out=paw_ij_out,&
     289                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     290                 :           0 : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     291                 :             :    end if
     292                 :             :  else
     293                 :             :    if (algo_option==1) then
     294                 :             :      call paw_ij_redistribute(paw_ij,old_comm_atom,mpi_enreg%comm_atom,&
     295                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     296                 :             : &         natom=dtset%natom)
     297                 :          20 :    else if (algo_option==2) then
     298                 :             :      call paw_ij_redistribute(paw_ij,old_comm_atom,mpi_enreg%comm_atom,&
     299                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     300                 :             : &         natom=dtset%natom,&
     301                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     302                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     303                 :             :    end if
     304                 :             :  end if
     305                 :          20 :  call timab(596,2,tsec)
     306                 :             : 
     307                 :             : !paw_an datastructure
     308                 :          20 :  call timab(597,1,tsec)
     309         [ -  + ]:          20 :  if (present(paw_an_out)) then
     310                 :           0 :    nullify(paw_an_out)
     311                 :             :    if (algo_option==1) then
     312                 :             :      call paw_an_redistribute(paw_an,old_comm_atom,mpi_enreg%comm_atom,&
     313                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     314                 :             : &         natom=dtset%natom,paw_an_out=paw_an_out)
     315                 :             :    else if (algo_option==2) then
     316                 :             :      call paw_an_redistribute(paw_an,old_comm_atom,mpi_enreg%comm_atom,&
     317                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     318                 :             : &         natom=dtset%natom,paw_an_out=paw_an_out,&
     319                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     320                 :           0 : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     321                 :             :    end if
     322                 :             :  else
     323                 :             :    if (algo_option==1) then
     324                 :             :      call paw_an_redistribute(paw_an,old_comm_atom,mpi_enreg%comm_atom,&
     325                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     326                 :             : &         natom=dtset%natom)
     327                 :          20 :    else if (algo_option==2) then
     328                 :             :      call paw_an_redistribute(paw_an,old_comm_atom,mpi_enreg%comm_atom,&
     329                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     330                 :             : &         natom=dtset%natom,&
     331                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     332                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     333                 :             :    end if
     334                 :             :  end if
     335                 :          20 :  call timab(597,2,tsec)
     336                 :             : 
     337                 :             : !pawfgrtab datastructure
     338                 :          20 :  call timab(598,1,tsec)
     339         [ -  + ]:          20 :  if (present(pawfgrtab_out)) then
     340                 :           0 :    nullify(pawfgrtab_out)
     341                 :             :    if (algo_option==1) then
     342                 :             :      call pawfgrtab_redistribute(pawfgrtab,old_comm_atom,mpi_enreg%comm_atom,&
     343                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     344                 :             : &         natom=dtset%natom,pawfgrtab_out=pawfgrtab_out)
     345                 :             :    else if (algo_option==2) then
     346                 :             :      call pawfgrtab_redistribute(pawfgrtab,old_comm_atom,mpi_enreg%comm_atom,&
     347                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     348                 :             : &         natom=dtset%natom,pawfgrtab_out=pawfgrtab_out,&
     349                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     350                 :           0 : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     351                 :             :    end if
     352                 :             :  else
     353                 :             :    if (algo_option==1) then
     354                 :             :      call pawfgrtab_redistribute(pawfgrtab,old_comm_atom,mpi_enreg%comm_atom,&
     355                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     356                 :             : &         natom=dtset%natom)
     357                 :          20 :    else if (algo_option==2) then
     358                 :             :      call pawfgrtab_redistribute(pawfgrtab,old_comm_atom,mpi_enreg%comm_atom,&
     359                 :             : &         mpi_atmtab_in=old_atmtab,mpi_atmtab_out=mpi_enreg%my_atmtab,&
     360                 :             : &         natom=dtset%natom,&
     361                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     362                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     363                 :             :    end if
     364                 :             :  end if
     365                 :          20 :  call timab(598,2,tsec)
     366                 :             : 
     367                 :             :  if (algo_option==2) then
     368         [ -  + ]:          20 :    ABI_FREE(SendAtomProc)
     369         [ -  + ]:          20 :    ABI_FREE(SendAtomList)
     370         [ -  + ]:          20 :    ABI_FREE(RecvAtomProc)
     371         [ -  + ]:          20 :    ABI_FREE(RecvAtomList)
     372                 :             :  end if
     373                 :             : 
     374                 :          20 :  call timab(593,2,tsec)
     375                 :             : 
     376                 :             : end  subroutine set_pert_paw
     377                 :             : !!***
     378                 :             : 
     379                 :             : !----------------------------------------------------------------------
     380                 :             : 
     381                 :             : !!****f* m_paral_pert/unset_pert_paw
     382                 :             : !! NAME
     383                 :             : !! unset_pert_paw
     384                 :             : !!
     385                 :             : !! FUNCTION
     386                 :             : !! Unset PAW data after the parallelization over perturbations:
     387                 :             : !!  Restore MPI communicator over atomic sites
     388                 :             : !!  Restore PAW on-site data
     389                 :             : !!
     390                 :             : !! INPUTS
     391                 :             : !!  dtset <type(dataset_type)>=all input variables for this dataset
     392                 :             : !!  old_atmtab=index of atoms to restore
     393                 :             : !!  old_comm_atom=MPI communicator to restore
     394                 :             : !!  mpi_enreg=information about MPI parallelization
     395                 :             : !!  my_natom=number of atoms treated by current processor
     396                 :             : !!
     397                 :             : !! OUTPUT
     398                 :             : !!  paw_an_out(my_natom)<type(paw_an_type)>= --optional--
     399                 :             : !!              redistributed PAW arrays given on angular mesh
     400                 :             : !!              if not present, paw_an is restored "in-place"
     401                 :             : !!  paw__ij_out(my_natom)<type(paw_ij_type)>= --optional--
     402                 :             : !!              redistributed PAW arrays given on (i,j) channels
     403                 :             : !!              if not present, paw_ij is restored "in-place"
     404                 :             : !!  pawfgrtab_out(my_natom)<type(pawfgrtab_type)>= --optional--
     405                 :             : !!              redistributed PAW atomic data given on fine grid
     406                 :             : !!              if not present, pawfgrtab is restored "in-place"
     407                 :             : !!  pawrhoij_out(my_natom)<type(pawrhoij_type)>= --optional--
     408                 :             : !!              redistributed PAW rhoij occupancies
     409                 :             : !!              if not present, pawrhoij is restored "in-place"
     410                 :             : !! old_atmtab=save the indexes of atoms treated by current proc
     411                 :             : !! old_comm_atom=save the identifier of the MPI communicator
     412                 :             : !!
     413                 :             : !! SIDE EFFECTS
     414                 :             : !!  mpi_enreg=information about MPI parallelization
     415                 :             : !!  my_natom=number of atoms treated by current processor
     416                 :             : !!  paw_an(my_natom)<type(paw_an_type)>=PAW arrays given on angular mesh
     417                 :             : !!  paw_ij(my_natom)<type(paw_ij_type)>=PAW arrays given on (i,j) channels
     418                 :             : !!  pawfgrtab(my_natom)<type(pawfgrtab_type)>=PAW atomic data given on fine grid
     419                 :             : !!  pawrhoij(my_natom)<type(pawrhoij_type)>=PAW rhoij occupancies
     420                 :             : !!
     421                 :             : !! SOURCE
     422                 :             : 
     423                 :         721 : subroutine unset_pert_paw(dtset,mpi_enreg,my_natom,old_atmtab,old_comm_atom,&
     424                 :             : &                       paw_an,paw_ij,pawfgrtab,pawrhoij,&
     425                 :             : &                       paw_an_out,paw_ij_out,pawfgrtab_out,pawrhoij_out)
     426                 :             : 
     427                 :             : !Arguments ---------------------------------------------
     428                 :             : !scalars
     429                 :             :  integer,intent(inout) :: my_natom
     430                 :             :  integer,intent(inout) :: old_comm_atom
     431                 :             :  type(dataset_type), intent(in) :: dtset
     432                 :             :  type(MPI_type), intent(inout) :: mpi_enreg
     433                 :             : !arrays
     434                 :             :  integer,pointer,intent(inout) :: old_atmtab(:)
     435                 :             :  type(paw_ij_type),allocatable,target,intent(inout) :: paw_ij(:)
     436                 :             :  type(paw_ij_type),optional,pointer,intent(inout) :: paw_ij_out(:)
     437                 :             :  type(paw_an_type),allocatable,target,intent(inout) :: paw_an(:)
     438                 :             :  type(paw_an_type),optional,pointer,intent(inout) :: paw_an_out(:)
     439                 :             :  type(pawfgrtab_type),allocatable,target,intent(inout) :: pawfgrtab(:)
     440                 :             :  type(pawfgrtab_type),optional,pointer,intent(inout) :: pawfgrtab_out(:)
     441                 :             :  type(pawrhoij_type),allocatable,target,intent(inout) :: pawrhoij(:)
     442                 :             :  type(pawrhoij_type),optional,pointer,intent(inout) :: pawrhoij_out(:)
     443                 :             : 
     444                 :             : !Local variables ---------------------------------------
     445                 :             : !scalars
     446                 :             : !Type of algo used for communications: 1-brute force, 2-asynchronous
     447                 :             :  integer,parameter :: algo_option=2
     448                 :             : integer :: my_natom_old
     449                 :             :  logical :: exchange,paral_atom
     450                 :             : !arrays
     451                 :         721 :  integer,allocatable :: SendAtomProc(:), SendAtomList(:)
     452                 :         721 :  integer,allocatable :: RecvAtomProc(:), RecvAtomList(:)
     453                 :             :  real(dp) :: tsec(2)
     454                 :             : 
     455                 :             : ! *************************************************************************
     456                 :             : 
     457                 :             : !Nothing to do when parallelization over atomic sites is not activated
     458   [ +  +  +  + ]:         721 :  if ((mpi_enreg%paral_pert==0).or.(dtset%usepaw==0)) return
     459         [ +  - ]:          20 :  if (.not.associated(old_atmtab)) return
     460                 :          20 :  paral_atom=(dtset%natom/=size(old_atmtab))
     461         [ +  - ]:          20 :  if (.not.paral_atom) return
     462                 :             : 
     463                 :             : !If "asynchronous algo", determine lists of atoms to be exchanged
     464                 :             : !  between me and other processes
     465                 :          20 :  exchange=.true.
     466                 :             :  if (present(pawrhoij_out).and.present(paw_ij_out).and. &
     467   [ -  +  -  - ]:          20 : &    present(paw_an_out)  .and.present(pawfgrtab_out)) exchange=.false.
     468                 :             :  if (algo_option==2.and.exchange) then
     469                 :          20 :    call timab(594,1,tsec)
     470                 :          20 :    my_natom_old=size(old_atmtab)
     471                 :             :    call get_exchatom_list1(mpi_enreg%comm_atom,old_comm_atom,mpi_enreg%my_atmtab,&
     472                 :             : &       old_atmtab,dtset%natom,SendAtomProc,&
     473                 :          20 : &       SendAtomList,RecvAtomProc,RecvAtomList)
     474                 :          20 :    call timab(594,2,tsec)
     475                 :             :  end if
     476                 :             : 
     477                 :             : !Redistribute PAW on-site data (if in-place storage)
     478                 :             : !or destroy them (out-of-place storage)
     479                 :             : 
     480                 :             : !pawrhoij datastructure
     481                 :          20 :  call timab(595,1,tsec)
     482         [ -  + ]:          20 :  if (present(pawrhoij_out)) then
     483                 :           0 :    call pawrhoij_free(pawrhoij_out)
     484         [ #  # ]:           0 :    ABI_FREE(pawrhoij_out)
     485                 :             :  else
     486                 :             :    if (algo_option==1) then
     487                 :             :      call pawrhoij_redistribute(pawrhoij,mpi_enreg%comm_atom,old_comm_atom,&
     488                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     489                 :             : &         natom=dtset%natom)
     490                 :          20 :    else if (algo_option==2) then
     491                 :             :        call pawrhoij_redistribute(pawrhoij,mpi_enreg%comm_atom,old_comm_atom,&
     492                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     493                 :             : &         natom=dtset%natom,&
     494                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     495                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     496                 :             :    end if
     497                 :             :  end if
     498                 :          20 :  call timab(595,2,tsec)
     499                 :             : 
     500                 :             : !paw_ij datastructure
     501                 :          20 :  call timab(596,1,tsec)
     502         [ -  + ]:          20 :  if (present(paw_ij_out)) then
     503                 :           0 :    call paw_ij_free(paw_ij_out)
     504         [ #  # ]:           0 :    ABI_FREE(paw_ij_out)
     505                 :             :  else
     506                 :             :    if (algo_option==1) then
     507                 :             :      call paw_ij_redistribute(paw_ij,mpi_enreg%comm_atom,old_comm_atom,&
     508                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     509                 :             : &         natom=dtset%natom)
     510                 :          20 :    else if (algo_option==2) then
     511                 :             :      call paw_ij_redistribute(paw_ij,mpi_enreg%comm_atom,old_comm_atom,&
     512                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     513                 :             : &         natom=dtset%natom,&
     514                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     515                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     516                 :             :    end if
     517                 :             :  end if
     518                 :          20 :  call timab(596,2,tsec)
     519                 :             : 
     520                 :             : !paw_an datastructure
     521                 :          20 :  call timab(597,1,tsec)
     522         [ -  + ]:          20 :  if (present(paw_an_out)) then
     523                 :           0 :    call paw_an_free(paw_an_out)
     524         [ #  # ]:           0 :    ABI_FREE(paw_an_out)
     525                 :             :  else
     526                 :             :    if (algo_option==1) then
     527                 :             :      call paw_an_redistribute(paw_an,mpi_enreg%comm_atom,old_comm_atom,&
     528                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     529                 :             : &         natom=dtset%natom)
     530                 :          20 :    else if (algo_option==2) then
     531                 :             :      call paw_an_redistribute(paw_an,mpi_enreg%comm_atom,old_comm_atom,&
     532                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     533                 :             : &         natom=dtset%natom,&
     534                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     535                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     536                 :             :    end if
     537                 :             :  end if
     538                 :          20 :  call timab(597,2,tsec)
     539                 :             : 
     540                 :             : !pawfgrtab datastructure
     541                 :          20 :  call timab(598,1,tsec)
     542         [ -  + ]:          20 :  if (present(pawfgrtab_out)) then
     543                 :           0 :    call pawfgrtab_free(pawfgrtab_out)
     544         [ #  # ]:           0 :    ABI_FREE(pawfgrtab_out)
     545                 :             :  else
     546                 :             :    if (algo_option==1) then
     547                 :             :      call pawfgrtab_redistribute(pawfgrtab,mpi_enreg%comm_atom,old_comm_atom,&
     548                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     549                 :             : &         natom=dtset%natom)
     550                 :          20 :    else if (algo_option==2) then
     551                 :             :      call pawfgrtab_redistribute(pawfgrtab,mpi_enreg%comm_atom,old_comm_atom,&
     552                 :             : &         mpi_atmtab_in=mpi_enreg%my_atmtab,mpi_atmtab_out=old_atmtab,&
     553                 :             : &         natom=dtset%natom,&
     554                 :             : &         SendAtomproc=SendAtomProc,SendAtomList=SendAtomList,&
     555                 :             : &         RecvAtomProc=RecvAtomProc,RecvAtomList=RecvAtomList)
     556                 :             :    end if
     557                 :             :  end if
     558                 :          20 :  call timab(598,2,tsec)
     559                 :             : 
     560                 :             : !Release some memory
     561         [ +  - ]:          20 :  if (algo_option==2.and.exchange) then
     562         [ -  + ]:          20 :    ABI_FREE(SendAtomProc)
     563         [ -  + ]:          20 :    ABI_FREE(SendAtomList)
     564         [ -  + ]:          20 :    ABI_FREE(RecvAtomProc)
     565         [ -  + ]:          20 :    ABI_FREE(RecvAtomList)
     566                 :             :  end if
     567                 :             : 
     568                 :             : !Restore communicator for atoms
     569         [ -  + ]:          20 :  ABI_FREE(old_atmtab)
     570                 :          20 :  old_comm_atom=mpi_enreg%comm_atom
     571                 :          20 :  call deep_copy(mpi_enreg%my_atmtab,old_atmtab)
     572                 :          20 :  call initmpi_atom(dtset,mpi_enreg)
     573                 :          20 :  my_natom=mpi_enreg%my_natom
     574                 :             : 
     575   [ -  +  -  +  :          20 : end  subroutine unset_pert_paw
             -  +  -  + ]
     576                 :             : !!***
     577                 :             : 
     578                 :             : !----------------------------------------------------------------------
     579                 :             : 
     580                 :             : !!****f* m_paral_atom/get_exchatom_list
     581                 :             : !! NAME
     582                 :             : !! get_exchatom_list
     583                 :             : !!
     584                 :             : !! FUNCTION
     585                 :             : !! This routine determine the list of atoms to be exchanged by current process and other processes.
     586                 :             : !! The initial communicator (mpicomm_in) should be a common ancestor of (mpicomm_in and mpicomm_out);
     587                 :             : !! It is splitted in "nbgroup" final communicators (mpicomm_out).
     588                 :             : !!
     589                 :             : !! INPUTS
     590                 :             : !!  mpicomm_in=input MPI communicator (over atoms) among which atoms are initially distributed
     591                 :             : !!  mpicomm_out=MPI communicator (over atoms) among which we want to distribute atoms
     592                 :             : !!  my_atmtab_in= Index of atoms initially treated by current proc (communicator mpicomm_in)
     593                 :             : !!  my_atmtab_out= Index of atoms finally treated by current proc (communicator mpicomm_out)
     594                 :             : !!  natom = total number of atoms
     595                 :             : !!  nbgroup = # of mpicomm_out communicators included in mpicomm_in
     596                 :             : !!
     597                 :             : !! OUTPUT
     598                 :             : !! For current proc :
     599                 :             : !! RecvAtomProc(:)= rank of processor from which I expect atom (in mpicomm_in)
     600                 :             : !! RecvAtomList(:)= indexes of atoms to be received by me
     601                 :             : !!   RecvAtomList(irecv) are the atoms I expect from RecvAtomProc(irecv)
     602                 :             : !! SendAtomProc(:)= ranks of process destination of atom (in mpicomm_in)
     603                 :             : !! SendAtomList(:)= indexes of atoms to be sent by me
     604                 :             : !!   SendAtomList(isend) are the atoms sent to SendAtomProc(isend)
     605                 :             : !!
     606                 :             : !! SOURCE
     607                 :             : 
     608                 :             : 
     609   [ -  +  -  + ]:          20 :  subroutine get_exchatom_list(mpicomm_in,mpicomm_out,my_atmtab_in,my_atmtab_out,natom, &
     610                 :             : &                             SendAtomProc,SendAtomList,RecvAtomProc,RecvAtomList)
     611                 :             : 
     612                 :             : !Arguments ---------------------------------------------
     613                 :             : !scalars
     614                 :             :  integer,intent(in) :: mpicomm_in,mpicomm_out,natom
     615                 :             : !arrays
     616                 :             :  integer,intent(in) :: my_atmtab_in(:),my_atmtab_out(:)
     617                 :             :  integer,allocatable,intent(out) :: RecvAtomProc(:),RecvAtomList(:)
     618                 :             :  integer,allocatable,intent(out) :: SendAtomList(:),SendAtomProc(:)
     619                 :             : 
     620                 :             : !Local variables ---------------------------------------
     621                 :             : !scalars
     622                 :             :  integer :: igroup,i1,ierr,ii,me_in,me_in_out,me_out,me_out0_in
     623                 :             :  integer :: my_natom_in,my_natom_out,nbgroup,nbsend,nproc_in,nproc_max,nproc_out
     624                 :             : !arrays
     625                 :             :  integer :: buf_int(3),rank0(1),ranks0_out_in(1)
     626                 :          20 :  integer, allocatable :: buf_int_all(:),group(:),master_commout(:),procs(:),ranks(:)
     627                 :          20 :  integer, allocatable  :: ranks1(:,:),sizecomm(:)
     628                 :             : 
     629                 :             : ! *************************************************************************
     630                 :             : 
     631                 :          20 :  nproc_in=xmpi_comm_size(mpicomm_in)
     632                 :          20 :  me_in=xmpi_comm_rank(mpicomm_in)
     633                 :          20 :  my_natom_in=size(my_atmtab_in)
     634                 :          20 :  nproc_out=xmpi_comm_size(mpicomm_out)
     635                 :          20 :  me_out=xmpi_comm_rank(mpicomm_out)
     636                 :          20 :  my_natom_out=size(my_atmtab_out)
     637                 :             : 
     638                 :          20 :  rank0(1)=0
     639                 :          20 :  call xmpi_comm_translate_ranks(mpicomm_out,1,rank0(1),mpicomm_in,ranks0_out_in(1))
     640                 :          20 :  me_out0_in=ranks0_out_in(1)
     641                 :             : 
     642   [ -  +  +  -  :          60 :  ABI_MALLOC(ranks,(1:nproc_in))
          +  -  +  -  -  
                +  -  + ]
     643   [ -  +  +  -  :          40 :  ABI_MALLOC(sizecomm,(1:nproc_in))
             -  +  -  + ]
     644   [ -  +  +  -  :          40 :  ABI_MALLOC(master_commout,(1:nproc_in))
             -  +  -  + ]
     645   [ -  +  +  -  :          60 :  ABI_MALLOC(group,(0:nproc_in-1))
          +  -  +  -  -  
                +  -  + ]
     646                 :          20 :  buf_int(1)=me_out; buf_int(2)=me_out0_in; buf_int(3)=nproc_out;
     647                 :             : 
     648   [ +  -  -  +  :          60 :  ABI_MALLOC(buf_int_all,(3*nproc_in))
          +  -  +  -  +  
             -  -  +  -  
                      + ]
     649                 :          20 :  call xmpi_allgather(buf_int,3,buf_int_all,mpicomm_in,ierr)
     650                 :          20 :  nbgroup=0;
     651                 :          20 :  nproc_max=0
     652   [ +  +  +  +  :         400 :  ranks(:)=-1;group(:)=-1;sizecomm(:)=-1;master_commout(:)=-1
             +  +  +  + ]
     653                 :             : 
     654         [ +  + ]:         100 :  do ii=1,nproc_in
     655                 :          80 :    ranks(ii)=buf_int_all(3*ii-2)    !me_out
     656                 :          80 :    master_commout(ii)=buf_int_all(3*ii-1) !rank of me_out=0 of mpicomm_out expressed in mpicomm_in
     657                 :             : 
     658         [ +  + ]:         100 :    if (ranks(ii)==0) then
     659                 :          36 :      nbgroup=nbgroup+1
     660                 :          36 :      sizecomm(nbgroup)=buf_int_all(3*ii) !nproc_out
     661                 :          36 :      group(master_commout(ii))=nbgroup
     662                 :          36 :      if (sizecomm(nbgroup)>nproc_max) nproc_max=sizecomm(nbgroup)
     663                 :             :    end if
     664                 :             : 
     665                 :             :  enddo
     666         [ -  + ]:          20 :  ABI_FREE(buf_int_all)
     667                 :             : 
     668                 :             : 
     669   [ -  +  +  -  :          80 :  ABI_MALLOC(ranks1,(nbgroup,0:nproc_max-1))
          -  +  +  -  +  
          -  +  -  -  +  
                   -  + ]
     670   [ +  +  +  + ]:         148 :  ranks1(:,:)=-1
     671         [ +  + ]:         100 :  do ii=1,nproc_in
     672                 :          80 :    me_in_out=ranks(ii)
     673                 :          80 :    igroup=group(master_commout(ii))
     674                 :         100 :    ranks1(igroup,me_in_out)=ii-1 !numbering of procs
     675                 :             :  enddo
     676                 :             : 
     677                 :             : !Send
     678                 :          20 :  nbsend=0
     679         [ +  + ]:          20 :  if (my_natom_in>0) then
     680   [ -  +  +  -  :          30 :    ABI_MALLOC(SendAtomList,(my_natom_in*nbgroup))
          +  -  +  -  -  
             +  -  +  -  
                      + ]
     681   [ -  +  +  -  :          20 :    ABI_MALLOC(SendAtomProc,(my_natom_in*nbgroup))
          -  +  -  +  -  
                      + ]
     682   [ -  +  +  -  :          30 :    ABI_MALLOC(procs,(my_natom_in))
          +  -  -  +  -  
                      + ]
     683         [ +  + ]:          28 :    do igroup=1,nbgroup
     684                 :          18 :      call get_atm_proc(my_atmtab_in,natom,sizecomm(igroup),procs)
     685         [ +  + ]:          46 :      do i1=1,my_natom_in
     686                 :          18 :        nbsend=nbsend+1
     687                 :          18 :        SendAtomProc(nbsend)=ranks1(igroup,procs(i1))
     688                 :          36 :        SendAtomList(nbsend)=my_atmtab_in(i1)
     689                 :             :      end do
     690                 :             :    end do
     691         [ -  + ]:          10 :    ABI_FREE(procs)
     692                 :             :  else
     693   [ -  +  -  + ]:          10 :   ABI_MALLOC(SendAtomList,(0))
     694   [ -  +  -  + ]:          10 :   ABI_MALLOC(SendAtomProc,(0))
     695                 :             : end if
     696                 :             : 
     697                 :             : !recv
     698         [ +  + ]:          20 :  if (my_natom_out>0) then !no return before because of xmpi_allgather and of the sending operation
     699   [ -  +  +  -  :          54 :    ABI_MALLOC(RecvAtomProc,(my_natom_out))
          +  -  -  +  -  
                +  -  + ]
     700   [ -  +  +  -  :          36 :    ABI_MALLOC(RecvAtomList,(my_natom_out))
          -  +  -  +  -  
                      + ]
     701         [ +  + ]:          36 :    RecvAtomList(:)=my_atmtab_out(:)
     702                 :             : !the atoms are put in increasing order,see get_my_atmtab so the procs are sorted by growing process
     703                 :          18 :    call get_atm_proc(RecvAtomList,natom,nproc_in,RecvAtomProc)
     704                 :             :  else
     705   [ -  +  -  + ]:           2 :    ABI_MALLOC(RecvAtomList,(0))
     706   [ -  +  -  + ]:           2 :    ABI_MALLOC(RecvAtomProc,(0))
     707                 :             :  end if
     708                 :             : 
     709         [ -  + ]:          20 :  ABI_FREE(master_commout)
     710         [ -  + ]:          20 :  ABI_FREE(ranks1)
     711         [ -  + ]:          20 :  ABI_FREE(group)
     712         [ -  + ]:          20 :  ABI_FREE(ranks)
     713         [ -  + ]:          20 :  ABI_FREE(sizecomm)
     714                 :             : 
     715         [ -  + ]:          20 : end subroutine get_exchatom_list
     716                 :             : !!***
     717                 :             : 
     718                 :             : !----------------------------------------------------------------------
     719                 :             : 
     720                 :             : !!****f* m_paral_atom/get_exchatom_list1
     721                 :             : !! NAME
     722                 :             : !! get_exchatom_list1
     723                 :             : !!
     724                 :             : !! FUNCTION
     725                 :             : !! This routine determine the list of atoms to be exchanged by current process and other processes.
     726                 :             : !! this function redistribute the atoms of one mpicomm_in among mpicomm_out
     727                 :             : !!
     728                 :             : !! INPUTS
     729                 :             : !!  mpicomm_in=input MPI communicator (over atoms) among which atoms are initially distributed
     730                 :             : !!  mpicomm_out=MPI communicator (over atoms) among which we want to distribute atoms
     731                 :             : !!  my_atmtab_in= Index of atoms initially treated by current proc (communicator mpicomm_in)
     732                 :             : !!  my_atmtab_out= Index of atoms finally treated by current proc (communicator mpicomm_out)
     733                 :             : !!  natom = total number of atoms
     734                 :             : !!
     735                 :             : !! OUTPUT
     736                 :             : !! For current proc:
     737                 :             : !! RecvAtomProc(:)= rank of processor from which I expect atom (in mpicomm_out)
     738                 :             : !! RecvAtomList(:)= indexes of atoms to be received by me
     739                 :             : !!   RecvAtomList(irecv) are the atoms I expect from RecvAtomProc(irecv)
     740                 :             : !! SendAtomProc(:)= ranks of process destination of atom (in mpicomm_out)
     741                 :             : !! SendAtomList(:)= indexes of atoms to be sent by me
     742                 :             : !!   SendAtomList(isend) are the atoms sent to SendAtomProc(isend)
     743                 :             : !!
     744                 :             : !! NOTES
     745                 :             : !! Previously mpicomm_out has be split in several mpicomm_in.
     746                 :             : !! In our purpose, we only need to redistribute the atoms of one mpicomm_in among mpicomm_out
     747                 :             : !! because all structures of atoms we have to exchange have the same value in each mpicomm_in.
     748                 :             : !! The mpicomm_in we choose is the one in which the processor 0 of mpicomm_out belong
     749                 :             : !!
     750                 :             : !! SOURCE
     751                 :             : 
     752   [ -  +  -  + ]:          20 : subroutine get_exchatom_list1(mpicomm_in,mpicomm_out,my_atmtab_in,my_atmtab_out,natom, &
     753                 :             : &                             SendAtomProc,SendAtomList,RecvAtomProc,RecvAtomList)
     754                 :             : 
     755                 :             : !Arguments ---------------------------------------------
     756                 :             : !scalars
     757                 :             :  integer,intent(in) :: mpicomm_in,mpicomm_out,natom
     758                 :             : !arrays
     759                 :             :  integer,intent(in) :: my_atmtab_in(:),my_atmtab_out(:)
     760                 :             :  integer,allocatable,intent(out) :: RecvAtomProc(:),RecvAtomList(:)
     761                 :             :  integer,allocatable,intent(out) :: SendAtomList(:),SendAtomProc(:)
     762                 :             : 
     763                 :             : !Local variables ---------------------------------------
     764                 :             : !scalars
     765                 :             :  integer :: i1,ier,me_out,my_natom_in,my_natom_out,nproc_in,nproc_out
     766                 :             :  logical :: sender
     767                 :             : !arrays
     768                 :          20 :  integer,allocatable :: ranks_in(:),ranks_in_out(:)
     769                 :             : 
     770                 :             : ! *************************************************************************
     771                 :             : 
     772                 :          20 :  me_out=xmpi_comm_rank(mpicomm_out)
     773                 :          20 :  my_natom_in=size(my_atmtab_in)
     774                 :          20 :  nproc_out=xmpi_comm_size(mpicomm_out)
     775                 :          20 :  my_natom_out=size(my_atmtab_out)
     776                 :          20 :  nproc_in=xmpi_comm_size(mpicomm_in)
     777                 :             : 
     778                 :          20 :  call xmpi_bcast(nproc_in,0,mpicomm_out,ier)
     779   [ -  +  +  -  :          60 :  ABI_MALLOC(ranks_in_out,(0:nproc_in-1))
          +  -  +  -  -  
                +  -  + ]
     780                 :             : 
     781                 :             : !All atoms are distributed among each mpicomm_in
     782                 :             : !redistribute the atoms of one mpicomm_in among mpicomm_out
     783                 :             : 
     784                 :             : !Look for the communicator mpicomm_in from which me_out=0 belong
     785                 :             : !Get ranks of all processors of mpicomm_in expressed in mpicomm_out
     786         [ +  + ]:          20 :  if (me_out==0) then
     787   [ -  +  +  -  :          10 :    ABI_MALLOC(ranks_in,(0:nproc_in-1))
             -  +  -  + ]
     788   [ +  -  +  +  :          51 :    ranks_in=(/ (i1,i1=0,nproc_in-1 )/)
          +  -  +  +  +  
          -  -  +  -  -  
                   +  + ]
     789                 :           5 :    call xmpi_comm_translate_ranks(mpicomm_in,nproc_in,ranks_in,mpicomm_out,ranks_in_out)
     790         [ -  + ]:           5 :    ABI_FREE(ranks_in)
     791                 :             :  end if
     792                 :          20 :  call xmpi_bcast(ranks_in_out,0,mpicomm_out,ier)
     793                 :             : 
     794                 :             : !Check if me_out is one of the sending proc.
     795                 :             : !(ie belongs to the mpicomm_in from which me_out belong)
     796                 :          20 :  sender = .false.
     797         [ +  + ]:          46 :  do i1=0,nproc_in-1
     798         [ +  + ]:          46 :    if (me_out==ranks_in_out(i1)) then
     799                 :             :      sender = .true.
     800                 :             :      exit
     801                 :             :    end if
     802                 :             :  end do
     803                 :             : 
     804                 :             : !Send
     805         [ +  + ]:          20 :  if (my_natom_in>0.and.sender) then
     806   [ -  +  +  -  :          30 :    ABI_MALLOC(SendAtomList,(my_natom_in))
          +  -  -  +  -  
                +  -  + ]
     807   [ -  +  +  -  :          20 :    ABI_MALLOC(SendAtomProc,(my_natom_in))
          -  +  -  +  -  
                      + ]
     808         [ +  + ]:          20 :    SendAtomList(:)=my_atmtab_in(:)
     809                 :             : !  The atoms are put in increasing order,see get_my_atmtab
     810                 :             : !  so the procs are sorted by growing process
     811                 :          10 :    call get_atm_proc(SendAtomList,natom,nproc_out,SendAtomProc)
     812                 :             :  else
     813   [ -  +  -  + ]:          10 :    ABI_MALLOC(SendAtomList,(0))
     814   [ -  +  -  + ]:          10 :    ABI_MALLOC(SendAtomProc,(0))
     815                 :             :  end if
     816                 :             : 
     817                 :             : !Recv
     818         [ +  + ]:          20 :  if (my_natom_out>0) then
     819   [ -  +  +  -  :          30 :    ABI_MALLOC(RecvAtomProc,(my_natom_out))
          +  -  -  +  -  
                +  -  + ]
     820   [ -  +  +  -  :          20 :    ABI_MALLOC(RecvAtomList,(my_natom_out))
          -  +  -  +  -  
                      + ]
     821         [ +  + ]:          20 :    RecvAtomList(:)=my_atmtab_out(:)
     822                 :             : !  The atoms are put in increasing order,see get_my_atmtab
     823                 :             : !  so the procs are sorted by growing process
     824                 :          10 :    call get_atm_proc(RecvAtomList,natom,nproc_in,RecvAtomProc)
     825         [ +  + ]:          20 :    RecvAtomProc(:)=ranks_in_out(RecvAtomProc(:))
     826                 :             :  else
     827   [ -  +  -  + ]:          10 :    ABI_MALLOC(RecvAtomList,(0))
     828   [ -  +  -  + ]:          10 :    ABI_MALLOC(RecvAtomProc,(0))
     829                 :             :  end if
     830                 :             : 
     831         [ -  + ]:          20 :  ABI_FREE(ranks_in_out)
     832                 :             : 
     833                 :          20 : end subroutine get_exchatom_list1
     834                 :             : !!***
     835                 :             : 
     836                 :             : !----------------------------------------------------------------------
     837                 :             : 
     838                 :             : END MODULE m_paral_pert
     839                 :             : !!***
        

Generated by: LCOV version 2.3-1