diff --git a/src/geometry_mod.F90 b/src/geometry_mod.F90 index 257510d1cf9d80d4387da4ea3a4337665e050b18..7352707ed92cc119d7498f66fa8ae6f541a307a0 100644 --- a/src/geometry_mod.F90 +++ b/src/geometry_mod.F90 @@ -37,7 +37,7 @@ implicit none ! Some geometrical coefficients REAL(dp), PUBLIC, DIMENSION(:,:) , ALLOCATABLE :: gradz_coeff ! 1 / [ J_{xyz} \hat{B} ] ! Array to map the index of mode (kx,ky,-pi) to (kx+2pi*s*ky,ky,pi) for sheared periodic boundary condition - INTEGER, PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ikx_zBC_map + INTEGER, PUBLIC, DIMENSION(:,:), ALLOCATABLE :: ikx_zBC_L, ikx_zBC_R ! Functions PUBLIC :: geometry_readinputs, geometry_outputinputs,& eval_magnetic_geometry, set_ikx_zBC_map @@ -271,44 +271,71 @@ CONTAINS SUBROUTINE set_ikx_zBC_map IMPLICIT NONE - INTEGER, DIMENSION(:), ALLOCATABLE :: ikx_array - INTEGER :: shift - ALLOCATE(ikx_array(ikxs:ikxe)) - DO ikx = ikxs,ikxe - ikx_array(ikx) = MODULO(ikx - Nx/2,Nx) + 1 + REAL :: shift, kx_shift, kxmax_, kxmin_ + ALLOCATE(ikx_zBC_R(ikys:ikye,ikxs:ikxe)) + ALLOCATE(ikx_zBC_L(ikys:ikye,ikxs:ikxe)) + !! No shear case (simple id mapping) + !3 | 1 2 3 4 5 6 | ky = 3 dky + !2 ky | 1 2 3 4 5 6 | ky = 2 dky + !1 A | 1 2 3 4 5 6 | ky = 1 dky + !0 | -> kx | 1____2____3____4____5____6 | ky = 0 dky + !(e.g.) kx = 0 0.1 0.2 0.3 -0.2 -0.1 (dkx=free) + DO iky = ikys,ikye + DO ikx = ikxs,ikxe + ikx_zBC_L(iky,ikx) = ikx + ikx_zBC_R(iky,ikx) = ikx + ENDDO ENDDO + ! Modify connection map only at border of z IF(SHEARED) THEN - !! We allocate a mapping to tell where the current mode will point for the - ! parallel periodic sheared BC for the kx index: - ! map for 0 Dirichlet BC - !3 | 1 2 3 4 5 -1 -1 -1| - !2 ky | 8 1 2 3 4 5 -1 -1| - !1 A | 7 8 1 2 3 4 5 -1| - !0 | -> kx | 6____7____8____1____2____3____4____5| - ALLOCATE(ikx_zBC_map(ikys:ikye,ikxs:ikxe)) - ikx_zBC_map(ikys:ikye,ikxs:ikxe) = -1 - DO iky = ikys,ikye - DO ikx = ikxs,ikxe - iky + 1 - shift = ikx_array(MODULO(ikx+iky-1,Nx+1)) - ikx_zBC_map(iky,ikx) = shift - ENDDO - ENDDO + ! connection map BC of the RIGHT boundary (z=pi*Npol-dz) + !3 | 4 x x x 2 3 | ky = 3 dky + !2 ky | 3 4 x x 1 2 | ky = 2 dky + !1 A | 2 3 4 x 6 1 | ky = 1 dky + !0 | -> kx | 1____2____3____4____5____6 | ky = 0 dky + !kx = 0 0.1 0.2 0.3 -0.2 -0.1 (dkx=2pi*shear*npol*dky) + kxmax_ = kx_max + IF(contains_zmax) THEN ! Check if the process is at the end of the FT + DO iky = ikys,ikye + shift = 2._dp*shear*PI*kyarray(iky)*Npol + DO ikx = ikxs,ikxe + kx_shift = kxarray(ikx) + shift + IF(kx_shift .GT. kxmax_) THEN ! outside of the frequ domain + ikx_zBC_R(iky,ikx) = -99 + ELSE + ikx_zBC_R(iky,ikx) = (ikx+iky)-1 + IF(SINGLE_KY) ikx_zBC_R(iky,ikx) = (ikx+(iky+1))-1 + IF( ikx_zBC_R(iky,ikx) .GT. Nkx ) & + ikx_zBC_R(iky,ikx) = ikx_zBC_R(iky,ikx) - Nkx + ENDIF + ENDDO + ENDDO + ENDIF + ! connection map BC of the LEFT boundary (z=-pi*Npol) + !3 | x 5 6 1 x x | ky = 3 dky + !2 ky | 5 6 1 2 x x | ky = 2 dky + !1 A | 6 1 2 3 x 5 | ky = 1 dky + !0 | -> kx | 1____2____3____4____5____6 | ky = 0 dky + !(e.g.) kx = 0 0.1 0.2 0.3 -0.2 -0.1 (dkx=2pi*shear*npol*dky) + kxmin_ = -kx_max+deltakx + IF(contains_zmin) THEN ! Check if the process is at the start of the FT + DO iky = ikys,ikye + shift = 2._dp*shear*PI*kyarray(iky)*Npol + DO ikx = ikxs,ikxe + kx_shift = kxarray(ikx) - shift + IF( kx_shift .LT. kxmin_ ) THEN ! outside of the frequ domain + ikx_zBC_L(iky,ikx) = -99 + ELSE + ikx_zBC_L(iky,ikx) = (ikx-iky)+1 + IF(SINGLE_KY) ikx_zBC_L(iky,ikx) = (ikx-(iky+1))+1 + IF( ikx_zBC_L(iky,ikx) .LE. 0 ) & + ikx_zBC_L(iky,ikx) = ikx_zBC_L(iky,ikx) + Nkx + ENDIF + ENDDO + ENDDO + ENDIF ELSE - !! No shear case (simple id mapping) - !3 | 6 7 8 1 2 3 4 5| - !2 ky | 6 7 8 1 2 3 4 5| - !1 A | 6 7 8 1 2 3 4 5| - !0 | -> kx | 6____7____8____1____2____3____4____5| - DO iky = ikys,ikye - ikx_zBC_map(iky,:) = ikx_array(:) - ENDDO ENDIF -! IF (my_id .EQ. 0) THEN -! write(*,*) 'ikx map for parallel BC' -! DO, iky = ikys,ikye -! write(*,*) ( ikx_zBC_map(iky,ikx), ikx=ikxs,ikxe ) -! enddo -! ENDIF END SUBROUTINE set_ikx_zBC_map ! diff --git a/src/ghosts_mod.F90 b/src/ghosts_mod.F90 index 81d23aba6f6400e1ee43ba9e7f97b51dbed1478c..2fa4bc65dba3ab3b3d88fa159f6f80f34222d42c 100644 --- a/src/ghosts_mod.F90 +++ b/src/ghosts_mod.F90 @@ -4,8 +4,7 @@ USE fields, ONLY : moments_e, moments_i, phi USE grid USE time_integration USE model, ONLY : KIN_E -USE geometry, ONLY : SHEARED, ikx_zBC_map - +USE geometry, ONLY : SHEARED, ikx_zBC_L, ikx_zBC_R IMPLICIT NONE INTEGER :: status(MPI_STATUS_SIZE), source, dest, count, ipg @@ -121,192 +120,179 @@ END SUBROUTINE update_ghosts_p_i ! ^ ^ !Periodic: 0 1 SUBROUTINE update_ghosts_z_e - + USE parallel, ONLY : buff_pjxy_zBC_e IMPLICIT NONE - INTEGER :: ikxBC - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF (num_procs_z .GT. 1) THEN - - count = (ipge_e-ipgs_e+1)*(ijge_e-ijgs_e+1)*(ikye-ikys+1)*(ikxe-ikxs+1) - - !!!!!!!!!!! Send ghost to up neighbour !!!!!!!!!!!!!!!!!!!!!! - ! Send the last local moment to fill the -1 neighbour ghost - CALL mpi_sendrecv(moments_e(:,:,:,:,ize ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 20, & ! Send to Up the last - moments_e(:,:,:,:,izs-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 20, & ! Recieve from Down the first-1 - comm0, status, ierr) - CALL mpi_sendrecv(moments_e(:,:,:,:,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 21, & ! Send to Up the last-1 - moments_e(:,:,:,:,izs-2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 21, & ! Recieve from Down the first-2 - comm0, status, ierr) + INTEGER :: ikxBC_L, ikxBC_R + IF(Nz .GT. 1) THEN + IF (num_procs_z .GT. 1) THEN + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + count = (ipge_e-ipgs_e+1)*(ijge_e-ijgs_e+1)*(ikye-ikys+1)*(ikxe-ikxs+1) - !!!!!!!!!!! Send ghost to up neighbour !!!!!!!!!!!!!!!!!!!!!! - CALL mpi_sendrecv(moments_e(:,:,:,:,izs ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 22, & ! Send to Down the first - moments_e(:,:,:,:,ize+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 22, & ! Recieve from Up the last+1 - comm0, status, ierr) - CALL mpi_sendrecv(moments_e(:,:,:,:,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 23, & ! Send to Down the first+1 - moments_e(:,:,:,:,ize+2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 23, & ! Recieve from Up the last+2 - comm0, status, ierr) - ELSE ! still need to perform periodic boundary conditions - IF(SHEARED) THEN - DO iky = ikys,ikye - DO ikx = ikxs,ikxe - ikxBC = ikx_zBC_map(ikx,iky); - IF (ikxBC .NE. -1) THEN ! Exchanging the modes that have a periodic pair (a) - ! first-1 gets last - moments_e(iky,ikx,:,:,izs-1,updatetlevel) = moments_e(iky,ikxBC,:,:,ize ,updatetlevel) - ! first-2 gets last-1 - moments_e(iky,ikx,:,:,izs-2,updatetlevel) = moments_e(iky,ikxBC,:,:,ize-1,updatetlevel) - ! last+1 gets first - moments_e(iky,ikx,:,:,ize+1,updatetlevel) = moments_e(iky,ikxBC,:,:,izs ,updatetlevel) - ! last+2 gets first+1 - moments_e(iky,ikx,:,:,ize+2,updatetlevel) = moments_e(iky,ikxBC,:,:,izs+1,updatetlevel) - ELSE - moments_e(iky,ikx,:,:,izs-1,updatetlevel) = 0._dp - moments_e(iky,ikx,:,:,izs-2,updatetlevel) = 0._dp - moments_e(iky,ikx,:,:,ize+1,updatetlevel) = 0._dp - moments_e(iky,ikx,:,:,ize+2,updatetlevel) = 0._dp - ENDIF - ENDDO - ENDDO - ELSE ! No shear so simple periodic BC - ! first-1 gets last - moments_e(:,:,:,:,izs-1,updatetlevel) = moments_e(:,:,:,:,ize ,updatetlevel) - ! first-2 gets last-1 - moments_e(:,:,:,:,izs-2,updatetlevel) = moments_e(:,:,:,:,ize-1,updatetlevel) - ! last+1 gets first - moments_e(:,:,:,:,ize+1,updatetlevel) = moments_e(:,:,:,:,izs ,updatetlevel) - ! last+2 gets first+1 - moments_e(:,:,:,:,ize+2,updatetlevel) = moments_e(:,:,:,:,izs+1,updatetlevel) - ENDIF + !!!!!!!!!!! Send ghost to up neighbour !!!!!!!!!!!!!!!!!!!!!! + ! Send the last local moment to fill the -1 neighbour ghost + CALL mpi_sendrecv(moments_e(:,:,:,:,ize ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 20, & ! Send to Up the last + buff_pjxy_zBC_e(:,:,:,:,-1), count, MPI_DOUBLE_COMPLEX, nbr_D, 20, & ! Recieve from Down the first-1 + comm0, status, ierr) + CALL mpi_sendrecv(moments_e(:,:,:,:,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 21, & ! Send to Up the last + buff_pjxy_zBC_e(:,:,:,:,-2), count, MPI_DOUBLE_COMPLEX, nbr_D, 21, & ! Recieve from Down the first-1 + comm0, status, ierr) + !!!!!!!!!!! Send ghost to down neighbour !!!!!!!!!!!!!!!!!!!!!! + CALL mpi_sendrecv(moments_e(:,:,:,:,izs ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 22, & ! Send to Up the last + buff_pjxy_zBC_e(:,:,:,:,+1), count, MPI_DOUBLE_COMPLEX, nbr_U, 22, & ! Recieve from Down the first-1 + comm0, status, ierr) + CALL mpi_sendrecv(moments_e(:,:,:,:,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 23, & ! Send to Up the last + buff_pjxy_zBC_e(:,:,:,:,+2), count, MPI_DOUBLE_COMPLEX, nbr_U, 23, & ! Recieve from Down the first-1 + comm0, status, ierr) + ELSE !No parallel (copy) + buff_pjxy_zBC_e(:,:,:,:,-1) = moments_e(:,:,:,:,ize ,updatetlevel) + buff_pjxy_zBC_e(:,:,:,:,-2) = moments_e(:,:,:,:,ize-1,updatetlevel) + buff_pjxy_zBC_e(:,:,:,:,+1) = moments_e(:,:,:,:,izs ,updatetlevel) + buff_pjxy_zBC_e(:,:,:,:,+2) = moments_e(:,:,:,:,izs+1,updatetlevel) + ENDIF + DO iky = ikys,ikye + DO ikx = ikxs,ikxe + ikxBC_L = ikx_zBC_L(iky,ikx); + IF (ikxBC_L .NE. -99) THEN ! Exchanging the modes that have a periodic pair (a) + ! first-1 gets last + moments_e(:,:,iky,ikx,izs-1,updatetlevel) = buff_pjxy_zBC_e(:,:,iky,ikxBC_L,-1) + ! first-2 gets last-1 + moments_e(:,:,iky,ikx,izs-2,updatetlevel) = buff_pjxy_zBC_e(:,:,iky,ikxBC_L,-2) + ELSE + moments_e(:,:,iky,ikx,izs-1,updatetlevel) = 0._dp + moments_e(:,:,iky,ikx,izs-2,updatetlevel) = 0._dp + ENDIF + ikxBC_R = ikx_zBC_R(iky,ikx); + IF (ikxBC_R .NE. -99) THEN ! Exchanging the modes that have a periodic pair (a) + ! last+1 gets first + moments_e(:,:,iky,ikx,ize+1,updatetlevel) = buff_pjxy_zBC_e(:,:,iky,ikxBC_R,+1) + ! last+2 gets first+1 + moments_e(:,:,iky,ikx,ize+2,updatetlevel) = buff_pjxy_zBC_e(:,:,iky,ikxBC_R,+2) + ELSE + moments_e(:,:,iky,ikx,ize+1,updatetlevel) = 0._dp + moments_e(:,:,iky,ikx,ize+2,updatetlevel) = 0._dp + ENDIF + ENDDO + ENDDO ENDIF END SUBROUTINE update_ghosts_z_e SUBROUTINE update_ghosts_z_i - + USE parallel, ONLY : buff_pjxy_zBC_i IMPLICIT NONE - INTEGER :: ikxBC - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) - IF (num_procs_z .GT. 1) THEN - - count = (ipge_i-ipgs_i+1)*(ijge_i-ijgs_i+1)*(ikye-ikys+1)*(ikxe-ikxs+1) - - !!!!!!!!!!! Send ghost to up neighbour !!!!!!!!!!!!!!!!!!!!!! - ! Send the last local moment to fill the -1 neighbour ghost - CALL mpi_sendrecv(moments_i(:,:,:,:,ize ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 30, & ! Send to Up the last - moments_i(:,:,:,:,izs-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 30, & ! Recieve from Down the first-1 - comm0, status, ierr) - CALL mpi_sendrecv(moments_i(:,:,:,:,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 31, & ! Send to Up the last-1 - moments_i(:,:,:,:,izs-2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 31, & ! Recieve from Down the first-2 - comm0, status, ierr) - - !!!!!!!!!!! Send ghost to down neighbour !!!!!!!!!!!!!!!!!!!!!! - CALL mpi_sendrecv(moments_i(:,:,:,:,izs ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 32, & ! Send to Down the first - moments_i(:,:,:,:,ize+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 32, & ! Recieve from Down the last+1 - comm0, status, ierr) - CALL mpi_sendrecv(moments_i(:,:,:,:,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 33, & ! Send to Down the first+1 - moments_i(:,:,:,:,ize+2,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 33, & ! Recieve from Down the last+2 - comm0, status, ierr) - ELSE ! still need to perform periodic boundary conditions - IF(SHEARED) THEN - DO iky = ikys,ikye - DO ikx = ikxs,ikxe - ikxBC = ikx_zBC_map(iky,ikx); - IF (ikxBC .NE. -1) THEN ! Exchanging the modes that have a periodic pair (a) - ! first-1 gets last - moments_i(:,:,iky,ikx,izs-1,updatetlevel) = moments_i(:,:,iky,ikxBC,ize ,updatetlevel) - ! first-2 gets last-1 - moments_i(:,:,iky,ikx,izs-2,updatetlevel) = moments_i(:,:,iky,ikxBC,ize-1,updatetlevel) - ! last+1 gets first - moments_i(:,:,iky,ikx,ize+1,updatetlevel) = moments_i(:,:,iky,ikxBC,izs ,updatetlevel) - ! last+2 gets first+1 - moments_i(:,:,iky,ikx,ize+2,updatetlevel) = moments_i(:,:,iky,ikxBC,izs+1,updatetlevel) - ELSE - moments_i(:,:,iky,ikx,izs-1,updatetlevel) = 0._dp - moments_i(:,:,iky,ikx,izs-2,updatetlevel) = 0._dp - moments_i(:,:,iky,ikx,ize+1,updatetlevel) = 0._dp - moments_i(:,:,iky,ikx,ize+2,updatetlevel) = 0._dp - ENDIF - ENDDO - ENDDO - ELSE ! No shear so simple periodic BC - ! first-1 gets last - moments_i(:,:,:,:,izs-1,updatetlevel) = moments_i(:,:,:,:,ize ,updatetlevel) - ! first-2 gets last-1 - moments_i(:,:,:,:,izs-2,updatetlevel) = moments_i(:,:,:,:,ize-1,updatetlevel) - ! last+1 gets first - moments_i(:,:,:,:,ize+1,updatetlevel) = moments_i(:,:,:,:,izs ,updatetlevel) - ! last+2 gets first+1 - moments_i(:,:,:,:,ize+2,updatetlevel) = moments_i(:,:,:,:,izs+1,updatetlevel) - ENDIF - ENDIF -END SUBROUTINE update_ghosts_z_i - -SUBROUTINE update_ghosts_z_phi - - IMPLICIT NONE - INTEGER :: ikxBC - CALL cpu_time(t1_ghost) + INTEGER :: ikxBC_L, ikxBC_R IF(Nz .GT. 1) THEN - CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) IF (num_procs_z .GT. 1) THEN - count = (ikye-ikys+1) * (ikxe-ikxs+1) + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + count = (ipge_i-ipgs_i+1)*(ijge_i-ijgs_i+1)*(ikye-ikys+1)*(ikxe-ikxs+1) !!!!!!!!!!! Send ghost to up neighbour !!!!!!!!!!!!!!!!!!!!!! ! Send the last local moment to fill the -1 neighbour ghost - CALL mpi_sendrecv(phi(:,:,ize ), count, MPI_DOUBLE_COMPLEX, nbr_U, 40, & ! Send to Up the last - phi(:,:,izs-1), count, MPI_DOUBLE_COMPLEX, nbr_D, 40, & ! Receive from Down the first-1 + CALL mpi_sendrecv(moments_i(:,:,:,:,ize ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 24, & ! Send to Up the last + buff_pjxy_zBC_i(:,:,:,:,-1), count, MPI_DOUBLE_COMPLEX, nbr_D, 24, & ! Recieve from Down the first-1 comm0, status, ierr) - CALL mpi_sendrecv(phi(:,:,ize-1), count, MPI_DOUBLE_COMPLEX, nbr_U, 41, & ! Send to Up the last-1 - phi(:,:,izs-2), count, MPI_DOUBLE_COMPLEX, nbr_D, 41, & ! Receive from Down the first-2 + CALL mpi_sendrecv(moments_i(:,:,:,:,ize-1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_U, 25, & ! Send to Up the last + buff_pjxy_zBC_i(:,:,:,:,-2), count, MPI_DOUBLE_COMPLEX, nbr_D, 25, & ! Recieve from Down the first-1 comm0, status, ierr) !!!!!!!!!!! Send ghost to down neighbour !!!!!!!!!!!!!!!!!!!!!! - CALL mpi_sendrecv(phi(:,:,izs ), count, MPI_DOUBLE_COMPLEX, nbr_D, 42, & ! Send to Down the first - phi(:,:,ize+1), count, MPI_DOUBLE_COMPLEX, nbr_U, 42, & ! Recieve from Up the last+1 + CALL mpi_sendrecv(moments_i(:,:,:,:,izs ,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 26, & ! Send to Up the last + buff_pjxy_zBC_i(:,:,:,:,+1), count, MPI_DOUBLE_COMPLEX, nbr_U, 26, & ! Recieve from Down the first-1 comm0, status, ierr) - CALL mpi_sendrecv(phi(:,:,izs+1), count, MPI_DOUBLE_COMPLEX, nbr_D, 43, & ! Send to Down the first+1 - phi(:,:,ize+2), count, MPI_DOUBLE_COMPLEX, nbr_U, 43, & ! Recieve from Up the last+2 + CALL mpi_sendrecv(moments_i(:,:,:,:,izs+1,updatetlevel), count, MPI_DOUBLE_COMPLEX, nbr_D, 27, & ! Send to Up the last + buff_pjxy_zBC_i(:,:,:,:,+2), count, MPI_DOUBLE_COMPLEX, nbr_U, 27, & ! Recieve from Down the first-1 comm0, status, ierr) - - ELSE ! still need to perform periodic boundary conditions - phi(:,:,izs-1) = phi(:,:,ize) - phi(:,:,izs-2) = phi(:,:,ize-1) - phi(:,:,ize+1) = phi(:,:,izs) - phi(:,:,ize+2) = phi(:,:,izs+1) - - IF(SHEARED) THEN - DO iky = ikys,ikye - DO ikx = ikxs,ikxe - ikxBC = ikx_zBC_map(iky,ikx); - IF (ikxBC .NE. -1) THEN ! Exchanging the modes that have a periodic pair (a) - ! first-1 gets last - phi(iky,ikx,izs-1) = phi(iky,ikxBC,ize ) - ! first-2 gets last-1 - phi(iky,ikx,izs-2) = phi(iky,ikxBC,ize-1) - ! last+1 gets first - phi(iky,ikx,ize+1) = phi(iky,ikxBC,izs ) - ! last+2 gets first+1 - phi(iky,ikx,ize+2) = phi(iky,ikxBC,izs+1) - ELSE - phi(iky,ikx,izs-1) = 0._dp - phi(iky,ikx,izs-2) = 0._dp - phi(iky,ikx,ize+1) = 0._dp - phi(iky,ikx,ize+2) = 0._dp - ENDIF - ENDDO - ENDDO - ELSE ! No shear so simple periodic BC - ! first-1 gets last - phi(:,:,izs-1) = phi(:,:,ize ) - ! first-2 gets last-1 - phi(:,:,izs-2) = phi(:,:,ize-1) - ! last+1 gets first - phi(:,:,ize+1) = phi(:,:,izs ) - ! last+2 gets first+1 - phi(:,:,ize+2) = phi(:,:,izs+1) - ENDIF + ELSE !No parallel (copy) + buff_pjxy_zBC_i(:,:,:,:,-1) = moments_i(:,:,:,:,ize ,updatetlevel) + buff_pjxy_zBC_i(:,:,:,:,-2) = moments_i(:,:,:,:,ize-1,updatetlevel) + buff_pjxy_zBC_i(:,:,:,:,+1) = moments_i(:,:,:,:,izs ,updatetlevel) + buff_pjxy_zBC_i(:,:,:,:,+2) = moments_i(:,:,:,:,izs+1,updatetlevel) ENDIF + DO iky = ikys,ikye + DO ikx = ikxs,ikxe + ikxBC_L = ikx_zBC_L(iky,ikx); + IF (ikxBC_L .NE. -99) THEN ! Exchanging the modes that have a periodic pair (a) + ! first-1 gets last + moments_i(:,:,iky,ikx,izs-1,updatetlevel) = buff_pjxy_zBC_i(:,:,iky,ikxBC_L,-1) + ! first-2 gets last-1 + moments_i(:,:,iky,ikx,izs-2,updatetlevel) = buff_pjxy_zBC_i(:,:,iky,ikxBC_L,-2) + ELSE + moments_i(:,:,iky,ikx,izs-1,updatetlevel) = 0._dp + moments_i(:,:,iky,ikx,izs-2,updatetlevel) = 0._dp + ENDIF + ikxBC_R = ikx_zBC_R(iky,ikx); + IF (ikxBC_R .NE. -99) THEN ! Exchanging the modes that have a periodic pair (a) + ! last+1 gets first + moments_i(:,:,iky,ikx,ize+1,updatetlevel) = buff_pjxy_zBC_i(:,:,iky,ikxBC_R,+1) + ! last+2 gets first+1 + moments_i(:,:,iky,ikx,ize+2,updatetlevel) = buff_pjxy_zBC_i(:,:,iky,ikxBC_R,+2) + ELSE + moments_i(:,:,iky,ikx,ize+1,updatetlevel) = 0._dp + moments_i(:,:,iky,ikx,ize+2,updatetlevel) = 0._dp + ENDIF + ENDDO + ENDDO + ENDIF +END SUBROUTINE update_ghosts_z_i + +SUBROUTINE update_ghosts_z_phi + USE parallel, ONLY : buff_xy_zBC + IMPLICIT NONE + INTEGER :: ikxBC_L, ikxBC_R + CALL cpu_time(t1_ghost) + IF(Nz .GT. 1) THEN + IF (num_procs_z .GT. 1) THEN + CALL MPI_BARRIER(MPI_COMM_WORLD,ierr) + count = (ikye-ikys+1) * (ikxe-ikxs+1) + !!!!!!!!!!! Send ghost to up neighbour !!!!!!!!!!!!!!!!!!!!!! + CALL mpi_sendrecv( phi(:,:,ize ), count, MPI_DOUBLE_COMPLEX, nbr_U, 30, & ! Send to Up the last + buff_xy_zBC(:,:,-1), count, MPI_DOUBLE_COMPLEX, nbr_D, 30, & ! Receive from Down the first-1 + comm0, status, ierr) + + CALL mpi_sendrecv( phi(:,:,ize-1), count, MPI_DOUBLE_COMPLEX, nbr_U, 31, & ! Send to Up the last + buff_xy_zBC(:,:,-2), count, MPI_DOUBLE_COMPLEX, nbr_D, 31, & ! Receive from Down the first-2 + comm0, status, ierr) + + !!!!!!!!!!! Send ghost to down neighbour !!!!!!!!!!!!!!!!!!!!!! + CALL mpi_sendrecv( phi(:,:,izs ), count, MPI_DOUBLE_COMPLEX, nbr_D, 32, & ! Send to Down the first + buff_xy_zBC(:,:,+1), count, MPI_DOUBLE_COMPLEX, nbr_U, 32, & ! Recieve from Up the last+1 + comm0, status, ierr) + + CALL mpi_sendrecv( phi(:,:,izs+1), count, MPI_DOUBLE_COMPLEX, nbr_D, 33, & ! Send to Down the first + buff_xy_zBC(:,:,+2), count, MPI_DOUBLE_COMPLEX, nbr_U, 33, & ! Recieve from Up the last+2 + comm0, status, ierr) + ELSE + buff_xy_zBC(:,:,-1) = phi(:,:,ize ) + buff_xy_zBC(:,:,-2) = phi(:,:,ize-1) + buff_xy_zBC(:,:,+1) = phi(:,:,izs ) + buff_xy_zBC(:,:,+2) = phi(:,:,izs+1) + ENDIF + DO iky = ikys,ikye + DO ikx = ikxs,ikxe + ikxBC_L = ikx_zBC_L(iky,ikx); + IF (ikxBC_L .NE. -99) THEN ! Exchanging the modes that have a periodic pair (a) + ! first-1 gets last + phi(iky,ikx,izs-1) = buff_xy_zBC(iky,ikxBC_L,-1) + ! first-2 gets last-1 + phi(iky,ikx,izs-2) = buff_xy_zBC(iky,ikxBC_L,-2) + ELSE + phi(iky,ikx,izs-1) = 0._dp + phi(iky,ikx,izs-2) = 0._dp + ENDIF + ikxBC_R = ikx_zBC_R(iky,ikx); + IF (ikxBC_R .NE. -99) THEN ! Exchanging the modes that have a periodic pair (a) + ! last+1 gets first + phi(iky,ikx,ize+1) = buff_xy_zBC(iky,ikxBC_R,+1) + ! last+2 gets first+1 + phi(iky,ikx,ize+2) = buff_xy_zBC(iky,ikxBC_R,+2) + ELSE + phi(iky,ikx,ize+1) = 0._dp + phi(iky,ikx,ize+2) = 0._dp + ENDIF + ENDDO + ENDDO ENDIF CALL cpu_time(t1_ghost) tc_ghost = tc_ghost + (t1_ghost - t0_ghost) END SUBROUTINE update_ghosts_z_phi + END MODULE ghosts diff --git a/src/grid_mod.F90 b/src/grid_mod.F90 index ed45fad1e2b78eec06e42b199050e7c32547daf4..2120042ff98ee876c620c840692ee206c1b7445e 100644 --- a/src/grid_mod.F90 +++ b/src/grid_mod.F90 @@ -82,7 +82,9 @@ MODULE grid LOGICAL, PUBLIC, PROTECTED :: contains_kx0 = .false. ! flag if the proc contains kx=0 index LOGICAL, PUBLIC, PROTECTED :: contains_ky0 = .false. ! flag if the proc contains ky=0 index LOGICAL, PUBLIC, PROTECTED :: contains_kymax = .false. ! flag if the proc contains kx=kxmax index - + LOGICAL, PUBLIC, PROTECTED :: contains_zmax = .false. ! flag if the proc contains z=pi-dz index + LOGICAL, PUBLIC, PROTECTED :: contains_zmin = .false. ! flag if the proc contains z=-pi index + LOGICAL, PUBLIC, PROTECTED :: SINGLE_KY = .false. ! to check if it is a single non 0 ky simulation ! Grid containing the polynomials degrees INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: parray_e, parray_e_full INTEGER, DIMENSION(:), ALLOCATABLE, PUBLIC :: parray_i, parray_i_full @@ -286,9 +288,9 @@ CONTAINS Nky = Ny/2+1 ! Defined only on positive kx since fields are real ! Grid spacings IF (Ny .EQ. 1) THEN - deltaky = 0._dp - ky_max = 0._dp - ky_min = 0._dp + deltaky = 2._dp*PI/Ly + ky_max = deltaky + ky_min = deltaky ELSE deltaky = 2._dp*PI/Ly ky_max = Nky*deltaky @@ -315,7 +317,13 @@ CONTAINS ENDDO ! Creating a grid ordered as dk*(0 1 2 3) DO iky = ikys,ikye - kyarray(iky) = REAL(iky-1,dp) * deltaky + IF(Ny .EQ. 1) THEN + kyarray(iky) = deltaky + kyarray_full(iky) = deltaky + SINGLE_KY = .TRUE. + ELSE + kyarray(iky) = REAL(iky-1,dp) * deltaky + ENDIF ! Finding kx=0 IF (kyarray(iky) .EQ. 0) THEN iky_0 = iky @@ -351,7 +359,7 @@ CONTAINS INTEGER :: i_, counter IF(shear .GT. 0._dp) THEN IF(my_id.EQ.0) write(*,*) 'Magnetic shear detected: set up sheared kx grid..' - Lx = Ly/(2._dp*pi*shear) + Lx = Ly/(2._dp*pi*shear*Npol) ENDIF Nkx = Nx; ! Local data @@ -361,7 +369,7 @@ CONTAINS local_nkx = ikxe - ikxs + 1 ALLOCATE(kxarray(ikxs:ikxe)) ALLOCATE(kxarray_full(1:Nkx)) - IF (Nx .EQ. 1) THEN ! "cancel" y dimension + IF (Nx .EQ. 1) THEN deltakx = 1._dp kxarray(1) = 0._dp ikx_0 = 1 @@ -419,7 +427,7 @@ CONTAINS USE model, ONLY: mu_z IMPLICIT NONE INTEGER :: i_, fid - REAL :: grid_shift, Lz + REAL :: grid_shift, Lz, zmax, zmin INTEGER :: ip, istart, iend, in total_nz = Nz ! Length of the flux tube (in ballooning angle) @@ -441,8 +449,11 @@ CONTAINS ! Build the full grids on process 0 to diagnose it without comm ALLOCATE(zarray_full(1:Nz)) IF (Nz .EQ. 1) Npol = 0 - DO iz = 1,total_nz - zarray_full(iz) = REAL(iz-1,dp)*deltaz - PI*REAL(Npol,dp) + zmax = 0; zmin = 0; + DO iz = 1,total_nz ! z in [-pi pi-dz] x Npol + zarray_full(iz) = REAL(iz-1,dp)*deltaz - Lz/2._dp + IF(zarray_full(iz) .GT. zmax) zmax = zarray_full(iz) + IF(zarray_full(iz) .LT. zmin) zmin = zarray_full(iz) END DO !! Parallel data distribution ! Local data distribution @@ -484,6 +495,10 @@ CONTAINS zarray(iz,1) = zarray_full(iz) + grid_shift ENDIF ENDDO + IF(abs(zarray(izs,0) - zmin) .LT. EPSILON(zmin)) & + contains_zmin = .TRUE. + IF(abs(zarray(ize,0) - zmax) .LT. EPSILON(zmax)) & + contains_zmax = .TRUE. ! Weitghs for Simpson rule ALLOCATE(zweights_SR(izs:ize)) DO iz = izs,ize diff --git a/src/parallel_mod.F90 b/src/parallel_mod.F90 index 96d8c27749b423139c06c832d946f945d7885917..7cef88194ea3cb91b116f629f01f082fe0881025 100644 --- a/src/parallel_mod.F90 +++ b/src/parallel_mod.F90 @@ -1,11 +1,8 @@ MODULE parallel USE basic - USE grid, ONLY: Nkx,Nky,Nz, ikys,ikye, izs,ize, local_nky, local_nz, & - local_np_e, local_np_i, Np_e, Np_i, Nj_e, Nj_i, & - pmaxi, pmaxe, ips_e, ipe_e, ips_i, ipe_i, & - jmaxi, jmaxe, ijs_e, ije_e, ijs_i, ije_i, & - rcv_p_e, rcv_p_i, dsp_p_e, dsp_p_i + USE grid use prec_const + USE model, ONLY: KIN_E IMPLICIT NONE ! recieve and displacement counts for gatherv INTEGER, DIMENSION(:), ALLOCATABLE :: rcv_y, dsp_y, rcv_zy, dsp_zy @@ -16,6 +13,11 @@ MODULE parallel INTEGER, DIMENSION(:), ALLOCATABLE :: rcv_yp_i, dsp_yp_i INTEGER, DIMENSION(:), ALLOCATABLE :: rcv_zyp_i, dsp_zyp_i + ! Various buffers used + COMPLEX(dp), ALLOCATABLE, DIMENSION(:,:,:) :: buff_xy_zBC + COMPLEX(dp), ALLOCATABLE, DIMENSION(:,:,:,:,:) :: buff_pjxy_zBC_e + COMPLEX(dp), ALLOCATABLE, DIMENSION(:,:,:,:,:) :: buff_pjxy_zBC_i + PUBLIC :: manual_0D_bcast, manual_3D_bcast, init_parallel_var, & gather_xyz, gather_pjz_i, gather_pjxyz_e, gather_pjxyz_i @@ -115,6 +117,12 @@ CONTAINS dsp_zyp_e(i_) =dsp_zyp_e(i_-1) + rcv_zyp_e(i_-1) END DO + !! Allocate some buffers + ALLOCATE(buff_xy_zBC(ikys:ikye,ikxs:ikxe,-2:2)) + IF(KIN_E) & + ALLOCATE(buff_pjxy_zBC_e(ipgs_e:ipge_e,ijgs_e:ijge_e,ikys:ikye,ikxs:ikxe,-2:2)) + ALLOCATE(buff_pjxy_zBC_i(ipgs_i:ipge_i,ijgs_i:ijge_i,ikys:ikye,ikxs:ikxe,-2:2)) + END SUBROUTINE init_parallel_var !!!!! Gather a field in spatial coordinates on rank 0 !!!!!