123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972 |
- MODULE lbcnfd
- !!======================================================================
- !! *** MODULE lbcnfd ***
- !! Ocean : north fold boundary conditions
- !!======================================================================
- !! History : 3.2 ! 2009-03 (R. Benshila) Original code
- !! 3.5 ! 2013-07 (I. Epicoco, S. Mocavero - CMCC) MPP optimization
- !!----------------------------------------------------------------------
- !!----------------------------------------------------------------------
- !! lbc_nfd : generic interface for lbc_nfd_3d and lbc_nfd_2d routines
- !! lbc_nfd_3d : lateral boundary condition: North fold treatment for a 3D arrays (lbc_nfd)
- !! lbc_nfd_2d : lateral boundary condition: North fold treatment for a 2D arrays (lbc_nfd)
- !! mpp_lbc_nfd_3d : North fold treatment for a 3D arrays optimized for MPP
- !! mpp_lbc_nfd_2d : North fold treatment for a 2D arrays optimized for MPP
- !!----------------------------------------------------------------------
- USE dom_oce ! ocean space and time domain
- USE in_out_manager ! I/O manager
- IMPLICIT NONE
- PRIVATE
- INTERFACE lbc_nfd
- MODULE PROCEDURE lbc_nfd_3d, lbc_nfd_2d
- END INTERFACE
- PUBLIC lbc_nfd ! north fold conditions
- INTERFACE mpp_lbc_nfd
- MODULE PROCEDURE mpp_lbc_nfd_3d, mpp_lbc_nfd_2d
- END INTERFACE
- PUBLIC mpp_lbc_nfd ! north fold conditions in parallel case
- INTEGER, PUBLIC, PARAMETER :: jpmaxngh = 3
- INTEGER, PUBLIC :: nsndto, nfsloop, nfeloop
- INTEGER, PUBLIC, DIMENSION (jpmaxngh) :: isendto ! processes to which communicate
- !!----------------------------------------------------------------------
- !! NEMO/OPA 3.3 , NEMO Consortium (2010)
- !! $Id: lbcnfd.F90 4686 2014-06-24 11:03:50Z epico $
- !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
- !!----------------------------------------------------------------------
- CONTAINS
- SUBROUTINE lbc_nfd_3d( pt3d, cd_type, psgn )
- !!----------------------------------------------------------------------
- !! *** routine lbc_nfd_3d ***
- !!
- !! ** Purpose : 3D lateral boundary condition : North fold treatment
- !! without processor exchanges.
- !!
- !! ** Method :
- !!
- !! ** Action : pt3d with updated values along the north fold
- !!----------------------------------------------------------------------
- CHARACTER(len=1) , INTENT(in ) :: cd_type ! define the nature of ptab array grid-points
- ! ! = T , U , V , F , W points
- REAL(wp) , INTENT(in ) :: psgn ! control of the sign change
- ! ! = -1. , the sign is changed if north fold boundary
- ! ! = 1. , the sign is kept if north fold boundary
- REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: pt3d ! 3D array on which the boundary condition is applied
- !
- INTEGER :: ji, jk
- INTEGER :: ijt, iju, ijpj, ijpjm1
- !!----------------------------------------------------------------------
- SELECT CASE ( jpni )
- CASE ( 1 ) ; ijpj = nlcj ! 1 proc only along the i-direction
- CASE DEFAULT ; ijpj = 4 ! several proc along the i-direction
- END SELECT
- ijpjm1 = ijpj-1
- DO jk = 1, jpk
- !
- SELECT CASE ( npolj )
- !
- CASE ( 3 , 4 ) ! * North fold T-point pivot
- !
- SELECT CASE ( cd_type )
- CASE ( 'T' , 'W' ) ! T-, W-point
- DO ji = 2, jpiglo
- ijt = jpiglo-ji+2
- pt3d(ji,ijpj,jk) = psgn * pt3d(ijt,ijpj-2,jk)
- END DO
- pt3d(1,ijpj,jk) = psgn * pt3d(3,ijpj-2,jk)
- DO ji = jpiglo/2+1, jpiglo
- ijt = jpiglo-ji+2
- pt3d(ji,ijpjm1,jk) = psgn * pt3d(ijt,ijpjm1,jk)
- END DO
- CASE ( 'U' ) ! U-point
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji+1
- pt3d(ji,ijpj,jk) = psgn * pt3d(iju,ijpj-2,jk)
- END DO
- pt3d( 1 ,ijpj,jk) = psgn * pt3d( 2 ,ijpj-2,jk)
- pt3d(jpiglo,ijpj,jk) = psgn * pt3d(jpiglo-1,ijpj-2,jk)
- DO ji = jpiglo/2, jpiglo-1
- iju = jpiglo-ji+1
- pt3d(ji,ijpjm1,jk) = psgn * pt3d(iju,ijpjm1,jk)
- END DO
- CASE ( 'V' ) ! V-point
- DO ji = 2, jpiglo
- ijt = jpiglo-ji+2
- pt3d(ji,ijpj-1,jk) = psgn * pt3d(ijt,ijpj-2,jk)
- pt3d(ji,ijpj ,jk) = psgn * pt3d(ijt,ijpj-3,jk)
- END DO
- pt3d(1,ijpj,jk) = psgn * pt3d(3,ijpj-3,jk)
- CASE ( 'F' ) ! F-point
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji+1
- pt3d(ji,ijpj-1,jk) = psgn * pt3d(iju,ijpj-2,jk)
- pt3d(ji,ijpj ,jk) = psgn * pt3d(iju,ijpj-3,jk)
- END DO
- pt3d( 1 ,ijpj,jk) = psgn * pt3d( 2 ,ijpj-3,jk)
- pt3d(jpiglo,ijpj,jk) = psgn * pt3d(jpiglo-1,ijpj-3,jk)
- END SELECT
- !
- CASE ( 5 , 6 ) ! * North fold F-point pivot
- !
- SELECT CASE ( cd_type )
- CASE ( 'T' , 'W' ) ! T-, W-point
- DO ji = 1, jpiglo
- ijt = jpiglo-ji+1
- pt3d(ji,ijpj,jk) = psgn * pt3d(ijt,ijpj-1,jk)
- END DO
- CASE ( 'U' ) ! U-point
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji
- pt3d(ji,ijpj,jk) = psgn * pt3d(iju,ijpj-1,jk)
- END DO
- pt3d(jpiglo,ijpj,jk) = psgn * pt3d(1,ijpj-1,jk)
- CASE ( 'V' ) ! V-point
- DO ji = 1, jpiglo
- ijt = jpiglo-ji+1
- pt3d(ji,ijpj,jk) = psgn * pt3d(ijt,ijpj-2,jk)
- END DO
- DO ji = jpiglo/2+1, jpiglo
- ijt = jpiglo-ji+1
- pt3d(ji,ijpjm1,jk) = psgn * pt3d(ijt,ijpjm1,jk)
- END DO
- CASE ( 'F' ) ! F-point
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji
- pt3d(ji,ijpj ,jk) = psgn * pt3d(iju,ijpj-2,jk)
- END DO
- pt3d(jpiglo,ijpj,jk) = psgn * pt3d(1,ijpj-2,jk)
- DO ji = jpiglo/2+1, jpiglo-1
- iju = jpiglo-ji
- pt3d(ji,ijpjm1,jk) = psgn * pt3d(iju,ijpjm1,jk)
- END DO
- END SELECT
- !
- CASE DEFAULT ! * closed : the code probably never go through
- !
- SELECT CASE ( cd_type)
- CASE ( 'T' , 'U' , 'V' , 'W' ) ! T-, U-, V-, W-points
- pt3d(:, 1 ,jk) = 0.e0
- pt3d(:,ijpj,jk) = 0.e0
- CASE ( 'F' ) ! F-point
- pt3d(:,ijpj,jk) = 0.e0
- END SELECT
- !
- END SELECT ! npolj
- !
- END DO
- !
- END SUBROUTINE lbc_nfd_3d
- SUBROUTINE lbc_nfd_2d( pt2d, cd_type, psgn, pr2dj )
- !!----------------------------------------------------------------------
- !! *** routine lbc_nfd_2d ***
- !!
- !! ** Purpose : 2D lateral boundary condition : North fold treatment
- !! without processor exchanges.
- !!
- !! ** Method :
- !!
- !! ** Action : pt2d with updated values along the north fold
- !!----------------------------------------------------------------------
- CHARACTER(len=1) , INTENT(in ) :: cd_type ! define the nature of ptab array grid-points
- ! ! = T , U , V , F , W points
- REAL(wp) , INTENT(in ) :: psgn ! control of the sign change
- ! ! = -1. , the sign is changed if north fold boundary
- ! ! = 1. , the sign is kept if north fold boundary
- REAL(wp), DIMENSION(:,:), INTENT(inout) :: pt2d ! 2D array on which the boundary condition is applied
- INTEGER , OPTIONAL , INTENT(in ) :: pr2dj ! number of additional halos
- !
- INTEGER :: ji, jl, ipr2dj
- INTEGER :: ijt, iju, ijpj, ijpjm1
- !!----------------------------------------------------------------------
- SELECT CASE ( jpni )
- CASE ( 1 ) ; ijpj = nlcj ! 1 proc only along the i-direction
- CASE DEFAULT ; ijpj = 4 ! several proc along the i-direction
- END SELECT
- !
- IF( PRESENT(pr2dj) ) THEN ! use of additional halos
- ipr2dj = pr2dj
- IF( jpni > 1 ) ijpj = ijpj + ipr2dj
- ELSE
- ipr2dj = 0
- ENDIF
- !
- ijpjm1 = ijpj-1
- SELECT CASE ( npolj )
- !
- CASE ( 3, 4 ) ! * North fold T-point pivot
- !
- SELECT CASE ( cd_type )
- !
- CASE ( 'T' , 'W' ) ! T- , W-points
- DO jl = 0, ipr2dj
- DO ji = 2, jpiglo
- ijt=jpiglo-ji+2
- pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-2-jl)
- END DO
- END DO
- pt2d(1,ijpj) = psgn * pt2d(3,ijpj-2)
- DO ji = jpiglo/2+1, jpiglo
- ijt=jpiglo-ji+2
- pt2d(ji,ijpj-1) = psgn * pt2d(ijt,ijpj-1)
- END DO
- CASE ( 'U' ) ! U-point
- DO jl = 0, ipr2dj
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji+1
- pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-2-jl)
- END DO
- END DO
- pt2d( 1 ,ijpj ) = psgn * pt2d( 2 ,ijpj-2)
- pt2d(jpiglo,ijpj ) = psgn * pt2d(jpiglo-1,ijpj-2)
- pt2d(1 ,ijpj-1) = psgn * pt2d(jpiglo ,ijpj-1)
- DO ji = jpiglo/2, jpiglo-1
- iju = jpiglo-ji+1
- pt2d(ji,ijpjm1) = psgn * pt2d(iju,ijpjm1)
- END DO
- CASE ( 'V' ) ! V-point
- DO jl = -1, ipr2dj
- DO ji = 2, jpiglo
- ijt = jpiglo-ji+2
- pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-3-jl)
- END DO
- END DO
- pt2d( 1 ,ijpj) = psgn * pt2d( 3 ,ijpj-3)
- CASE ( 'F' ) ! F-point
- DO jl = -1, ipr2dj
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji+1
- pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-3-jl)
- END DO
- END DO
- pt2d( 1 ,ijpj) = psgn * pt2d( 2 ,ijpj-3)
- pt2d(jpiglo,ijpj) = psgn * pt2d(jpiglo-1,ijpj-3)
- pt2d(jpiglo,ijpj-1) = psgn * pt2d(jpiglo-1,ijpj-2)
- pt2d( 1 ,ijpj-1) = psgn * pt2d( 2 ,ijpj-2)
- CASE ( 'I' ) ! ice U-V point (I-point)
- DO jl = 0, ipr2dj
- pt2d(2,ijpj+jl) = psgn * pt2d(3,ijpj-1+jl)
- DO ji = 3, jpiglo
- iju = jpiglo - ji + 3
- pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
- END DO
- END DO
- CASE ( 'J' ) ! first ice U-V point
- DO jl =0, ipr2dj
- pt2d(2,ijpj+jl) = psgn * pt2d(3,ijpj-1+jl)
- DO ji = 3, jpiglo
- iju = jpiglo - ji + 3
- pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
- END DO
- END DO
- CASE ( 'K' ) ! second ice U-V point
- DO jl =0, ipr2dj
- pt2d(2,ijpj+jl) = psgn * pt2d(3,ijpj-1+jl)
- DO ji = 3, jpiglo
- iju = jpiglo - ji + 3
- pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
- END DO
- END DO
- END SELECT
- !
- CASE ( 5, 6 ) ! * North fold F-point pivot
- !
- SELECT CASE ( cd_type )
- CASE ( 'T' , 'W' ) ! T-, W-point
- DO jl = 0, ipr2dj
- DO ji = 1, jpiglo
- ijt = jpiglo-ji+1
- pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-1-jl)
- END DO
- END DO
- CASE ( 'U' ) ! U-point
- DO jl = 0, ipr2dj
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji
- pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-1-jl)
- END DO
- END DO
- pt2d(jpiglo,ijpj) = psgn * pt2d(1,ijpj-1)
- CASE ( 'V' ) ! V-point
- DO jl = 0, ipr2dj
- DO ji = 1, jpiglo
- ijt = jpiglo-ji+1
- pt2d(ji,ijpj+jl) = psgn * pt2d(ijt,ijpj-2-jl)
- END DO
- END DO
- DO ji = jpiglo/2+1, jpiglo
- ijt = jpiglo-ji+1
- pt2d(ji,ijpjm1) = psgn * pt2d(ijt,ijpjm1)
- END DO
- CASE ( 'F' ) ! F-point
- DO jl = 0, ipr2dj
- DO ji = 1, jpiglo-1
- iju = jpiglo-ji
- pt2d(ji,ijpj+jl) = psgn * pt2d(iju,ijpj-2-jl)
- END DO
- END DO
- pt2d(jpiglo,ijpj) = psgn * pt2d(1,ijpj-2)
- DO ji = jpiglo/2+1, jpiglo-1
- iju = jpiglo-ji
- pt2d(ji,ijpjm1) = psgn * pt2d(iju,ijpjm1)
- END DO
- CASE ( 'I' ) ! ice U-V point (I-point)
- pt2d( 2 ,ijpj:ijpj+ipr2dj) = 0.e0
- DO jl = 0, ipr2dj
- DO ji = 2 , jpiglo-1
- ijt = jpiglo - ji + 2
- pt2d(ji,ijpj+jl)= 0.5 * ( pt2d(ji,ijpj-1-jl) + psgn * pt2d(ijt,ijpj-1-jl) )
- END DO
- END DO
- CASE ( 'J' ) ! first ice U-V point
- pt2d( 2 ,ijpj:ijpj+ipr2dj) = 0.e0
- DO jl = 0, ipr2dj
- DO ji = 2 , jpiglo-1
- ijt = jpiglo - ji + 2
- pt2d(ji,ijpj+jl)= pt2d(ji,ijpj-1-jl)
- END DO
- END DO
- CASE ( 'K' ) ! second ice U-V point
- pt2d( 2 ,ijpj:ijpj+ipr2dj) = 0.e0
- DO jl = 0, ipr2dj
- DO ji = 2 , jpiglo-1
- ijt = jpiglo - ji + 2
- pt2d(ji,ijpj+jl)= pt2d(ijt,ijpj-1-jl)
- END DO
- END DO
- END SELECT
- !
- CASE DEFAULT ! * closed : the code probably never go through
- !
- SELECT CASE ( cd_type)
- CASE ( 'T' , 'U' , 'V' , 'W' ) ! T-, U-, V-, W-points
- pt2d(:, 1:1-ipr2dj ) = 0.e0
- pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
- CASE ( 'F' ) ! F-point
- pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
- CASE ( 'I' ) ! ice U-V point
- pt2d(:, 1:1-ipr2dj ) = 0.e0
- pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
- CASE ( 'J' ) ! first ice U-V point
- pt2d(:, 1:1-ipr2dj ) = 0.e0
- pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
- CASE ( 'K' ) ! second ice U-V point
- pt2d(:, 1:1-ipr2dj ) = 0.e0
- pt2d(:,ijpj:ijpj+ipr2dj) = 0.e0
- END SELECT
- !
- END SELECT
- !
- END SUBROUTINE lbc_nfd_2d
- SUBROUTINE mpp_lbc_nfd_3d( pt3dl, pt3dr, cd_type, psgn )
- !!----------------------------------------------------------------------
- !! *** routine mpp_lbc_nfd_3d ***
- !!
- !! ** Purpose : 3D lateral boundary condition : North fold treatment
- !! without processor exchanges.
- !!
- !! ** Method :
- !!
- !! ** Action : pt3d with updated values along the north fold
- !!----------------------------------------------------------------------
- CHARACTER(len=1) , INTENT(in ) :: cd_type ! define the nature of ptab array grid-points
- ! ! = T , U , V , F , W points
- REAL(wp) , INTENT(in ) :: psgn ! control of the sign change
- ! ! = -1. , the sign is changed if north fold boundary
- ! ! = 1. , the sign is kept if north fold boundary
- REAL(wp), DIMENSION(:,:,:), INTENT(inout) :: pt3dl ! 3D array on which the boundary condition is applied
- REAL(wp), DIMENSION(:,:,:), INTENT(in) :: pt3dr ! 3D array on which the boundary condition is applied
- !
- INTEGER :: ji, jk
- INTEGER :: ijt, iju, ijpj, ijpjm1, ijta, ijua, jia, startloop, endloop
- !!----------------------------------------------------------------------
- SELECT CASE ( jpni )
- CASE ( 1 ) ; ijpj = nlcj ! 1 proc only along the i-direction
- CASE DEFAULT ; ijpj = 4 ! several proc along the i-direction
- END SELECT
- ijpjm1 = ijpj-1
- !
- SELECT CASE ( npolj )
- !
- CASE ( 3 , 4 ) ! * North fold T-point pivot
- !
- SELECT CASE ( cd_type )
- CASE ( 'T' , 'W' ) ! T-, W-point
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 2
- ENDIF
- DO jk = 1, jpk
- DO ji = startloop, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- pt3dl(ji,ijpj,jk) = psgn * pt3dr(ijt,ijpj-2,jk)
- END DO
- IF(nimpp .eq. 1) THEN
- pt3dl(1,ijpj,jk) = psgn * pt3dl(3,ijpj-2,jk)
- ENDIF
- END DO
- IF(nimpp .ge. (jpiglo/2+1)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
- startloop = jpiglo/2+1 - nimpp + 1
- ELSE
- startloop = nlci + 1
- ENDIF
- IF(startloop .le. nlci) THEN
- DO jk = 1, jpk
- DO ji = startloop, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- jia = ji + nimpp - 1
- ijta = jpiglo - jia + 2
- IF((ijta .ge. (startloop + nimpp - 1)) .and. (ijta .lt. jia)) THEN
- pt3dl(ji,ijpjm1,jk) = psgn * pt3dl(ijta-nimpp+1,ijpjm1,jk)
- ELSE
- pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(ijt,ijpjm1,jk)
- ENDIF
- END DO
- END DO
- ENDIF
- CASE ( 'U' ) ! U-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO jk = 1, jpk
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt3dl(ji,ijpj,jk) = psgn * pt3dr(iju,ijpj-2,jk)
- END DO
- IF(nimpp .eq. 1) THEN
- pt3dl( 1 ,ijpj,jk) = psgn * pt3dl( 2 ,ijpj-2,jk)
- ENDIF
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt3dl(nlci,ijpj,jk) = psgn * pt3dl(nlci-1,ijpj-2,jk)
- ENDIF
- END DO
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- IF(nimpp .ge. (jpiglo/2)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2)) .AND. (nimpp .lt. (jpiglo/2))) THEN
- startloop = jpiglo/2 - nimpp + 1
- ELSE
- startloop = endloop + 1
- ENDIF
- IF (startloop .le. endloop) THEN
- DO jk = 1, jpk
- DO ji = startloop, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- jia = ji + nimpp - 1
- ijua = jpiglo - jia + 1
- IF((ijua .ge. (startloop + nimpp - 1)) .and. (ijua .lt. jia)) THEN
- pt3dl(ji,ijpjm1,jk) = psgn * pt3dl(ijua-nimpp+1,ijpjm1,jk)
- ELSE
- pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(iju,ijpjm1,jk)
- ENDIF
- END DO
- END DO
- ENDIF
- CASE ( 'V' ) ! V-point
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 2
- ENDIF
- DO jk = 1, jpk
- DO ji = startloop, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- pt3dl(ji,ijpj-1,jk) = psgn * pt3dr(ijt,ijpj-2,jk)
- pt3dl(ji,ijpj ,jk) = psgn * pt3dr(ijt,ijpj-3,jk)
- END DO
- IF(nimpp .eq. 1) THEN
- pt3dl(1,ijpj,jk) = psgn * pt3dl(3,ijpj-3,jk)
- ENDIF
- END DO
- CASE ( 'F' ) ! F-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO jk = 1, jpk
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt3dl(ji,ijpj-1,jk) = psgn * pt3dr(iju,ijpj-2,jk)
- pt3dl(ji,ijpj ,jk) = psgn * pt3dr(iju,ijpj-3,jk)
- END DO
- IF(nimpp .eq. 1) THEN
- pt3dl( 1 ,ijpj,jk) = psgn * pt3dl( 2 ,ijpj-3,jk)
- ENDIF
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt3dl(nlci,ijpj,jk) = psgn * pt3dl(nlci-1,ijpj-3,jk)
- ENDIF
- END DO
- END SELECT
- !
- CASE ( 5 , 6 ) ! * North fold F-point pivot
- !
- SELECT CASE ( cd_type )
- CASE ( 'T' , 'W' ) ! T-, W-point
- DO jk = 1, jpk
- DO ji = 1, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt3dl(ji,ijpj,jk) = psgn * pt3dr(ijt,ijpj-1,jk)
- END DO
- END DO
- CASE ( 'U' ) ! U-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO jk = 1, jpk
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
- pt3dl(ji,ijpj,jk) = psgn * pt3dr(iju,ijpj-1,jk)
- END DO
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt3dl(nlci,ijpj,jk) = psgn * pt3dr(1,ijpj-1,jk)
- ENDIF
- END DO
- CASE ( 'V' ) ! V-point
- DO jk = 1, jpk
- DO ji = 1, nlci
- ijt = jpiglo - ji- nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt3dl(ji,ijpj,jk) = psgn * pt3dr(ijt,ijpj-2,jk)
- END DO
- END DO
- IF(nimpp .ge. (jpiglo/2+1)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
- startloop = jpiglo/2+1 - nimpp + 1
- ELSE
- startloop = nlci + 1
- ENDIF
- IF(startloop .le. nlci) THEN
- DO jk = 1, jpk
- DO ji = startloop, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(ijt,ijpjm1,jk)
- END DO
- END DO
- ENDIF
- CASE ( 'F' ) ! F-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO jk = 1, jpk
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
- pt3dl(ji,ijpj ,jk) = psgn * pt3dr(iju,ijpj-2,jk)
- END DO
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt3dl(nlci,ijpj,jk) = psgn * pt3dr(1,ijpj-2,jk)
- ENDIF
- END DO
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- IF(nimpp .ge. (jpiglo/2+1)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
- startloop = jpiglo/2+1 - nimpp + 1
- ELSE
- startloop = endloop + 1
- ENDIF
- IF (startloop .le. endloop) THEN
- DO jk = 1, jpk
- DO ji = startloop, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
- pt3dl(ji,ijpjm1,jk) = psgn * pt3dr(iju,ijpjm1,jk)
- END DO
- END DO
- ENDIF
- END SELECT
- CASE DEFAULT ! * closed : the code probably never go through
- !
- SELECT CASE ( cd_type)
- CASE ( 'T' , 'U' , 'V' , 'W' ) ! T-, U-, V-, W-points
- pt3dl(:, 1 ,jk) = 0.e0
- pt3dl(:,ijpj,jk) = 0.e0
- CASE ( 'F' ) ! F-point
- pt3dl(:,ijpj,jk) = 0.e0
- END SELECT
- !
- END SELECT ! npolj
- !
- !
- END SUBROUTINE mpp_lbc_nfd_3d
- SUBROUTINE mpp_lbc_nfd_2d( pt2dl, pt2dr, cd_type, psgn )
- !!----------------------------------------------------------------------
- !! *** routine mpp_lbc_nfd_2d ***
- !!
- !! ** Purpose : 2D lateral boundary condition : North fold treatment
- !! without processor exchanges.
- !!
- !! ** Method :
- !!
- !! ** Action : pt2d with updated values along the north fold
- !!----------------------------------------------------------------------
- CHARACTER(len=1) , INTENT(in ) :: cd_type ! define the nature of ptab array grid-points
- ! ! = T , U , V , F , W points
- REAL(wp) , INTENT(in ) :: psgn ! control of the sign change
- ! ! = -1. , the sign is changed if north fold boundary
- ! ! = 1. , the sign is kept if north fold boundary
- REAL(wp), DIMENSION(:,:), INTENT(inout) :: pt2dl ! 2D array on which the boundary condition is applied
- REAL(wp), DIMENSION(:,:), INTENT(in) :: pt2dr ! 2D array on which the boundary condition is applied
- !
- INTEGER :: ji
- INTEGER :: ijt, iju, ijpj, ijpjm1, ijta, ijua, jia, startloop, endloop
- !!----------------------------------------------------------------------
- SELECT CASE ( jpni )
- CASE ( 1 ) ; ijpj = nlcj ! 1 proc only along the i-direction
- CASE DEFAULT ; ijpj = 4 ! several proc along the i-direction
- END SELECT
- !
- ijpjm1 = ijpj-1
- SELECT CASE ( npolj )
- !
- CASE ( 3, 4 ) ! * North fold T-point pivot
- !
- SELECT CASE ( cd_type )
- !
- CASE ( 'T' , 'W' ) ! T- , W-points
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 2
- ENDIF
- DO ji = startloop, nlci
- ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1-1)
- END DO
- IF (nimpp .eq. 1) THEN
- pt2dl(1,ijpj) = psgn * pt2dl(3,ijpj-2)
- ENDIF
- IF(nimpp .ge. (jpiglo/2+1)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
- startloop = jpiglo/2+1 - nimpp + 1
- ELSE
- startloop = nlci + 1
- ENDIF
- DO ji = startloop, nlci
- ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- jia = ji + nimpp - 1
- ijta = jpiglo - jia + 2
- IF((ijta .ge. (startloop + nimpp - 1)) .and. (ijta .lt. jia)) THEN
- pt2dl(ji,ijpjm1) = psgn * pt2dl(ijta-nimpp+1,ijpjm1)
- ELSE
- pt2dl(ji,ijpjm1) = psgn * pt2dr(ijt,ijpjm1)
- ENDIF
- END DO
- CASE ( 'U' ) ! U-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1-1)
- END DO
- IF (nimpp .eq. 1) THEN
- pt2dl( 1 ,ijpj ) = psgn * pt2dl( 2 ,ijpj-2)
- pt2dl(1 ,ijpj-1) = psgn * pt2dr(jpiglo - nfiimpp(isendto(1), jpnj) + 1, ijpj-1)
- ENDIF
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt2dl(nlci,ijpj ) = psgn * pt2dl(nlci-1,ijpj-2)
- ENDIF
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- IF(nimpp .ge. (jpiglo/2)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2)) .AND. (nimpp .lt. (jpiglo/2))) THEN
- startloop = jpiglo/2 - nimpp + 1
- ELSE
- startloop = endloop + 1
- ENDIF
- DO ji = startloop, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- jia = ji + nimpp - 1
- ijua = jpiglo - jia + 1
- IF((ijua .ge. (startloop + nimpp - 1)) .and. (ijua .lt. jia)) THEN
- pt2dl(ji,ijpjm1) = psgn * pt2dl(ijua-nimpp+1,ijpjm1)
- ELSE
- pt2dl(ji,ijpjm1) = psgn * pt2dr(iju,ijpjm1)
- ENDIF
- END DO
- CASE ( 'V' ) ! V-point
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 2
- ENDIF
- DO ji = startloop, nlci
- ijt=jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- pt2dl(ji,ijpjm1) = psgn * pt2dr(ijt,ijpjm1-1)
- pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1-2)
- END DO
- IF (nimpp .eq. 1) THEN
- pt2dl( 1 ,ijpj) = psgn * pt2dl( 3 ,ijpj-3)
- ENDIF
- CASE ( 'F' ) ! F-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt2dl(ji,ijpjm1) = psgn * pt2dr(iju,ijpjm1-1)
- pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1-2)
- END DO
- IF (nimpp .eq. 1) THEN
- pt2dl( 1 ,ijpj) = psgn * pt2dl( 2 ,ijpj-3)
- pt2dl( 1 ,ijpj-1) = psgn * pt2dl( 2 ,ijpj-2)
- ENDIF
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt2dl(nlci,ijpj) = psgn * pt2dl(nlci-1,ijpj-3)
- pt2dl(nlci,ijpj-1) = psgn * pt2dl(nlci-1,ijpj-2)
- ENDIF
- CASE ( 'I' ) ! ice U-V point (I-point)
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 3
- pt2dl(2,ijpj) = psgn * pt2dr(3,ijpjm1)
- ENDIF
- DO ji = startloop, nlci
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 5
- pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
- END DO
- CASE ( 'J' ) ! first ice U-V point
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 3
- pt2dl(2,ijpj) = psgn * pt2dl(3,ijpjm1)
- ENDIF
- DO ji = startloop, nlci
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 5
- pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
- END DO
- CASE ( 'K' ) ! second ice U-V point
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 3
- pt2dl(2,ijpj) = psgn * pt2dl(3,ijpjm1)
- ENDIF
- DO ji = startloop, nlci
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 5
- pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
- END DO
- END SELECT
- !
- CASE ( 5, 6 ) ! * North fold F-point pivot
- !
- SELECT CASE ( cd_type )
- CASE ( 'T' , 'W' ) ! T-, W-point
- DO ji = 1, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1)
- END DO
- CASE ( 'U' ) ! U-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
- pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1)
- END DO
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt2dl(nlci,ijpj) = psgn * pt2dr(1,ijpj-1)
- ENDIF
- CASE ( 'V' ) ! V-point
- DO ji = 1, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt2dl(ji,ijpj) = psgn * pt2dr(ijt,ijpjm1-1)
- END DO
- IF(nimpp .ge. (jpiglo/2+1)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
- startloop = jpiglo/2+1 - nimpp + 1
- ELSE
- startloop = nlci + 1
- ENDIF
- DO ji = startloop, nlci
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 3
- pt2dl(ji,ijpjm1) = psgn * pt2dr(ijt,ijpjm1)
- END DO
- CASE ( 'F' ) ! F-point
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO ji = 1, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
- pt2dl(ji,ijpj) = psgn * pt2dr(iju,ijpjm1-1)
- END DO
- IF((nimpp + nlci - 1) .eq. jpiglo) THEN
- pt2dl(nlci,ijpj) = psgn * pt2dr(1,ijpj-2)
- ENDIF
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- IF(nimpp .ge. (jpiglo/2+1)) THEN
- startloop = 1
- ELSEIF(((nimpp+nlci-1) .ge. (jpiglo/2+1)) .AND. (nimpp .lt. (jpiglo/2+1))) THEN
- startloop = jpiglo/2+1 - nimpp + 1
- ELSE
- startloop = endloop + 1
- ENDIF
- DO ji = startloop, endloop
- iju = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 2
- pt2dl(ji,ijpjm1) = psgn * pt2dr(iju,ijpjm1)
- END DO
- CASE ( 'I' ) ! ice U-V point (I-point)
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 2
- ENDIF
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO ji = startloop , endloop
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- pt2dl(ji,ijpj)= 0.5 * (pt2dl(ji,ijpjm1) + psgn * pt2dr(ijt,ijpjm1))
- END DO
- CASE ( 'J' ) ! first ice U-V point
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 2
- ENDIF
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO ji = startloop , endloop
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- pt2dl(ji,ijpj) = pt2dl(ji,ijpjm1)
- END DO
- CASE ( 'K' ) ! second ice U-V point
- IF (nimpp .ne. 1) THEN
- startloop = 1
- ELSE
- startloop = 2
- ENDIF
- IF ((nimpp + nlci - 1) .ne. jpiglo) THEN
- endloop = nlci
- ELSE
- endloop = nlci - 1
- ENDIF
- DO ji = startloop, endloop
- ijt = jpiglo - ji - nimpp - nfiimpp(isendto(1),jpnj) + 4
- pt2dl(ji,ijpj) = pt2dr(ijt,ijpjm1)
- END DO
- END SELECT
- !
- CASE DEFAULT ! * closed : the code probably never go through
- !
- SELECT CASE ( cd_type)
- CASE ( 'T' , 'U' , 'V' , 'W' ) ! T-, U-, V-, W-points
- pt2dl(:, 1 ) = 0.e0
- pt2dl(:,ijpj) = 0.e0
- CASE ( 'F' ) ! F-point
- pt2dl(:,ijpj) = 0.e0
- CASE ( 'I' ) ! ice U-V point
- pt2dl(:, 1 ) = 0.e0
- pt2dl(:,ijpj) = 0.e0
- CASE ( 'J' ) ! first ice U-V point
- pt2dl(:, 1 ) = 0.e0
- pt2dl(:,ijpj) = 0.e0
- CASE ( 'K' ) ! second ice U-V point
- pt2dl(:, 1 ) = 0.e0
- pt2dl(:,ijpj) = 0.e0
- END SELECT
- !
- END SELECT
- !
- END SUBROUTINE mpp_lbc_nfd_2d
- END MODULE lbcnfd
|