print*,'enter a temperature, salinity and depth' read*,temp,salt,dep eps = .001 d0 = dens_unesco(temp,salt,dep) dt = dens_unesco(temp+eps,salt,dep) ds = dens_unesco(temp,salt+eps,dep) print*,d0,(dt-d0)/eps,(ds-d0)/eps stop end function dens_unesco (temp, sal, pres) c-------------------------------------------- real*8 rh, rh0 ccccccccccccccccccccccccccccccccccccccccccccccc c Gilles's variant: c situ = theta (pres, temp, sal, 0.) c then, for insitu dens (for poten. dens pres = 0.): c call dens_eos (pres, situ, sal, rh0, rh) c dens_unesco = 1.e3 * real(rh - 1.d0) c c "sigth" variant: c call dens_eos (pres, thet, sal, rh0, rh) c dens_unesco = 1.e3 * real(rh0 - 1.d0) ccccccccccccccccccccccccccccccccccccccccccccccc call dens_eos (pres, temp, sal, rh0, rh) dens_unesco = 1.e3 * real(rh - 1.d0) return end function sdens_pnt (temp, sal, pres) c------------------------------------------------- include 'comm_para.h' include 'comm_new.h' if (isalt .eq. 1) then sdens_pnt = SIGMA0 - TCOEF * (temp - TEMP_BOT) elseif (isalt .eq. 2) then sdens_pnt = pdens1 (temp) elseif (isalt .eq. 3) then sdens_pnt = pdens4 (temp, sal, pres) elseif (isalt .eq. 4) then sdens_pnt = pdens12 (temp, sal, pres) elseif (isalt .eq. 5) then sdens_pnt = pdens17 (temp, sal, pres) elseif (isalt .eq. 6) then situ = theta_eos (pres, temp, sal, 0.) sdens_pnt = dens_unesco (situ, sal, pres) elseif (isalt .eq. 7) then sdens_pnt = dens_marina (temp) endif return end function pdens_pnt (thet, sal) c------------------------------------------------- include 'comm_para.h' include 'comm_new.h' if (isalt .eq. 1) then pdens_pnt = SIGMA0 - TCOEF * (thet - TEMP_BOT) elseif (isalt .eq. 2) then pdens_pnt = pdens1 (thet) elseif (isalt .eq. 3) then pdens_pnt = pdens4 (thet, sal, 0.) elseif (isalt .eq. 4) then pdens_pnt = pdens012 (thet, sal) elseif (isalt .eq. 5) then pdens_pnt = pdens017 (thet, sal) elseif (isalt .eq. 6) then pdens_pnt = dens_unesco (thet, sal, 0.) elseif (isalt .eq. 7) then pdens_pnt = dens_marina (thet) endif return end c----------------------------------------------------- subroutine dens_init (npt, nz, nzi, t, sal, dens, h) c----------------------------------------------------- csenq dimension t(npt,1), sal(npt,1), dens(npt,1), nzi(1), h(npt,1) include 'comm_new.h' c do i = 1, npt do k = 1, nzi(i) POTND_BOT = amax1(POTND_BOT,pdens_pnt (t(i,k),sal(i,k))) enddo enddo POTND_BOT = amax1(POTND_BOT,pdens_pnt (TEMP_BOT, SALT_BOT)) call situ_dens (npt, nz, nzi, t, sal, dens, h) SITUD_BOT = POTND_BOT do i = 1, npt do k = 1, nzi(i) SITUD_BOT = amax1(SITUD_BOT,dens(i,k)) enddo enddo SITUD_BOT = amax1(SITUD_BOT,sdens_pnt (TEMP_BOT, SALT_BOT, dep_max)) write (iout, *) 'TEMP_BOT = ', TEMP_BOT write (iout, *) 'SALT_BOT = ', SALT_BOT write (iout, *) 'MAX_DEPTH = ', dep_max write (iout, *) 'DENS_BOT(in situ) = ', SITUD_BOT write (iout, *) 'DENS_BOT(potential) = ', POTND_BOT return end c---------------------------------------------------------------- subroutine situ_dens (npt, nz, nzi, tem, sal, dens, h) c---------------------------------------------------------------- implicit real(a-h,o-z),integer(i-n) include 'comm_para.h' include 'comm_new.h' dimension tem(npt,nz), sal(npt,nz), dens(npt,nz), h(npt,nz), nzi(npt) c in situ SIGMA density as a function of potential temperature, c salinity & pressure. sigma == 1000. * (rho - 1.); c Senya Basin 1992 c if (isalt .eq. 1) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = SIGMA0 - TCOEF * (tem(i,k) - TEMP_BOT) enddo enddo elseif (isalt .eq. 2) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = pdens1 (tem(i,k)) enddo enddo elseif (isalt .eq. 3) then do i = 1, npt pp = h(i,1)/2. pp1 = pp pp0 = -pp do k = 1, nzi(i) dens(i,k) = pdens4 (tem(i,k), sal(i,k), pp) pp = pp0 + 2.*h(i,k) pp0 = pp1 pp1 = pp enddo enddo elseif (isalt .eq. 4) then do i = 1, npt pp = h(i,1)/2. pp1 = pp pp0 = -pp do k = 1, nzi(i) dens(i,k) = pdens12 (tem(i,k), sal(i,k), pp) pp = pp0 + 2.*h(i,k) pp0 = pp1 pp1 = pp enddo enddo elseif (isalt .eq. 5) then do i = 1, npt pp = h(i,1)/2. pp1 = pp pp0 = -pp do k = 1, nzi(i) dens(i,k) = pdens17 (tem(i,k), sal(i,k), pp) pp = pp0 + 2.*h(i,k) pp0 = pp1 pp1 = pp enddo enddo elseif (isalt .eq. 6) then do i = 1, npt pp = h(i,1)/2. pp1 = pp pp0 = -pp do k = 1, nzi(i) salt = sal(i,k) c Gilles variant: situ = theta_eos (pp, tem(i,k), salt, 0.) dens(i,k) = dens_unesco (situ, salt, pp) pp = pp0 + 2.*h(i,k) pp0 = pp1 pp1 = pp enddo enddo elseif (isalt .eq. 7) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = dens_marina (tem(i,k)) enddo enddo endif return end c---------------------------------------------------------------- subroutine potn_dens (npt, nzi, tem, sal, dens) c---------------------------------------------------------------- implicit real(a-h,o-z),integer(i-n) include 'comm_para.h' include 'comm_new.h' dimension tem(npt,1), sal(npt,1), dens(npt,1), nzi(1) c Potential SIGMA density as a function of potential temperature & salinity c sigma == 1000. * (rho - 1.); c Senya Basin 1992 c if (isalt .eq. 1) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = SIGMA0 - TCOEF * (tem(i,k) - TEMP_BOT) enddo enddo elseif (isalt .eq. 2) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = pdens1 (tem(i,k)) enddo enddo elseif (isalt .eq. 3) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = pdens4 (tem(i,k), sal(i,k), 0.) enddo enddo elseif (isalt .eq. 4) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = pdens012 (tem(i,k), sal(i,k)) enddo enddo elseif (isalt .eq. 5) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = pdens017 (tem(i,k), sal(i,k)) enddo enddo elseif (isalt .eq. 6) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = dens_unesco (tem(i,k), sal(i,k), 0.) enddo enddo elseif (isalt .eq. 7) then do i = 1, npt do k = 1, nzi(i) dens(i,k) = dens_marina (tem(i,k)) enddo enddo endif return end c------------------------------------------------------------------------------ subroutine dconv (npt,nz,nzi,u,v,uc,vc,h,t,sal,dens,tr,convn,zmld) c------------------------------------------------------------------------------ c main aim: removing possible static instability in density. c No influence on layer depths in this version c (see isopycnal mixing model in Ragu's version) c-----------------------------------------------------------------Senq Ltd. Co. c c boundary condition at bottom changed - instead of t(i,nzi) = t_bot c i prefer t(i,nzi)_after = t(i,nzi)_before - NHN implicit real(a-h,o-z),integer(i-n) include 'comm_new.h' common /errors/ ioerr, nstep c dimension u(npt,nz), v(npt,nz), uc(npt,nz), vc(npt,nz), h(npt,nz), * t(npt,nz), sal(npt,nz), dens(npt,nz), convn(npt,nz), nzi(npt), * tr(npt,nz,1),zmld(npt) parameter (ERR_LEV = 1.e-4) do i=1,npt zbotint = 0. if_first = 1 do k=1,nzi(i)-1 kp = k+1 zbotint = zbotint + h(i,k) rhok = sdens_pnt(t(i,k) ,sal(i,k) ,zbotint) rhokp = sdens_pnt(t(i,kp),sal(i,kp),zbotint) if (rhok .gt. rhokp + ERR_LEV) then hinv = h(i,k) + h(i,kp) oldpotener = (dens(i,kp)*h(i,kp) + dens(i,k)*hinv)/2. hinv = 1.0 / hinv hki = hinv * h(i,k) hkpi = hinv * h(i,kp) tmp = uc(i,k) + uc(i,kp) uc(i,k) = tmp * hki uc(i,kp) = tmp * hkpi tmp = hinv * tmp u(i,k) = tmp u(i,kp) = tmp tmp = vc(i,k) + vc(i,kp) vc(i,k) = tmp * hki vc(i,kp) = tmp * hkpi tmp = hinv * tmp v(i,k) = tmp v(i,kp) = tmp tmp1 = hki*t(i,k) + hkpi*t(i,kp) t(i,k) = tmp1 t(i,kp) = tmp1 tmp = hki*sal(i,k) + hkpi*sal(i,kp) sal(i,k) = tmp sal(i,kp) = tmp tmp = pdens_pnt (tmp1, tmp) dens(i,k) = tmp dens(i,kp) = tmp do m = 1, ntrac_tot tmp = hki*tr(i,k,m) + hkpi*tr(i,kp,m) tr(i,k,m) = tmp tr(i,kp,m) = tmp enddo znewpotener = dens(i,k)*(h(i,kp) + h(i,k)/2.) convn(i,k) = oldpotener - znewpotener else if (if_first.eq.1) zmld(i) = max(zmld(i),zbotint) if_first = 0 endif enddo enddo return end c------------------------------------------------------------------------------ subroutine dconv_cl (npt,nz,nzi,h,t,sal,dens) c------------------------------------------------------------------------------ c main aim: removing possible static instability in density. c No influence on layer depths in this version c (see isopycnal mixing model in Ragu's version) c-----------------------------------------------------------------Senq Ltd. Co. c c boundary condition at bottom changed - instead of t(i,nzi) = t_bot c i prefer t(i,nzi)_after = t(i,nzi)_before - NHN implicit real(a-h,o-z),integer(i-n) include 'comm_new.h' common /errors/ ioerr, nstep c dimension h(npt,nz), * t(npt,nz), sal(npt,nz), dens(npt,nz), nzi(npt) parameter (ERR_LEV = 1.e-4) c do i = 1, npt do k = 1, nzi(i) - 1 kp = k + 1 if (dens(i,k)-dens(i,kp) .gt. ERR_LEV) then hinv = h(i,k) + h(i,kp) oldpotener = (dens(i,kp)*h(i,kp) + dens(i,k)*hinv)/2. hinv = 1.0 / hinv hki = hinv * h(i,k) hkpi = hinv * h(i,kp) tmp1 = hki*t(i,k) + hkpi*t(i,kp) t(i,k) = tmp1 t(i,kp) = tmp1 tmp = hki*sal(i,k) + hkpi*sal(i,kp) sal(i,k) = tmp sal(i,kp) = tmp tmp = pdens_pnt (tmp1, tmp) dens(i,k) = tmp dens(i,kp) = tmp znewpotener = tmp*(h(i,kp) + h(i,k)/2.) endif enddo enddo return end c--------------------------------------------------------------------- subroutine drich_mix (npt, nz, nzi, h,u,v,uc,vc,tem,sal,tr, richn) c--------------------------------------------------------------------- c Senya Basin, 1992 implicit real(a-h,o-z),integer(i-n) include 'comm_para.h' include 'comm_new.h' dimension rnu(MAXNZ), rka(MAXNZ) dimension u(npt,nz), v(npt,nz), uc(npt,nz), vc(npt,nz), h(npt,nz), * tem(npt,nz), sal(npt,nz), nzi(npt), tr(npt,nz,1) * ,richn(npt,nz) common /errors/ ioerr, nstep common /tria_loc/ ixy, ndim, alf(MAXNZ),bet(MAXNZ),gam(MAXNZ),aga(MAXNZ) parameter (R_COEF = -0.5 * GRAVTY/1000.) parameter (R_CRIT = 2.e5) c parameter (DUZ_0 = 1.e-5) parameter (DUZ_0 = 1.e-4) parameter (DRHO_0 = -1.e-6) c c Ri = -(g/rho0) * d(rho)/dz / (du/dz**2 + du/dz**2) c do i = 1, npt ndim = nzi(i) rnu(ndim) = 0. rka(ndim) = 0. zbotint = 0. do k = 1, ndim-1 kp = k + 1 uu = u(i,k) - u(i,kp) vv = v(i,k) - v(i,kp) h12 = h(i,k) + h(i,kp) du2 = uu*uu + vv*vv c if (du2 .lt. DUZ_0) du2 = DUZ_0 du2 = du2 + DUZ_0 zbotint = zbotint + h(i,k) rhom = sdens_pnt(tem(i,k ),sal(i,k ),zbotint) rhop = sdens_pnt(tem(i,kp),sal(i,kp),zbotint) drho = rhom - rhop drho = min(drho, DRHO_0* h12) rich = R_COEF * h12 * drho / du2 richn(i,k) = rich ! save for output call visc_diff (rich, vnu, vka) tmp = DLT_MIX / h12 rnu(k) = tmp * vnu rka(k) = tmp * vka enddo ixy = i call tria_init (npt, rnu, h) call tria_tem (npt, u, 0.) call tria_tem (npt, v, 0.) call tria_init (npt, rka, h) tb = tem(i,ndim) sb = sal(i,ndim) call tria_tem (npt, tem, tb) call tria_tem (npt, sal, sb) do m = 1, ntrac_tot trb = tr(i,ndim,m) call tria_tem (npt, tr(1,1,m), trb) enddo enddo do i = 1, npt do k = 1, nzi(i) hi = h(i,k) uc(i,k) = u(i,k) * hi vc(i,k) = v(i,k) * hi enddo enddo return end c--------------------------------------------- subroutine visc_diff (Ri, rnu, rka) c--------------------------------------------- c eddy viscosity & diffusivity c a'la Pacanowski & Philander [1981] c--------------------------------------------- c from PP-1981: c parameter (GAMMA = 5., RNU_0 = 0.01, RNU_B = 5.e-5, RKA_B = 5.e-6) c c suggested by Gilles to Senya (?): parameter (GAMMA = 5., RNU_0 = 0.05, RNU_B = 1.34e-5, RKA_B = 1.34e-6) parameter (RNU_NEG = RNU_B + RNU_0) parameter (RKA_NEG = RKA_B + RNU_NEG) if ( Ri .gt. 0. ) then tmp = 1. + GAMMA * Ri rnu = RNU_B + RNU_0 / (tmp * tmp) rka = RKA_B + rnu / tmp else rnu = RNU_NEG rka = RKA_NEG endif return end c------------------------------------------------------ subroutine tria_init (npt, cappa, h) c------------------------------------------------------ csenq include 'comm_para.h' real cappa(1), h(npt,1) common /tria_loc/ ixy, ndim, alf(MAXNZ),bet(MAXNZ),gam(MAXNZ),aga(MAXNZ) capk = cappa(1) hi = h(ixy,1) tmp = capk + hi betk = capk / tmp bet(1) = betk gam(1) = hi / tmp do k = 2, ndim betkm1 = betk capkm1 = capk capk = cappa(k) hi = h(ixy,k) tmp = hi + capk + capkm1 - betkm1 * capkm1 betk = capk / tmp bet(k) = betk aga(k) = capkm1 / tmp gam(k) = hi / tmp enddo bet(ndim) = 0. return end subroutine tria_run (npt, data) c------------------------------------- csenq include 'comm_para.h' real data(npt,1) common /tria_loc/ ixy, ndim, alf(MAXNZ),bet(MAXNZ),gam(MAXNZ),aga(MAXNZ) alfa = data(ixy,1)*gam(1) alf(1) = alfa do k = 2, ndim alfa = data(ixy,k)*gam(k) + alfa*aga(k) alf(k) = alfa enddo prev = 0. do k = ndim , 1, -1 prev = alf(k) + bet(k) * prev data(ixy,k) = prev enddo return end subroutine tria_tem (npt, data, botval) c-------------------------------------------- csenq include 'comm_para.h' real data(npt,1) common /tria_loc/ ixy, ndim, alf(MAXNZ),bet(MAXNZ),gam(MAXNZ),aga(MAXNZ) alfa = data(ixy,1)*gam(1) alf(1) = alfa do k = 2, ndim alfa = data(ixy,k)*gam(k) + alfa*aga(k) alf(k) = alfa enddo prev = botval do k = ndim, 1, -1 prev = alf(k) + bet(k) * prev data(ixy,k) = prev enddo return end c**************************************************************************** subroutine dens_eos(pr, t, s, r0, rr) c**************************************************************************** c sub to compute density c calls sub 'sbulk', for secant bulk modulas c c r0 is density at p = 0 - returned in gr cm**3 c rr is in situ density - returned c implicit double precision (a-z) real*4 t, s, pr c dimension a(0:5), b(0:4), c(0:2) parameter 1 (a0=999.842594d+00,a1=6.793952d-02,a2=-9.095290d-03, 2 a3=1.001685d-04,a4=-1.120083d-06,a5=6.536332d-09, 3 b0=8.24493d-01,b1=-4.0899d-03,b2=7.6438d-05, 4 b3=-8.2467d-07,b4=5.3875d-09, 5 c0=-5.72466d-03,c1=1.0227d-04,c2=-1.6546d-06, 6 d=4.8314d-04) if (t.lt.-4.0 .or. t.gt.40.0) then r0 = -99.9 rr = -99.9 return else if (s.lt.0.0 .or. s.gt.42.0) then r0 = -99.9 rr = -99.9 return else if (pr.lt.0.0 .or. pr.gt.10000.0) then r0 = -99.9 rr = -99.9 return end if call sbulk(pr, t, s, kk) c secant bulk modulas (k) of seawater c c density of smow c rw = ((((a5*t + a4)*t + a3)*t + a2)*t + a1)*t +a0 c c density at p = 0 c r0 = rw + s*((((b4*t + b3)*t + b2)*t + b1)*t + b0) * + s*sqrt(s)*((c2*t + c1)*t + c0) + s*s*d c c in situ density c p = pr / 10.0 c p is in bars rr = r0 / (1.d0 - p / kk) rr = rr / 1.d3 c densities are returned in r0 = r0 / 1.d3 c grams / cubic centimeter return end c**************************************************************************** function theta_eos(p0, t0, s, pf) c**************************************************************************** c c to compute local potential temperature at pf c c oct 12 1975 n. fofonoff c p = p0 t = t0 h = pf - p xk = h * atg(p, t, s) t = t + 0.5 * xk q = xk p = p + 0.5 * h xk = h*atg(p,t,s) t = t + 0.29298322*(xk-q) q = 0.58578644*xk + 0.121320344*q xk = h*atg(p,t,s) t = t + 1.707106781*(xk-q) q = 3.414213562*xk - 4.121320344*q p = p + 0.5*h xk = h*atg(p,t,s) theta = t + (xk - 2.0 * q) / 6.0 return end c**************************************************************************** c**************************************************************************** subroutine sbulk(pr, t, s, kk) c**************************************************************************** c c subroutines to calculate density, spec vol, secant bulk c modulas and alpha & beta c based on unesco 1981 report c equation of state for seawater - millero c programmer - c. greengrove, jan 1982 c modified for hp - p mele, sep '82 c c range: c s = 0 to 42 (practical salinity) c t = -4 to 40 (c) c pr = 0 to 10000 (decibars) c c other units: c density = kg/m3 **3 c bulk deni mod.(k) = bars c c c kk is secant bulk modulas - returned c implicit double precision (a-z) real*4 t, s, pr, s12 c single precision parameter 1 (e0=19652.21d+00,e1=148.4206d+00,e2=-2.327105d+00, 2 e3=1.360477d-02,e4=-5.155288d-05, 3 f0=54.6746d+00,f1=-.603459d+00,f2=1.09987d-02,f3=-6.167d-05, 4 g0=7.944d-02,g1=1.6483d-02,g2=-5.3009d-04, 5 h0=3.239908d+00,h1=1.43713d-03,h2=1.16092d-04,h3=-5.77905d-07, 6 i0=2.2838d-03,i1=-1.0981d-05,i2=-1.6078d-06, 7 j=1.91075d-04, 8 k0=8.50935d-05,k1=-6.12293d-06,k2=5.2787d-08, 9 m0=-9.9348d-07,m1=2.0816d-08,m2=9.1697d-10) if (t.lt.-4.0 .or. t.gt.40.0) then c range specifications kk = -99.9 return else if (s.lt.0.0 .or. s.gt.42.0) then kk = -99.9 return else if (pr.lt.0.0 .or. pr.gt.10000.0) then kk = -99.9 return end if p = pr / 10.0 c convert to bars c define sqrt(s) s12=sqrt(s) c c secant bulk modulas (k) of seawater c c pure water terms of sbm are w series c kw = (((e4*t + e3)*t + e2)*t + e1)*t + e0 aw = ((h3*t + h2)*t + h1)*t + h0 bw = (k2*t + k1)*t + k0 c c coeff for final equation c aa = aw + s*((i2*t + i1)*t + i0 + j*s12) bb = bw + s*((m2*t + m1)*t + m0) c c sbm at p = 0 first term in the final eq c ko = kw + s*(((f3*t + f2)*t + f1)*t + f0) * + s*s12*((g2*t + g1)*t + g0) c c final eq sbm c kk = (bb*p + aa)*p + ko return end c**************************************************************************** function atg(p, t, s) c**************************************************************************** c c adiabatic temperature gradient (bryden 1973) c ds = s - 35.0 atg = (((-2.1687e-16 * t + 1.8676e-14) * t - 4.6206e-13) * p + * ((2.7759e-12 * t - 1.1351e-10) * ds + ((-5.4481e-14 * t + * 8.733e-12) * t - 6.7795e-10) * t + 1.8741e-8)) * p + * (-4.2393e-8 * t + 1.8932e-6) * ds + ((6.6228e-10 * t - * 6.836e-8) * t + 8.5258e-6) * t + 3.5803e-5 return end c ------------------------------------------------------------------ subroutine comp_bncy (npt,nzi,dens,bncy) c ------------------------------------------------------------------ c Compute boyoncy as : b = -g(rho-rho_0)/rho_0 c ------------------------------------------------------------------ include 'comm_para.h' include 'comm_new.h' dimension dens(npt,1),bncy(npt,1),nzi(npt) c coef = -GRAVTY/(1000. + POTND_BOT) do i = 1, npt do k = 1, nzi(i) bncy(i,k) = coef * (dens(i,k) - POTND_BOT) enddo enddo return end c ------------------------------------------------------------------ subroutine cvmix(npt,nzi,h,t,s,b,u,v) c ------------------------------------------------------------------ c Convective adjustment as of Dake Chen. include 'comm_new.h' dimension nzi(npt),h(npt,1),t(npt,1),s(npt,1),b(npt,1),u(npt,1),v(npt,1) c do ns = 1, 2 do ks = 1, 2 do i = 1, npt do k = ks, nzi(i)-1, 2 k1 = k + 1 if (b(i,k) .lt. b(i,k1)) then hik = h(i,k) hik1 = h(i,k1) hsum1 = 1. / (hik + hik1) t(i,k) = (hik*t(i,k) + hik1*t(i,k1))*hsum1 t(i,k1) = t(i,k) s(i,k) = (hik*s(i,k) + hik1*s(i,k1))*hsum1 s(i,k1) = s(i,k) b(i,k) = (hik*b(i,k) + hik1*b(i,k1))*hsum1 b(i,k1) = b(i,k) endif enddo enddo enddo enddo return end c ---------------------------------------------------------------- function tke0(wp,b0,br,h,hp) c ---------------------------------------------------------------- hp2 = hp + hp hexp = h - hp2 + (h + hp2)*exp(-h/hp) bp = b0*h + br*hexp tke0 = wp - bp return end c --------------------------------------------------------------------- subroutine ktmix(npt,nsig,ddt,h,t,s,b,u,v,q,qr,ep,taux,tauy,sigma,dh1) c --------------------------------------------------------------------- c Vertical Mixing Using Kraus-Turner Scheme.(Dake Chen, 1995) include 'comm_new.h' dimension u(npt,1),v(npt,1),h(npt,1),t(npt,1),s(npt,1),b(npt,1), + dh1(1),q(1),qr(1),ep(1),taux(1),tauy(1),sigma(1) data alph/2.55e-4/, beta/7.6e-4/, gravty/9.8/, taumin/3.e-5/, hp/17./ c ga = alph*gravty gb = beta*gravty c cm2 = 2.0 * cm_mix cn2 = cn_mix / 2.0 do i = 1, npt h10 = h(i,1) tau = sqrt(taux(i)**2 + tauy(i)**2) tau = amax1(tau,taumin) ustar = sqrt(tau) wp = cm2 * ustar * tau br = ga*qr(i) b0 = ga*q(i) - gb*ep(i) dbh = (b(i,1) - b(i,2))*h10 b0 = b0 - cn2 * (b0-abs(b0)) dbh = amax1(dbh,1.e-5) tke = tke0(wp,b0,br,h10,hp) if( tke .lt. 0.) then h1 = h10 h2 = 0.5*h1 f1 = tke0(wp,b0,br,h1,hp) do iter = 1, 10 f2 = tke0(wp,b0,br,h2,hp) hnew = h2 - f2*(h2-h1)/(f2-f1) err = abs(hnew-h2)/h2 if (err .lt. 1.e-4) goto 15 h1 = h2 h2 = hnew f1 = f2 enddo 15 continue hnew = amin1(h10, hnew) else h1 = h10 h2 = h10 + h10 hm = h10 f1 = -ddt*tke0(wp,b0,br,hm,hp) do iter = 1, 10 hm = 0.5*(h2+h10) f2 = dbh*(h2-h10) - ddt*tke0(wp,b0,br,hm,hp) hnew = h2 - f2*(h2-h1)/(f2-f1) err = abs(hnew-h2)/h2 if (err .lt. 1.e-4) goto 25 h1 = h2 h2 = hnew f1 = f2 enddo 25 continue hnew = amax1(h10, hnew) endif hnew = amax1(hmin_mix, hnew) hnew = amin1(hmax_mix, hnew) dh = hnew - h10 adh = amin1(abs(dh), h(i,2)) dh1(i) = sign(adh, dh) enddo call impmix (npt,nsig,dh1,u,v,h,t,s,sigma) return end c ---------------------------------------------------------------- subroutine impmix (npt,nz,dh1,u,v,h,t,s,sigma) c ---------------------------------------------------------------- c Adjust vertical profiles according to the depth change of the c mixed layer as of Dake Chen. /modified by Senya Basin, July 1995/ include 'comm_para.h' include 'comm_new.h' dimension dh1(1),u(npt,1),v(npt,1),h(npt,1), * t(npt,1),s(npt,1), sigma(1), * u1(MAXNZ),u2(MAXNZ),v1(MAXNZ),v2(MAXNZ),t1(MAXNZ),t2(MAXNZ), * aa(MAXNZ),bb(MAXNZ),cc(MAXNZ),dh(MAXNZ),we(MAXNZ),hr(MAXNZ), * s1(MAXNZ),s2(MAXNZ) do i = 1, npt dh_mix = dh1(i) if (dh_mix .ne. 0.) then dh(1) = dh_mix do k = 2, nz dh(k) = -1.5*(sigma(k)+sigma(k+1))*dh_mix enddo we(1) = dh_mix do k = 2, nz-1 we(k) = we(k-1) + dh(k) enddo do k = 1, nz hik = h(i,k) u1(k) = u(i,k)*hik v1(k) = v(i,k)*hik t1(k) = t(i,k)*hik s1(k) = s(i,k)*hik h(i,k) = hik + dh(k) enddo do k = 1, nz-1 hr(k) = we(k)/(h(i,k)+h(i,k+1)) enddo hr1 = 0.5*(dh_mix - abs(dh_mix)) / h(i,1) hr2 = 0.5*(dh_mix + abs(dh_mix)) / h(i,2) cc(1) = -hr2 bb(1) = 1. - hr1 aa(2) = hr1 cc(2) = -hr(2) bb(2) = 1. - hr(2) + hr2 aa(nz) = hr(nz-1) bb(nz) = 1. + aa(nz) hr_k = hr(2) do k = 3, nz-1 hr_km1 = hr_k hr_k = hr(k) aa(k) = hr_km1 cc(k) = -hr_k bb(k) = 1. + hr_km1 - hr_k enddo call tridiag(aa,bb,cc,u1,u2,nz) call tridiag(aa,bb,cc,v1,v2,nz) call tridiag(aa,bb,cc,t1,t2,nz) call tridiag(aa,bb,cc,s1,s2,nz) do k = 1, nz hik = 1./h(i,k) u(i,k) = hik*u2(k) v(i,k) = hik*v2(k) t(i,k) = hik*t2(k) s(i,k) = hik*s2(k) enddo endif enddo return end c ------------------------------------------------------------------ subroutine jpmix (npt,nz,nzi,h,t,s,b,u,v) c ------------------------------------------------------------------ c Reduce gradient Richardson # instability using a Jim Price criterion. include 'comm_para.h' include 'comm_new.h' dimension u(npt,1),v(npt,1),h(npt,1),t(npt,1),s(npt,1),b(npt,1), * gama(MAXNZ), ric(MAXNZ), nzi(npt) logical use_gamma save EPSILON, use_gamma, ifirst, ric, ric_inv data EPSLON/1.e-9/, ifirst/0/ c if ( ifirst .eq. 0 ) then ifirst = 1 gama(1) = gam1_mix ric(1) = ric1_mix do k = 2, nz gama(k) = gam2_mix ric(k) = ric2_mix enddo use_gamma = (iuse_gam .eq. 1) endif do kn = 1, 2 do ks = 1, 2 do i = 1, npt do k = ks, nzi(i)-1, 2 Rik = ric(k) Rik_inv = 1./ric(k) gamkt = gama(k) gamkv = 0.5*(1.+gama(k)) c compute the gradient Richardson number hm = h(i,k) + h(i,k+1) bd = b(i,k) - b(i,k+1) dd = 0.5 * hm * bd ud = u(i,k+1) - u(i,k) vd = v(i,k+1) - v(i,k) dv = ud*ud + vd*vd Ri = amax1(dd,0.)/amax1(dv,EPSLON) c check to see if Ri is critical or not if (Ri .lt. Rik) then c partially mix layers k and k+1 if ( use_gamma ) then ri2 = Ri*Rik_inv ct = 1.- ri2**gamkt cv = 1.- ri2**gamkv else ct = 1. - Ri*Rik_inv cv = ct endif c1 = h(i,k) / hm c2 = h(i,k+1) / hm td = (t(i,k+1)-t(i,k))*ct sd = (s(i,k+1)-s(i,k))*ct bd = -bd*ct ud = ud*cv vd = vd*cv t(i,k+1) = t(i,k+1) - td*c1 t(i,k) = t(i,k) + td*c2 s(i,k+1) = s(i,k+1) - sd*c1 s(i,k) = s(i,k) + sd*c2 b(i,k+1) = b(i,k+1) - bd*c1 b(i,k) = b(i,k) + bd*c2 u(i,k+1) = u(i,k+1) - ud*c1 u(i,k) = u(i,k) + ud*c2 v(i,k+1) = v(i,k+1) - vd*c1 v(i,k) = v(i,k) + vd*c2 endif enddo enddo enddo enddo return end c---------------------------------------------------------------------------- subroutine tridiag(A,B,C,Y,X,N) c---------------------------------------------------------------------------- c Modified 2 Feb 1991 c This routine solves a matrix equation of the form MX=Y where Y is c the know vector and M is an NxN tridiagonal matrix with a diagonal of c B, a lower diagonal of A and an upper diagonal of C. It should be c noted that N will be equal to the number of layers (nz). If there c are more than 100 the array size will exceed memory allocation. c c This routine requires the matrix elements (A,B,C), the known vector c (Y) and the dimensions of both (N). c c This routine supplies the new vector X. c The variables are defined as: c c Name Type Description c ==== ==== =========== c c a(n) From Lower diagonal elements c dimpl c b(n) From Main diagonal elements c dimpl c bit Internal Storage variable c c(n) From Upper diagonal elements c dimpl c gam(nmax) Internal Storage array c nmax Internal Maximum array size c x(n) Ret to new velocity (temp) field c dimpl c y(n) From Original velocity (temp) field c dimpl c c------------------ Establish variables and constants ----------------------- parameter (nmax=100) dimension gam(nmax),a(n),b(n),c(n),y(n),x(n) bet = b(1) x(1) = y(1)/bet c-------------------------- Forward substitute ------------------------------ do j = 2, n gam(j) = c(j-1)/bet bet = b(j) - a(j)*gam(j) x(j) = (y(j) - a(j)*x(j-1)) / bet enddo c-------------------------- Back substitute ------------------------------ do j = n-1, 1, -1 x(j) = x(j) - gam(j+1)*x(j+1) enddo return end c----------------------------------------------------------- subroutine windmix(npt,nz,dtmix,limp,delt,windm0,windz0, & nzi,u,v,uc,vc,h,t,sal,dens,tr,convn,wnd,zmld) c----------------------------------------------------------- c Kraus-Turner mixing AND convective adjustment (a la dconv) c for use with a level grid; includes the effect of c wind stirring c c Uses the Kraus-Turner vertical mixing algorithm described in: c Stefan Rahmstorf, 1991: A zonal-averaged model of the c ocean's response to climate change, JGR Oceans, V.96, c p. 6951-6963; c implicit real(a-h,o-z),integer(i-n) include 'comm_new.h' include 'comm_para.h' c include 'comm_tracer.h' common /errors/ ioerr, nstep real m,m0 dimension u(npt,nz),v(npt,nz),uc(npt,nz),vc(npt,nz), & h(npt,nz),t(npt,nz),sal(npt,nz),dens(npt,nz), & convn(npt,nz),nzi(npt),tr(npt,nz,1),wnd(npt,3),zmld(npt) CD = 1.3e-3 cd3 = CD**1.5 c windm0 from input parameter file; do i=1,npt zbotint = 0. tmix = t(i,1) smix = sal(i,1) wspeed = wnd(i,1) wspeed3 = wspeed*wspeed*wspeed ustar3 = wspeed3*cd3 if_first = 1 do k=1,nzi(i)-1 kp = k+1 zbotint = zbotint + h(i,k) rhomix = sdens_pnt(tmix,smix,zbotint) rhok = sdens_pnt(t(i,kp),sal(i,kp),zbotint) c compute buoyancy [isn't this really potential energy since c I'm multiplying buoyancy by depth???] buoy = GRAVTY/(1000.+SITUD_BOT)*(rhok-rhomix)*zbotint c compute wind energy m = windm0*exp(-zbotint/windz0) winden = m*ustar3*(delt*limp*86400.)/zbotint c check for mixing if (winden .ge. buoy) then hinv = h(i,k) + h(i,kp) oldpotener = (dens(i,kp)*h(i,kp) + dens(i,k)*hinv)/2. hinv = 1.0 / hinv hki = hinv * h(i,k) hkpi = hinv * h(i,kp) tmp = uc(i,k) + uc(i,kp) uc(i,k) = tmp * hki uc(i,kp) = tmp * hkpi tmp = hinv * tmp u(i,k) = tmp u(i,kp) = tmp tmp = vc(i,k) + vc(i,kp) vc(i,k) = tmp * hki vc(i,kp) = tmp * hkpi tmp = hinv * tmp v(i,k) = tmp v(i,kp) = tmp tmp1 = hki*t(i,k) + hkpi*t(i,kp) t(i,k) = tmp1 t(i,kp) = tmp1 tmp = hki*sal(i,k) + hkpi*sal(i,kp) sal(i,k) = tmp sal(i,kp) = tmp tmp = pdens_pnt (tmp1, tmp) dens(i,k) = tmp dens(i,kp) = tmp do m = 1, ntrac_tot tmp = hki*tr(i,k,m) + hkpi*tr(i,kp,m) tr(i,k,m) = tmp tr(i,kp,m) = tmp enddo znewpotener = dens(i,k)*(h(i,kp) + h(i,k)/2.) convn(i,k) = oldpotener - znewpotener tmix = t(i,k) smix = sal(i,k) else if (if_first.eq.1) zmld(i) = max(zmld(i),zbotint) ustar3 = 0. if_first = 0 endif enddo enddo return end