!WRF:MODEL_LAYER:PHYSICS
!
MODULE module_sf_3dpwp 1
CONTAINS
!-------------------------------------------------------------------
! cyl: Implemented a three-dimensional ocean model (DPWP) Chiaying Lee RSMAS/UM
!---------------------------------------------------------------------------
SUBROUTINE DPWP (ims,ime, jms,jme, kms,kme,its,ite, jts,jte, kts,kte, & 1,3
ids,ide, jds,jde, kds,kde,okms, okme, &
om_tmp,om_s,om_u, om_v, om_density, om_depth, om_ml, &
om_lat, om_lon, &
HFX, QFX, GSW, GLW, UST, U_PHY, V_PHY, &
STBOLT, DELTSM, TSK, LH, XLAND, &
rdx, rdy, msfu, msfv, msft,xtime,om_tini,om_sini,id,omdt)
!----------------------------------------------------------------------------
implicit none
!----------------------------------------------------------------------------
! Subroutine DPWP is a three-dimensional full physics ocean circulation model based
! on Price et al. (1994, JPO). This ocean model is coupled with WRF
! at every ocean time step. It is developed as a part of the University of Miami Coupled Model
! (UMCM, Chen et al. 2012, JAS). A detailed description of the coupling process can
! be found in Lee and Chen (2013, MWR).
!
! This ocean model can be used with multi-nested grids the same manner as in WRF. It is recommended
! to use grid spacing > 3 km for the ocean model while WRF can be configured at smaller
! grid spacing then the ocean model.
!
! The ocean model can be initialized with observed satellite SST or global model analyzed SST.
! The and upper ocean temperature and sanility profiles can be initialized from climatology,
! in-situ observations, and global ocean model analysis fields.
!
!-- om_tmp 3-dimensional ocean temperature (k)
!-- om_s 3-dimensional ocean salinity (psu)
!-- om_u 3-dimensional ocean current in x-direction (ms-1)
!-- om_v 3-dimensional ocean current in y-direction (ms-1)
!-- om_depth 3-dimensional ocean depth (m)
!-- om_ml ocean mixed layer depth (m)
!-- om_tini temperature reference profile based on ocean initial condition (k)
!-- om_sini salinity reference profile based on ocean initial condition (psu)
!-- om_dt ocean timestep (s)
!-------------------------------------------------------------------------------
!logical number to control the dynamics of ocean model
integer :: noasym, nonlcl, nodeep, nopg, idia
! spatial variables
INTEGER , INTENT(IN) :: id
INTEGER, INTENT(IN ) :: ids,ide, jds,jde, kds,kde, &
ims,ime, jms,jme, kms,kme, &
its,ite, jts,jte, kts,kte
REAL , INTENT(IN ) :: rdx, &
rdy,xtime
integer :: i_start, i_end, j_start, j_end
!physical variables from WRF
REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) :: msfu, &
msfv, &
msft
real :: mrdx, mrdy
real :: pscale, hascale, vascale
REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(IN ) ::HFX, QFX, LH, GSW, GLW, UST,&
XLAND
REAL , DIMENSION( ims:ime , jms:jme ) , INTENT(INOUT) :: TSK
REAL, INTENT(IN ) :: STBOLT, DELTSM
REAL , DIMENSION( ims:ime ,kms:kme, jms:jme ),INTENT(IN ) :: U_PHY, V_PHY
!constant variables
real :: cp, crbc, cadv, ddx, g
real :: d2r, ro, rhoair, cpw, rb, rg, udrag, ucon
real , dimension (ims:ime, jms:jme) :: f, dml, tr, sr
real :: beta1,beta2
real , dimension (ims:ime, jms:jme) :: dr, alpha, beta
integer :: i, j, k, im, ip,jm,jp,km,kp,kk
integer :: ii, ntss
!ocean variables ::
integer, intent(in) :: okms, okme
real, dimension(ims:ime, okms:okme, jms:jme), INTENT(INOUT):: OM_TMP,OM_S,OM_U,OM_V,OM_DEPTH
real, dimension(ims:ime, okms:okme, jms:jme), INTENT(IN):: OM_TINI,OM_SINI
real, dimension(ims:ime, okms:okme, jms:jme), INTENT(INOUT):: OM_DENSITY
real, dimension(ims:ime, okms:okme, jms:jme):: OM_W
real, dimension(ims:ime, jms:jme),INTENT(INOUT):: OM_ML, OM_LAT, OM_LON
real, dimension(ims:ime, okms:okme, jms:jme):: tt, st, ut, vt, t9, s9, u9,v9
real, dimension(ims:ime, okms:okme, jms:jme):: pp, tentm, t0, s0, u0,v0
real, dimension(ims:ime, okms:okme, jms:jme):: dz, tham, tvam
real :: divu, divv, tha, sha, uha, vha, tva, vva, sva, uva, pgx, pgy
real, dimension(okms:okme) :: tb5, sb5, ub5, vb5, tb4, sb4, ub4, vb4
real, dimension(ims:ime,okms:okme, jms:jme) :: trr, srr
real, dimension(ims:ime, okms:okme, jms:jme)::bbeta, aalpha,sg
! other variables
real :: dt, dti,dt7,vs, us,omdt
real :: dtdy, dtdx, dsdy, dsdx, dudy, dudx, dvdy, dvdx, wavg, &
dtdz, dsdz, dudz, dvdz
integer :: iupw, kvs, kus, ia, ja
i_start = max(its,ids+1)
i_end = min(ite,ide-2)
j_start = max(jts,jds+1)
j_end = min(jte,jde-2)
print*,'3DPWP domain',id,' run ocean'
dtdy = 0.0
dtdx = 0.0
dsdy = 0.0
dudy = 0.0
dudx = 0.0
dsdx = 0.0
dvdy = 0.0
dvdx = 0.0
wavg = 0.0
dtdz = 0.0
dsdz = 0.0
dudz = 0.0
dvdz = 0.0
divu = 0.0
divv = 0.0
tha = 0.0
sha = 0.0
uha = 0.0
vha = 0.0
tva = 0.0
vva = 0.0
sva = 0.0
uva = 0.0
pgx = 0.0
pgy = 0.0
!----------------------------------------------------------------
! these flags control the dynamics of the model:
!
! noasym = 1 shuts off the asymmetry of the storm winds
! = 2 also shuts off radial wind component of storm winds
! nonlcl = 1 shuts off horizontal advection,
! = 2 shuts off horizontal and vertical advection,
! = 3 above plus applies spatially constant wind stress
! (useful for testing 1-d dynamics)
! nodeep = 1 shuts off ml deepening by entrainment
! nopg = 1 shuts off pressure gradients
! idia = 1 turns on diagnostics
! to calculate 1D pwp just choose nonlcl = 2, and nopg = 1
!
! set flags to default values
noasym = 0
nonlcl = 0
nodeep = 0
nopg = 0
idia = 0
! set some scales that are used for diagnostics - be careful with these !!
pscale = 1.0
if(nopg.eq.1) pscale = 0.
hascale = 1.0
if(nonlcl.ge.1) hascale = 0.
vascale = 1.0
if(nonlcl.ge.2) then
vascale = 0.
hascale = 0.
end if
!------------------------------------------------------------------
! calculate the expansion coefficient
d2r = 2*3.14159/360.
g = 9.8
ro = 1.024e3 ! kg/m3
rhoair = 1
cpw = 4183.3
beta1 = .6
beta2 = 20.0
rb = 0.65
rg = 0.25
cp = 1.5
do i = i_start-1, i_end+1
do j = j_start-1, j_end+1
f (i,j)= 2.0*7.29e-5*sin(om_lat(i,j)*d2r)
if (om_tmp(i,1,j) .gt. 0.0) then
do k = 1,okme
trr(i,k,j) = om_tini(i,k,j)
srr(i,k,j) = om_sini(i,k,j)
aalpha(i,k,j) = sgt
(trr(i,k,j)+0.5, srr(i,k,j), sg(i,k,j))- &
sgt(trr(i,k,j)-0.5,srr(i,k,j), sg(i,k,j))
bbeta(i,k,j) = sgt
(trr(i,k,j), srr(i,k,j)+0.5, sg(i,k,j) )-sgt(trr(i,k,j),srr(i,k,j)-0.5, sg(i,k,j))
enddo
endif
enddo
enddo
udrag = 9999.
ucon = 0.
!set time step
dt =omdt*60.0
dti = 2.*dt
ntss =2
do 1111 ii = 1, ntss
if (ii .eq. 2) go to 88
do i= i_start-1, i_end+1
do j = j_start-1, j_end+1
do k = 1, okme
tt(i,k,j) = 0.0
ut(i,k,j) = 0.0
vt(i,k,j) = 0.0
st(i,k,j) = 0.0
t9(i,k,j) = om_tmp(i,k,j)
u9(i,k,j) = om_u(i,k,j)
v9(i,k,j) = om_v(i,k,j)
s9(i,k,j) = om_s(i,k,j)
t0(i,k,j) = om_tmp(i,k,j)
u0(i,k,j) = om_u(i,k,j)
v0(i,k,j) = om_v(i,k,j)
s0(i,k,j) = om_s(i,k,j)
om_w(i,k,j) = 0.0
pp(i,k,j) = 0.0
tham(i,k,j) = 0.0
tentm(i,k,j) = 0.0
enddo
enddo
enddo
go to 89
!second iteration
88 continue
dti = dt/2.
do i = i_start-1, i_end+1
do j = j_start-1, j_end+1
do k = 1, okme
t0(i,k,j) = t9(i,k,j)
u0(i,k,j) = u9(i,k,j)
v0(i,k,j) = v9(i,k,j)
s0(i,k,j) = s9(i,k,j)
om_w(i,k,j) = 0.0
pp(i,k,j) = 0.0
tham(i,k,j) = 0.0
tentm(i,k,j) = 0.0
enddo
enddo
enddo
89 continue
do 635 j = j_start, j_end
do 635 i = i_start, i_end
jp = j + 1
jm = j - 1
ip = i + 1
im = i - 1
if (om_tmp(ip,1,j) .le. 0 .or. om_tmp(im,1,j) .le. 0 .or. om_tmp(i,1,jp) .le. 0 .or. om_tmp(i,1,jm) .le.0 ) then
do k = 1, okme
om_w(i,k,j) = 0.0
enddo
else
do 6381 k = 1, okme
mrdx = rdx* msfu(i,j)
mrdy = rdy* msfv(i,j)
if (k .eq. 1) then
dz(i,k,j) = om_depth(i,k,j)
else
dz(i,k,j) = om_depth(i,k,j)-om_depth(i,k-1,j)
endif
divu = dz(i,k,j)*(om_u(ip,k,j)-om_u(im,k,j))*mrdx/2.0
divv = dz(i,k,j)*(om_v(i,k,jp)-om_v(i,k,jm))*mrdy/2.0
om_w(i,k,j) = divu+divv
6381 continue
do k = 2, okme
om_w(i,k,j) = om_w(i,k,j)+om_w(i,k-1,j)
enddo
endif
635 continue
do 6328 k = 1, okme
if (jts .eq. jds) then
do i = its, ite
om_w(i,k,jts) = om_w(i,k,jts+1)
enddo
endif
if (jte .eq. jde-1) then
do i = its, ite
om_w(i,k,jte) = om_w(i,k,jte-1)
enddo
endif
if (its .eq. ids) then
do j = jts, jte
om_w(its,k,j) = om_w(its+1,k,j)
enddo
endif
if (ite.eq. ide-1) then
do j = jts, jte
om_w(ite,k,j) = om_w(ite-1,k,j)
enddo
endif
if(its.eq. ids.and.jts .eq. jds) then
om_w(its,k,jts) = om_w(its+1,k,jts+1)
endif
if(its.eq. ids.and.jte .eq. jde-1) then
om_w(its,k,jte) = om_w(its+1,k,jte-1)
endif
if(ite.eq. ide-1.and.jte .eq. jde-1) then
om_w(ite,k,jte) = om_w(ite-1,k,jte-1)
endif
if(ite.eq. ide-1.and.jts .eq. jds) then
om_w(ite,k,jts) = om_w(ite-1,k,jts+1)
endif
6328 continue
! compute the pressure perturbation by integrating
do 6327 i = i_start-1, i_end+1
do 6327 j = j_start-1, j_end+1
do k = 1, okme
if (k .eq. 1) then
dz(i,k,j) = om_depth(i,k,j)
else
dz(i,k,j) = om_depth(i,k,j)-om_depth(i,k-1,j)
endif
enddo
if (om_tmp(i,1,j) .gt. 0) then
pp (i,okme,j) = -g*dz(i,okme,j)*(aalpha(i,okme,j)*(om_tmp(i,okme,j)-trr(i,okme,j))+ &
bbeta(i,okme,j)*(om_s(i,okme,j)-srr(i,okme,j)))
do 632 k = 1,okme-1
kk = okme - k
pp(i,kk,j) = -g*dz(i,kk,j)*(aalpha(i,kk,j)*(om_tmp(i,kk,j)-trr(i,kk,j))+ &
bbeta(i,kk,j)*(om_s(i,kk,j)-srr(i,kk,j)))+pp(i,kk+1,j)
632 continue
endif
6327 continue
do 410 j = j_start, j_end
jp = j+1
jm = j-1
do 410 i = i_start, i_end
ip = i + 1
im = i - 1
do 420 k = 1 ,okme
mrdx = rdx* msfu(i,j)
mrdy = rdy* msfv(i,j)
tha = 0.
sha = 0.
uha = 0.
vha = 0.
tva = 0.
sva = 0.
vva = 0.
uva = 0.
pgx = 0.
pgy = 0.
! estimate the tendencies due to horizontal advection
IUPW = 1
if (IUPW .eq. 1) then
vs = sign(1.,om_v(i,k,j))
kvs = -1* nint(vs)
us = sign(1.,om_u(i,k,j))
kus = -1* nint(us)
dtdy = vs*(om_tmp(i,k,j)-om_tmp(i,k,j+kvs))*mrdy
dtdx = us*(om_tmp(i,k,j)-om_tmp(i+kus,k,j))*mrdx
dsdy = vs*(om_s(i,k,j)-om_s(i,k,j+kvs))*mrdy
dsdx = us*(om_s(i,k,j)-om_s(i+kus,k,j))*mrdx
dudy = vs*(om_u(i,k,j)-om_u(i,k,j+kvs))*mrdy
dudx = us*(om_u(i,k,j)-om_u(i+kus,k,j))*mrdx
dvdy = vs*(om_v(i,k,j)-om_v(i,k,j+kvs))*mrdy
dvdx = us*(om_v(i,k,j)-om_v(i+kus,k,j))*mrdx
tha =-(om_v(i,k,j)*dtdy + om_u(i,k,j)*dtdx)
sha =-(om_v(i,k,j)*dsdy + om_u(i,k,j)*dsdx)
uha =-(om_v(i,k,j)*dudy + om_u(i,k,j)*dudx)
vha =-(om_v(i,k,j)*dvdy + om_u(i,k,j)*dvdx)
endif
! estimate the tendencies due to vertical advection
! skip if k = 1, assume that there is no vertical advection at surface
if ( k .eq. 1) go to 3323
wavg = 0.5*(om_w(i,k-1,j) + om_w(i,k,j))
km = k - 1
kp = k + 1
if (k .eq. okme) kp = k
dtdz = (om_tmp(i,km,j)-om_tmp(i,kp,j))/(om_depth(i,km,j)-om_depth(i,kp,j))
dsdz = (om_s(i,km,j)-om_s(i,kp,j))/(om_depth(i,km,j)-om_depth(i,kp,j))
dudz = (om_u(i,km,j)-om_u(i,kp,j))/(om_depth(i,km,j)-om_depth(i,kp,j))
dvdz = (om_v(i,km,j)-om_v(i,kp,j))/(om_depth(i,km,j)-om_depth(i,kp,j))
tva =wavg*dtdz
sva =wavg*dsdz
uva =wavg*dudz
vva =wavg*dvdz
3323 continue
!calculate pressure gradient
pgx = (pp(ip,k,j) - pp(im,k,j))*mrdx/2.0
pgy = (pp(i,k,jp) - pp(i,k,jm))*mrdy/2.0
if (( i .eq. its .and. its .eq. ids) .or. (i .eq. ite .and. ite .eq. ide-1) .or. &
( j .eq. jts .and. jts .eq. jds) .or. (j .eq. jte .and. jte .eq. jde-1)) then
tt(i,k,j) = tt(i,k,j)
st(i,k,j) = st(i,k,j)
ut(i,k,j) = ut(i,k,j)
vt(i,k,j) = vt(i,k,j)
else
tt(i,k,j) = tt(i,k,j) + tha*hascale + tva*vascale
st(i,k,j) = st(i,k,j) + sha*hascale + sva*vascale
ut(i,k,j) = ut(i,k,j) + uha*hascale + uva*vascale - pgx*pscale/1023.0
vt(i,k,j) = vt(i,k,j) + vha*hascale + vva*vascale - pgy*pscale/1023.0
endif
420 continue
410 continue
do 700 k = 1, okme
if (jts .eq. jds)then
ja = 1
do 794 i = its, ite
crbc = -cp*rdy*msfv(i,j)
j = jts
tt(i,k,j) = tt(i,k,j) + crbc*(om_tmp(i,k,j) - om_tmp(i, k, j+ja))
st(i,k,j) = st(i,k,j) + crbc*(om_s(i,k,j) - om_s(i, k, j+ja))
ut(i,k,j) = ut(i,k,j) + crbc*(om_u(i,k,j) - om_u(i, k, j+ja))
vt(i,k,j) = vt(i,k,j) + crbc*(om_v(i,k,j) - om_v(i, k, j+ja))
794 continue
endif
ja = -1
if (jte .eq. jde-1)then
do 795 i = its, ite
crbc = -cp*rdy*msfv(i,j)
j = jte
tt(i,k,j) = tt(i,k,j) + crbc*(om_tmp(i,k,j) - om_tmp(i, k, j+ja))
st(i,k,j) = st(i,k,j) + crbc*(om_s(i,k,j) - om_s(i, k, j+ja))
ut(i,k,j) = ut(i,k,j) + crbc*(om_u(i,k,j) - om_u(i, k, j+ja))
vt(i,k,j) = vt(i,k,j) + crbc*(om_v(i,k,j) - om_v(i, k, j+ja))
795 continue
endif
if (its .eq. ids)then
do 796 j = jts , jte
ia = 1
crbc = -cp*(rdx*msfu(i,j))
i = its
tt(i,k,j) = tt(i,k,j) + crbc*(om_tmp(i,k,j) - om_tmp(i+ia, k, j))
st(i,k,j) = st(i,k,j) + crbc*(om_s(i,k,j) - om_s(i+ia, k, j))
ut(i,k,j) = ut(i,k,j) + crbc*(om_u(i,k,j) - om_u(i+ia, k, j))
vt(i,k,j) = vt(i,k,j) + crbc*(om_v(i,k,j) - om_v(i+ia, k, j))
796 continue
endif
if (ite .eq. ide-1)then
do 797 j = jts , jte
ia = -1
crbc = -cp*(rdx*msfu(i,j))
i = ite
tt(i,k,j) = tt(i,k,j) + crbc*(om_tmp(i,k,j) - om_tmp(i+ia, k, j))
st(i,k,j) = st(i,k,j) + crbc*(om_s(i,k,j) - om_s(i+ia, k, j))
ut(i,k,j) = ut(i,k,j) + crbc*(om_u(i,k,j) - om_u(i+ia, k, j))
vt(i,k,j) = vt(i,k,j) + crbc*(om_v(i,k,j) - om_v(i+ia, k, j))
797 continue
endif
if (its .eq. ids .and. jts .eq. jds) then
tt(its,k,jts) = tt(its+1,k,jts+1)
endif
if (its .eq. ids .and. jte .eq. jde-1) then
tt(its,k,jte) = tt(its+1,k,jte-1)
endif
if (ite .eq. ide-1 .and. jte .eq. jde-1) then
tt(ite,k,jte) = tt(ite-1,k,jte-1)
endif
if (ite .eq. ide-1 .and. jts .eq. jds) then
tt(ite,k,jts) = tt(ite-1,k,jts+1)
endif
700 enddo
!!end radiation bc
! apply the wind stress and air-sea heat hluxes, and deepen the mixed layer by 1Dpwp
! do 510 i = i_start, i_end
! do 510 j = j_start, j_end
do 510 i = its, ite
do 510 j = jts, jte
if (ii .eq. 1) then
do k = 1, okme
tb5(k) = om_tmp(i,k,j)
sb5(k) = om_s(i,k,j)
ub5(k) = om_u(i,k,j)
vb5(k) = om_v(i,k,j)
tb4(k) = tb5(k)
sb4(k) = sb5(k)
ub4(k) = ub5(k)
vb4(k) = vb5(k)
enddo
endif
if (ii .eq. 2) then
do k = 1, okme
tb5(k) =t0(i,k,j)
sb5(k) =s0(i,k,j)
ub5(k) =u0(i,k,j)
vb5(k) =v0(i,k,j)
tb4(k) = tb5(k)
sb4(k) = sb5(k)
ub4(k) = ub5(k)
vb4(k) = vb5(k)
enddo
endif
! vertical mixing
call PWP
(i,j,k,ims, ime, jms, jme, okms,okme,tb4,&
sb4,om_density(i,:,j),om_depth(i,:,j),ub4,&
vb4,om_ml(i,j),om_lat(i,j),&
om_lon(i,j),HFX(i,j), QFX(i,j),LH(i,j), GSW(i,j),&
GLW(i,j), UST(i,j),U_PHY(i,kts,j),V_PHY(i,kts,j),&
STBOLT,DELTSM,aalpha(i,:,j),bbeta(i,:,j),om_tini(i,:,j),&
om_sini(i,:,j),trr(i,:,j),srr(i,:,j),omdt)
! add mixing tendencies
do k = 1 , okme
tt(i,k,j) = tt(i,k,j) + (tb4(k)-tb5(k))/dt
st(i,k,j) = st(i,k,j) + (sb4(k)-sb5(k))/dt
ut(i,k,j) = ut(i,k,j) + (ub4(k)-ub5(k))/dt
vt(i,k,j) = vt(i,k,j) + (vb4(k)-vb5(k))/dt
enddo
510 continue
do 24 i = its, ite
do 24 j = jts, jte
do 24 k = 1, okme
om_tmp(i,k,j) = t0(i,k,j) + dti*tt(i,k,j)
om_s(i,k,j) = s0(i,k,j) + dti*st(i,k,j)
om_u(i,k,j) = u0(i,k,j) + dti*ut(i,k,j)
om_v(i,k,j) = v0(i,k,j) + dti*vt(i,k,j)
24 continue
do i = its, ite
do j = jts, jte
if (XLAND(i,j).GE.1.5)then
TSK(i,j) = om_tmp(i, 1, j)
endif
enddo
enddo
1111 enddo
return
END subroutine DPWP
! cyl: end 3D PWP
!------------------------------------------------------------------
! cyl: add 1D PWP
SUBROUTINE PWP(i,j,k,ims, ime, jms, jme, okms,okme,om_tmp,om_s, & 1,21
om_density, om_depth,om_u, om_v,om_ml,om_lat, om_lon, &
HFX, QFX,LH, GSW, GLW, UST,UAIR,VAIR,STBOLT,DELTSM,aalpha,bbeta,&
om_tini, om_sini,trr,srr,omdt)
implicit none
!----------------------------------------------------------------------------
! Subroutine PWP is a one-dimensional vertical mixing scheme used in DPWP
! based on on Price et al. (1994, JPO).
!----------------------------------------------------------------------------
integer i, j, k
integer ,intent(in) ::ims, ime, jms, jme, okms,okme !dimensions
integer ::ml,kml,mml
real, dimension(okms:okme), intent(inout):: om_tmp, om_s, &
om_density,om_depth
real, dimension(okms:okme),intent(inout):: om_u, om_v
real,intent(inout) :: om_ml
real,intent(inout) :: om_lat, om_lon
real TSK
real,intent(in) :: HFX, QFX,LH, GSW, GLW, ust,STBOLT,DELTSM
real, dimension(okms:okme)::absrb,u,v
real dt, dz
real :: tauxair, tauyair, taux, tauy, &
wspd
real d2r, g, hcon, f, tr, sr, dr, alpha, beta, energy, sg, &
ang,dml
real ro, rhoair, cpw
real beta1, beta2, ql, qi
real sipe
real rb,rv, rvc, delr, duv,rg,du,dv
real sa,ca,uair,vair,rc
real udrag, ucon
real, intent(in) :: omdt
real, dimension(okms:okme),intent(in)::aalpha,bbeta, om_tini,om_sini,trr,srr
dt = omdt*60.0
d2r = 2*3.14159/360.
g = 9.8
ro = 1.024e3 ! kg/m3
rhoair = 1
cpw = 4183.3
f = 2*7.29e-5*sin(om_lat*d2r)
beta1 = .6
beta2 = 20.0
rb = 0.65
rg = 0.25
dml = om_ml
tr = trr(1)
sr = srr(1)
dr = sgt
(tr,sr,sg) ! unit of density is sigma
alpha = sgt
(tr+0.5, sr, sg )-sgt(tr-0.5,sr, sg)
beta = sgt
(tr, sr+0.5, sg )-sgt(tr,sr-0.5, sg)
udrag = 9999.
ucon = 0.
if (udrag .lt. 100) ucon = 1./(86400*udrag)
call absorb
(i,j, ims, ime,jms,jme,okms,okme, beta1,beta2, &
absrb, om_depth,GSW,GLW)
ql = -1.*(HFX+STBOLT*om_tmp(1)**4)
qi = GLW+GSW
ql = ql+absrb(1)*qi
om_tmp(1) = om_tmp(1) + dt*ql/(om_depth(1)*ro*cpw)
om_s(1)=om_s(1)-om_s(1)*QFX*dt/ro/om_depth(1) ! check physical meaning.. ok!
do k = 2, okme
dz = om_depth(k)-om_depth(k-1)
om_tmp(k) = om_tmp(k) + dt*qi*absrb(k)/(dz*ro*cpw)
enddo
do k = 1, okme
om_density(k) = (dr+1000.0) +alpha*(om_tmp(k)-tr)+ &
beta*(om_s(k)-sr)
enddo
ml = 0
call mldep
(i,j,k,ims,ime,jms,jme,okms,okme, om_density, &
om_depth, ml)
if (dml .gt. 100) print*,'mldep1',dml
call si
(i, j, ims,ime,jms,jme,okms,okme,om_density, &
om_depth,sipe, ml)
if (ml .gt. 1) then
call mix1
(om_tmp, ml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_s, ml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_u, ml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_v, ml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_density, ml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
endif
! above this, should be statically stable
ang = f*dt/2.
sa = sin(ang)
ca = cos(ang)
do k = 1, okme
call rot
(i, j,ims,ime,jms,jme,okms,okme, om_u(k), om_v(k), sa, ca)
enddo
call mldep
(i,j,k, ims,ime,jms,jme,okms,okme, om_density, &
om_depth, ml)
if (ml .eq. 1 ) then
om_ml = om_depth(ml)
else
om_ml = om_depth(ml)+(om_depth(ml) - om_depth(ml-1))/2.
endif
dml = om_ml
wspd = max(sqrt(uair*uair+vair*vair), 0.1)
tauxair = ust*ust*uair/wspd
taux = rhoair/ro*tauxair
tauyair = ust*ust*vair/wspd
tauy = rhoair/ro*tauyair
du = taux*dt/dml
dv = tauy*dt/dml
do k = 1,ml
om_u(k) = om_u(k) + du
om_v(k) = om_v(k) + dv
enddo
if(ucon .gt. 1.e-10) then
do k = 1,okme
om_u(k) = om_u(k)*(1. - dt*ucon)
om_v(k) = om_v(k)*(1. - dt*ucon)
enddo
endif
! In pwp origional code, Dr. Price turns off the diffusion
! To use it, check the diffusion parameter in subroutine first
! call diffusion(okms,okme,dt,om_tmp,om_depth)
! call diffusion(okms,okme,dt,om_s,om_depth)
! call diffusion(okms,okme,dt,om_u,om_depth)
! call diffusion(okms,okme,dt,om_v,om_depth)
! call diffusion(okms,okme,dt,om_density,om_depth)
! print*,'ca,sa',ca,sa
if(rb .le. 0.00001) go to 50
rvc = rb
do 40 k = ml, okme-1
if (k .eq. 1) then
dz = om_depth(k)
else
dz = om_depth(k) + (om_depth(k) - om_depth(k-1))/2.
endif
delr = (om_density(k+1)-om_density(k))/ro
duv =(om_u(k+1)-om_u(k))**2+(om_v(k+1) &
-om_v(k))**2 + 1.e-8
rv = g*delr*dz/duv
if (rv .gt. rvc) go to 41
mml=k+1
call mix1
(om_tmp, mml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_s, mml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_u, mml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_v, mml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
call mix1
(om_density, mml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
40 continue
41 continue
50 continue
if (rg .gt. 1.e-4) call rimix
(i,j,k,ims,ime,jms,jme,okms, &
okme,rc, &
rg,om_density,om_depth, om_u, om_v, om_s, om_tmp)
do k = 1, okme
call rot
(i,j,ims,ime,jms,jme,okms,okme, om_u(k), om_v(k), &
sa, ca)
enddo
call mldep
(i,j,k, ims,ime,jms,jme,okms,okme, om_density, &
om_depth, ml)
if (ml .eq. 1) then
om_ml = om_depth(ml)
else
om_ml = om_depth(ml)+ (om_depth(ml) - om_depth(ml-1))/2.
endif
! TSK = om_tmp(1)
return
END SUBROUTINE PWP
! cyl : end PWP
! cyl : PWP's subrouting
! cyl--------------------
SUBROUTINE absorb(i,j, ims, ime, jms, jme, okms,okme,beta1, & 1
beta2, absrb, om_depth,GSW,GLW)
implicit none
integer i,j,k
integer ims, ime, jms, jme, okms, okme
real, dimension(okms:okme),intent(inout)::absrb, om_depth
real abss, rs1, rs2, beta1, beta2, z1b1, z2b1, z2b2, z1b2,&
z1,z2,GSW,GLW
abss = 0.
rs1 = GSW/(GSW+GLW)
rs2 = 1.0 - rs1
do k = 1, okme
absrb(k) = 0.
enddo
do k =1, okme
if (k .eq. 1) then
z1 = 0
else
z1 = om_depth(k-1)
endif
z2 = om_depth(k)
z1b1 = z1/beta1
z2b1 = z2/beta1
z1b2 = z1/beta2
z2b2 = z2/beta2
if (z2b1 .lt. 70) absrb(k) = absrb(k) + &
rs1*(exp(-z1b1)-exp(-z2b1))
if (z2b2 .lt. 70) absrb(k) = absrb(k) + &
rs2*(exp(-z1b2)-exp(-z2b2))
abss = abss + absrb(k)
enddo
return
END SUBROUTINE absorb
!cyl--------------------
SUBROUTINE mldep (i,j,k, ims,ime,jms,jme,okms,okme, om_density, & 3
om_depth, ml)
integer i,j,k,kk, ims,ime,jms,jme,okms,okme
real deps, dml, dd
integer ml
real, dimension(okms:okme),intent(inout)::om_density,om_depth
deps = 1.e-5
do 70 k = 1, okme-1
dd = abs(om_density(k+1) - om_density(k))
if (dd .gt. deps) go to 71
70 continue
71 continue
ml = k
return
END SUBROUTINE mldep
!cyl--------------------
SUBROUTINE si(i, j, ims,ime,jms,jme,okms,okme,om_density, & 1,1
om_depth, &
sipe, ml)
integer i, j, k, ims,ime,jms,jme,okms,okme, mml,ml
real, dimension(okms:okme),intent(inout)::om_density, om_depth
real, dimension(okms:okme) :: temp_density
real pesum, sipe
do k = 1, okme
temp_density(k) = om_density(k)
enddo
mml = 1
do 80 k = 2, okme
if (om_density(k) .gt. om_density(k-1)) go to 81
if (om_density(k) .lt. om_density(k-1))then
mml = k
call mix1
(om_density, mml, i, j,ims,ime,jms,jme,okms,okme,om_depth)
endif
80 continue
81 continue
ml = mml
return
END SUBROUTINE si
!cyl--------------------
SUBROUTINE mix1(b,mml, i, j,ims,ime,jms,jme,okms,okme,om_depth) 11
integer i, j, k, ims,ime,jms,jme,okms,okme, mml
real,dimension(okms:okme),intent(inout) :: b
real,dimension(okms:okme),intent(in) :: om_depth
real,dimension(okms:okme) :: dz
real bs,zs
do k = 1, okme
if (k .eq. 1) then
dz(k) = om_depth(k)
else
dz(k) = om_depth(k)-om_depth(k-1)
endif
enddo
bs = 0.
zs = 0.
do k = 1, mml
bs = bs + b(k)*dz(k)
zs = zs + dz(k)
enddo
bs = bs/zs
do k = 1, mml
b(k) = bs
enddo
return
END SUBROUTINE mix1
!cyl--------------------
SUBROUTINE rot(i, j,ims,ime,jms,jme,okms,okme, om_u, om_v, sa, ca) 2
integer i, j, k, ims,ime,jms,jme,okms,okme
real,intent(inout)::om_u, om_v
real:: u0, v0
real sa, ca
u0= om_u
v0= om_v
om_u = u0*ca+v0*sa
om_v = v0*ca-u0*sa
return
END SUBROUTINE rot
!cyl--------------------
SUBROUTINE rimix(i,j,k,ims,ime,jms,jme,okms,okme,rc, rg, & 1,5
om_density,om_depth, om_u, om_v, om_s, om_tmp)
implicit none
integer i,j,k,ims,ime,jms,jme,okms,okme,kcd,nmix,k1,k2,ks
real rc, rg,dd,g,dz,dv,ro,rs
real,dimension(okms:okme) :: r
real, dimension(okms:okme),intent(inout)::om_density, om_u, &
om_depth,om_v, om_s, om_tmp
ro = 1000.
rc = rg
g = 9.8
kcd = 0
nmix = 0
k1 = 1
k2 = okme - 1
10 continue
do 1 k = k1, k2
dd = om_density(k+1)-om_density(k)
if (dd .lt. 1.e-3) dd = 1.e-3
dv = (om_u(k+1)-om_u(k))**2 + (om_v(k+1)-om_v(k))**2
if(dv .lt. 1.e-6) dv = 1.e-6
if (k .eq. 1) then
dz = (om_depth(1) + om_depth(2) - om_depth(1))/2.
else
dz = (om_depth(k)-om_depth(k-1) + om_depth(k+1) - om_depth(k))/2.
endif
r(k) = g*dz*dd/(dv*ro)
1 continue
rs = r(1)
ks = 1
do 2 k = 2, okme-1
if (r(k) .lt. rs) go to 3
go to 2
3 continue
rs =r(k)
ks = k
2 continue
if (rs .ge. rc) go to 99
if (ks .ge. kcd ) kcd = ks + 1
call stir
(i,j,ims,ime,jms,jme,okms,okme,rc,rs, om_tmp, ks,om_depth)
call stir
(i,j,ims,ime,jms,jme,okms,okme,rc,rs, om_s, ks,om_depth)
call stir
(i,j,ims,ime,jms,jme,okms,okme,rc,rs, om_density, ks,om_depth)
call stir
(i,j,ims,ime,jms,jme,okms,okme,rc,rs, om_u, ks,om_depth)
call stir
(i,j,ims,ime,jms,jme,okms,okme,rc,rs, om_v, ks,om_depth)
nmix = nmix +1
k1 = ks - 2
if (k1 .lt. 1) k1 = 1
k2 = ks +2
if (k2 .gt. okme-1) k2 = okme -1
go to 10
99 continue
return
END SUBROUTINE rimix
!cyl--------------------
SUBROUTINE diffusion(okms,okme,dt,a,om_depth)
implicit none
integer okms,okme,k
real dt,rkz,dz
real, dimension(okms:okme):: a, work,dconst,om_depth
rkz =0.3
do k = okms, okme
if (k .eq. 1) then
dz = om_depth(1)
else
dz = om_depth(k)-om_depth(k-1)
endif
dconst(k) = dt*rkz/dz**2
enddo
do k = 2, okme-1
work(k) = dconst(k)*(a(k-1)+a(k+1)-2.*a(k))
enddo
do k = 2, okme-1
a(k) = a(k) + work(k)
enddo
return
END SUBROUTINE diffusion
!cyl--------------------
SUBROUTINE stir(i,j,ims,ime,jms,jme,okms,okme,rc,rs,a,ks,depth) 5
implicit none
integer i,j,k,ims,ime,jms,jme,okms,okme,ks,b
real, dimension(okms:okme),intent(inout)::a
real, dimension(okms:okme),intent(in)::depth
real, dimension(okms:okme)::dz
real rcon,rc,rs,ff,rnew,da
rnew = 0.3
ff = 1. - rs/rnew
do k = 1,okme
if (k.eq. 1) then
dz(k) = depth(1)
else
dz(k) = depth(k) -depth(k-1)
endif
enddo
da = (a(ks+1)- a(ks))*ff/2.
b=2./(1.+dz(ks)/dz(ks+1))
a(ks+1)= a(ks+1)-da*b*dz(ks)/dz(ks+1)
a(ks) = a(ks)+da*b
! print*,'da',da
! print*,'a',a(ks+1),a(ks)
return
END SUBROUTINE stir
!cyl--------------------
FUNCTION sg0(s) 1
implicit none
real s,sg0
sg0 = ((6.76786136e-6*s-4.8249614e-4)*s+0.814876577)*s &
-0.0934458632
return
END FUNCTION sg0
FUNCTION sgt(tt,s,sg) 5,1
implicit none
real tt,t, s, sg,sgt
t=tt-273.0
sg = sg0
(s)
20 sgt = ((((-1.43803061e-7*t-1.98248399e-3)*t-0.545939111)*t &
+4.53168426)*t)/(t+67.26)+((((1.667e-8*t-8.164e-7)*t &
+1.803e-5)*t)*sg+((-1.0843e-6*t+9.8185e-5)*t-4.7867e-3)*t &
+1.0)*sg
return
END FUNCTION sgt
!--------------------
END MODULE module_sf_3dpwp