LCOV - code coverage report
Current view: top level - src/45_geomoptim - m_predict_pimd.F90 (source / functions) Coverage Total Hit
Test: coverage.info Lines: 53.7 % 162 87
Test Date: 2026-09-19 17:42:43 Functions: 100.0 % 1 1

            Line data    Source code
       1              : !!****m* ABINIT/m_predict_pimd
       2              : !! NAME
       3              : !!  m_predict_pimd
       4              : !!
       5              : !! FUNCTION
       6              : !!
       7              : !!
       8              : !! COPYRIGHT
       9              : !!  Copyright (C) 2010-2026 ABINIT group (GG)
      10              : !!  This file is distributed under the terms of the
      11              : !!  GNU General Public License, see ~abinit/COPYING
      12              : !!  or http://www.gnu.org/copyleft/gpl.txt .
      13              : !!
      14              : !! SOURCE
      15              : 
      16              : #if defined HAVE_CONFIG_H
      17              : #include "config.h"
      18              : #endif
      19              : 
      20              : #include "abi_common.h"
      21              : 
      22              : module m_predict_pimd
      23              : 
      24              :  use defs_basis
      25              :  use m_abicore
      26              :  use m_pimd
      27              :  use m_xmpi
      28              :  use m_results_img
      29              : 
      30              :  use defs_abitypes,    only : MPI_type
      31              :  use m_geometry,       only : mkradim, mkrdim
      32              :  use m_pimd_langevin,  only : pimd_langevin_npt, pimd_langevin_nvt
      33              :  use m_pimd_nosehoover, only : pimd_nosehoover_npt, pimd_nosehoover_nvt
      34              : 
      35              :  implicit none
      36              : 
      37              :  private
      38              : !!***
      39              : 
      40              :  public :: predict_pimd
      41              : !!***
      42              : 
      43              : contains
      44              : !!***
      45              : 
      46              : !!****f* ABINIT/predict_pimd
      47              : !! NAME
      48              : !! predict_pimd
      49              : !!
      50              : !! FUNCTION
      51              : !! Predicts new positions in Path Integral Molecular Dynamics
      52              : !! Given the positions at time t and t-dtion, an estimation of the velocities at time t,
      53              : !! the forces and an estimation of the stress at time t, and an estimation of the cell at time t,
      54              : !! computes in the Path Integral Molecular Dynamics framework the new positions at time t+dtion,
      55              : !! computes self-consistently the velocities, the stress and the cell at time t and produces
      56              : !! an estimation of the velocities, stress and new cell at time t+dtion
      57              : !! No change of acell and rprim at present.
      58              : !!
      59              : !! INPUTS
      60              : !! imgmov=gives the algorithm to be used for prediction of new set of images
      61              : !! itimimage=time index for image propagation (itimimage+1 is to be predicted here)
      62              : !! itimimage_eff=time index in the history
      63              : !! mpi_enreg=MPI-parallelisation information
      64              : !! natom=dimension of vel_timimage and xred_timimage
      65              : !! nimage=number of images (treated by current proc)
      66              : !! nimage_tot=total number of images
      67              : !! ntimimage_stored=number of time steps stored in the history
      68              : !! results_gs_timimage(ntimimage,nimage)=datastructure that hold all the history of previous computations.
      69              : !! pimd_param=datastructure that contains all the parameters necessary to Path-Integral MD
      70              : !! prtvolimg=printing volume
      71              : !!
      72              : !! OUTPUT
      73              : !!
      74              : !! SIDE EFFECTS
      75              : !! results_img(ntimimage_stored,nimage)=datastructure that holds the history of previous computations.
      76              : !!   results_img(:,:)%acell(3)
      77              : !!    at input, history of the values of acell for all images
      78              : !!    at output, the predicted values of acell for all images
      79              : !!   results_img(:,:)%results_gs
      80              : !!    at input, history of the values of energies and forces for all images
      81              : !!   results_img(:,:)%rprim(3,3)
      82              : !!    at input, history of the values of rprim for all images
      83              : !!    at output, the predicted values of rprim for all images
      84              : !!   results_img(:,:)%vel(3,natom)
      85              : !!    at input, history of the values of vel for all images
      86              : !!    at output, the predicted values of vel for all images
      87              : !!   results_img(:,:)%vel_cell(3,3)
      88              : !!    at input, history of the values of vel_cell for all images
      89              : !!    at output, the predicted values of vel_cell for all images
      90              : !!   results_img(:,:)%xred(3,natom)
      91              : !!    at input, history of the values of xred for all images
      92              : !!    at output, the predicted values of xred for all images
      93              : !!
      94              : !! SOURCE
      95              : 
      96           35 : subroutine predict_pimd(imgmov,itimimage,itimimage_eff,mpi_enreg,natom,nimage,nimage_tot,&
      97           35 : &                       ntimimage_stored,pimd_param,prtvolimg,results_img)
      98              : 
      99              : !Arguments ------------------------------------
     100              : !scalars
     101              :  integer,intent(in) :: imgmov,itimimage,itimimage_eff,natom
     102              :  integer,intent(in) :: nimage,nimage_tot,ntimimage_stored,prtvolimg
     103              :  type(MPI_type),intent(in) :: mpi_enreg
     104              :  type(pimd_type),intent(inout) :: pimd_param
     105              : !arrays
     106              :  type(results_img_type) :: results_img(nimage,ntimimage_stored)
     107              : 
     108              : !Local variables-------------------------------
     109              : !scalars
     110              :  integer :: ierr,ii,itime,itime_next,itime_prev
     111              :  real(dp) :: volume
     112              : !arrays
     113              :  real(dp) :: rprimd(3,3),rprimd_next(3,3),rprimd_prev(3,3),vel_cell(3,3),vel_cell_next(3,3)
     114           35 :  real(dp),allocatable :: mpibuf(:),mpibuffer(:,:,:),mpibuffer_all(:,:,:)
     115           35 :  real(dp),allocatable :: etotal(:),forces(:,:,:),stressin(:,:,:)
     116           35 :   real(dp),allocatable :: vel(:,:,:),vel_next(:,:,:)
     117           35 :  real(dp),allocatable :: xred(:,:,:),xred_next(:,:,:),xred_prev(:,:,:)
     118              : 
     119              : ! *************************************************************************
     120              : 
     121              : !############# Parallelism stuff 1 #######################
     122              : 
     123              : !Parallelism over image: only one process per image of the cell
     124           35 :  if (mpi_enreg%me_cell==0) then
     125              : 
     126           35 :    itime=itimimage_eff
     127           35 :    itime_prev=itime-1;if (itime_prev<1) itime_prev=ntimimage_stored
     128              : 
     129           35 :    if (mpi_enreg%paral_img==0.or.mpi_enreg%me_img==0) then
     130          140 :      ABI_MALLOC(xred,(3,natom,nimage_tot))
     131          105 :      ABI_MALLOC(xred_prev,(3,natom,nimage_tot))
     132          105 :      ABI_MALLOC(xred_next,(3,natom,nimage_tot))
     133          105 :      ABI_MALLOC(etotal,(nimage_tot))
     134          105 :      ABI_MALLOC(forces,(3,natom,nimage_tot))
     135          105 :      ABI_MALLOC(stressin,(3,3,nimage_tot))
     136          105 :      ABI_MALLOC(vel,(3,natom,nimage_tot))
     137          105 :      ABI_MALLOC(vel_next,(3,natom,nimage_tot))
     138              :    end if
     139              : 
     140              : !  Parallelism: Gather positions/forces/velocities/stresses/energy from all images
     141           35 :    if (mpi_enreg%paral_img==1) then
     142            0 :      ABI_MALLOC(mpibuffer,(12,natom+1,nimage))
     143            0 :      do ii=1,nimage
     144            0 :        mpibuffer(1:3  ,1:natom,ii)=results_img(ii,itime)%xred(1:3,1:natom)
     145            0 :        mpibuffer(4:6  ,1:natom,ii)=results_img(ii,itime_prev)%xred(1:3,1:natom)
     146            0 :        mpibuffer(7:9  ,1:natom,ii)=results_img(ii,itime)%results_gs%fcart(1:3,1:natom)
     147            0 :        mpibuffer(10:12,1:natom,ii)=results_img(ii,itime)%vel(1:3,1:natom)
     148            0 :        mpibuffer(1:6  ,natom+1,ii)=results_img(ii,itime)%results_gs%strten(1:6)
     149            0 :        mpibuffer(7:12 ,natom+1,ii)=zero
     150              :      end do
     151            0 :      if (mpi_enreg%me_img==0)  then
     152            0 :        ABI_MALLOC(mpibuffer_all,(12,natom+1,nimage_tot))
     153              :      end if
     154            0 :      call gather_array_img(mpibuffer,mpibuffer_all,mpi_enreg,only_one_per_img=.true.,allgather=.false.)
     155            0 :      ABI_FREE(mpibuffer)
     156            0 :      if (mpi_enreg%me_img==0) then
     157            0 :        do ii=1,nimage_tot
     158            0 :          xred     (1:3,1:natom,ii)=mpibuffer_all(1:3  ,1:natom,ii)
     159            0 :          xred_prev(1:3,1:natom,ii)=mpibuffer_all(4:6  ,1:natom,ii)
     160            0 :          forces   (1:3,1:natom,ii)=mpibuffer_all(7:9  ,1:natom,ii)
     161            0 :          vel      (1:3,1:natom,ii)=mpibuffer_all(10:12,1:natom,ii)
     162            0 :          stressin (1,1,ii)        =mpibuffer_all(1,natom+1,ii)
     163            0 :          stressin (2,2,ii)        =mpibuffer_all(2,natom+1,ii)
     164            0 :          stressin (3,3,ii)        =mpibuffer_all(3,natom+1,ii)
     165            0 :          stressin (3,2,ii)        =mpibuffer_all(4,natom+1,ii)
     166            0 :          stressin (3,1,ii)        =mpibuffer_all(5,natom+1,ii)
     167            0 :          stressin (2,1,ii)        =mpibuffer_all(6,natom+1,ii)
     168            0 :          stressin (2,3,ii)=stressin (3,2,ii)
     169            0 :          stressin (1,3,ii)=stressin (3,1,ii)
     170            0 :          stressin (1,2,ii)=stressin (2,1,ii)
     171              :        end do
     172            0 :        ABI_FREE(mpibuffer_all)
     173              :      end if
     174            0 :      ABI_MALLOC(mpibuf,(nimage))
     175            0 :      if (mpi_enreg%me_img/=0) then
     176            0 :        ABI_MALLOC(etotal,(0))
     177              :      end if
     178            0 :      do ii=1,nimage
     179            0 :        mpibuf(ii)=results_img(ii,itime)%results_gs%etotal
     180              :      end do
     181            0 :      call xmpi_gather(mpibuf,nimage,etotal,nimage,0,mpi_enreg%comm_img,ierr)
     182            0 :      ABI_FREE(mpibuf)
     183            0 :      if (mpi_enreg%me_img/=0) then
     184            0 :        ABI_FREE(etotal)
     185              :      end if
     186              : 
     187              : !    No parallelism: simply copy positions/forces/velocities/stresses/energy
     188              :    else
     189          240 :      do ii=1,nimage
     190         2245 :        xred     (:,:,ii)=results_img(ii,itime)%xred(:,:)
     191         2245 :        xred_prev(:,:,ii)=results_img(ii,itime_prev)%xred(:,:)
     192         2245 :        forces   (:,:,ii)=results_img(ii,itime)%results_gs%fcart(:,:)
     193         2245 :        vel      (:,:,ii)=results_img(ii,itime)%vel(:,:)
     194          205 :        etotal   (    ii)=results_img(ii,itime)%results_gs%etotal
     195          205 :        stressin (1,1,ii)=results_img(ii,itime)%results_gs%strten(1)
     196          205 :        stressin (2,2,ii)=results_img(ii,itime)%results_gs%strten(2)
     197          205 :        stressin (3,3,ii)=results_img(ii,itime)%results_gs%strten(3)
     198          205 :        stressin (3,2,ii)=results_img(ii,itime)%results_gs%strten(4)
     199          205 :        stressin (3,1,ii)=results_img(ii,itime)%results_gs%strten(5)
     200          205 :        stressin (2,1,ii)=results_img(ii,itime)%results_gs%strten(6)
     201          205 :        stressin (2,3,ii)=stressin (3,2,ii)
     202          205 :        stressin (1,3,ii)=stressin (3,1,ii)
     203          240 :        stressin (1,2,ii)=stressin (2,1,ii)
     204              :      end do
     205              :    end if
     206              : 
     207              : !  Parallelism over image: only one process does the job
     208           35 :    if (mpi_enreg%paral_img==0.or.mpi_enreg%me_img==0) then
     209              : 
     210              : !    ############# PIMD MD algorithm #########################
     211              : 
     212              : !    Some useful quantities about the cells (common to all images)
     213              : !    Take acell and rprim from 1st image
     214           35 :      call mkrdim(results_img(1,itime)%acell,results_img(1,itime)%rprim,rprimd)
     215           35 :      call mkrdim(results_img(1,itime_prev)%acell,results_img(1,itime_prev)%rprim,rprimd_prev)
     216          455 :      vel_cell(:,:)=results_img(1,itime)%vel_cell(:,:)
     217              : 
     218              : !    Compute the volume of the supercell
     219              :      volume=rprimd(1,1)*(rprimd(2,2)*rprimd(3,3)-rprimd(3,2)*rprimd(2,3))+&
     220              : &     rprimd(2,1)*(rprimd(3,2)*rprimd(1,3)-rprimd(1,2)*rprimd(3,3))+&
     221           35 : &     rprimd(3,1)*(rprimd(1,2)*rprimd(2,3)-rprimd(2,2)*rprimd(1,3))
     222           35 :      volume=abs(volume)
     223              : 
     224           55 :      select case(imgmov)
     225              : 
     226              :      case(9,10)  !Langevin
     227              : 
     228           55 :        select case(pimd_param%optcell)
     229              :        case(0)  !NVT
     230              :          call pimd_langevin_nvt(etotal,forces,itimimage,natom,pimd_param,prtvolimg,&
     231           20 : &         rprimd,stressin,nimage_tot,vel,vel_next,volume,xred,xred_next,xred_prev)
     232              :        case(2)  !NPT
     233              :          call pimd_langevin_npt(etotal,forces,itimimage,natom,pimd_param,prtvolimg,&
     234              : &         rprimd,rprimd_next,rprimd_prev,stressin,nimage_tot,vel,vel_next,vel_cell,&
     235           20 : &         vel_cell_next,volume,xred,xred_next,xred_prev)
     236              :        end select
     237              : 
     238              :      case(13)  !Nose Hoover chains
     239              : 
     240           35 :        select case(pimd_param%optcell)
     241              :        case(0)  !NVT
     242              :          call pimd_nosehoover_nvt(etotal,forces,itimimage,natom,pimd_param,prtvolimg,&
     243           15 : &         rprimd,stressin,nimage_tot,vel,vel_next,volume,xred,xred_next,xred_prev)
     244              :        case(2)  !NPT
     245              :          call pimd_nosehoover_npt(etotal,forces,itimimage,natom,pimd_param,prtvolimg,&
     246              : &         rprimd,rprimd_next,rprimd_prev,stressin,nimage_tot,vel,vel_next,vel_cell,&
     247           15 : &         vel_cell_next,volume,xred,xred_next,xred_prev)
     248              :        end select
     249              : 
     250              :      end select
     251              : 
     252              : !    ############# Parallelism stuff 2 ########################
     253              : 
     254              :    end if ! mpi_enreg%me_img==0
     255              : 
     256              : !  Parallelism: dispatch results
     257              : !  The trick: use (9,natom) to store xred,xred_next,vel for all atoms
     258              : !  use (9      ) to store rprimd_next
     259          140 :    ABI_MALLOC(mpibuffer,(12,natom+4,nimage))
     260           35 :    if (mpi_enreg%paral_img==1) then
     261            0 :      if (mpi_enreg%me_img==0) then
     262            0 :        ABI_MALLOC(mpibuffer_all,(12,natom+4,nimage_tot))
     263            0 :        do ii=1,nimage_tot
     264            0 :          mpibuffer_all(1:3,1:natom,ii)=xred_next(1:3,1:natom,ii)
     265            0 :          mpibuffer_all(4:6,1:natom,ii)=xred(1:3,1:natom,ii)
     266            0 :          mpibuffer_all(7:9,1:natom,ii)=vel_next(1:3,1:natom,ii)
     267            0 :          mpibuffer_all(10:12,1:natom,ii)=vel(1:3,1:natom,ii)
     268            0 :          mpibuffer_all(1:3,natom+1,ii)=rprimd_next(1:3,1)
     269            0 :          mpibuffer_all(4:6,natom+1,ii)=rprimd_next(1:3,2)
     270            0 :          mpibuffer_all(7:9,natom+1,ii)=rprimd_next(1:3,3)
     271            0 :          mpibuffer_all(1:3,natom+3,ii)=rprimd(1:3,1)
     272            0 :          mpibuffer_all(4:6,natom+3,ii)=rprimd(1:3,2)
     273            0 :          mpibuffer_all(7:9,natom+3,ii)=rprimd(1:3,3)
     274            0 :          mpibuffer_all(1:3,natom+2,ii)=vel_cell_next(1:3,1)
     275            0 :          mpibuffer_all(4:6,natom+2,ii)=vel_cell_next(1:3,2)
     276            0 :          mpibuffer_all(7:9,natom+2,ii)=vel_cell_next(1:3,3)
     277            0 :          mpibuffer_all(1:3,natom+2,ii)=vel_cell(1:3,1)
     278            0 :          mpibuffer_all(4:6,natom+2,ii)=vel_cell(1:3,2)
     279            0 :          mpibuffer_all(7:9,natom+2,ii)=vel_cell(1:3,3)
     280              :        end do
     281              :      end if
     282            0 :      call scatter_array_img(mpibuffer,mpibuffer_all,mpi_enreg)
     283            0 :      if (mpi_enreg%me_img==0)  then
     284            0 :        ABI_FREE(mpibuffer_all)
     285              :      end if
     286              :    else
     287          240 :      do ii=1,nimage
     288         2245 :        mpibuffer(1:3,1:natom,ii)=xred_next(1:3,1:natom,ii)
     289         2245 :        mpibuffer(4:6,1:natom,ii)=xred(1:3,1:natom,ii)
     290         2245 :        mpibuffer(7:9,1:natom,ii)=vel_next(1:3,1:natom,ii)
     291         2245 :        mpibuffer(10:12,1:natom,ii)=vel(1:3,1:natom,ii)
     292          820 :        mpibuffer(1:3,natom+1,ii)=rprimd_next(1:3,1)
     293          820 :        mpibuffer(4:6,natom+1,ii)=rprimd_next(1:3,2)
     294          820 :        mpibuffer(7:9,natom+1,ii)=rprimd_next(1:3,3)
     295          820 :        mpibuffer(1:3,natom+3,ii)=rprimd(1:3,1)
     296          820 :        mpibuffer(4:6,natom+3,ii)=rprimd(1:3,2)
     297          820 :        mpibuffer(7:9,natom+3,ii)=rprimd(1:3,3)
     298          820 :        mpibuffer(1:3,natom+2,ii)=vel_cell_next(1:3,1)
     299          820 :        mpibuffer(4:6,natom+2,ii)=vel_cell_next(1:3,2)
     300          820 :        mpibuffer(7:9,natom+2,ii)=vel_cell_next(1:3,3)
     301          820 :        mpibuffer(1:3,natom+2,ii)=vel_cell(1:3,1)
     302          820 :        mpibuffer(4:6,natom+2,ii)=vel_cell(1:3,2)
     303          855 :        mpibuffer(7:9,natom+2,ii)=vel_cell(1:3,3)
     304              :      end do
     305              :    end if
     306              : 
     307           35 :    if (mpi_enreg%paral_img==0.or.mpi_enreg%me_img==0) then
     308           35 :      ABI_FREE(xred)
     309           35 :      ABI_FREE(xred_prev)
     310           35 :      ABI_FREE(xred_next)
     311           35 :      ABI_FREE(etotal)
     312           35 :      ABI_FREE(forces)
     313           35 :      ABI_FREE(stressin)
     314           35 :      ABI_FREE(vel)
     315           35 :      ABI_FREE(vel_next)
     316              :    end if
     317              : 
     318              :  else
     319            0 :    ABI_MALLOC(mpibuffer,(12,natom+4,nimage))
     320              : 
     321              :  end if ! mpi_enreg%me_cell==0
     322              : 
     323              : !Send results to all procs treating the same image
     324           35 :  call xmpi_bcast(mpibuffer,0,mpi_enreg%comm_cell,ierr)
     325              : 
     326              : !Store results in final place
     327           35 :  itime=itimimage_eff
     328           35 :  itime_prev=itime-1;if (itime_prev<1) itime_prev=ntimimage_stored
     329           35 :  itime_next=itime+1;if (itime_next>ntimimage_stored) itime_next=1
     330          240 :  do ii=1,nimage
     331         2245 :    results_img(ii,itime_next)%xred(1:3,1:natom)=mpibuffer(1:3,1:natom,ii)
     332         2245 :    results_img(ii,itime)%xred(1:3,1:natom)=mpibuffer(4:6,1:natom,ii)
     333         2245 :    results_img(ii,itime_next)%vel(1:3,1:natom)=mpibuffer(7:9,1:natom,ii)
     334         2280 :    results_img(ii,itime)%vel(1:3,1:natom)=mpibuffer(10:12,1:natom,ii)
     335              :  end do
     336           35 :  if (pimd_param%optcell/=0) then
     337            0 :    do ii=1,nimage
     338            0 :      rprimd(1:3,1)=mpibuffer(1:3,natom+1,ii)
     339            0 :      rprimd(1:3,2)=mpibuffer(4:6,natom+1,ii)
     340            0 :      rprimd(1:3,3)=mpibuffer(7:9,natom+1,ii)
     341            0 :      call mkradim(results_img(ii,itime_next)%acell,results_img(ii,itime_next)%rprim,rprimd)
     342            0 :      rprimd_prev(1:3,1)=mpibuffer(1:3,natom+2,ii)
     343            0 :      rprimd_prev(1:3,2)=mpibuffer(4:6,natom+2,ii)
     344            0 :      rprimd_prev(1:3,3)=mpibuffer(7:9,natom+2,ii)
     345            0 :      call mkradim(results_img(ii,itime)%acell,results_img(ii,itime)%rprim,rprimd_prev)
     346            0 :      results_img(ii,itime_next)%vel_cell(1:3,1)=mpibuffer(1:3,natom+3,ii)
     347            0 :      results_img(ii,itime_next)%vel_cell(1:3,2)=mpibuffer(4:6,natom+3,ii)
     348            0 :      results_img(ii,itime_next)%vel_cell(1:3,3)=mpibuffer(7:9,natom+3,ii)
     349            0 :      results_img(ii,itime)%vel_cell(1:3,1)=mpibuffer(1:3,natom+4,ii)
     350            0 :      results_img(ii,itime)%vel_cell(1:3,2)=mpibuffer(4:6,natom+4,ii)
     351            0 :      results_img(ii,itime)%vel_cell(1:3,3)=mpibuffer(7:9,natom+4,ii)
     352              :    end do
     353              :  end if
     354           35 :  ABI_FREE(mpibuffer)
     355              : 
     356           35 : end subroutine predict_pimd
     357              : !!***
     358              : 
     359              : end module m_predict_pimd
     360              : !!***
        

Generated by: LCOV version 2.3-1