c2--567--1---------2---------3---------4---------5---------6---------712 Subroutine interpol_t(t, p_top, tlvl_fine, n, nlvl_fine, 1 lam1, lamn, normal) c c -- Interpol_t/Interpolation of temperature from Umkehr to fine c layers/N. Nath/June '01 c c -- Function: Given average temperature in Umkehr layers, this c routine determines temperature at equidistant, fine c log(pressure) levels suitable for computation of SBUV c radiances. Umkehr layers may be given from bottom to top of c the atmosphere (starting with layer 0), or from top to bottom. c implicit none c c -- Input & Output Variables: c real t(n), p_top !average temperature in Umkehr layers (K), ! pressure at top of the fine layers ! (atmos) (input) real tlvl_fine(nlvl_fine) !interpolated temperature at fine levels ! (K) (output) integer n, nlvl_fine !number of Umkehr layers, number of fine ! levels (input) real lam1, lamn !end parameters for spline interpolation ! (input) logical normal!if true, Umkehr layer data are ordered ! from 0 upward; if false, the opposite ! (input) c c -- Local Variables: c integer nl, nlvl_finel, ns !maximum values of n & nlvl_fine, ! & number of auxiliary t's parameter (nl = 13, nlvl_finel = 81, ns = 8) c real h !pressure scale height at z = 0 & standard ! temperature (cm) parameter (h = 7.996e5) real t0(nl), z(nl), dz, zlvl_fine(nlvl_finel), 1 dz_fine !t save array, z array & dz for Umkehr ! layers, zlvl array & dz for fine layers real tmid(nl), slope !best guess of Umkehr mid-layer ! temperature such that the spline ! average agrees with t; slope in top ! layers real z_aux(nl*ns), t_aux(nl*ns), dz_aux, tav(nl), sum !quantities needed for auxiliary computns real devn2, devn, tol parameter (tol = 1e-4) c real maxdevn c integer imax integer i, nlvl_spl, is, n_aux, irpt c c Order data from bottom to top c if (.not. normal) then do i = 1,n t0(i) = t(i) end do do i = 1,n t(i) = t0(n+1-i) end do end if c c Prepare for interpolation c dz = h*log(2.0) !define dz & z array do i = 1,n z(i) = dz/2.0 + (i - 1)*dz end do dz_fine = - h*log(p_top)/(nlvl_fine - 1) !define dz_fine & z_fine array do i = 1,nlvl_fine zlvl_fine(i) = (i - 1)*dz_fine end do c c Find Umkehr mid-layer temperature such that the average of c the resulting spline agrees with t c do i = 1,n tmid(i) = t(i) end do c c o Iterate until the desired accuracy is attained c dz_aux = dz/ns n_aux = n*ns do i = 1,n_aux z_aux(i) = dz_aux/2.0 + (i - 1)*dz_aux end do do irpt = 1,4 !four iterations should suffice call spline(z, tmid, n, z_aux, t_aux, n_aux, lam1, lamn) do i = 1,n sum = 0.0 do is = 1,ns sum = sum + t_aux((i-1)*ns + is) end do tav(i) = sum/ns !tav(i) should be close to t(i) tmid(i) = tmid(i)*t(i)/tav(i) !correction so in the next step tmid(i) ! will be closer to t(i) end do devn2 = 0.0 c imax = 0 c maxdevn = 0.0 do i = 1,n devn = abs(1.0 - tav(i)/t(i)) devn2 = devn2 + devn**2 c if (devn .gt. maxdevn) then c imax = i c maxdevn = devn c end if end do devn = sqrt(devn2/n) c write (*, *) tav c write (*, *) "devn, imax, maxdevn: ", devn, imax, maxdevn if (devn .lt. tol) go to 100 end do 100 continue c c Perform spline interpolation up to middle of the top layer c nlvl_spl = int((n - 0.5)*dz/dz_fine) + 1 call spline(z, tmid, n, zlvl_fine, tlvl_fine, nlvl_spl, lam1, 1 lamn) !extrapol'n at lower end with end ! parameter -1; this may not be necessary c c Extrapolate linearly above nlvl_spl c slope = (tmid(n) - tmid(n-1))/dz do i = nlvl_spl+1,nlvl_fine tlvl_fine(i) = tmid(n) + slope*(zlvl_fine(i) - z(n)) end do c c Return original data c if (.not. normal) then do i = 1,n t(i) = t0(i) end do end if c return end