- Timestamp:
- 2020-05-14T21:46:00+02:00 (4 years ago)
- Location:
- NEMO/branches/2019/dev_r11078_OSMOSIS_IMMERSE_Nurser
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
NEMO/branches/2019/dev_r11078_OSMOSIS_IMMERSE_Nurser
- Property svn:externals
-
old new 6 6 ^/vendors/FCM@HEAD ext/FCM 7 7 ^/vendors/IOIPSL@HEAD ext/IOIPSL 8 9 # SETTE 10 ^/utils/CI/sette@HEAD sette
-
- Property svn:externals
-
NEMO/branches/2019/dev_r11078_OSMOSIS_IMMERSE_Nurser/src/OCE/BDY/bdytides.F90
r12178 r12928 18 18 USE phycst ! physical constants 19 19 USE bdy_oce ! ocean open boundary conditions 20 USE tide ini!20 USE tide_mod ! 21 21 USE daymod ! calendar 22 22 ! … … 30 30 31 31 PUBLIC bdytide_init ! routine called in bdy_init 32 PUBLIC bdytide_update ! routine called in bdy_dta33 32 PUBLIC bdy_dta_tides ! routine called in dyn_spg_ts 34 33 … … 45 44 TYPE(OBC_DATA) , PUBLIC, DIMENSION(jp_bdy) :: dta_bdy_s !: bdy external data (slow component) 46 45 46 INTEGER :: kt_tide 47 48 !! * Substitutions 49 # include "do_loop_substitute.h90" 47 50 !!---------------------------------------------------------------------- 48 51 !! NEMO/OCE 4.0 , NEMO Consortium (2018) … … 62 65 !! namelist variables 63 66 !!------------------- 64 CHARACTER(len=80) :: filtide !: Filename root for tidal input files 65 LOGICAL :: ln_bdytide_2ddta !: If true, read 2d harmonic data 66 LOGICAL :: ln_bdytide_conj !: If true, assume complex conjugate tidal data 67 CHARACTER(len=80) :: filtide ! Filename root for tidal input files 68 LOGICAL :: ln_bdytide_2ddta ! If true, read 2d harmonic data 67 69 !! 68 INTEGER :: ib_bdy, itide, ib ! :dummy loop indices69 INTEGER :: ii, ij ! :dummy loop indices70 INTEGER :: ib_bdy, itide, ib ! dummy loop indices 71 INTEGER :: ii, ij ! dummy loop indices 70 72 INTEGER :: inum, igrd 71 INTEGER , DIMENSION(3) :: ilen0 !: length of boundary data (from OBC arrays)73 INTEGER :: isz ! bdy data size 72 74 INTEGER :: ios ! Local integer output status for namelist read 73 CHARACTER(len=80) :: clfile !: full file name for tidal input file 74 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:) :: dta_read !: work space to read in tidal harmonics data 75 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: ztr, zti !: " " " " " " " " 75 INTEGER :: nbdy_rdstart, nbdy_loc 76 CHARACTER(LEN=50) :: cerrmsg ! error string 77 CHARACTER(len=80) :: clfile ! full file name for tidal input file 78 REAL(wp),ALLOCATABLE, DIMENSION(:,:,:) :: dta_read ! work space to read in tidal harmonics data 79 REAL(wp),ALLOCATABLE, DIMENSION(:,:) :: ztr, zti ! " " " " " " " " 76 80 !! 77 TYPE(TIDES_DATA), POINTER :: td !: local short cut 81 TYPE(TIDES_DATA), POINTER :: td ! local short cut 82 TYPE( OBC_DATA), POINTER :: dta ! local short cut 78 83 !! 79 NAMELIST/nambdy_tide/filtide, ln_bdytide_2ddta , ln_bdytide_conj84 NAMELIST/nambdy_tide/filtide, ln_bdytide_2ddta 80 85 !!---------------------------------------------------------------------- 81 86 ! … … 84 89 IF(lwp) WRITE(numout,*) '~~~~~~~~~~~~' 85 90 86 REWIND(numnam_cfg) 87 91 92 nbdy_rdstart = 1 88 93 DO ib_bdy = 1, nb_bdy 89 94 IF( nn_dyn2d_dta(ib_bdy) >= 2 ) THEN 90 95 ! 91 td => tides(ib_bdy) 92 96 td => tides(ib_bdy) 97 dta => dta_bdy(ib_bdy) 98 93 99 ! Namelist nambdy_tide : tidal harmonic forcing at open boundaries 94 100 filtide(:) = '' 95 101 96 REWIND( numnam_ref )97 102 READ ( numnam_ref, nambdy_tide, IOSTAT = ios, ERR = 901) 98 103 901 IF( ios /= 0 ) CALL ctl_nam ( ios , 'nambdy_tide in reference namelist' ) 99 ! Don't REWIND here - may need to read more than one of these namelists. 100 READ ( numnam_cfg, nambdy_tide, IOSTAT = ios, ERR = 902 ) 104 ! 105 ! Need to support possibility of reading more than one 106 ! nambdy_tide from the namelist_cfg internal file. 107 ! Do this by finding the ib_bdy'th occurence of nambdy_tide in the 108 ! character buffer as the starting point. 109 ! 110 nbdy_loc = INDEX( numnam_cfg( nbdy_rdstart: ), 'nambdy_tide' ) 111 IF( nbdy_loc .GT. 0 ) THEN 112 nbdy_rdstart = nbdy_rdstart + nbdy_loc 113 ELSE 114 WRITE(cerrmsg,'(A,I4,A)') 'Error: entry number ',ib_bdy,' of nambdy_tide not found' 115 ios = -1 116 CALL ctl_nam ( ios , cerrmsg ) 117 ENDIF 118 READ ( numnam_cfg( MAX( 1, nbdy_rdstart - 2 ): ), nambdy_tide, IOSTAT = ios, ERR = 902) 101 119 902 IF( ios > 0 ) CALL ctl_nam ( ios , 'nambdy_tide in configuration namelist' ) 102 120 IF(lwm) WRITE ( numond, nambdy_tide ) … … 105 123 IF(lwp) WRITE(numout,*) ' Namelist nambdy_tide : tidal harmonic forcing at open boundaries' 106 124 IF(lwp) WRITE(numout,*) ' read tidal data in 2d files: ', ln_bdytide_2ddta 107 IF(lwp) WRITE(numout,*) ' assume complex conjugate : ', ln_bdytide_conj108 125 IF(lwp) WRITE(numout,*) ' Number of tidal components to read: ', nb_harmo 109 126 IF(lwp) THEN 110 127 WRITE(numout,*) ' Tidal components: ' 111 128 DO itide = 1, nb_harmo 112 WRITE(numout,*) ' ', Wave(ntide(itide))%cname_tide129 WRITE(numout,*) ' ', tide_harmonics(itide)%cname_tide 113 130 END DO 114 131 ENDIF 115 132 IF(lwp) WRITE(numout,*) ' ' 116 133 117 ! Allocate space for tidal harmonics data - get size from OBC data arrays 134 ! Allocate space for tidal harmonics data - get size from BDY data arrays 135 ! Allocate also slow varying data in the case of time splitting: 136 ! Do it anyway because at this stage knowledge of free surface scheme is unknown 118 137 ! ----------------------------------------------------------------------- 119 120 ! JC: If FRS scheme is used, we assume that tidal is needed over the whole 121 ! relaxation area 122 IF( cn_dyn2d(ib_bdy) == 'frs' ) THEN ; ilen0(:) = idx_bdy(ib_bdy)%nblen (:) 123 ELSE ; ilen0(:) = idx_bdy(ib_bdy)%nblenrim(:) 124 ENDIF 125 126 ALLOCATE( td%ssh0( ilen0(1), nb_harmo, 2 ) ) 127 ALLOCATE( td%ssh ( ilen0(1), nb_harmo, 2 ) ) 128 129 ALLOCATE( td%u0( ilen0(2), nb_harmo, 2 ) ) 130 ALLOCATE( td%u ( ilen0(2), nb_harmo, 2 ) ) 131 132 ALLOCATE( td%v0( ilen0(3), nb_harmo, 2 ) ) 133 ALLOCATE( td%v ( ilen0(3), nb_harmo, 2 ) ) 134 135 td%ssh0(:,:,:) = 0._wp 136 td%ssh (:,:,:) = 0._wp 137 td%u0 (:,:,:) = 0._wp 138 td%u (:,:,:) = 0._wp 139 td%v0 (:,:,:) = 0._wp 140 td%v (:,:,:) = 0._wp 141 138 IF( ASSOCIATED(dta%ssh) ) THEN ! we use bdy ssh on this mpi subdomain 139 isz = SIZE(dta%ssh) 140 ALLOCATE( td%ssh0( isz, nb_harmo, 2 ), td%ssh( isz, nb_harmo, 2 ), dta_bdy_s(ib_bdy)%ssh( isz ) ) 141 dta_bdy_s(ib_bdy)%ssh(:) = 0._wp ! needed? 142 ENDIF 143 IF( ASSOCIATED(dta%u2d) ) THEN ! we use bdy u2d on this mpi subdomain 144 isz = SIZE(dta%u2d) 145 ALLOCATE( td%u0 ( isz, nb_harmo, 2 ), td%u ( isz, nb_harmo, 2 ), dta_bdy_s(ib_bdy)%u2d( isz ) ) 146 dta_bdy_s(ib_bdy)%u2d(:) = 0._wp ! needed? 147 ENDIF 148 IF( ASSOCIATED(dta%v2d) ) THEN ! we use bdy v2d on this mpi subdomain 149 isz = SIZE(dta%v2d) 150 ALLOCATE( td%v0 ( isz, nb_harmo, 2 ), td%v ( isz, nb_harmo, 2 ), dta_bdy_s(ib_bdy)%v2d( isz ) ) 151 dta_bdy_s(ib_bdy)%v2d(:) = 0._wp ! needed? 152 ENDIF 153 154 ! fill td%ssh0, td%u0, td%v0 155 ! ----------------------------------------------------------------------- 142 156 IF( ln_bdytide_2ddta ) THEN 157 ! 143 158 ! It is assumed that each data file contains all complex harmonic amplitudes 144 159 ! given on the global domain (ie global, jpiglo x jpjglo) … … 147 162 ! 148 163 ! SSH fields 149 clfile = TRIM(filtide)//'_grid_T.nc' 150 CALL iom_open( clfile , inum ) 151 igrd = 1 ! Everything is at T-points here 152 DO itide = 1, nb_harmo 153 CALL iom_get( inum, jpdom_autoglo, TRIM(Wave(ntide(itide))%cname_tide)//'_z1', ztr(:,:) ) 154 CALL iom_get( inum, jpdom_autoglo, TRIM(Wave(ntide(itide))%cname_tide)//'_z2', zti(:,:) ) 155 DO ib = 1, ilen0(igrd) 156 ii = idx_bdy(ib_bdy)%nbi(ib,igrd) 157 ij = idx_bdy(ib_bdy)%nbj(ib,igrd) 158 IF( ii == 1 .OR. ii == jpi .OR. ij == 1 .OR. ij == jpj ) CYCLE ! to remove? 159 td%ssh0(ib,itide,1) = ztr(ii,ij) 160 td%ssh0(ib,itide,2) = zti(ii,ij) 161 END DO 162 END DO 163 CALL iom_close( inum ) 164 IF( ASSOCIATED(dta%ssh) ) THEN ! we use bdy ssh on this mpi subdomain 165 clfile = TRIM(filtide)//'_grid_T.nc' 166 CALL iom_open( clfile , inum ) 167 igrd = 1 ! Everything is at T-points here 168 DO itide = 1, nb_harmo 169 CALL iom_get( inum, jpdom_autoglo, TRIM(tide_harmonics(itide)%cname_tide)//'_z1', ztr(:,:) ) 170 CALL iom_get( inum, jpdom_autoglo, TRIM(tide_harmonics(itide)%cname_tide)//'_z2', zti(:,:) ) 171 DO ib = 1, SIZE(dta%ssh) 172 ii = idx_bdy(ib_bdy)%nbi(ib,igrd) 173 ij = idx_bdy(ib_bdy)%nbj(ib,igrd) 174 td%ssh0(ib,itide,1) = ztr(ii,ij) 175 td%ssh0(ib,itide,2) = zti(ii,ij) 176 END DO 177 END DO 178 CALL iom_close( inum ) 179 ENDIF 164 180 ! 165 181 ! U fields 166 clfile = TRIM(filtide)//'_grid_U.nc' 167 CALL iom_open( clfile , inum ) 168 igrd = 2 ! Everything is at U-points here 169 DO itide = 1, nb_harmo 170 CALL iom_get ( inum, jpdom_autoglo, TRIM(Wave(ntide(itide))%cname_tide)//'_u1', ztr(:,:) ) 171 CALL iom_get ( inum, jpdom_autoglo, TRIM(Wave(ntide(itide))%cname_tide)//'_u2', zti(:,:) ) 172 DO ib = 1, ilen0(igrd) 173 ii = idx_bdy(ib_bdy)%nbi(ib,igrd) 174 ij = idx_bdy(ib_bdy)%nbj(ib,igrd) 175 IF( ii == 1 .OR. ii == jpi .OR. ij == 1 .OR. ij == jpj ) CYCLE ! to remove? 176 td%u0(ib,itide,1) = ztr(ii,ij) 177 td%u0(ib,itide,2) = zti(ii,ij) 178 END DO 179 END DO 180 CALL iom_close( inum ) 182 IF( ASSOCIATED(dta%u2d) ) THEN ! we use bdy u2d on this mpi subdomain 183 clfile = TRIM(filtide)//'_grid_U.nc' 184 CALL iom_open( clfile , inum ) 185 igrd = 2 ! Everything is at U-points here 186 DO itide = 1, nb_harmo 187 CALL iom_get ( inum, jpdom_autoglo, TRIM(tide_harmonics(itide)%cname_tide)//'_u1', ztr(:,:) ) 188 CALL iom_get ( inum, jpdom_autoglo, TRIM(tide_harmonics(itide)%cname_tide)//'_u2', zti(:,:) ) 189 DO ib = 1, SIZE(dta%u2d) 190 ii = idx_bdy(ib_bdy)%nbi(ib,igrd) 191 ij = idx_bdy(ib_bdy)%nbj(ib,igrd) 192 td%u0(ib,itide,1) = ztr(ii,ij) 193 td%u0(ib,itide,2) = zti(ii,ij) 194 END DO 195 END DO 196 CALL iom_close( inum ) 197 ENDIF 181 198 ! 182 199 ! V fields 183 clfile = TRIM(filtide)//'_grid_V.nc' 184 CALL iom_open( clfile , inum ) 185 igrd = 3 ! Everything is at V-points here 186 DO itide = 1, nb_harmo 187 CALL iom_get ( inum, jpdom_autoglo, TRIM(Wave(ntide(itide))%cname_tide)//'_v1', ztr(:,:) ) 188 CALL iom_get ( inum, jpdom_autoglo, TRIM(Wave(ntide(itide))%cname_tide)//'_v2', zti(:,:) ) 189 DO ib = 1, ilen0(igrd) 190 ii = idx_bdy(ib_bdy)%nbi(ib,igrd) 191 ij = idx_bdy(ib_bdy)%nbj(ib,igrd) 192 IF( ii == 1 .OR. ii == jpi .OR. ij == 1 .OR. ij == jpj ) CYCLE ! to remove? 193 td%v0(ib,itide,1) = ztr(ii,ij) 194 td%v0(ib,itide,2) = zti(ii,ij) 195 END DO 196 END DO 197 CALL iom_close( inum ) 200 IF( ASSOCIATED(dta%v2d) ) THEN ! we use bdy v2d on this mpi subdomain 201 clfile = TRIM(filtide)//'_grid_V.nc' 202 CALL iom_open( clfile , inum ) 203 igrd = 3 ! Everything is at V-points here 204 DO itide = 1, nb_harmo 205 CALL iom_get ( inum, jpdom_autoglo, TRIM(tide_harmonics(itide)%cname_tide)//'_v1', ztr(:,:) ) 206 CALL iom_get ( inum, jpdom_autoglo, TRIM(tide_harmonics(itide)%cname_tide)//'_v2', zti(:,:) ) 207 DO ib = 1, SIZE(dta%v2d) 208 ii = idx_bdy(ib_bdy)%nbi(ib,igrd) 209 ij = idx_bdy(ib_bdy)%nbj(ib,igrd) 210 td%v0(ib,itide,1) = ztr(ii,ij) 211 td%v0(ib,itide,2) = zti(ii,ij) 212 END DO 213 END DO 214 CALL iom_close( inum ) 215 ENDIF 198 216 ! 199 217 DEALLOCATE( ztr, zti ) … … 203 221 ! Read tidal data only on bdy segments 204 222 ! 205 ALLOCATE( dta_read( MAXVAL( ilen0(1:3)), 1, 1 ) )223 ALLOCATE( dta_read( MAXVAL( idx_bdy(ib_bdy)%nblen(:) ), 1, 1 ) ) 206 224 ! 207 225 ! Open files and read in tidal forcing data … … 210 228 DO itide = 1, nb_harmo 211 229 ! ! SSH fields 212 clfile = TRIM(filtide)//TRIM(Wave(ntide(itide))%cname_tide)//'_grid_T.nc' 213 CALL iom_open( clfile, inum ) 214 CALL fld_map( inum, 'z1' , dta_read(1:ilen0(1),1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,1) ) 215 td%ssh0(:,itide,1) = dta_read(1:ilen0(1),1,1) 216 CALL fld_map( inum, 'z2' , dta_read(1:ilen0(1),1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,1) ) 217 td%ssh0(:,itide,2) = dta_read(1:ilen0(1),1,1) 218 CALL iom_close( inum ) 230 IF( ASSOCIATED(dta%ssh) ) THEN ! we use bdy ssh on this mpi subdomain 231 isz = SIZE(dta%ssh) 232 clfile = TRIM(filtide)//TRIM(tide_harmonics(itide)%cname_tide)//'_grid_T.nc' 233 CALL iom_open( clfile, inum ) 234 CALL fld_map( inum, 'z1', dta_read(1:isz,1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,1) ) 235 td%ssh0(:,itide,1) = dta_read(1:isz,1,1) 236 CALL fld_map( inum, 'z2', dta_read(1:isz,1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,1) ) 237 td%ssh0(:,itide,2) = dta_read(1:isz,1,1) 238 CALL iom_close( inum ) 239 ENDIF 219 240 ! ! U fields 220 clfile = TRIM(filtide)//TRIM(Wave(ntide(itide))%cname_tide)//'_grid_U.nc' 221 CALL iom_open( clfile, inum ) 222 CALL fld_map( inum, 'u1' , dta_read(1:ilen0(2),1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,2) ) 223 td%u0(:,itide,1) = dta_read(1:ilen0(2),1,1) 224 CALL fld_map( inum, 'u2' , dta_read(1:ilen0(2),1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,2) ) 225 td%u0(:,itide,2) = dta_read(1:ilen0(2),1,1) 226 CALL iom_close( inum ) 241 IF( ASSOCIATED(dta%u2d) ) THEN ! we use bdy u2d on this mpi subdomain 242 isz = SIZE(dta%u2d) 243 clfile = TRIM(filtide)//TRIM(tide_harmonics(itide)%cname_tide)//'_grid_U.nc' 244 CALL iom_open( clfile, inum ) 245 CALL fld_map( inum, 'u1', dta_read(1:isz,1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,2) ) 246 td%u0(:,itide,1) = dta_read(1:isz,1,1) 247 CALL fld_map( inum, 'u2', dta_read(1:isz,1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,2) ) 248 td%u0(:,itide,2) = dta_read(1:isz,1,1) 249 CALL iom_close( inum ) 250 ENDIF 227 251 ! ! V fields 228 clfile = TRIM(filtide)//TRIM(Wave(ntide(itide))%cname_tide)//'_grid_V.nc' 229 CALL iom_open( clfile, inum ) 230 CALL fld_map( inum, 'v1' , dta_read(1:ilen0(3),1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,3) ) 231 td%v0(:,itide,1) = dta_read(1:ilen0(3),1,1) 232 CALL fld_map( inum, 'v2' , dta_read(1:ilen0(3),1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,3) ) 233 td%v0(:,itide,2) = dta_read(1:ilen0(3),1,1) 234 CALL iom_close( inum ) 252 IF( ASSOCIATED(dta%v2d) ) THEN ! we use bdy v2d on this mpi subdomain 253 isz = SIZE(dta%v2d) 254 clfile = TRIM(filtide)//TRIM(tide_harmonics(itide)%cname_tide)//'_grid_V.nc' 255 CALL iom_open( clfile, inum ) 256 CALL fld_map( inum, 'v1', dta_read(1:isz,1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,3) ) 257 td%v0(:,itide,1) = dta_read(1:isz,1,1) 258 CALL fld_map( inum, 'v2', dta_read(1:isz,1:1,1:1) , 1, idx_bdy(ib_bdy)%nbmap(:,3) ) 259 td%v0(:,itide,2) = dta_read(1:isz,1,1) 260 CALL iom_close( inum ) 261 ENDIF 235 262 ! 236 263 END DO ! end loop on tidal components … … 240 267 ENDIF ! ln_bdytide_2ddta=.true. 241 268 ! 242 IF( ln_bdytide_conj ) THEN ! assume complex conjugate in data files243 td%ssh0(:,:,2) = - td%ssh0(:,:,2)244 td%u0 (:,:,2) = - td%u0 (:,:,2)245 td%v0 (:,:,2) = - td%v0 (:,:,2)246 ENDIF247 !248 ! Allocate slow varying data in the case of time splitting:249 ! Do it anyway because at this stage knowledge of free surface scheme is unknown250 ALLOCATE( dta_bdy_s(ib_bdy)%ssh ( ilen0(1) ) )251 ALLOCATE( dta_bdy_s(ib_bdy)%u2d ( ilen0(2) ) )252 ALLOCATE( dta_bdy_s(ib_bdy)%v2d ( ilen0(3) ) )253 dta_bdy_s(ib_bdy)%ssh(:) = 0._wp254 dta_bdy_s(ib_bdy)%u2d(:) = 0._wp255 dta_bdy_s(ib_bdy)%v2d(:) = 0._wp256 !257 269 ENDIF ! nn_dyn2d_dta(ib_bdy) >= 2 258 270 ! … … 262 274 263 275 264 SUBROUTINE bdytide_update( kt, idx, dta, td, kit, kt_offset ) 265 !!---------------------------------------------------------------------- 266 !! *** SUBROUTINE bdytide_update *** 267 !! 268 !! ** Purpose : - Add tidal forcing to ssh, u2d and v2d OBC data arrays. 269 !! 270 !!---------------------------------------------------------------------- 271 INTEGER , INTENT(in ) :: kt ! Main timestep counter 272 TYPE(OBC_INDEX) , INTENT(in ) :: idx ! OBC indices 273 TYPE(OBC_DATA) , INTENT(inout) :: dta ! OBC external data 274 TYPE(TIDES_DATA) , INTENT(inout) :: td ! tidal harmonics data 275 INTEGER, OPTIONAL, INTENT(in ) :: kit ! Barotropic timestep counter (for timesplitting option) 276 INTEGER, OPTIONAL, INTENT(in ) :: kt_offset ! time offset in units of timesteps. NB. if kit 277 ! ! is present then units = subcycle timesteps. 278 ! ! kt_offset = 0 => get data at "now" time level 279 ! ! kt_offset = -1 => get data at "before" time level 280 ! ! kt_offset = +1 => get data at "after" time level 281 ! ! etc. 282 ! 283 INTEGER :: itide, igrd, ib ! dummy loop indices 284 INTEGER :: time_add ! time offset in units of timesteps 285 INTEGER, DIMENSION(3) :: ilen0 ! length of boundary data (from OBC arrays) 286 REAL(wp) :: z_arg, z_sarg, zflag, zramp ! local scalars 287 REAL(wp), DIMENSION(jpmax_harmo) :: z_sist, z_cost 288 !!---------------------------------------------------------------------- 289 ! 290 ilen0(1) = SIZE(td%ssh(:,1,1)) 291 ilen0(2) = SIZE(td%u(:,1,1)) 292 ilen0(3) = SIZE(td%v(:,1,1)) 293 294 zflag=1 295 IF ( PRESENT(kit) ) THEN 296 IF ( kit /= 1 ) zflag=0 297 ENDIF 298 299 IF ( (nsec_day == NINT(0.5_wp * rdt) .OR. kt==nit000) .AND. zflag==1 ) THEN 300 ! 301 kt_tide = kt - (nsec_day - 0.5_wp * rdt)/rdt 302 ! 303 IF(lwp) THEN 304 WRITE(numout,*) 305 WRITE(numout,*) 'bdytide_update : (re)Initialization of the tidal bdy forcing at kt=',kt 306 WRITE(numout,*) '~~~~~~~~~~~~~~ ' 307 ENDIF 308 ! 309 CALL tide_init_elevation ( idx, td ) 310 CALL tide_init_velocities( idx, td ) 311 ! 312 ENDIF 313 314 time_add = 0 315 IF( PRESENT(kt_offset) ) THEN 316 time_add = kt_offset 317 ENDIF 318 319 IF( PRESENT(kit) ) THEN 320 z_arg = ((kt-kt_tide) * rdt + (kit+0.5_wp*(time_add-1)) * rdt / REAL(nn_baro,wp) ) 321 ELSE 322 z_arg = ((kt-kt_tide)+time_add) * rdt 323 ENDIF 324 325 ! Linear ramp on tidal component at open boundaries 326 zramp = 1._wp 327 IF (ln_tide_ramp) zramp = MIN(MAX( (z_arg + (kt_tide-nit000)*rdt)/(rdttideramp*rday),0._wp),1._wp) 328 329 DO itide = 1, nb_harmo 330 z_sarg = z_arg * omega_tide(itide) 331 z_cost(itide) = COS( z_sarg ) 332 z_sist(itide) = SIN( z_sarg ) 333 END DO 334 335 DO itide = 1, nb_harmo 336 igrd=1 ! SSH on tracer grid 337 DO ib = 1, ilen0(igrd) 338 dta%ssh(ib) = dta%ssh(ib) + zramp*(td%ssh(ib,itide,1)*z_cost(itide) + td%ssh(ib,itide,2)*z_sist(itide)) 339 END DO 340 igrd=2 ! U grid 341 DO ib = 1, ilen0(igrd) 342 dta%u2d(ib) = dta%u2d(ib) + zramp*(td%u (ib,itide,1)*z_cost(itide) + td%u (ib,itide,2)*z_sist(itide)) 343 END DO 344 igrd=3 ! V grid 345 DO ib = 1, ilen0(igrd) 346 dta%v2d(ib) = dta%v2d(ib) + zramp*(td%v (ib,itide,1)*z_cost(itide) + td%v (ib,itide,2)*z_sist(itide)) 347 END DO 348 END DO 349 ! 350 END SUBROUTINE bdytide_update 351 352 353 SUBROUTINE bdy_dta_tides( kt, kit, kt_offset ) 276 SUBROUTINE bdy_dta_tides( kt, kit, pt_offset ) 354 277 !!---------------------------------------------------------------------- 355 278 !! *** SUBROUTINE bdy_dta_tides *** … … 360 283 INTEGER, INTENT(in) :: kt ! Main timestep counter 361 284 INTEGER, OPTIONAL, INTENT(in) :: kit ! Barotropic timestep counter (for timesplitting option) 362 INTEGER, OPTIONAL, INTENT(in) :: kt_offset ! time offset in units of timesteps. NB. if kit 363 ! ! is present then units = subcycle timesteps. 364 ! ! kt_offset = 0 => get data at "now" time level 365 ! ! kt_offset = -1 => get data at "before" time level 366 ! ! kt_offset = +1 => get data at "after" time level 367 ! ! etc. 285 REAL(wp),OPTIONAL, INTENT(in) :: pt_offset ! time offset in units of timesteps 368 286 ! 369 287 LOGICAL :: lk_first_btstp ! =.TRUE. if time splitting and first barotropic step 370 INTEGER :: itide, ib_bdy, ib, igrd ! loop indices 371 INTEGER :: time_add ! time offset in units of timesteps 372 INTEGER, DIMENSION(jpbgrd) :: ilen0 373 INTEGER, DIMENSION(1:jpbgrd) :: nblen, nblenrim ! short cuts 374 REAL(wp) :: z_arg, z_sarg, zramp, zoff, z_cost, z_sist 288 INTEGER :: itide, ib_bdy, ib ! loop indices 289 REAL(wp) :: z_arg, z_sarg, zramp, zoff, z_cost, z_sist, zt_offset 375 290 !!---------------------------------------------------------------------- 376 291 ! … … 378 293 IF ( PRESENT(kit).AND.( kit /= 1 ) ) THEN ; lk_first_btstp=.FALSE. ; ENDIF 379 294 380 time_add = 0 381 IF( PRESENT(kt_offset) ) THEN 382 time_add = kt_offset 383 ENDIF 295 zt_offset = 0._wp 296 IF( PRESENT(pt_offset) ) zt_offset = pt_offset 384 297 385 298 ! Absolute time from model initialization: 386 299 IF( PRESENT(kit) ) THEN 387 z_arg = ( kt + (kit+time_add-1) / REAL(nn_baro,wp) ) * rdt300 z_arg = ( REAL(kt, wp) + ( REAL(kit, wp) + zt_offset - 1. ) / REAL(nn_e, wp) ) * rn_Dt 388 301 ELSE 389 z_arg = ( kt + time_add ) * rdt302 z_arg = ( REAL(kt, wp) + zt_offset ) * rn_Dt 390 303 ENDIF 391 304 392 305 ! Linear ramp on tidal component at open boundaries 393 306 zramp = 1. 394 IF (ln_tide_ramp) zramp = MIN(MAX( (z_arg - nit000*rdt)/(rdttideramp*rday),0.),1.)307 IF (ln_tide_ramp) zramp = MIN(MAX( (z_arg - REAL(nit000,wp)*rn_Dt)/(rn_tide_ramp_dt*rday),0.),1.) 395 308 396 309 DO ib_bdy = 1,nb_bdy 397 310 ! 398 311 IF( nn_dyn2d_dta(ib_bdy) >= 2 ) THEN 399 !400 nblen(1:jpbgrd) = idx_bdy(ib_bdy)%nblen(1:jpbgrd)401 nblenrim(1:jpbgrd) = idx_bdy(ib_bdy)%nblenrim(1:jpbgrd)402 !403 IF( cn_dyn2d(ib_bdy) == 'frs' ) THEN ; ilen0(:) = nblen (:)404 ELSE ; ilen0(:) = nblenrim(:)405 ENDIF406 312 ! 407 313 ! We refresh nodal factors every day below 408 314 ! This should be done somewhere else 409 IF ( ( nsec_day == NINT(0.5_wp * r dt) .OR. kt==nit000 ) .AND. lk_first_btstp ) THEN410 ! 411 kt_tide = kt - (nsec_day - 0.5_wp * rdt)/rdt315 IF ( ( nsec_day == NINT(0.5_wp * rn_Dt) .OR. kt==nit000 ) .AND. lk_first_btstp ) THEN 316 ! 317 kt_tide = kt - NINT((REAL(nsec_day,wp) - 0.5_wp * rn_Dt)/rn_Dt) 412 318 ! 413 319 IF(lwp) THEN … … 421 327 ! 422 328 ENDIF 423 zoff = -kt_tide * rdt ! time offset relative to nodal factor computation time329 zoff = REAL(-kt_tide,wp) * rn_Dt ! time offset relative to nodal factor computation time 424 330 ! 425 331 ! If time splitting, initialize arrays from slow varying open boundary data: 426 332 IF ( PRESENT(kit) ) THEN 427 IF ( dta_bdy(ib_bdy)%lneed_ssh ) dta_bdy(ib_bdy)%ssh(1:ilen0(1)) = dta_bdy_s(ib_bdy)%ssh(1:ilen0(1))428 IF ( dta_bdy(ib_bdy)%lneed_dyn2d ) dta_bdy(ib_bdy)%u2d(1:ilen0(2)) = dta_bdy_s(ib_bdy)%u2d(1:ilen0(2))429 IF ( dta_bdy(ib_bdy)%lneed_dyn2d ) dta_bdy(ib_bdy)%v2d(1:ilen0(3)) = dta_bdy_s(ib_bdy)%v2d(1:ilen0(3))333 IF ( ASSOCIATED(dta_bdy(ib_bdy)%ssh) ) dta_bdy(ib_bdy)%ssh(:) = dta_bdy_s(ib_bdy)%ssh(:) 334 IF ( ASSOCIATED(dta_bdy(ib_bdy)%u2d) ) dta_bdy(ib_bdy)%u2d(:) = dta_bdy_s(ib_bdy)%u2d(:) 335 IF ( ASSOCIATED(dta_bdy(ib_bdy)%v2d) ) dta_bdy(ib_bdy)%v2d(:) = dta_bdy_s(ib_bdy)%v2d(:) 430 336 ENDIF 431 337 ! … … 433 339 DO itide = 1, nb_harmo 434 340 ! 435 z_sarg = (z_arg + zoff) * omega_tide(itide)341 z_sarg = (z_arg + zoff) * tide_harmonics(itide)%omega 436 342 z_cost = zramp * COS( z_sarg ) 437 343 z_sist = zramp * SIN( z_sarg ) 438 344 ! 439 IF ( dta_bdy(ib_bdy)%lneed_ssh ) THEN 440 igrd=1 ! SSH on tracer grid 441 DO ib = 1, ilen0(igrd) 345 IF ( ASSOCIATED(dta_bdy(ib_bdy)%ssh) ) THEN ! SSH on tracer grid 346 DO ib = 1, SIZE(dta_bdy(ib_bdy)%ssh) 442 347 dta_bdy(ib_bdy)%ssh(ib) = dta_bdy(ib_bdy)%ssh(ib) + & 443 348 & ( tides(ib_bdy)%ssh(ib,itide,1)*z_cost + & … … 446 351 ENDIF 447 352 ! 448 IF ( dta_bdy(ib_bdy)%lneed_dyn2d ) THEN 449 igrd=2 ! U grid 450 DO ib = 1, ilen0(igrd) 353 IF ( ASSOCIATED(dta_bdy(ib_bdy)%u2d) ) THEN ! U grid 354 DO ib = 1, SIZE(dta_bdy(ib_bdy)%u2d) 451 355 dta_bdy(ib_bdy)%u2d(ib) = dta_bdy(ib_bdy)%u2d(ib) + & 452 356 & ( tides(ib_bdy)%u(ib,itide,1)*z_cost + & 453 357 & tides(ib_bdy)%u(ib,itide,2)*z_sist ) 454 358 END DO 455 igrd=3 ! V grid 456 DO ib = 1, ilen0(igrd) 359 ENDIF 360 ! 361 IF ( ASSOCIATED(dta_bdy(ib_bdy)%v2d) ) THEN ! V grid 362 DO ib = 1, SIZE(dta_bdy(ib_bdy)%v2d) 457 363 dta_bdy(ib_bdy)%v2d(ib) = dta_bdy(ib_bdy)%v2d(ib) + & 458 364 & ( tides(ib_bdy)%v(ib,itide,1)*z_cost + & … … 460 366 END DO 461 367 ENDIF 368 ! 462 369 END DO 463 END 370 ENDIF 464 371 END DO 465 372 ! … … 474 381 TYPE(TIDES_DATA), INTENT(inout) :: td ! tidal harmonics data 475 382 ! 476 INTEGER :: itide, igrd, ib ! dummy loop indices 477 INTEGER, DIMENSION(1) :: ilen0 ! length of boundary data (from OBC arrays) 383 INTEGER :: itide, isz, ib ! dummy loop indices 478 384 REAL(wp),ALLOCATABLE, DIMENSION(:) :: mod_tide, phi_tide 479 385 !!---------------------------------------------------------------------- 480 386 ! 481 igrd=1 482 ! SSH on tracer grid. 483 ilen0(1) = SIZE(td%ssh0(:,1,1)) 484 ! 485 ALLOCATE( mod_tide(ilen0(igrd)), phi_tide(ilen0(igrd)) ) 486 ! 487 DO itide = 1, nb_harmo 488 DO ib = 1, ilen0(igrd) 489 mod_tide(ib)=SQRT(td%ssh0(ib,itide,1)**2.+td%ssh0(ib,itide,2)**2.) 490 phi_tide(ib)=ATAN2(-td%ssh0(ib,itide,2),td%ssh0(ib,itide,1)) 387 IF( ASSOCIATED(td%ssh0) ) THEN ! SSH on tracer grid. 388 ! 389 isz = SIZE( td%ssh0, dim = 1 ) 390 ALLOCATE( mod_tide(isz), phi_tide(isz) ) 391 ! 392 DO itide = 1, nb_harmo 393 DO ib = 1, isz 394 mod_tide(ib)=SQRT( td%ssh0(ib,itide,1)*td%ssh0(ib,itide,1) + td%ssh0(ib,itide,2)*td%ssh0(ib,itide,2) ) 395 phi_tide(ib)=ATAN2(-td%ssh0(ib,itide,2),td%ssh0(ib,itide,1)) 396 END DO 397 DO ib = 1, isz 398 mod_tide(ib)=mod_tide(ib)*tide_harmonics(itide)%f 399 phi_tide(ib)=phi_tide(ib)+tide_harmonics(itide)%v0+tide_harmonics(itide)%u 400 END DO 401 DO ib = 1, isz 402 td%ssh(ib,itide,1)= mod_tide(ib)*COS(phi_tide(ib)) 403 td%ssh(ib,itide,2)=-mod_tide(ib)*SIN(phi_tide(ib)) 404 END DO 491 405 END DO 492 DO ib = 1 , ilen0(igrd) 493 mod_tide(ib)=mod_tide(ib)*ftide(itide) 494 phi_tide(ib)=phi_tide(ib)+v0tide(itide)+utide(itide) 495 ENDDO 496 DO ib = 1 , ilen0(igrd) 497 td%ssh(ib,itide,1)= mod_tide(ib)*COS(phi_tide(ib)) 498 td%ssh(ib,itide,2)=-mod_tide(ib)*SIN(phi_tide(ib)) 499 ENDDO 500 END DO 501 ! 502 DEALLOCATE( mod_tide, phi_tide ) 406 ! 407 DEALLOCATE( mod_tide, phi_tide ) 408 ! 409 ENDIF 503 410 ! 504 411 END SUBROUTINE tide_init_elevation … … 512 419 TYPE(TIDES_DATA), INTENT(inout) :: td ! tidal harmonics data 513 420 ! 514 INTEGER :: itide, igrd, ib ! dummy loop indices 515 INTEGER, DIMENSION(3) :: ilen0 ! length of boundary data (from OBC arrays) 421 INTEGER :: itide, isz, ib ! dummy loop indices 516 422 REAL(wp),ALLOCATABLE, DIMENSION(:) :: mod_tide, phi_tide 517 423 !!---------------------------------------------------------------------- 518 424 ! 519 ilen0(2) = SIZE(td%u0(:,1,1)) 520 ilen0(3) = SIZE(td%v0(:,1,1)) 521 ! 522 igrd=2 ! U grid. 523 ! 524 ALLOCATE( mod_tide(ilen0(igrd)) , phi_tide(ilen0(igrd)) ) 525 ! 526 DO itide = 1, nb_harmo 527 DO ib = 1, ilen0(igrd) 528 mod_tide(ib)=SQRT(td%u0(ib,itide,1)**2.+td%u0(ib,itide,2)**2.) 529 phi_tide(ib)=ATAN2(-td%u0(ib,itide,2),td%u0(ib,itide,1)) 425 IF( ASSOCIATED(td%u0) ) THEN ! U grid. we use bdy u2d on this mpi subdomain 426 ! 427 isz = SIZE( td%u0, dim = 1 ) 428 ALLOCATE( mod_tide(isz), phi_tide(isz) ) 429 ! 430 DO itide = 1, nb_harmo 431 DO ib = 1, isz 432 mod_tide(ib)=SQRT( td%u0(ib,itide,1)*td%u0(ib,itide,1) + td%u0(ib,itide,2)*td%u0(ib,itide,2) ) 433 phi_tide(ib)=ATAN2(-td%u0(ib,itide,2),td%u0(ib,itide,1)) 434 END DO 435 DO ib = 1, isz 436 mod_tide(ib)=mod_tide(ib)*tide_harmonics(itide)%f 437 phi_tide(ib)=phi_tide(ib)+tide_harmonics(itide)%v0 + tide_harmonics(itide)%u 438 END DO 439 DO ib = 1, isz 440 td%u(ib,itide,1)= mod_tide(ib)*COS(phi_tide(ib)) 441 td%u(ib,itide,2)=-mod_tide(ib)*SIN(phi_tide(ib)) 442 END DO 530 443 END DO 531 DO ib = 1, ilen0(igrd) 532 mod_tide(ib)=mod_tide(ib)*ftide(itide) 533 phi_tide(ib)=phi_tide(ib)+v0tide(itide)+utide(itide) 534 ENDDO 535 DO ib = 1, ilen0(igrd) 536 td%u(ib,itide,1)= mod_tide(ib)*COS(phi_tide(ib)) 537 td%u(ib,itide,2)=-mod_tide(ib)*SIN(phi_tide(ib)) 538 ENDDO 539 END DO 540 ! 541 DEALLOCATE( mod_tide , phi_tide ) 542 ! 543 igrd=3 ! V grid. 544 ! 545 ALLOCATE( mod_tide(ilen0(igrd)) , phi_tide(ilen0(igrd)) ) 546 547 DO itide = 1, nb_harmo 548 DO ib = 1, ilen0(igrd) 549 mod_tide(ib)=SQRT(td%v0(ib,itide,1)**2.+td%v0(ib,itide,2)**2.) 550 phi_tide(ib)=ATAN2(-td%v0(ib,itide,2),td%v0(ib,itide,1)) 444 ! 445 DEALLOCATE( mod_tide, phi_tide ) 446 ! 447 ENDIF 448 ! 449 IF( ASSOCIATED(td%v0) ) THEN ! V grid. we use bdy u2d on this mpi subdomain 450 ! 451 isz = SIZE( td%v0, dim = 1 ) 452 ALLOCATE( mod_tide(isz), phi_tide(isz) ) 453 ! 454 DO itide = 1, nb_harmo 455 DO ib = 1, isz 456 mod_tide(ib)=SQRT( td%v0(ib,itide,1)*td%v0(ib,itide,1) + td%v0(ib,itide,2)*td%v0(ib,itide,2) ) 457 phi_tide(ib)=ATAN2(-td%v0(ib,itide,2),td%v0(ib,itide,1)) 458 END DO 459 DO ib = 1, isz 460 mod_tide(ib)=mod_tide(ib)*tide_harmonics(itide)%f 461 phi_tide(ib)=phi_tide(ib)+tide_harmonics(itide)%v0 + tide_harmonics(itide)%u 462 END DO 463 DO ib = 1, isz 464 td%v(ib,itide,1)= mod_tide(ib)*COS(phi_tide(ib)) 465 td%v(ib,itide,2)=-mod_tide(ib)*SIN(phi_tide(ib)) 466 END DO 551 467 END DO 552 DO ib = 1, ilen0(igrd) 553 mod_tide(ib)=mod_tide(ib)*ftide(itide) 554 phi_tide(ib)=phi_tide(ib)+v0tide(itide)+utide(itide) 555 ENDDO 556 DO ib = 1, ilen0(igrd) 557 td%v(ib,itide,1)= mod_tide(ib)*COS(phi_tide(ib)) 558 td%v(ib,itide,2)=-mod_tide(ib)*SIN(phi_tide(ib)) 559 ENDDO 560 END DO 561 ! 562 DEALLOCATE( mod_tide, phi_tide ) 563 ! 564 END SUBROUTINE tide_init_velocities 468 ! 469 DEALLOCATE( mod_tide, phi_tide ) 470 ! 471 ENDIF 472 ! 473 END SUBROUTINE tide_init_velocities 565 474 566 475 !!======================================================================
Note: See TracChangeset
for help on using the changeset viewer.