16 use machine ,
only : kind_phys
36 subroutine dtm_1p(kdt,timestep,rich,tox,toy,i0,q,sss,sep,q_ts,hl_ts,rho, &
37 alpha,beta,alon,sinlat,soltim,grav,le,d_conv, &
38 xt,xs,xu,xv,xz,xzts,xtts)
40 integer,
intent(in) :: kdt
41 real(kind=kind_phys),
intent(in) :: timestep,rich,tox,toy,i0,q,sss,sep,q_ts,&
42 hl_ts,rho,alpha,beta,alon,sinlat,soltim,&
44 real(kind=kind_phys),
intent(inout) :: xt,xs,xu,xv,xz,xzts,xtts
81 if ( xt <= zero )
then
82 call dtm_onset(kdt,timestep,rich,tox,toy,i0,q,sss,sep,q_ts,hl_ts,rho,alpha, &
83 beta,alon,sinlat,soltim,grav,le,xt,xs,xu,xv,xz,xzts,xtts)
84 elseif ( xt > zero )
then
88 call eulerm(kdt,timestep,rich,tox,toy,i0,q,sss,sep,q_ts,hl_ts,rho,alpha, &
89 beta,alon,sinlat,soltim,grav,le,d_conv, &
90 xt,xs,xu,xv,xz,xzts,xtts)
97 subroutine eulerm(kdt,timestep,rich,tox,toy,i0,q,sss,sep,q_ts,hl_ts,rho,alpha, &
98 beta,alon,sinlat,soltim,grav,le,d_conv, &
99 xt,xs,xu,xv,xz,xzts,xtts)
104 integer,
intent(in) :: kdt
105 real(kind=kind_phys),
intent(in) :: timestep,rich,tox,toy,i0,q,sss,sep,q_ts, &
106 hl_ts,rho,alpha,beta,alon,sinlat,soltim, &
108 real(kind=kind_phys),
intent(inout) :: xt,xs,xu,xv,xz,xzts,xtts
110 real(kind=kind_phys) :: xt0,xs0,xu0,xv0,xz0,xzts0,xtts0
111 real(kind=kind_phys) :: fw,aw,q_warm
112 real(kind=kind_phys) :: xt1,xs1,xu1,xv1,xz1,xzts1,xtts1
113 real(kind=kind_phys) :: xt2,xs2,xu2,xv2,xz2,xzts2,xtts2
114 real(kind=kind_phys) :: dzw,drho,fc
115 real(kind=kind_phys) :: alat,speed
158 speed = max(1.0e-8, xu0*xu0+xv0*xv0)
160 alat = asin(sinlat)*rad2deg
162 fc = const_rot*sinlat
170 drho = -alpha*q_warm/(rho*cp_w) + omg_m*beta*sep
174 dzw = xz0 * ((tox*xu0+toy*xv0) / (rho*speed) &
175 + xz0*xz0*drho*grav / (4.0*rich*speed))
177 xt1 = xt0 + timestep*q_warm/(rho*cp_w)
178 xs1 = xs0 + timestep*sep
179 xu1 = xu0 + timestep*(fc*xv0+tox/rho)
180 xv1 = xv0 + timestep*(-fc*xu0+toy/rho)
181 xz1 = xz0 + timestep*dzw
186 if ( xt1 <= zero .or. xz1 <= zero .or. xz1 > z_w_max )
then
193 xzts1 = xzts0 + timestep*((1.0/(xu0*xu0+xv0*xv0)) * &
194 ( (alpha*q_ts/cp_w+omg_m*beta*sss*hl_ts/le)*grav*xz0**3/(4.0*rich*rho) &
195 +( (tox*xu0+toy*xv0)/rho+(3.0*drho-alpha*i0*aw*xz0/(rho*cp_w)) &
196 *grav*xz0*xz0/(4.0*rich) )*xzts0 ))
197 xtts1 = xtts0 + timestep*(i0*aw*xzts0-q_ts)/(rho*cp_w)
207 drho = -alpha*q_warm/(rho*cp_w) + omg_m*beta*sep
208 dzw = xz1*(tox*xu1+toy*xv1) / (rho*(xu1*xu1+xv1*xv1)) &
209 + xz1*xz1*xz1*drho*grav / (4.0*rich*(xu1*xu1+xv1*xv1))
211 xt2 = xt0 + timestep*q_warm/(rho*cp_w)
212 xs2 = xs0 + timestep*sep
213 xu2 = xu0 + timestep*(fc*xv1+tox/rho)
214 xv2 = xv0 + timestep*(-fc*xu1+toy/rho)
215 xz2 = xz0 + timestep*dzw
219 if ( xt2 <= zero .or. xz2 <= zero .or. xz2 > z_w_max )
then
224 xzts2 = xzts0 + timestep*((1.0/(xu1*xu1+xv1*xv1)) * &
225 ( (alpha*q_ts/cp_w+omg_m*beta*sss*hl_ts/le)*grav*xz1**3/(4.0*rich*rho) &
226 +( (tox*xu1+toy*xv1)/rho+(3.0*drho-alpha*i0*aw*xz1/(rho*cp_w))* &
227 grav*xz1*xz1/(4.0*rich) )*xzts1 ))
228 xtts2 = xtts0 + timestep*(i0*aw*xzts1-q_ts)/(rho*cp_w)
235 xzts = 0.5*(xzts1 + xzts2)
236 xtts = 0.5*(xtts1 + xtts2)
238 if ( xt <= zero .or. xz < zero .or. xz > z_w_max )
then
249 end subroutine eulerm
253 subroutine dtm_1p_zwa(kdt,timestep,i0,q,rho,d_conv,xt,xs,xu,xv,xz,tr_mda,tr_fca,tr_tla,tr_mwa)
259 integer,
intent(in) :: kdt
260 real(kind=kind_phys),
intent(in) :: timestep,i0,q,rho,d_conv
261 real(kind=kind_phys),
intent(inout) :: xt,xs,xu,xv,xz
262 real(kind=kind_phys),
intent(out) :: tr_mda,tr_fca,tr_tla,tr_mwa
264 real(kind=kind_phys) :: dz,t0,ttop0,ttop,fw,q_warm
266 real(kind=kind_phys) :: xz_fca,xz_tla,xz_mwa
268 real(kind=kind_phys) :: xz_mda
270 tr_mda = zero; tr_fca = zero; tr_tla = zero; tr_mwa = zero
273 if ( z_w_min > xz )
then
277 if ( d_conv > zero )
then
278 xz_fca = 2.0*xt/((2.0*xt/xz)*(1.0-d_conv/(2.0*xz)))
280 if ( xz_fca >= z_w_max )
then
281 call dtl_reset_cv(xt,xs,xu,xv,xz)
286 dz = min(xz,max(d_conv,delz))
290 if ( q_warm > zero )
then
291 call cal_ttop(kdt,timestep,q_warm,rho,dz,xt,xz,ttop0)
293 ttop = ((xt+xt)/xz)*(1.0-dz/(xz+xz))
294 if ( ttop > ttop0 )
then
295 xz_tla = (xt+sqrt(xt*(xt-delz*ttop0)))/ttop0
297 if ( xz_tla >= z_w_max )
then
298 call dtl_reset_cv(xt,xs,xu,xv,xz)
306 if ( t0 > tw_max )
then
307 if ( xz >= z_w_max )
then
308 call dtl_reset_cv(xt,xs,xu,xv,xz)
313 xz = max(xz_mda,xz_fca,xz_tla,xz_mwa)
315 end subroutine dtm_1p_zwa
323 real(kind=kind_phys),
intent(in) :: d_conv,xt,xtts
324 real(kind=kind_phys),
intent(inout) :: xz,xzts
326 real(kind=kind_phys) :: t_fcl,t0
329 t_fcl = t0*(1.0-d_conv/(2.0*xz))
341 real(kind=kind_phys),
intent(in) :: dz,te,xt,xtts
342 real(kind=kind_phys),
intent(inout) :: xz,xzts
344 real(kind=kind_phys) :: tem
348 xz = (xt+sqrt(xt*(xt-dz*te)))/te
361 real(kind=kind_phys),
intent(in) :: xt,xtts
362 real(kind=kind_phys),
intent(inout) :: xz,xzts
375 real(kind=kind_phys),
intent(in) :: xt,xtts
376 real(kind=kind_phys),
intent(inout) :: xz,xzts
378 real(kind=kind_phys) :: ta
392 real(kind=kind_phys),
intent(in) :: dta,xt,xtts
393 real(kind=kind_phys),
intent(inout) :: xz,xzts
395 real(kind=kind_phys) :: ta
397 ta = max(zero,2.0*xt/xz-dta)
398 if ( ta > zero )
then
409 subroutine convdepth(kdt,timestep,i0,q,sss,sep,rho,alpha,beta,xt,xs,xz,d_conv)
415 integer,
intent(in) :: kdt
416 real(kind=kind_phys),
intent(in) :: timestep,i0,q,sss,sep,rho,alpha,beta
417 real(kind=kind_phys),
intent(in) :: xt,xs,xz
418 real(kind=kind_phys),
intent(out) :: d_conv
419 real(kind=kind_phys) :: t,s,d_conv_ini,d_conv2,fxp,aw,s1,s2,fac1
447 s1 = alpha*rho*t-omg_m*beta*rho*s
449 if ( s1 == zero )
then
453 fac1 = alpha*q/cp_w+omg_m*beta*rho*sep
454 if ( i0 <= zero )
then
455 d_conv2=(2.0*xz*timestep/s1)*fac1
456 if ( d_conv2 > zero )
then
457 d_conv = sqrt(d_conv2)
461 elseif ( i0 > zero )
then
465 iter_conv:
do n = 1, niter_conv
468 s2 = alpha*(q-(fxp-aw*d_conv_ini)*i0)/cp_w+omg_m*beta*rho*sep
469 d_conv2=(2.0*xz*timestep/s1)*s2
470 if ( d_conv2 < zero )
then
474 d_conv = sqrt(d_conv2)
475 if ( abs(d_conv-d_conv_ini) < eps_conv .and. n <= niter_conv )
exit iter_conv
478 d_conv = max(zero,min(d_conv,z_w_max))
491 subroutine dtm_onset(kdt,timestep,rich,tox,toy,i0,q,sss,sep,q_ts,hl_ts,rho, &
492 alpha,beta,alon,sinlat,soltim,grav,le,xt,xs,xu,xv,xz,xzts,xtts)
497 integer,
intent(in) :: kdt
498 real(kind=kind_phys),
intent(in) :: timestep,rich,tox,toy,i0,q,sss,sep,q_ts, &
499 hl_ts,rho,alpha,beta,alon,sinlat,soltim,grav,le
500 real(kind=kind_phys),
intent(out) :: xt,xs,xu,xv,xz,xzts,xtts
501 real(kind=kind_phys) :: xt0,xs0,xu0,xv0,xz0
502 real(kind=kind_phys) :: xt1,xs1,xu1,xv1,xz1
503 real(kind=kind_phys) :: fw,aw,q_warm,ft0,fs0,fu0,fv0,fz0,ft1,fs1,fu1,fv1,fz1
504 real(kind=kind_phys) :: coeff1,coeff2,ftime,z_w,z_w_tmp,fc,warml,alat
534 fc=1.46/10000.0/2.0*sinlat
550 if ( abs(alat) > 1.0 )
then
551 ftime=sqrt((2.0-2.0*cos(fc*timestep))/(fc*fc*timestep))
556 coeff1=alpha*grav/cp_w
557 coeff2=omg_m*beta*grav*rho
558 warml = coeff1*q_warm-coeff2*sep
560 if ( warml > zero .and. q_warm > zero)
then
561 iters_z_w:
do n = 1,niter_z_w
562 if ( warml > zero .and. q_warm > zero )
then
563 z_w=sqrt(2.0*rich*ftime/rho)*sqrt(tox**2+toy**2)/sqrt(warml)
571 if (abs(z_w - z_w_tmp) < eps_z_w .and. z_w/=z_w_max .and. n < niter_z_w)
exit iters_z_w
575 warml = coeff1*q_warm-coeff2*sep
581 xz0 = max(z_w,z_w_min)
586 if ( z_w < z_w_max .and. q_warm > zero)
then
591 ft0 = q_warm/(rho*cp_w)
594 fv0 = -fc*xu0+toy/rho
596 xt1 = xt0 + timestep*ft0
597 xs1 = xs0 + timestep*fs0
598 xu1 = xu0 + timestep*fu0
599 xv1 = xv0 + timestep*fv0
601 fz0 = xz0*((tox*xu1+toy*xv1)/rho+omg_m*beta*grav*sep*xz0*xz0/(4.0*rich) &
602 -alpha*grav*q_warm*xz0*xz0/(4.0*rich*cp_w*rho))/(xu1*xu1+xv1*xv1)
603 xz1 = xz0 + timestep*fz0
605 xz1 = max(xz1,z_w_min)
607 if ( xt1 < zero .or. xz1 > z_w_max )
then
615 ft1 = q_warm/(rho*cp_w)
618 fv1 = -fc*xu1+toy/rho
620 fz1 = xz1*((tox*xu1+toy*xv1)/rho+omg_m*beta*grav*sep*xz1*xz1/(4.0*rich) &
621 -alpha*grav*q_warm*xz1*xz1/(4.0*rich*cp_w*rho))/(xu1*xu1+xv1*xv1)
623 xt = xt0 + 0.5*timestep*(ft0+ft1)
624 xs = xs0 + 0.5*timestep*(fs0+fs1)
625 xu = xu0 + 0.5*timestep*(fu0+fu1)
626 xv = xv0 + 0.5*timestep*(fv0+fv1)
627 xz = xz0 + 0.5*timestep*(fz0+fz1)
634 xzts = (q_ts+omg_m*rho*cp_w*beta*sss*hl_ts*xz/(le*alpha))/(i0*xz*aw+2.0*q_warm-2.0*omg_m*rho*cp_w*beta*sss*sep/(le*alpha))
635 xtts = timestep*(i0*aw*xzts-q_ts)/(rho*cp_w)
638 if ( xt < zero .or. xz > z_w_max )
then
644 end subroutine dtm_onset
649 subroutine cal_w(kdt,xz,xt,xzts,xtts,w_0,w_d)
666 integer,
intent(in) :: kdt
667 real(kind=kind_phys),
intent(in) :: xz,xt,xzts,xtts
668 real(kind=kind_phys),
intent(out) :: w_0,w_d
670 w_0 = 2.0*(xtts-xt*xzts/xz)/xz
671 w_d = (2.0*xt*xzts/xz**2-w_0)/xz
681 subroutine cal_ttop(kdt,timestep,q_warm,rho,dz,xt,xz,ttop)
699 integer,
intent(in) :: kdt
700 real(kind=kind_phys),
intent(in) :: timestep,q_warm,rho,dz,xt,xz
701 real(kind=kind_phys),
intent(out) :: ttop
702 real(kind=kind_phys) :: dt_warm,t0
705 t0 = dt_warm*(1.0-dz/(xz+xz))
706 ttop = t0 + q_warm*timestep/(rho*cp_w*dz)
713 subroutine app_sfs(kdt,xt,xs,xu,xv,alpha,beta,grav,d_1p,xz)
733 integer,
intent(in) :: kdt
734 real(kind=kind_phys),
intent(in) :: xt,xs,xu,xv,alpha,beta,grav,d_1p
735 real(kind=kind_phys),
intent(out) :: xz
737 real(kind=kind_phys) :: cc,l,d_sfs,tem
738 real(kind=kind_phys),
parameter :: c2 = 0.3782
742 tem = alpha*xt - beta*xs
744 d_sfs = sqrt(2.0*cc*(xu*xu+xv*xv)/tem)
760 l = int_epn(zero,d_sfs,zero,d_sfs,2)
768 end subroutine app_sfs
772 subroutine cal_tztr(kdt,xt,c_0,c_d,w_0,w_d,zc,zw,z,tztr)
790 integer,
intent(in) :: kdt
791 real(kind=kind_phys),
intent(in) :: xt,c_0,c_d,w_0,w_d,zc,zw,z
792 real(kind=kind_phys),
intent(out) :: tztr
794 if ( xt > zero )
then
797 tztr = (1.0+z*(w_d-c_d))/(1.0-w_0+c_0)
798 elseif ( z > zc .and. z < zw )
then
800 tztr = (1.0+c_0+z*w_d)/(1.0-w_0+c_0)
801 elseif ( z >= zw )
then
804 elseif ( xt == zero )
then
807 tztr = (1.0-z*c_d)/(1.0+c_0)
816 end subroutine cal_tztr
821 subroutine cool_skin(ustar_a,f_nsol,f_sol_0,evap,sss,alpha,beta,rho_w,rho_a,ts,q_ts,hl_ts,grav,le,deltat_c,z_c,c_0,c_d)
848 real(kind=kind_phys),
intent(in) :: ustar_a,f_nsol,f_sol_0,evap,sss,alpha,beta,rho_w,rho_a,ts,q_ts,hl_ts,grav,le
849 real(kind=kind_phys),
intent(out) :: deltat_c,z_c,c_0,c_d
851 real(kind=kind_phys),
parameter :: a1=0.065, a2=11.0, a3=6.6e-5, a4=8.0e-4, tcw=0.6, tcwi=1.0/tcw
852 real(kind=kind_phys) :: a_c,b_c,zc_ts,bc1,bc2
853 real(kind=kind_phys) :: xi,hb,ustar1_a,bigc,deltaf,fxp
854 real(kind=kind_phys) :: zcsq
855 real(kind=kind_phys) :: cc1,cc2,cc3
860 ustar1_a = max(ustar_a,ustar_a_min)
865 hb = alpha*(f_nsol-deltaf)+beta*sss*cp_w*evap/le
866 bigc = 16*grav*cp_w*(rho_w*visw)**3/(rho_a*rho_a*kw*kw)
869 xi = 6./(1+(bigc*hb/ustar1_a**4)**0.75)**0.3333333
873 z_c = min(z_c_max,xi*visw/(sqrt(rho_a/rho_w)*ustar1_a ))
878 deltaf = f_nsol - deltaf
879 if ( deltaf > 0 )
then
880 deltat_c = deltaf * z_c / kw
888 if ( z_c > zero )
then
889 cc1 = 6.0*visw / (tcw*ustar1_a*sqrt(rho_a/rho_w))
890 cc2 = bigc*alpha / max(ustar_a,ustar_a_min)**4
891 cc3 = beta*sss*cp_w/(alpha*le)
893 a_c = a2 + a3/zcsq - (a3/(a4*z_c)+a3/zcsq) * exp(-z_c/a4)
895 if ( hb > zero .and. zcsq > zero .and. alpha > zero)
then
896 bc1 = zcsq * (q_ts+cc3*hl_ts)
897 bc2 = zcsq * f_sol_0*a_c - 4.0*(cc1*tcw)**3*(hb/alpha)**0.25/(cc2**0.75*zcsq)
900 b_c = (q_ts+cc3*hl_ts)/(f_sol_0*a_c &
901 - 4.0*(cc1*tcw)**3*(hb/alpha)**0.25/(cc2**0.75*zcsq*zcsq))
902 c_0 = (z_c*q_ts+(f_nsol-deltaf-f_sol_0*a_c*z_c)*b_c)*tcwi
903 c_d = (f_sol_0*a_c*z_c*b_c-q_ts)*tcwi
930 real function int_epn(z1,z2,zmx,ztr,n)
934 real(kind_phys) :: z1,z2,zmx,ztr,zi
935 real(kind_phys) :: fa,fb,fi,int
938 m = nint((z2-z1)/delz)
939 fa = exp(-exp_const*((z1-zmx)/(ztr-zmx))**n)
940 fb = exp(-exp_const*((z2-zmx)/(ztr-zmx))**n)
943 zi = z1 + delz*float(i)
944 fi = exp(-exp_const*((zi-zmx)/(ztr-zmx))**n)
947 int_epn = delz*((fa+fb)/2.0 + int)
952 subroutine dtl_reset_cv(xt,xs,xu,xv,xz)
953 real(kind=kind_phys),
intent(inout) :: xt,xs,xu,xv,xz
959 end subroutine dtl_reset_cv
964 real(kind=kind_phys),
intent(inout) :: xt,xs,xu,xv,xz,xzts,xtts
subroutine, public convdepth(kdt, timestep, i0, q, sss, sep, rho, alpha, beta, xt, xs, xz, d_conv)
This subroutine calculates depth for convective adjustment.
subroutine, public dtm_1p_mwa(xt, xtts, xz, xzts)
This subroutine applies maximum warming adjustment (mwa).
subroutine, public dtm_1p_fca(d_conv, xt, xtts, xz, xzts)
This subroutine applies free convection adjustment(fca).
subroutine, public cal_ttop(kdt, timestep, q_warm, rho, dz, xt, xz, ttop)
This subroutine calculates the diurnal warming amount at the top layer with thickness of delz.
subroutine, public dtm_1p_mta(dta, xt, xtts, xz, xzts)
This subroutine applies maximum temperature adjustment (mta).
subroutine, public dtm_1p(kdt, timestep, rich, tox, toy, i0, q, sss, sep, q_ts, hl_ts, rho, alpha, beta, alon, sinlat, soltim, grav, le, d_conv, xt, xs, xu, xv, xz, xzts, xtts)
This subroutine contains the module of diurnal thermocline layer model.
subroutine, public dtm_1p_mda(xt, xtts, xz, xzts)
This subroutine applies minimum depth adjustment (xz adjustment).
subroutine, public dtl_reset(xt, xs, xu, xv, xz, xzts, xtts)
This subroutine resets the value of xt,xs,xu,xv,xz,xtts,xzts.
subroutine, public dtm_1p_tla(dz, te, xt, xtts, xz, xzts)
This subroutine applies top layer adjustment (tla).
subroutine, public cal_w(kdt, xz, xt, xzts, xtts, w_0, w_d)
This subroutine computes coefficients (w_0 and w_d) to calculate d(tw)/d(ts).
subroutine, public cool_skin(ustar_a, f_nsol, f_sol_0, evap, sss, alpha, beta, rho_w, rho_a, ts, q_ts, hl_ts, grav, le, deltat_c, z_c, c_0, c_d)
This subroutine contains the upper ocean cool-skin parameterization (Fairall et al,...
This module contains constants and parameters used in GFS near surface sea temperature scheme.
This module contains GFS NSST water property subroutines.
This module contains the diurnal thermocline layer model (DTM) of the GFS NSST scheme.