MODULE analytical_mod ! !svn $Id: analytical.F 334 2009-03-24 22:38:49Z arango $ !================================================== Hernan G. Arango === ! Copyright (c) 2002-2009 The ROMS/TOMS Group ! ! Licensed under a MIT/X style license ! ! See License_ROMS.txt ! !======================================================================= ! ! ! PACKAGE: ! ! ! ! This package is used to provide various analytical fields to the ! ! model when appropriate. ! ! ! !======================================================================= ! implicit none CONTAINS SUBROUTINE ana_btflux (ng, tile, model, itrc) ! !======================================================================= ! ! ! This routine sets kinematic bottom flux of tracer type variables ! ! (tracer units m/s). ! ! ! !======================================================================= ! USE mod_param USE mod_forces USE mod_ncparam ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model, itrc integer :: IminS, ImaxS, JminS, JmaxS integer :: LBi, UBi, LBj, UBj, LBij, UBij ! ! Set horizontal starting and ending indices for automatic private storage ! arrays. ! IminS=BOUNDS(ng)%Istr(tile)-3 ImaxS=BOUNDS(ng)%Iend(tile)+3 JminS=BOUNDS(ng)%Jstr(tile)-3 JmaxS=BOUNDS(ng)%Jend(tile)+3 ! ! Determine array lower and upper bounds in the I- and J-directions. ! LBi=BOUNDS(ng)%LBi(tile) UBi=BOUNDS(ng)%UBi(tile) LBj=BOUNDS(ng)%LBj(tile) UBj=BOUNDS(ng)%UBj(tile) ! ! Set array lower and upper bounds for MIN(I,J)- and MAX(I,J)-directions. ! LBij=BOUNDS(ng)%LBij UBij=BOUNDS(ng)%UBij ! CALL ana_btflux_tile (ng, tile, model, itrc, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & FORCES(ng) % btflx) ! ! Set analytical header file name used. ! IF (Lanafile) THEN ANANAME( 3)="ROMS/Functionals/ana_btflux.h" END IF RETURN END SUBROUTINE ana_btflux ! !*********************************************************************** SUBROUTINE ana_btflux_tile (ng, tile, model, itrc, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & btflx) !*********************************************************************** ! USE mod_param USE mod_scalars ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model, itrc integer, intent(in) :: LBi, UBi, LBj, UBj integer, intent(in) :: IminS, ImaxS, JminS, JmaxS ! real(r8), intent(inout) :: btflx(LBi:,LBj:,:) ! ! Local variable declarations. ! integer :: i, j ! !----------------------------------------------------------------------- ! Set lower and upper tile bounds and staggered variables bounds for ! this horizontal domain partition. Notice that if tile=-1, it will ! set the values for the global grid. !----------------------------------------------------------------------- ! integer :: Istr, IstrR, IstrT, IstrU, Iend, IendR, IendT integer :: Jstr, JstrR, JstrT, JstrV, Jend, JendR, JendT ! Istr =BOUNDS(ng)%Istr (tile) IstrR=BOUNDS(ng)%IstrR(tile) IstrT=BOUNDS(ng)%IstrT(tile) IstrU=BOUNDS(ng)%IstrU(tile) Iend =BOUNDS(ng)%Iend (tile) IendR=BOUNDS(ng)%IendR(tile) IendT=BOUNDS(ng)%IendT(tile) Jstr =BOUNDS(ng)%Jstr (tile) JstrR=BOUNDS(ng)%JstrR(tile) JstrT=BOUNDS(ng)%JstrT(tile) JstrV=BOUNDS(ng)%JstrV(tile) Jend =BOUNDS(ng)%Jend (tile) JendR=BOUNDS(ng)%JendR(tile) JendT=BOUNDS(ng)%JendT(tile) ! !----------------------------------------------------------------------- ! Set kinematic bottom heat flux (degC m/s) at horizontal RHO-points. !----------------------------------------------------------------------- ! IF (itrc.eq.itemp) THEN DO j=JstrR,JendR DO i=IstrR,IendR btflx(i,j,itrc)=0.0_r8 END DO END DO ! !----------------------------------------------------------------------- ! Set kinematic bottom salt flux (m/s) at horizontal RHO-points, ! scaling by bottom salinity is done elsewhere. !----------------------------------------------------------------------- ! ELSE IF (itrc.eq.isalt) THEN DO j=JstrR,JendR DO i=IstrR,IendR btflx(i,j,itrc)=0.0_r8 END DO END DO ! !----------------------------------------------------------------------- ! Set kinematic bottom flux (T m/s) of passive tracers, if any. !----------------------------------------------------------------------- ! ELSE DO j=JstrR,JendR DO i=IstrR,IendR btflx(i,j,itrc)=0.0_r8 END DO END DO END IF RETURN END SUBROUTINE ana_btflux_tile SUBROUTINE ana_fsobc (ng, tile, model) ! !======================================================================= ! ! ! This routine sets free-surface open boundary conditions using ! ! analytical expressions. ! ! ! !======================================================================= ! USE mod_param USE mod_ncparam ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer :: IminS, ImaxS, JminS, JmaxS integer :: LBi, UBi, LBj, UBj, LBij, UBij ! ! Set horizontal starting and ending indices for automatic private storage ! arrays. ! IminS=BOUNDS(ng)%Istr(tile)-3 ImaxS=BOUNDS(ng)%Iend(tile)+3 JminS=BOUNDS(ng)%Jstr(tile)-3 JmaxS=BOUNDS(ng)%Jend(tile)+3 ! ! Determine array lower and upper bounds in the I- and J-directions. ! LBi=BOUNDS(ng)%LBi(tile) UBi=BOUNDS(ng)%UBi(tile) LBj=BOUNDS(ng)%LBj(tile) UBj=BOUNDS(ng)%UBj(tile) ! ! Set array lower and upper bounds for MIN(I,J)- and MAX(I,J)-directions. ! LBij=BOUNDS(ng)%LBij UBij=BOUNDS(ng)%UBij ! CALL ana_fsobc_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS) ! ! Set analytical header file name used. ! IF (Lanafile) THEN ANANAME( 6)="ROMS/Functionals/ana_fsobc.h" END IF RETURN END SUBROUTINE ana_fsobc ! !*********************************************************************** SUBROUTINE ana_fsobc_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS) !*********************************************************************** ! USE mod_param USE mod_boundary USE mod_grid USE mod_scalars ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer, intent(in) :: LBi, UBi, LBj, UBj integer, intent(in) :: IminS, ImaxS, JminS, JmaxS ! ! Local variable declarations. ! integer :: i, j real(r8) :: cff, fac, omega, phase, val ! !----------------------------------------------------------------------- ! Set lower and upper tile bounds and staggered variables bounds for ! this horizontal domain partition. Notice that if tile=-1, it will ! set the values for the global grid. !----------------------------------------------------------------------- ! integer :: Istr, IstrR, IstrT, IstrU, Iend, IendR, IendT integer :: Jstr, JstrR, JstrT, JstrV, Jend, JendR, JendT ! Istr =BOUNDS(ng)%Istr (tile) IstrR=BOUNDS(ng)%IstrR(tile) IstrT=BOUNDS(ng)%IstrT(tile) IstrU=BOUNDS(ng)%IstrU(tile) Iend =BOUNDS(ng)%Iend (tile) IendR=BOUNDS(ng)%IendR(tile) IendT=BOUNDS(ng)%IendT(tile) Jstr =BOUNDS(ng)%Jstr (tile) JstrR=BOUNDS(ng)%JstrR(tile) JstrT=BOUNDS(ng)%JstrT(tile) JstrV=BOUNDS(ng)%JstrV(tile) Jend =BOUNDS(ng)%Jend (tile) JendR=BOUNDS(ng)%JendR(tile) JendT=BOUNDS(ng)%JendT(tile) ! !----------------------------------------------------------------------- ! Free-surface open boundary conditions. !----------------------------------------------------------------------- ! IF (Iend.eq.Lm(ng)) THEN DO j=JstrR,JendR BOUNDARY(ng)%zeta_east(j)=0.0_r8 END DO END IF IF (Istr.eq.1) THEN DO j=JstrR,JendR BOUNDARY(ng)%zeta_west(j)=0.0_r8 END DO END IF IF (Jstr.eq.1) THEN DO i=IstrR,IendR BOUNDARY(ng)%zeta_south(i)=0.0_r8 END DO END IF RETURN END SUBROUTINE ana_fsobc_tile SUBROUTINE ana_m2obc (ng, tile, model) ! !======================================================================= ! ! ! This routine sets 2D momentum open boundary conditions using ! ! analytical expressions. ! ! ! !======================================================================= ! USE mod_param USE mod_grid USE mod_ncparam USE mod_ocean USE mod_stepping ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer :: IminS, ImaxS, JminS, JmaxS integer :: LBi, UBi, LBj, UBj, LBij, UBij ! ! Set horizontal starting and ending indices for automatic private storage ! arrays. ! IminS=BOUNDS(ng)%Istr(tile)-3 ImaxS=BOUNDS(ng)%Iend(tile)+3 JminS=BOUNDS(ng)%Jstr(tile)-3 JmaxS=BOUNDS(ng)%Jend(tile)+3 ! ! Determine array lower and upper bounds in the I- and J-directions. ! LBi=BOUNDS(ng)%LBi(tile) UBi=BOUNDS(ng)%UBi(tile) LBj=BOUNDS(ng)%LBj(tile) UBj=BOUNDS(ng)%UBj(tile) ! ! Set array lower and upper bounds for MIN(I,J)- and MAX(I,J)-directions. ! LBij=BOUNDS(ng)%LBij UBij=BOUNDS(ng)%UBij ! CALL ana_m2obc_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & knew(ng), & & GRID(ng) % angler, & & GRID(ng) % h, & & GRID(ng) % pm, & & GRID(ng) % pn, & & GRID(ng) % on_u, & & GRID(ng) % umask, & & OCEAN(ng) % zeta) ! ! Set analytical header file name used. ! IF (Lanafile) THEN ANANAME(12)="ROMS/Functionals/ana_m2obc.h" END IF RETURN END SUBROUTINE ana_m2obc ! !*********************************************************************** SUBROUTINE ana_m2obc_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & knew, & & angler, h, pm, pn, on_u, & & umask, & & zeta) !*********************************************************************** ! USE mod_param USE mod_boundary USE mod_grid USE mod_scalars ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer, intent(in) :: LBi, UBi, LBj, UBj integer, intent(in) :: IminS, ImaxS, JminS, JmaxS integer, intent(in) :: knew ! real(r8), intent(in) :: angler(LBi:,LBj:) real(r8), intent(in) :: h(LBi:,LBj:) real(r8), intent(in) :: pm(LBi:,LBj:) real(r8), intent(in) :: pn(LBi:,LBj:) real(r8), intent(in) :: on_u(LBi:,LBj:) real(r8), intent(in) :: umask(LBi:,LBj:) real(r8), intent(in) :: zeta(LBi:,LBj:,:) ! ! Local variable declarations. ! integer :: i, j real(r8) :: angle, cff, fac, major, minor, omega, phase, val real(r8) :: ramp ! !----------------------------------------------------------------------- ! Set lower and upper tile bounds and staggered variables bounds for ! this horizontal domain partition. Notice that if tile=-1, it will ! set the values for the global grid. !----------------------------------------------------------------------- ! integer :: Istr, IstrR, IstrT, IstrU, Iend, IendR, IendT integer :: Jstr, JstrR, JstrT, JstrV, Jend, JendR, JendT ! Istr =BOUNDS(ng)%Istr (tile) IstrR=BOUNDS(ng)%IstrR(tile) IstrT=BOUNDS(ng)%IstrT(tile) IstrU=BOUNDS(ng)%IstrU(tile) Iend =BOUNDS(ng)%Iend (tile) IendR=BOUNDS(ng)%IendR(tile) IendT=BOUNDS(ng)%IendT(tile) Jstr =BOUNDS(ng)%Jstr (tile) JstrR=BOUNDS(ng)%JstrR(tile) JstrT=BOUNDS(ng)%JstrT(tile) JstrV=BOUNDS(ng)%JstrV(tile) Jend =BOUNDS(ng)%Jend (tile) JendR=BOUNDS(ng)%JendR(tile) JendT=BOUNDS(ng)%JendT(tile) ! !----------------------------------------------------------------------- ! 2D momentum open boundary conditions. !----------------------------------------------------------------------- ! IF (Iend.eq.Lm(ng)) THEN DO j=JstrR,JendR BOUNDARY(ng)%ubar_east(j)=0.0_r8 END DO DO j=Jstr,JendR BOUNDARY(ng)%vbar_east(j)=0.0_r8 END DO END IF IF (Istr.eq.1) THEN DO j=JstrR,JendR BOUNDARY(ng)%ubar_west(j)=0.0_r8 END DO DO j=Jstr,JendR BOUNDARY(ng)%vbar_west(j)=0.0_r8 END DO END IF IF (Jstr.eq.1) THEN DO i=Istr,IendR BOUNDARY(ng)%ubar_south(i)=0.0_r8 END DO DO i=IstrR,IendR BOUNDARY(ng)%vbar_south(i)=0.0_r8 END DO END IF RETURN END SUBROUTINE ana_m2obc_tile SUBROUTINE ana_rain (ng, tile, model) ! !======================================================================= ! ! ! This routine sets precipitation rate (kg/m2/s) using an ! ! analytical expression. ! ! ! !======================================================================= ! USE mod_param USE mod_forces USE mod_ncparam ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer :: IminS, ImaxS, JminS, JmaxS integer :: LBi, UBi, LBj, UBj, LBij, UBij ! ! Set horizontal starting and ending indices for automatic private storage ! arrays. ! IminS=BOUNDS(ng)%Istr(tile)-3 ImaxS=BOUNDS(ng)%Iend(tile)+3 JminS=BOUNDS(ng)%Jstr(tile)-3 JmaxS=BOUNDS(ng)%Jend(tile)+3 ! ! Determine array lower and upper bounds in the I- and J-directions. ! LBi=BOUNDS(ng)%LBi(tile) UBi=BOUNDS(ng)%UBi(tile) LBj=BOUNDS(ng)%LBj(tile) UBj=BOUNDS(ng)%UBj(tile) ! ! Set array lower and upper bounds for MIN(I,J)- and MAX(I,J)-directions. ! LBij=BOUNDS(ng)%LBij UBij=BOUNDS(ng)%UBij ! CALL ana_rain_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & FORCES(ng) % rain) ! ! Set analytical header file name used. ! IF (Lanafile) THEN ANANAME(21)="/home/beach/guest/dafu8991/CALUS/FUNCTIONALS/ana_rain.h" END IF RETURN END SUBROUTINE ana_rain ! !*********************************************************************** SUBROUTINE ana_rain_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & rain) !*********************************************************************** ! USE mod_param ! USE mp_exchange_mod, ONLY : mp_exchange2d ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer, intent(in) :: LBi, UBi, LBj, UBj integer, intent(in) :: IminS, ImaxS, JminS, JmaxS ! real(r8), intent(out) :: rain(LBi:,LBj:) ! ! Local variable declarations. ! logical :: EWperiodic=.FALSE. logical :: NSperiodic=.FALSE. integer :: i, j ! !----------------------------------------------------------------------- ! Set lower and upper tile bounds and staggered variables bounds for ! this horizontal domain partition. Notice that if tile=-1, it will ! set the values for the global grid. !----------------------------------------------------------------------- ! integer :: Istr, IstrR, IstrT, IstrU, Iend, IendR, IendT integer :: Jstr, JstrR, JstrT, JstrV, Jend, JendR, JendT ! Istr =BOUNDS(ng)%Istr (tile) IstrR=BOUNDS(ng)%IstrR(tile) IstrT=BOUNDS(ng)%IstrT(tile) IstrU=BOUNDS(ng)%IstrU(tile) Iend =BOUNDS(ng)%Iend (tile) IendR=BOUNDS(ng)%IendR(tile) IendT=BOUNDS(ng)%IendT(tile) Jstr =BOUNDS(ng)%Jstr (tile) JstrR=BOUNDS(ng)%JstrR(tile) JstrT=BOUNDS(ng)%JstrT(tile) JstrV=BOUNDS(ng)%JstrV(tile) Jend =BOUNDS(ng)%Jend (tile) JendR=BOUNDS(ng)%JendR(tile) JendT=BOUNDS(ng)%JendT(tile) ! !----------------------------------------------------------------------- ! Set analytical precipitation rate (kg/m2/s). !----------------------------------------------------------------------- ! DO j=JstrR,JendR DO i=IstrR,IendR rain(i,j)=0.0_r8 END DO END DO CALL mp_exchange2d (ng, tile, model, 1, & & LBi, UBi, LBj, UBj, & & NghostPoints, EWperiodic, NSperiodic, & & rain) RETURN END SUBROUTINE ana_rain_tile SUBROUTINE ana_srflux (ng, tile, model) ! !======================================================================= ! ! ! This subroutine sets kinematic surface solar shortwave radiation ! ! flux "srflx" (degC m/s) using an analytical expression. ! ! ! !======================================================================= ! USE mod_param USE mod_forces USE mod_grid USE mod_ncparam ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer :: IminS, ImaxS, JminS, JmaxS integer :: LBi, UBi, LBj, UBj, LBij, UBij ! ! Set horizontal starting and ending indices for automatic private storage ! arrays. ! IminS=BOUNDS(ng)%Istr(tile)-3 ImaxS=BOUNDS(ng)%Iend(tile)+3 JminS=BOUNDS(ng)%Jstr(tile)-3 JmaxS=BOUNDS(ng)%Jend(tile)+3 ! ! Determine array lower and upper bounds in the I- and J-directions. ! LBi=BOUNDS(ng)%LBi(tile) UBi=BOUNDS(ng)%UBi(tile) LBj=BOUNDS(ng)%LBj(tile) UBj=BOUNDS(ng)%UBj(tile) ! ! Set array lower and upper bounds for MIN(I,J)- and MAX(I,J)-directions. ! LBij=BOUNDS(ng)%LBij UBij=BOUNDS(ng)%UBij ! CALL ana_srflux_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & GRID(ng) % lonr, & & GRID(ng) % latr, & & FORCES(ng) % srflx) ! ! Set analytical header file name used. ! IF (Lanafile) THEN ANANAME(27)="/home/beach/guest/dafu8991/CALUS/FUNCTIONALS/ana_srflux.h" END IF RETURN END SUBROUTINE ana_srflux ! !*********************************************************************** SUBROUTINE ana_srflux_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & lonr, latr, & & srflx) !*********************************************************************** ! USE mod_param USE mod_scalars ! USE mp_exchange_mod, ONLY : mp_exchange2d ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer, intent(in) :: LBi, UBi, LBj, UBj integer, intent(in) :: IminS, ImaxS, JminS, JmaxS ! real(r8), intent(in) :: lonr(LBi:,LBj:) real(r8), intent(in) :: latr(LBi:,LBj:) real(r8), intent(out) :: srflx(LBi:,LBj:) ! ! Local variable declarations. ! logical :: EWperiodic=.FALSE. logical :: NSperiodic=.FALSE. integer :: i, j integer :: iday, month, year real(r8) :: Dangle, Hangle, LatRad real(r8) :: cff1, cff2, hour, yday real(r8) :: cff ! !----------------------------------------------------------------------- ! Set lower and upper tile bounds and staggered variables bounds for ! this horizontal domain partition. Notice that if tile=-1, it will ! set the values for the global grid. !----------------------------------------------------------------------- ! integer :: Istr, IstrR, IstrT, IstrU, Iend, IendR, IendT integer :: Jstr, JstrR, JstrT, JstrV, Jend, JendR, JendT ! Istr =BOUNDS(ng)%Istr (tile) IstrR=BOUNDS(ng)%IstrR(tile) IstrT=BOUNDS(ng)%IstrT(tile) IstrU=BOUNDS(ng)%IstrU(tile) Iend =BOUNDS(ng)%Iend (tile) IendR=BOUNDS(ng)%IendR(tile) IendT=BOUNDS(ng)%IendT(tile) Jstr =BOUNDS(ng)%Jstr (tile) JstrR=BOUNDS(ng)%JstrR(tile) JstrT=BOUNDS(ng)%JstrT(tile) JstrV=BOUNDS(ng)%JstrV(tile) Jend =BOUNDS(ng)%Jend (tile) JendR=BOUNDS(ng)%JendR(tile) JendT=BOUNDS(ng)%JendT(tile) ! !----------------------------------------------------------------------- ! Compute shortwave radiation (degC m/s): ! ! ALBEDO option: Compute shortwave radiation flux using the Laevastu ! cloud correction to the Zillman equation for cloudless ! radiation (Parkinson and Washington 1979, JGR, 84, 311-337). Notice ! that flux is scaled from W/m2 to degC m/s by dividing by (rho0*Cp). ! ! option: Modulate shortwave radiation SRFLX (which ! read and interpolated elsewhere) by the local ! diurnal cycle (a function of longitude, latitude and day-of-year). ! This option is provided for cases where SRFLX computed by SET_DATA is ! an average over >= 24 hours. For "diurnal_srflux" to work ana_srflux ! must be undefined. If you want a strictly analytical diurnal cycle ! enter it explicitly at the end of this subroutine or use the "albedo" ! option. ! ! For a review of shortwave radiation formulations check: ! ! Niemela, S., P. Raisanen, and H. Savijarvi, 2001: Comparison of ! surface radiative flux parameterizations, Part II, Shortwave ! radiation, Atmos. Res., 58, 141-154. ! !----------------------------------------------------------------------- ! ! Assume time is in modified Julian day. Get hour and year day. ! CALL caldate (r_date, tdays(ng), year, yday, month, iday, hour) ! ! Estimate solar declination angle (radians). ! Dangle=23.44_r8*COS((172.0_r8-yday)*2.0_r8*pi/365.25_r8) Dangle=Dangle*deg2rad ! ! Compute hour angle (radians). ! Hangle=(12.0_r8-hour)*pi/12.0_r8 ! DO j=JstrR,JendR DO i=IstrR,IendR ! ! Local daylight is a function of the declination (Dangle) and hour ! angle adjusted for the local meridian (Hangle-lonr(i,j)/15.0). ! The 15.0 factor is because the sun moves 15 degrees every hour. ! LatRad=latr(i,j)*deg2rad cff1=SIN(LatRad)*SIN(Dangle) cff2=COS(LatRad)*COS(Dangle) ! ! SRFLX is reset on each time step in subroutine SET_DATA which ! interpolates values in the forcing file to the current date. ! This option is provided so that SRFLX values ! corresponding to a greater or equal daily average can be modulated ! by the local length of day to produce a diurnal cycle with the ! same daily average as the original data. This approach assumes ! the net effect of clouds is incorporated into the SRFLX data. ! ! Normalization = (1/2*pi)*INTEGRAL{ABS(a+b*COS(t)) dt} from 0 to 2*pi ! = (a*ARCCOS(-a/b)+SQRT(b**2-a**2))/pi for |a| < |b| ! IF (ABS(cff1).gt.ABS(cff2)) THEN IF (cff1*cff2.gt.0.0_r8) THEN cff=cff1 ! All day case srflx(i,j)=MAX(0.0_r8, & & srflx(i,j)/cff* & & (cff1+cff2*COS(Hangle-lonr(i,j)*deg2rad))) ELSE srflx(i,j)=0.0_r8 ! All night case END IF ELSE cff=(cff1*ACOS(-cff1/cff2)+SQRT(cff2*cff2-cff1*cff1))/pi srflx(i,j)=MAX(0.0_r8, & & srflx(i,j)/cff* & & (cff1+cff2*COS(Hangle-lonr(i,j)*deg2rad))) END IF END DO END DO CALL mp_exchange2d (ng, tile, model, 1, & & LBi, UBi, LBj, UBj, & & NghostPoints, EWperiodic, NSperiodic, & & srflx) RETURN END SUBROUTINE ana_srflux_tile SUBROUTINE ana_stflux (ng, tile, model, itrc) ! !======================================================================= ! ! ! This routine sets kinematic surface flux of tracer type variables ! ! "stflx" (tracer units m/s) using analytical expressions. ! ! ! !======================================================================= ! USE mod_param USE mod_forces USE mod_ncparam ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model, itrc integer :: IminS, ImaxS, JminS, JmaxS integer :: LBi, UBi, LBj, UBj, LBij, UBij ! ! Set horizontal starting and ending indices for automatic private storage ! arrays. ! IminS=BOUNDS(ng)%Istr(tile)-3 ImaxS=BOUNDS(ng)%Iend(tile)+3 JminS=BOUNDS(ng)%Jstr(tile)-3 JmaxS=BOUNDS(ng)%Jend(tile)+3 ! ! Determine array lower and upper bounds in the I- and J-directions. ! LBi=BOUNDS(ng)%LBi(tile) UBi=BOUNDS(ng)%UBi(tile) LBj=BOUNDS(ng)%LBj(tile) UBj=BOUNDS(ng)%UBj(tile) ! ! Set array lower and upper bounds for MIN(I,J)- and MAX(I,J)-directions. ! LBij=BOUNDS(ng)%LBij UBij=BOUNDS(ng)%UBij ! CALL ana_stflux_tile (ng, tile, model, itrc, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & FORCES(ng) % srflx, & & FORCES(ng) % stflx) ! ! Set analytical header file name used. ! IF (Lanafile) THEN ANANAME(31)="ROMS/Functionals/ana_stflux.h" END IF RETURN END SUBROUTINE ana_stflux ! !*********************************************************************** SUBROUTINE ana_stflux_tile (ng, tile, model, itrc, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & srflx, & & stflx) !*********************************************************************** ! USE mod_param USE mod_scalars ! USE mp_exchange_mod, ONLY : mp_exchange2d ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model, itrc integer, intent(in) :: LBi, UBi, LBj, UBj integer, intent(in) :: IminS, ImaxS, JminS, JmaxS ! real(r8), intent(in) :: srflx(LBi:,LBj:) real(r8), intent(inout) :: stflx(LBi:,LBj:,:) ! ! Local variable declarations. ! logical :: EWperiodic=.FALSE. logical :: NSperiodic=.FALSE. integer :: i, j ! !----------------------------------------------------------------------- ! Set lower and upper tile bounds and staggered variables bounds for ! this horizontal domain partition. Notice that if tile=-1, it will ! set the values for the global grid. !----------------------------------------------------------------------- ! integer :: Istr, IstrR, IstrT, IstrU, Iend, IendR, IendT integer :: Jstr, JstrR, JstrT, JstrV, Jend, JendR, JendT ! Istr =BOUNDS(ng)%Istr (tile) IstrR=BOUNDS(ng)%IstrR(tile) IstrT=BOUNDS(ng)%IstrT(tile) IstrU=BOUNDS(ng)%IstrU(tile) Iend =BOUNDS(ng)%Iend (tile) IendR=BOUNDS(ng)%IendR(tile) IendT=BOUNDS(ng)%IendT(tile) Jstr =BOUNDS(ng)%Jstr (tile) JstrR=BOUNDS(ng)%JstrR(tile) JstrT=BOUNDS(ng)%JstrT(tile) JstrV=BOUNDS(ng)%JstrV(tile) Jend =BOUNDS(ng)%Jend (tile) JendR=BOUNDS(ng)%JendR(tile) JendT=BOUNDS(ng)%JendT(tile) ! !----------------------------------------------------------------------- ! Set kinematic surface heat flux (degC m/s) at horizontal ! RHO-points. !----------------------------------------------------------------------- ! IF (itrc.eq.itemp) THEN DO j=JstrR,JendR DO i=IstrR,IendR stflx(i,j,itrc)=0.0_r8 END DO END DO ! !----------------------------------------------------------------------- ! Set kinematic surface freshwater flux (m/s) at horizontal ! RHO-points, scaling by surface salinity is done in STEP3D. !----------------------------------------------------------------------- ! ELSE IF (itrc.eq.isalt) THEN DO j=JstrR,JendR DO i=IstrR,IendR stflx(i,j,itrc)=0.0_r8 END DO END DO ! !----------------------------------------------------------------------- ! Set kinematic surface flux (T m/s) of passive tracers, if any. !----------------------------------------------------------------------- ! ELSE DO j=JstrR,JendR DO i=IstrR,IendR stflx(i,j,itrc)=0.0_r8 END DO END DO END IF CALL mp_exchange2d (ng, tile, model, 1, & & LBi, UBi, LBj, UBj, & & NghostPoints, EWperiodic, NSperiodic, & & stflx(:,:,itrc)) RETURN END SUBROUTINE ana_stflux_tile SUBROUTINE ana_wwave (ng, tile, model) ! !======================================================================= ! ! ! This subroutine sets wind induced wave amplitude, direction and ! ! period to be used in the bottom boundary layer formulation. ! ! ! !======================================================================= ! USE mod_param USE mod_forces USE mod_grid USE mod_ncparam ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer :: IminS, ImaxS, JminS, JmaxS integer :: LBi, UBi, LBj, UBj, LBij, UBij ! ! Set horizontal starting and ending indices for automatic private storage ! arrays. ! IminS=BOUNDS(ng)%Istr(tile)-3 ImaxS=BOUNDS(ng)%Iend(tile)+3 JminS=BOUNDS(ng)%Jstr(tile)-3 JmaxS=BOUNDS(ng)%Jend(tile)+3 ! ! Determine array lower and upper bounds in the I- and J-directions. ! LBi=BOUNDS(ng)%LBi(tile) UBi=BOUNDS(ng)%UBi(tile) LBj=BOUNDS(ng)%LBj(tile) UBj=BOUNDS(ng)%UBj(tile) ! ! Set array lower and upper bounds for MIN(I,J)- and MAX(I,J)-directions. ! LBij=BOUNDS(ng)%LBij UBij=BOUNDS(ng)%UBij ! CALL ana_wwave_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & FORCES(ng) % Dwave, & & FORCES(ng) % Hwave, & & FORCES(ng) % Lwave, & & FORCES(ng) % Pwave_bot, & & FORCES(ng) % Ub_swan, & & GRID(ng) % angler, & & GRID(ng) % h) ! ! Set analytical header file name used. ! IF (Lanafile) THEN ANANAME(37)="/home/beach/guest/dafu8991/CALUS/FUNCTIONALS/ana_wwave.h" END IF RETURN END SUBROUTINE ana_wwave ! !*********************************************************************** SUBROUTINE ana_wwave_tile (ng, tile, model, & & LBi, UBi, LBj, UBj, & & IminS, ImaxS, JminS, JmaxS, & & Dwave, & & Hwave, & & Lwave, & & Pwave_bot, & & Ub_swan, & & angler, h) !*********************************************************************** ! USE mod_param USE mod_scalars ! USE mp_exchange_mod, ONLY : mp_exchange2d ! ! Imported variable declarations. ! integer, intent(in) :: ng, tile, model integer, intent(in) :: LBi, UBi, LBj, UBj integer, intent(in) :: IminS, ImaxS, JminS, JmaxS ! real(r8), intent(in) :: angler(LBi:,LBj:) real(r8), intent(in) :: h(LBi:,LBj:) real(r8), intent(inout) :: Dwave(LBi:,LBj:) real(r8), intent(inout) :: Hwave(LBi:,LBj:) real(r8), intent(inout) :: Lwave(LBi:,LBj:) real(r8), intent(inout) :: Pwave_bot(LBi:,LBj:) real(r8), intent(inout) :: Ub_swan(LBi:,LBj:) ! ! Local variable declarations. ! logical :: EWperiodic=.FALSE. logical :: NSperiodic=.FALSE. integer :: i, j real(r8) :: cff, wdir ! !----------------------------------------------------------------------- ! Set lower and upper tile bounds and staggered variables bounds for ! this horizontal domain partition. Notice that if tile=-1, it will ! set the values for the global grid. !----------------------------------------------------------------------- ! integer :: Istr, IstrR, IstrT, IstrU, Iend, IendR, IendT integer :: Jstr, JstrR, JstrT, JstrV, Jend, JendR, JendT ! Istr =BOUNDS(ng)%Istr (tile) IstrR=BOUNDS(ng)%IstrR(tile) IstrT=BOUNDS(ng)%IstrT(tile) IstrU=BOUNDS(ng)%IstrU(tile) Iend =BOUNDS(ng)%Iend (tile) IendR=BOUNDS(ng)%IendR(tile) IendT=BOUNDS(ng)%IendT(tile) Jstr =BOUNDS(ng)%Jstr (tile) JstrR=BOUNDS(ng)%JstrR(tile) JstrT=BOUNDS(ng)%JstrT(tile) JstrV=BOUNDS(ng)%JstrV(tile) Jend =BOUNDS(ng)%Jend (tile) JendR=BOUNDS(ng)%JendR(tile) JendT=BOUNDS(ng)%JendT(tile) ! !----------------------------------------------------------------------- ! Set wind induced wave amplitude (m), direction (radians) and ! period (s) at RHO-points. !----------------------------------------------------------------------- ! wdir=210.0_r8*deg2rad DO j=JstrR,JendR DO i=IstrR,IendR Hwave(i,j)=0.1_r8 Dwave(i,j)=wdir Pwave_bot(i,j)=8.0_r8 ! Pwave_top(i,j)=8.0_r8 ! Ub_swan(i,j)=0.05_r8 Lwave(i,j)=20.0_r8 END DO END DO RETURN END SUBROUTINE ana_wwave_tile END MODULE analytical_mod