!>
!> @file pex3.f90
!>
!> @brief 1d/2d time-dependent profiles using "append" (parallel version)
!>
!> @copyright
!> Copyright (©) 2021 EPFL (Ecole Polytechnique Fédérale de Lausanne)
!> SPC (Swiss Plasma Center)
!>
!> futils is free software: you can redistribute it and/or modify it under
!> the terms of the GNU Lesser General Public License as published by the Free
!> Software Foundation, either version 3 of the License, or (at your option)
!> any later version.
!>
!> futils is distributed in the hope that it will be useful, but WITHOUT ANY
!> WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
!> FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
!>
!> You should have received a copy of the GNU Lesser General Public License
!> along with this program. If not, see .
!>
!> @authors
!> (in alphabetical order)
!> @author Trach-Minh Tran
!>
PROGRAM main
!
! Multi-dim (+UNLIMITED time dim) profiles
!
USE futils
IMPLICIT NONE
INCLUDE "mpif.h"
CHARACTER(len=32) :: file='pprof.h5'
INTEGER, PARAMETER :: nx=256, ny=512
INTEGER :: me, npes, offset, nyp
INTEGER :: fid, rank, dims(7)
INTEGER :: i, j, istep, ierr, n, nrun=50
DOUBLE PRECISION, ALLOCATABLE :: xg(:), yg(:), phi2(:,:)
DOUBLE PRECISION :: dx, dy, pi, time, x0, s
!===========================================================================
! 1. Prologue
!
! Init MPI
CALL mpi_init(ierr)
CALL mpi_comm_size(MPI_COMM_WORLD, npes, ierr)
CALL mpi_comm_rank(MPI_COMM_WORLD, me, ierr)
!
! 1D partition in Y-direction
CALL dist1d(0, ny, offset, nyp)
WRITE(*,'(a,i3.3,a,2i6)') 'PE', me, ': offset, nyp', offset, nyp
ALLOCATE(xg(nx), yg(nyp), phi2(nx,nyp))
!
! Init HDF5
CALL creatf(file, fid, 'A simple simulation', mpicomm=MPI_COMM_WORLD)
CALL creatg(fid, "/profile_2d", "1D profiles")
!
rank = 0
CALL creatd(fid, rank, dims, "/profile_2d/time", "Normalized Time")
!
rank = 2
dims(1) = nx; dims(2) = nyp
CALL creatd(fid, rank, dims, "/profile_2d/phi", "Potential", pardim=2)
IF( me .EQ. 0 ) WRITE(*,'(a)') 'extendible datasets in /profile_1d created'
!===========================================================================
! 2. Initialization
!
pi = 4*ATAN(1.0d0)
dx = 2.*pi/REAL(nx-1)
dy = pi/real(ny-1)
DO i=1,nx
xg(i) = (i-1)*dx
END DO
DO j=1,nyp
yg(j) = (j+offset-1)*dy
END DO
CALL putarr(fid, "/profile_2d/xg", xg, "x mesh")
IF( me .EQ. 0 ) WRITE(*,'(a)') 'x-mesh'
CALL putarr(fid, "/profile_2d/yg", yg, "y mesh", pardim=1)
IF( me .EQ. 0 ) WRITE(*,'(a)') 'y-mesh'
!===========================================================================
! 3. Time loop
!
x0 = 0.5
DO istep=1,nrun
!
time = istep-1
s = 0.1+0.1*time
DO i=1,nx
DO j=1,nyp
phi2(i,j) = SIN(xg(i)) * COS(yg(j)) * COS(0.04*pi*time)
END DO
END DO
!
CALL append(fid, "/profile_2d/time", time, ionode=0) ! Only rank=0 writes it
!!$ CALL append(fid, "/profile_2d/time", time)
CALL append(fid, "/profile_2d/phi", phi2, pardim=2)
IF( me .EQ. 0 ) WRITE(*,'(a,i5,a)') 'Step', istep, ' done'
!
END DO
!===========================================================================
! 9. Epilogue
!
CALL closef(fid)
CALL mpi_finalize(ierr)
END PROGRAM main
SUBROUTINE dist1d(s0, ntot, s, nloc)
IMPLICIT NONE
INCLUDE 'mpif.h'
INTEGER, INTENT(in) :: s0, ntot
INTEGER, INTENT(out) :: s, nloc
INTEGER :: me, npes, ierr, naver, rem
!
CALL MPI_COMM_SIZE(MPI_COMM_WORLD, npes, ierr)
CALL MPI_COMM_RANK(MPI_COMM_WORLD, me, ierr)
naver = ntot/npes
rem = MODULO(ntot,npes)
s = s0 + MIN(rem,me) + me*naver
nloc = naver
IF( me.LT.rem ) nloc = nloc+1
!
END SUBROUTINE dist1d