New URL for NEMO forge!   http://forge.nemo-ocean.eu

Since March 2022 along with NEMO 4.2 release, the code development moved to a self-hosted GitLab.
This present forge is now archived and remained online for history.
Changeset 8908 for branches/2017/dev_METO_2017/NEMOGCM/NEMO/OPA_SRC/SBC/sbcwave.F90 – NEMO

Ignore:
Timestamp:
2017-12-06T10:36:02+01:00 (7 years ago)
Author:
timgraham
Message:

Merged branches/UKMO/r8727_WAVE-2_Clementi_add_coupling into branch

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/2017/dev_METO_2017/NEMOGCM/NEMO/OPA_SRC/SBC/sbcwave.F90

    r7864 r8908  
    3333 
    3434   PUBLIC   sbc_stokes      ! routine called in sbccpl 
     35   PUBLIC   sbc_wstress     ! routine called in sbcmod  
    3536   PUBLIC   sbc_wave        ! routine called in sbcmod 
    3637   PUBLIC   sbc_wave_init   ! routine called in sbcmod 
     
    4243   LOGICAL, PUBLIC ::   cpl_sdrfty = .FALSE. 
    4344   LOGICAL, PUBLIC ::   cpl_wper   = .FALSE. 
     45   LOGICAL, PUBLIC ::   cpl_wfreq  = .FALSE. 
    4446   LOGICAL, PUBLIC ::   cpl_wnum   = .FALSE. 
    45    LOGICAL, PUBLIC ::   cpl_wstrf  = .FALSE. 
     47   LOGICAL, PUBLIC ::   cpl_tauoc  = .FALSE. 
     48   LOGICAL, PUBLIC ::   cpl_tauw   = .FALSE. 
    4649   LOGICAL, PUBLIC ::   cpl_wdrag  = .FALSE. 
    4750 
     
    5154   INTEGER ::   jp_hsw   ! index of significant wave hight      (m)      at T-point 
    5255   INTEGER ::   jp_wmp   ! index of mean wave period            (s)      at T-point 
     56   INTEGER ::   jp_wfr   ! index of wave peak frequency         (1/s)    at T-point 
    5357 
    5458   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_cd      ! structure of input fields (file informations, fields read) Drag Coefficient 
     
    5660   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_wn      ! structure of input fields (file informations, fields read) wave number for Qiao 
    5761   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_tauoc   ! structure of input fields (file informations, fields read) normalized wave stress into the ocean 
     62   TYPE(FLD), ALLOCATABLE, DIMENSION(:) ::   sf_tauw    ! structure of input fields (file informations, fields read) ocean stress components from wave model 
     63 
    5864   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   cdn_wave            !: 
    5965   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   hsw, wmp, wnum      !:  
     66   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   wfreq               !:  
    6067   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   tauoc_wave          !:   
     68   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   tauw_x, tauw_y      !:   
    6169   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   tsd2d               !:  
    6270   REAL(wp), PUBLIC, ALLOCATABLE, DIMENSION(:,:)   ::   div_sd              !: barotropic stokes drift divergence 
     
    96104      CALL wrk_alloc( jpi,jpj,       zk_t, zk_u, zk_v, zu0_sd, zv0_sd ) 
    97105      ! 
    98       ! 
    99       zfac =  2.0_wp * rpi / 16.0_wp 
    100       DO jj = 1, jpj                ! exp. wave number at t-point    (Eq. (19) in Breivick et al. (2014) ) 
    101          DO ji = 1, jpi 
     106      ! select parameterization for the calculation of vertical Stokes drift 
     107      ! exp. wave number at t-point 
     108      IF( nn_sdrift==jp_breivik .OR. nn_sdrift==jp_phillips ) THEN   ! (Eq. (19) in Breivick et al. (2014) ) 
     109         zfac = 2.0_wp * rpi / 16.0_wp 
     110         DO jj = 1, jpj 
     111            DO ji = 1, jpi 
    102112               ! Stokes drift velocity estimated from Hs and Tmean 
    103                ztransp = zfac * hsw(ji,jj)*hsw(ji,jj) / MAX( wmp(ji,jj) , 0.0000001_wp ) 
     113               ztransp = zfac * hsw(ji,jj)*hsw(ji,jj) / MAX( wmp(ji,jj), 0.0000001_wp ) 
    104114               ! Stokes surface speed 
    105                zsp0 = SQRT( ut0sd(ji,jj)*ut0sd(ji,jj) + vt0sd(ji,jj)*vt0sd(ji,jj) ) 
    106                tsd2d(ji,jj) = zsp0 
     115               tsd2d(ji,jj) = SQRT( ut0sd(ji,jj)*ut0sd(ji,jj) + vt0sd(ji,jj)*vt0sd(ji,jj)) 
    107116               ! Wavenumber scale 
    108                zk_t(ji,jj) = ABS( zsp0 ) / MAX( ABS( 5.97_wp*ztransp ) , 0.0000001_wp ) 
    109          END DO 
    110       END DO       
    111       DO jj = 1, jpjm1              ! exp. wave number & Stokes drift velocity at u- & v-points 
    112          DO ji = 1, jpim1 
    113             zk_u(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji+1,jj) ) 
    114             zk_v(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji,jj+1) ) 
    115             ! 
    116             zu0_sd(ji,jj) = 0.5_wp * ( ut0sd(ji,jj) + ut0sd(ji+1,jj) ) 
    117             zv0_sd(ji,jj) = 0.5_wp * ( vt0sd(ji,jj) + vt0sd(ji,jj+1) ) 
    118          END DO 
    119       END DO 
     117               zk_t(ji,jj) = ABS( tsd2d(ji,jj) ) / MAX( ABS( 5.97_wp*ztransp ), 0.0000001_wp ) 
     118            END DO 
     119         END DO 
     120         DO jj = 1, jpjm1              ! exp. wave number & Stokes drift velocity at u- & v-points 
     121            DO ji = 1, jpim1 
     122               zk_u(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji+1,jj) ) 
     123               zk_v(ji,jj) = 0.5_wp * ( zk_t(ji,jj) + zk_t(ji,jj+1) ) 
     124               ! 
     125               zu0_sd(ji,jj) = 0.5_wp * ( ut0sd(ji,jj) + ut0sd(ji+1,jj) ) 
     126               zv0_sd(ji,jj) = 0.5_wp * ( vt0sd(ji,jj) + vt0sd(ji,jj+1) ) 
     127            END DO 
     128         END DO 
     129      ELSE IF( nn_sdrift==jp_peakfr ) THEN    ! peak wave number calculated from the peak frequency received by the wave model 
     130         DO jj = 1, jpjm1 
     131            DO ji = 1, jpim1 
     132               zk_u(ji,jj) = 0.5_wp * ( wfreq(ji,jj)*wfreq(ji,jj) + wfreq(ji+1,jj)*wfreq(ji+1,jj) ) / grav 
     133               zk_v(ji,jj) = 0.5_wp * ( wfreq(ji,jj)*wfreq(ji,jj) + wfreq(ji,jj+1)*wfreq(ji,jj+1) ) / grav 
     134               ! 
     135               zu0_sd(ji,jj) = 0.5_wp * ( ut0sd(ji,jj) + ut0sd(ji+1,jj) ) 
     136               zv0_sd(ji,jj) = 0.5_wp * ( vt0sd(ji,jj) + vt0sd(ji,jj+1) ) 
     137            END DO 
     138         END DO 
     139      ENDIF 
    120140      ! 
    121141      !                       !==  horizontal Stokes Drift 3D velocity  ==! 
    122       DO jk = 1, jpkm1 
    123          DO jj = 2, jpjm1 
    124             DO ji = 2, jpim1 
    125                zdep_u = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji+1,jj,jk) ) 
    126                zdep_v = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji,jj+1,jk) ) 
    127                !                           
    128                zkh_u = zk_u(ji,jj) * zdep_u     ! k * depth 
    129                zkh_v = zk_v(ji,jj) * zdep_v 
    130                !                                ! Depth attenuation 
    131                zda_u = EXP( -2.0_wp*zkh_u ) / ( 1.0_wp + 8.0_wp*zkh_u ) 
    132                zda_v = EXP( -2.0_wp*zkh_v ) / ( 1.0_wp + 8.0_wp*zkh_v ) 
    133                ! 
    134                usd(ji,jj,jk) = zda_u * zu0_sd(ji,jj) * umask(ji,jj,jk) 
    135                vsd(ji,jj,jk) = zda_v * zv0_sd(ji,jj) * vmask(ji,jj,jk) 
    136             END DO 
    137          END DO 
    138       END DO    
     142      IF( nn_sdrift==jp_breivik ) THEN 
     143         DO jk = 1, jpkm1 
     144            DO jj = 2, jpjm1 
     145               DO ji = 2, jpim1 
     146                  zdep_u = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji+1,jj,jk) ) 
     147                  zdep_v = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji,jj+1,jk) ) 
     148                  !                           
     149                  zkh_u = zk_u(ji,jj) * zdep_u     ! k * depth 
     150                  zkh_v = zk_v(ji,jj) * zdep_v 
     151                  !                                ! Depth attenuation 
     152                  zda_u = EXP( -2.0_wp*zkh_u ) / ( 1.0_wp + 8.0_wp*zkh_u ) 
     153                  zda_v = EXP( -2.0_wp*zkh_v ) / ( 1.0_wp + 8.0_wp*zkh_v ) 
     154                  ! 
     155                  usd(ji,jj,jk) = zda_u * zu0_sd(ji,jj) * umask(ji,jj,jk) 
     156                  vsd(ji,jj,jk) = zda_v * zv0_sd(ji,jj) * vmask(ji,jj,jk) 
     157               END DO 
     158            END DO 
     159         END DO 
     160      ELSE IF( nn_sdrift==jp_phillips .OR. nn_sdrift==jp_peakfr ) THEN 
     161         DO jk = 1, jpkm1 
     162            DO jj = 2, jpjm1 
     163               DO ji = 2, jpim1 
     164                  zdep_u = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji+1,jj,jk) ) 
     165                  zdep_v = 0.5_wp * ( gdept_n(ji,jj,jk) + gdept_n(ji,jj+1,jk) ) 
     166                  !                           
     167                  zkh_u = zk_u(ji,jj) * zdep_u     ! k * depth 
     168                  zkh_v = zk_v(ji,jj) * zdep_v 
     169                  !                                ! Depth attenuation 
     170                  zda_u = EXP( -2.0_wp*zkh_u ) - SQRT(2.0_wp*rpi*zkh_u) * ERFC(SQRT(2.0_wp*zkh_u)) 
     171                  zda_v = EXP( -2.0_wp*zkh_v ) - SQRT(2.0_wp*rpi*zkh_v) * ERFC(SQRT(2.0_wp*zkh_v)) 
     172                  ! 
     173                  usd(ji,jj,jk) = zda_u * zu0_sd(ji,jj) * umask(ji,jj,jk) 
     174                  vsd(ji,jj,jk) = zda_v * zv0_sd(ji,jj) * vmask(ji,jj,jk) 
     175               END DO 
     176            END DO 
     177         END DO 
     178      ENDIF 
     179 
    139180      CALL lbc_lnk( usd(:,:,:), 'U', vsd(:,:,:), 'V', -1. ) 
    140181      ! 
     
    189230 
    190231 
     232   SUBROUTINE sbc_wstress( ) 
     233      !!--------------------------------------------------------------------- 
     234      !!                     ***  ROUTINE sbc_wstress  *** 
     235      !! 
     236      !! ** Purpose :   Updates the ocean momentum modified by waves 
     237      !! 
     238      !! ** Method  : - Calculate u,v components of stress depending on stress 
     239      !!                model  
     240      !!              - Calculate the stress module 
     241      !!              - The wind module is not modified by waves  
     242      !! ** action   
     243      !!--------------------------------------------------------------------- 
     244      INTEGER  ::   jj, ji   ! dummy loop argument 
     245      ! 
     246      IF( ln_tauoc ) THEN 
     247         utau(:,:) = utau(:,:)*tauoc_wave(:,:) 
     248         vtau(:,:) = vtau(:,:)*tauoc_wave(:,:) 
     249         taum(:,:) = taum(:,:)*tauoc_wave(:,:) 
     250      ENDIF 
     251      ! 
     252      IF( ln_tauw ) THEN 
     253         DO jj = 1, jpjm1 
     254            DO ji = 1, jpim1 
     255               ! Stress components at u- & v-points 
     256               utau(ji,jj) = 0.5_wp * ( tauw_x(ji,jj) + tauw_x(ji+1,jj) ) 
     257               vtau(ji,jj) = 0.5_wp * ( tauw_y(ji,jj) + tauw_y(ji,jj+1) ) 
     258               ! 
     259               ! Stress module at t points 
     260               taum(ji,jj) = SQRT( tauw_x(ji,jj)*tauw_x(ji,jj) + tauw_y(ji,jj)*tauw_y(ji,jj) ) 
     261            END DO 
     262         END DO 
     263 
     264      ENDIF 
     265      ! 
     266   END SUBROUTINE sbc_wstress 
     267 
     268 
    191269   SUBROUTINE sbc_wave( kt ) 
    192270      !!--------------------------------------------------------------------- 
     
    211289      ENDIF 
    212290 
    213       IF( ln_tauoc .AND. .NOT. cpl_wstrf ) THEN    !==  Wave induced stress  ==! 
     291      IF( ln_tauoc .AND. .NOT. cpl_tauoc ) THEN    !==  Wave induced stress  ==! 
    214292         CALL fld_read( kt, nn_fsbc, sf_tauoc )          ! read wave norm stress from external forcing 
    215293         tauoc_wave(:,:) = sf_tauoc(1)%fnow(:,:,1) 
     294      ENDIF 
     295 
     296      IF( ln_tauw .AND. .NOT. cpl_tauw ) THEN      !==  Wave induced stress  ==! 
     297         CALL fld_read( kt, nn_fsbc, sf_tauw )           ! read ocean stress components from external forcing (T grid) 
     298         tauw_x(:,:) = sf_tauw(1)%fnow(:,:,1) 
     299         tauw_y(:,:) = sf_tauw(2)%fnow(:,:,1) 
    216300      ENDIF 
    217301 
     
    222306            IF( jp_hsw > 0 )   hsw  (:,:) = sf_sd(jp_hsw)%fnow(:,:,1)   ! significant wave height 
    223307            IF( jp_wmp > 0 )   wmp  (:,:) = sf_sd(jp_wmp)%fnow(:,:,1)   ! wave mean period 
     308            IF( jp_wfr > 0 )   wfreq(:,:) = sf_sd(jp_wfr)%fnow(:,:,1)   ! Peak wave frequency 
    224309            IF( jp_usd > 0 )   ut0sd(:,:) = sf_sd(jp_usd)%fnow(:,:,1)   ! 2D zonal Stokes Drift at T point 
    225310            IF( jp_vsd > 0 )   vt0sd(:,:) = sf_sd(jp_vsd)%fnow(:,:,1)   ! 2D meridional Stokes Drift at T point 
     
    234319         !                                         !==  Computation of the 3d Stokes Drift  ==!  
    235320         ! 
    236          IF( jpfld == 4 )   CALL sbc_stokes()            ! Calculate only if required fields are read 
    237          !                                               ! In coupled wave model-NEMO case the call is done after coupling 
     321         IF( ((nn_sdrift==jp_breivik .OR. nn_sdrift==jp_phillips) .AND. & 
     322                          jp_hsw>0 .AND. jp_wmp>0 .AND. jp_usd>0 .AND. jp_vsd>0) .OR. & 
     323             (nn_sdrift==jp_peakfr .AND. jp_wfr>0 .AND. jp_usd>0 .AND. jp_vsd>0) ) & 
     324            CALL sbc_stokes()            ! Calculate only if required fields are read 
     325         !                               ! In coupled wave model-NEMO case the call is done after coupling 
    238326         ! 
    239327      ENDIF 
     
    260348      !! 
    261349      CHARACTER(len=100)     ::  cn_dir                          ! Root directory for location of drag coefficient files 
    262       TYPE(FLD_N), ALLOCATABLE, DIMENSION(:) ::   slf_i     ! array of namelist informations on the fields to read 
     350      TYPE(FLD_N), ALLOCATABLE, DIMENSION(:) ::   slf_i, slf_j     ! array of namelist informations on the fields to read 
    263351      TYPE(FLD_N)            ::  sn_cdg, sn_usd, sn_vsd,  & 
    264                              &   sn_hsw, sn_wmp, sn_wnum, sn_tauoc      ! informations about the fields to be read 
    265       ! 
    266       NAMELIST/namsbc_wave/  sn_cdg, cn_dir, sn_usd, sn_vsd, sn_hsw, sn_wmp, sn_wnum, sn_tauoc 
     352                             &   sn_hsw, sn_wmp, sn_wfr, sn_wnum, & 
     353                             &   sn_tauoc, sn_tauwx, sn_tauwy      ! informations about the fields to be read 
     354      ! 
     355      NAMELIST/namsbc_wave/  sn_cdg, cn_dir, sn_usd, sn_vsd, sn_hsw, sn_wmp, sn_wfr, & 
     356                             sn_wnum, sn_tauoc, sn_tauwx, sn_tauwy 
    267357      !!--------------------------------------------------------------------- 
    268358      ! 
     
    289379 
    290380      IF( ln_tauoc ) THEN 
    291          IF( .NOT. cpl_wstrf ) THEN 
     381         IF( .NOT. cpl_tauoc ) THEN 
    292382            ALLOCATE( sf_tauoc(1), STAT=ierror )           !* allocate and fill sf_wave with sn_tauoc 
    293383            IF( ierror > 0 )   CALL ctl_stop( 'STOP', 'sbc_wave_init: unable to allocate sf_wave structure' ) 
     
    300390      ENDIF 
    301391 
     392      IF( ln_tauw ) THEN 
     393         IF( .NOT. cpl_tauw ) THEN 
     394            ALLOCATE( sf_tauw(2), STAT=ierror )           !* allocate and fill sf_wave with sn_tauwx/y 
     395            IF( ierror > 0 )   CALL ctl_stop( 'STOP', 'sbc_wave_init: unable to allocate sf_tauw structure' ) 
     396            ! 
     397            ALLOCATE( slf_j(2) ) 
     398            slf_j(1) = sn_tauwx 
     399            slf_j(2) = sn_tauwy 
     400                                    ALLOCATE( sf_tauw(1)%fnow(jpi,jpj,1)   ) 
     401                                    ALLOCATE( sf_tauw(2)%fnow(jpi,jpj,1)   ) 
     402            IF( slf_j(1)%ln_tint )  ALLOCATE( sf_tauw(1)%fdta(jpi,jpj,1,2) ) 
     403            IF( slf_j(2)%ln_tint )  ALLOCATE( sf_tauw(2)%fdta(jpi,jpj,1,2) ) 
     404            CALL fld_fill( sf_tauw, (/ slf_j /), cn_dir, 'sbc_wave_init', 'read wave input', 'namsbc_wave' ) 
     405         ENDIF 
     406         ALLOCATE( tauw_x(jpi,jpj) ) 
     407         ALLOCATE( tauw_y(jpi,jpj) ) 
     408      ENDIF 
     409 
    302410      IF( ln_sdw ) THEN   ! Find out how many fields have to be read from file if not coupled 
    303411         jpfld=0 
    304          jp_usd=0   ;   jp_vsd=0   ;   jp_hsw=0   ;   jp_wmp=0 
     412         jp_usd=0   ;   jp_vsd=0   ;   jp_hsw=0   ;   jp_wmp=0   ;   jp_wfr=0 
    305413         IF( .NOT. cpl_sdrftx ) THEN 
    306414            jpfld  = jpfld + 1 
     
    311419            jp_vsd = jpfld 
    312420         ENDIF 
    313          IF( .NOT. cpl_hsig ) THEN 
     421         IF( .NOT. cpl_hsig .AND. (nn_sdrift==jp_breivik .OR. nn_sdrift==jp_phillips) ) THEN 
    314422            jpfld  = jpfld + 1 
    315423            jp_hsw = jpfld 
    316424         ENDIF 
    317          IF( .NOT. cpl_wper ) THEN 
     425         IF( .NOT. cpl_wper .AND. (nn_sdrift==jp_breivik .OR. nn_sdrift==jp_phillips) ) THEN 
    318426            jpfld  = jpfld + 1 
    319427            jp_wmp = jpfld 
     428         ENDIF 
     429         IF( .NOT. cpl_wfreq .AND. nn_sdrift==jp_peakfr ) THEN 
     430            jpfld  = jpfld + 1 
     431            jp_wfr = jpfld 
    320432         ENDIF 
    321433 
     
    327439            IF( jp_hsw > 0 )   slf_i(jp_hsw) = sn_hsw 
    328440            IF( jp_wmp > 0 )   slf_i(jp_wmp) = sn_wmp 
     441            IF( jp_wfr > 0 )   slf_i(jp_wfr) = sn_wfr 
     442 
    329443            ALLOCATE( sf_sd(jpfld), STAT=ierror )   !* allocate and fill sf_sd with stokes drift 
    330444            IF( ierror > 0 )   CALL ctl_stop( 'STOP', 'sbc_wave_init: unable to allocate sf_wave structure' ) 
     
    339453         ALLOCATE( usd  (jpi,jpj,jpk), vsd  (jpi,jpj,jpk), wsd(jpi,jpj,jpk) ) 
    340454         ALLOCATE( hsw  (jpi,jpj)    , wmp  (jpi,jpj)     ) 
     455         ALLOCATE( wfreq(jpi,jpj) ) 
    341456         ALLOCATE( ut0sd(jpi,jpj)    , vt0sd(jpi,jpj)     ) 
    342457         ALLOCATE( div_sd(jpi,jpj) ) 
Note: See TracChangeset for help on using the changeset viewer.