Changeset 7058 for branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC
- Timestamp:
- 2016-10-20T15:19:01+02:00 (8 years ago)
- Location:
- branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcbdy.F90
r6862 r7058 9 9 !! 3.5 ! 2012 (S. Mocavero, I. Epicoco) Optimization of BDY communications 10 10 !! 3.6 ! 2015 (T. Lovato) Adapt BDY for tracers in TOP component 11 !! 4.0 ! 2016 (T. Lovato) Generalize OBC structure 11 12 !!---------------------------------------------------------------------- 12 13 #if defined key_top 13 14 !!---------------------------------------------------------------------- 14 !! trc_bdy : Apply open boundary conditions to T and S 15 !! trc_bdy_frs : Apply Flow Relaxation Scheme 15 !! trc_bdy : Apply open boundary conditions & damping to tracers 16 16 !!---------------------------------------------------------------------- 17 17 USE timing ! Timing … … 22 22 USE lbclnk ! ocean lateral boundary conditions (or mpp link) 23 23 USE in_out_manager ! I/O manager 24 USE bdy_oce, only: idx_bdy , OBC_INDEX, BDYTMASK, ln_bdy! ocean open boundary conditions24 USE bdy_oce, only: idx_bdy ! ocean open boundary conditions 25 25 26 26 IMPLICIT NONE 27 27 PRIVATE 28 29 ! Local structure to rearrange tracers data 30 TYPE, PUBLIC :: ztrcbdy 31 REAL(wp), POINTER, DIMENSION(:,:) :: trc 32 REAL(wp), POINTER :: fac 33 END TYPE 28 34 29 35 PUBLIC trc_bdy ! routine called in trcnxt.F90 … … 31 37 32 38 !!---------------------------------------------------------------------- 33 !! NEMO/OPA 3.6 , NEMO Consortium (2015)39 !! NEMO/OPA 4.0 , NEMO Consortium (2016) 34 40 !! $Id$ 35 41 !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt) … … 41 47 !! *** SUBROUTINE trc_bdy *** 42 48 !! 43 !! ** Purpose : - Apply open boundary conditions for tracers in TOP component 44 !! and scale the tracer data 49 !! ** Purpose : - Apply open boundary conditions for TOP tracers 45 50 !! 46 51 !!---------------------------------------------------------------------- … … 48 53 !! 49 54 INTEGER :: ib_bdy, jn ! Loop indeces 55 TYPE(ztrcbdy) :: zdta ! Temporary data structure 50 56 !!---------------------------------------------------------------------- 51 57 ! 52 58 IF( nn_timing == 1 ) CALL timing_start('trc_bdy') 53 59 ! 54 DO jn = 1, jptra 55 DO ib_bdy=1, nb_bdy 56 57 SELECT CASE( trcdta_bdy(jn,ib_bdy)%cn_obc ) 58 CASE('none') 59 CYCLE 60 CASE('frs') 61 CALL bdy_trc_frs( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), kt ) 62 CASE('specified') 63 CALL bdy_trc_spe( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), kt ) 64 CASE('neumann') 65 CALL bdy_trc_nmn( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), kt ) 66 CASE('orlanski') 67 CALL bdy_trc_orlanski( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), ll_npo=.false. ) 68 CASE('orlanski_npo') 69 CALL bdy_trc_orlanski( jn, idx_bdy(ib_bdy), trcdta_bdy(jn,ib_bdy), ll_npo=.true. ) 70 CASE DEFAULT 71 CALL ctl_stop( 'trc_bdy : unrecognised option for open boundaries for passive tracers' ) 60 DO ib_bdy=1, nb_bdy 61 DO jn = 1, jptra 62 ! 63 zdta%trc => trcdta_bdy(jn,ib_bdy)%trc 64 zdta%fac => trcdta_bdy(jn,ib_bdy)%rn_fac 65 ! 66 SELECT CASE( TRIM(trcdta_bdy(jn,ib_bdy)%cn_obc) ) 67 CASE('none' ) ; CYCLE 68 CASE('frs' ) ; CALL bdy_frs( idx_bdy(ib_bdy), tra(:,:,:,jn), zdta%trc*zdta%fac ) 69 CASE('specified' ) ; CALL bdy_spe( idx_bdy(ib_bdy), tra(:,:,:,jn), zdta%trc*zdta%fac ) 70 CASE('neumann' ) ; CALL bdy_nmn( idx_bdy(ib_bdy), tra(:,:,:,jn) ) 71 CASE('orlanski' ) ; CALL bdy_orl( idx_bdy(ib_bdy), trb(:,:,:,jn), tra(:,:,:,jn), zdta%trc*zdta%fac, ll_npo=.false. ) 72 CASE('orlanski_npo') ; CALL bdy_orl( idx_bdy(ib_bdy), trb(:,:,:,jn), tra(:,:,:,jn), zdta%trc*zdta%fac, ll_npo=.true. ) 73 CASE DEFAULT ; CALL ctl_stop( 'trc_bdy : unrecognised option for open boundaries for passive tracers' ) 72 74 END SELECT 73 74 75 ! Boundary points should be updated 75 76 CALL lbc_bdy_lnk( tra(:,:,:,jn), 'T', 1., ib_bdy ) 76 77 END DO78 END DO77 ! 78 END DO 79 END DO 79 80 ! 80 81 IF( nn_timing == 1 ) CALL timing_stop('trc_bdy') 81 82 82 83 END SUBROUTINE trc_bdy 83 84 SUBROUTINE bdy_trc_frs( jn, idx, dta, kt )85 !!----------------------------------------------------------------------86 !! *** SUBROUTINE bdy_trc_frs ***87 !!88 !! ** Purpose : Apply the Flow Relaxation Scheme for tracers at open boundaries.89 !!90 !! Reference : Engedahl H., 1995, Tellus, 365-382.91 !!----------------------------------------------------------------------92 INTEGER, INTENT(in) :: kt93 INTEGER, INTENT(in) :: jn ! Tracer index94 TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices95 TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data96 !!97 REAL(wp) :: zwgt ! boundary weight98 INTEGER :: ib, ik, igrd ! dummy loop indices99 INTEGER :: ii, ij ! 2D addresses100 !!----------------------------------------------------------------------101 !102 IF( nn_timing == 1 ) CALL timing_start('bdy_trc_frs')103 !104 igrd = 1 ! Everything is at T-points here105 DO ib = 1, idx%nblen(igrd)106 DO ik = 1, jpkm1107 ii = idx%nbi(ib,igrd)108 ij = idx%nbj(ib,igrd)109 zwgt = idx%nbw(ib,igrd)110 tra(ii,ij,ik,jn) = ( tra(ii,ij,ik,jn) + zwgt * ( ( dta%trc(ib,ik) * dta%rn_fac) &111 & - tra(ii,ij,ik,jn) ) ) * tmask(ii,ij,ik)112 END DO113 END DO114 !115 IF( kt .eq. nit000 ) CLOSE( unit = 102 )116 !117 IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_frs')118 !119 END SUBROUTINE bdy_trc_frs120 121 SUBROUTINE bdy_trc_spe( jn, idx, dta, kt )122 !!----------------------------------------------------------------------123 !! *** SUBROUTINE bdy_trc_frs ***124 !!125 !! ** Purpose : Apply a specified value for tracers at open boundaries.126 !!127 !!----------------------------------------------------------------------128 INTEGER, INTENT(in) :: kt129 INTEGER, INTENT(in) :: jn ! Tracer index130 TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices131 TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data132 !!133 REAL(wp) :: zwgt ! boundary weight134 INTEGER :: ib, ik, igrd ! dummy loop indices135 INTEGER :: ii, ij ! 2D addresses136 !!----------------------------------------------------------------------137 !138 IF( nn_timing == 1 ) CALL timing_start('bdy_trc_spe')139 !140 igrd = 1 ! Everything is at T-points here141 DO ib = 1, idx%nblenrim(igrd)142 ii = idx%nbi(ib,igrd)143 ij = idx%nbj(ib,igrd)144 DO ik = 1, jpkm1145 tra(ii,ij,ik,jn) = dta%trc(ib,ik) * dta%rn_fac * tmask(ii,ij,ik)146 END DO147 END DO148 !149 IF( kt .eq. nit000 ) CLOSE( unit = 102 )150 !151 IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_spe')152 !153 END SUBROUTINE bdy_trc_spe154 155 SUBROUTINE bdy_trc_nmn( jn, idx, dta, kt )156 !!----------------------------------------------------------------------157 !! *** SUBROUTINE bdy_trc_nmn ***158 !!159 !! ** Purpose : Duplicate the value for tracers at open boundaries.160 !!161 !!----------------------------------------------------------------------162 INTEGER, INTENT(in) :: kt163 INTEGER, INTENT(in) :: jn ! Tracer index164 TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices165 TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data166 !!167 REAL(wp) :: zwgt ! boundary weight168 INTEGER :: ib, ik, igrd ! dummy loop indices169 INTEGER :: ii, ij, zcoef, zcoef1, zcoef2, ip, jp ! 2D addresses170 !!----------------------------------------------------------------------171 !172 IF( nn_timing == 1 ) CALL timing_start('bdy_trc_nmn')173 !174 igrd = 1 ! Everything is at T-points here175 DO ib = 1, idx%nblenrim(igrd)176 ii = idx%nbi(ib,igrd)177 ij = idx%nbj(ib,igrd)178 DO ik = 1, jpkm1179 ! search the sense of the gradient180 zcoef1 = bdytmask(ii-1,ij ) + bdytmask(ii+1,ij )181 zcoef2 = bdytmask(ii ,ij-1) + bdytmask(ii ,ij+1)182 IF ( zcoef1+zcoef2 == 0) THEN183 ! corner184 zcoef = tmask(ii-1,ij,ik) + tmask(ii+1,ij,ik) + tmask(ii,ij-1,ik) + tmask(ii,ij+1,ik)185 tra(ii,ij,ik,jn) = tra(ii-1,ij ,ik,jn) * tmask(ii-1,ij ,ik) + &186 & tra(ii+1,ij ,ik,jn) * tmask(ii+1,ij ,ik) + &187 & tra(ii ,ij-1,ik,jn) * tmask(ii ,ij-1,ik) + &188 & tra(ii ,ij+1,ik,jn) * tmask(ii ,ij+1,ik)189 tra(ii,ij,ik,jn) = ( tra(ii,ij,ik,jn) / MAX( 1, zcoef) ) * tmask(ii,ij,ik)190 ELSE191 ip = bdytmask(ii+1,ij ) - bdytmask(ii-1,ij )192 jp = bdytmask(ii ,ij+1) - bdytmask(ii ,ij-1)193 tra(ii,ij,ik,jn) = tra(ii+ip,ij+jp,ik,jn) * tmask(ii+ip,ij+jp,ik)194 ENDIF195 END DO196 END DO197 !198 IF( kt .eq. nit000 ) CLOSE( unit = 102 )199 !200 IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_nmn')201 !202 END SUBROUTINE bdy_trc_nmn203 204 205 SUBROUTINE bdy_trc_orlanski( jn, idx, dta, ll_npo )206 !!----------------------------------------------------------------------207 !! *** SUBROUTINE bdy_trc_orlanski ***208 !!209 !! - Apply Orlanski radiation to tracers of TOP component.210 !! - Wrapper routine for bdy_orlanski_3d211 !!212 !!213 !! References: Marchesiello, McWilliams and Shchepetkin, Ocean Modelling vol. 3 (2001)214 !!----------------------------------------------------------------------215 INTEGER, INTENT(in) :: jn ! Tracer index216 TYPE(OBC_INDEX), INTENT(in) :: idx ! OBC indices217 TYPE(OBC_DATA), INTENT(in) :: dta ! OBC external data218 LOGICAL, INTENT(in) :: ll_npo ! switch for NPO version219 220 INTEGER :: igrd ! grid index221 !!----------------------------------------------------------------------222 223 IF( nn_timing == 1 ) CALL timing_start('bdy_trc_orlanski')224 !225 igrd = 1 ! Orlanski bc on tracers;226 !227 CALL bdy_orlanski_3d( idx, igrd, trb(:,:,:,jn), tra(:,:,:,jn), (dta%trc * dta%rn_fac), ll_npo )228 !229 IF( nn_timing == 1 ) CALL timing_stop('bdy_trc_orlanski')230 !231 232 END SUBROUTINE bdy_trc_orlanski233 84 234 85 SUBROUTINE trc_bdy_dmp( kt ) -
branches/2016/dev_r6522_SIMPLIF_3/NEMOGCM/NEMO/TOP_SRC/trcsub.F90
r6862 r7058 499 499 z1_rau0 = 0.5 / rau0 500 500 ssha(:,:) = ( sshb(:,:) - z2dt * ( z1_rau0 * ( emp_b(:,:) + emp(:,:) ) + zhdiv(:,:) ) ) * tmask(:,:,1) 501 #if ! defined key_dynspg_ts 501 502 IF( .NOT.ln_dynspg_ts ) THEN 502 503 ! These lines are not necessary with time splitting since 503 504 ! boundary condition on sea level is set during ts loop … … 505 506 CALL agrif_ssh( kt ) 506 507 #endif 507 IF( ln_bdy ) THEN508 ssha(:,:) = ssha(:,:) * bdytmask(:,:)509 CALL lbc_lnk( ssha, 'T', 1. )510 ENDIF511 #endif 508 IF( ln_bdy ) THEN 509 ssha(:,:) = ssha(:,:) * bdytmask(:,:) 510 CALL lbc_lnk( ssha, 'T', 1. ) 511 ENDIF 512 ENDIF 512 513 ! 513 514 ! !------------------------------!
Note: See TracChangeset
for help on using the changeset viewer.