22subroutine get_amip_sst_ (Time, Interp, sst, err_msg, lon_model, lat_model)
23 type (time_type),
intent(in) :: Time
24 type (amip_interp_type),
target,
intent(inout) :: Interp
25 real(FMS_AMIP_INTERP_KIND_),
intent(out) :: sst(:,:)
26 character(len=*),
optional,
intent(out) :: err_msg
28 real(FMS_AMIP_INTERP_KIND_),
dimension(mobs,nobs) :: sice
29 real(FMS_AMIP_INTERP_KIND_),
allocatable,
save :: temp1(:,:), temp2(:,:)
31 integer :: year1, year2, month1, month2
32 real(FMS_AMIP_INTERP_KIND_) :: fmonth
33 type (date_type) :: Date1, Date2, Udate1, Udate2
35 type(time_type) :: Amip_Time
36 integer :: tod(3),dum(3)
39 real(FMS_AMIP_INTERP_KIND_),
intent(in),
dimension(:,:),
optional :: lon_model, lat_model
40 real(FMS_AMIP_INTERP_KIND_) :: pert
41 integer :: i, j, mobs_sst, nobs_sst
43 type (time_type) :: Udate
44 character(len=4) :: yyyy
45 integer :: nrecords, ierr, k, yr, mo, dy
46 integer,
dimension(:),
allocatable :: ryr, rmo, rdy
47 character(len=30) :: time_unit
48 real(FMS_AMIP_INTERP_KIND_),
dimension(:),
allocatable :: timeval
49 character(len=FMS_FILE_LEN) :: ncfilename
50 type(FmsNetcdfFile_t) :: fileobj
51 logical :: the_file_exists
53 logical,
parameter :: DEBUG = .false.
56 integer,
parameter :: lkind = fms_amip_interp_kind_
58 if(
present(err_msg)) err_msg =
''
59 if(.not.interp%I_am_initialized)
then
60 if(fms_error_handler(
'get_amip_sst',
'The amip_interp_type variable is not initialized',err_msg))
return
66 if ( use_ncep_sst .and. forecast_mode ) no_anom_sst = .false.
68 if (all(amip_date>0))
then
69 call get_date(time,dum(1),dum(2),dum(3),tod(1),tod(2),tod(3))
70 amip_time = set_date(amip_date(1),amip_date(2),amip_date(3),tod(1),tod(2),tod(3))
76if ( .not.use_daily )
then
79 if ( .not.
allocated(temp1) )
allocate (temp1(mobs,nobs))
80 if ( .not.
allocated(temp2) )
allocate (temp2(mobs,nobs))
83 call zonal_sst_ (amip_time, sice, temp1)
84 call horiz_interp (interp%Hintrp, temp1, sst)
91 call time_interp (amip_time, fmonth, year1, year2, month1, month2)
93 if (interp%use_climo)
then
96 if (interp%use_annual)
then
102 date1 = date_type( year1, month1, 0 )
103 date2 = date_type( year2, month2, 0 )
109 if (date1 /= interp%Date1)
then
111 if (date1 == interp%Date2)
then
112 interp%Date1 = interp%Date2
113 interp%DATA1_ = interp%DATA2_
114 temp1(:,:) = temp2(:,:)
116 call read_record_ (
'sst', date1, udate1, temp1)
117 if ( use_ncep_sst .and. (.not. no_anom_sst) )
then
118 temp1 = temp1 + sst_anom_
120 call horiz_interp ( interp%Hintrp, temp1, interp%DATA1_)
121 call clip_data_ (
'sst', interp%DATA1_)
128 if (date2 /= interp%Date2)
then
129 call read_record_ (
'sst', date2, udate2, temp2)
130 if ( use_ncep_sst .and. (.not. no_anom_sst) )
then
131 temp2 = temp2 + sst_anom_
133 call horiz_interp ( interp%Hintrp, temp2, interp%DATA2_)
134 call clip_data_ (
'sst', interp%DATA2_)
141 sst = interp%DATA1_ + fmonth * (interp%DATA2_ - interp%DATA1_)
148 if ( use_ncep_sst .and. no_anom_sst )
then
149 sst_anom = sst_ncep_ - (temp1 + fmonth*(temp2 - temp1))
150 call horiz_interp (interp%Hintrp, sst_ncep_, sst)
151 call clip_data_ (
'sst', sst)
156 call get_date(amip_time,jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6))
157 if (mpp_pe() == 0)
then
158 write (*,200)
'JHC: use_daily = F, AMIP_Time: ',jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5), &
160 write (*,300)
'JHC: use_daily = F, interped SST: ', sst(1,1),sst(5,5),sst(10,10)
169 call get_date(amip_time,jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6))
170 if (mpp_pe() == mpp_root_pe())
write(*,200)
'amip_interp_mod: use_daily = T, Amip_Time = ',jhctod(1), &
171 & jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6)
173 yr = jhctod(1); mo = jhctod(2); dy = jhctod(3)
175 write (yyyy,
'(i4)') jhctod(1)
177 file_name_sst =
'INPUT/' //
'sst.day.mean.'//yyyy//
'.v2.nc'
178 ncfilename = trim(file_name_sst)
179 time_unit =
'days since 1978-01-01 00:00:00'
181 mobs_sst = 1440; nobs_sst = 720
183 call set_sst_grid_edges_daily_ (mobs_sst, nobs_sst)
184 call horiz_interp_new ( interp%Hintrp2, lon_bnd_, lat_bnd_, &
185 lon_model, lat_model, interp_method=
"bilinear" )
187 the_file_exists = fms2_io_file_exists(ncfilename)
189 if ( (.NOT. the_file_exists) )
then
190 call mpp_error (
'amip_interp_mod', &
191 'cannot find daily SST input data file: '//trim(ncfilename), note)
193 if (mpp_pe() == mpp_root_pe())
call mpp_error (
'amip_interp_mod', &
194 'Reading NetCDF formatted daily SST from: '//trim(ncfilename), note)
196 if(.not. open_file(fileobj, trim(ncfilename),
'read')) &
197 call error_mesg (
'get_amip_sst',
'Error in opening file '//trim(ncfilename), fatal)
199 call get_dimension_size(fileobj,
'TIME', nrecords)
200 if (nrecords < 1)
call mpp_error(
'amip_interp_mod', &
201 'Invalid number of SST records in daily SST data file: '//trim(ncfilename), fatal)
202 allocate(timeval(nrecords), ryr(nrecords), rmo(nrecords), rdy(nrecords))
203 call fms2_io_read_data(fileobj,
'TIME', timeval)
206 if (mpp_pe() == 0)
then
207 print *,
'JHC: nrecords = ', nrecords
208 print *,
'JHC: TIME = ', timeval
215 udate = get_cal_time(timeval(k), time_unit,
'julian')
216 call get_date(udate,jhctod(1),jhctod(2),jhctod(3),jhctod(4),jhctod(5),jhctod(6))
217 ryr(k) = jhctod(1); rmo(k) = jhctod(2); rdy(k) = jhctod(3)
219 if ( yr == ryr(k) .and. mo == rmo(k) .and. dy == rdy(k) ) ierr = 0
225 if (mpp_pe() == 0)
then
226 print *,
'JHC: k =', k
227 print *,
'JHC: ryr(k) rmo(k) rdy(k)',ryr(k), rmo(k), rdy(k)
228 print *,
'JHC: yr mo dy ',yr, mo, dy
232 if (ierr .ne. 0)
call mpp_error(
'amip_interp_mod', &
233 'Model time is out of range not in SST data: '//trim(ncfilename), fatal)
238 if ( .not.
allocated(tempamip) ) &
239 &
allocate (tempamip(mobs_sst,nobs_sst))
241 if (the_file_exists)
then
242 call fms2_io_read_data(fileobj,
'SST', tempamip, unlim_dim_level=k)
243 call close_file(fileobj)
244 tempamip = tempamip + tfreeze
248 if (mpp_pe() == 0)
then
249 print*,
'JHC: TFREEZE = ', real(tfreeze, fms_amip_interp_kind_)
252 print*, lbound(tempamip)
253 print*, ubound(tempamip)
254 write(*,300)
'JHC: tempamip : ', tempamip(100,100), tempamip(200,200), tempamip(300,300)
258 call horiz_interp ( interp%Hintrp2, tempamip_, sst )
259 call clip_data_ (
'sst', sst)
264 if (mpp_pe() == 400)
then
265 write(*,300)
'JHC: use_daily = T, daily SST: ', sst(1,1),sst(5,5),sst(10,10)
266 print *,
'JHC: use_daily = T, daily SST: ', sst
270200
format(a35, 6(i5,1x))
271300
format(a35, 3(f7.3,2x))
279 if ( do_sst_pert )
then
281 if ( trim(sst_pert_type) ==
'fixed' )
then
282 sst = sst + real(sst_pert, fms_amip_interp_kind_)
283 else if ( trim(sst_pert_type) ==
'random' )
then
287 if (mpp_pe() == 0)
then
288 print*,
'mobs = ', mobs
289 print*,
'nobs = ', nobs
295 do i = 1,
size(sst,1)
296 do j = 1,
size(sst,2)
297 call random_number(pert)
298 sst(i,j) = sst(i,j) + real(sst_pert, fms_amip_interp_kind_)*((pert-0.5_lkind)*2)
305 end subroutine get_amip_sst_
308subroutine get_amip_ice_ (Time, Interp, ice, err_msg)
309 type (time_type),
intent(in) :: Time
310 type (amip_interp_type),
target,
intent(inout) :: Interp
311 real(FMS_AMIP_INTERP_KIND_),
intent(out) :: ice(:,:)
312 character(len=*),
optional,
intent(out) :: err_msg
314 real(FMS_AMIP_INTERP_KIND_),
dimension(mobs,nobs) :: sice, temp
316 integer :: year1, year2, month1, month2
317 real(FMS_AMIP_INTERP_KIND_) :: fmonth
318 type (date_type) :: Date1, Date2, Udate1, Udate2
320 type(time_type) :: Amip_Time
321 integer :: tod(3),dum(3)
322 integer,
parameter :: lkind = fms_amip_interp_kind_
324 if(
present(err_msg)) err_msg =
''
325 if(.not.interp%I_am_initialized)
then
326 if(fms_error_handler(
'get_amip_ice',
'The amip_interp_type variable is not initialized',err_msg))
return
333 if (any(amip_date>0))
then
335 call get_date(time,dum(1),dum(2),dum(3),tod(1),tod(2),tod(3))
337 amip_time = set_date(amip_date(1),amip_date(2),amip_date(3),tod(1),tod(2),tod(3))
347 call zonal_sst_ (amip_time, sice, temp)
348 call horiz_interp ( interp%Hintrp, sice, ice )
356 call time_interp (amip_time, fmonth, year1, year2, month1, month2)
359 if (interp%use_climo)
then
362 if (interp%use_annual)
then
368 date1 = date_type( year1, month1, 0 )
369 date2 = date_type( year2, month2, 0 )
374 if (date1 /= interp%Date1)
then
376 if (date1 == interp%Date2)
then
377 interp%Date1 = interp%Date2
378 interp%DATA1_ = interp%DATA2_
383 if ( use_ncep_sst .and. use_ncep_ice )
then
384 where ( sst_ncep_ <= (real(tfreeze, fms_amip_interp_kind_)+real(tice_crit, fms_amip_interp_kind_)) )
390 call read_record_ (
'ice', date1, udate1, sice)
393 call horiz_interp ( interp%Hintrp, sice, interp%DATA1_)
394 call clip_data_ (
'ice', interp%DATA1_)
401 if (date2 /= interp%Date2)
then
404 if ( use_ncep_sst .and. use_ncep_ice )
then
405 where ( sst_ncep_ <= (real(tfreeze, fms_amip_interp_kind_)+real(tice_crit, fms_amip_interp_kind_)) )
411 call read_record_ (
'ice', date2, udate2, sice)
414 call horiz_interp ( interp%Hintrp, sice, interp%DATA2_)
415 call clip_data_ (
'ice', interp%DATA2_)
424 ice = interp%DATA1_ + fmonth * (interp%DATA2_ - interp%DATA1_)
427 end subroutine get_amip_ice_
430 function amip_interp_new_1d_ ( lon , lat , mask , use_climo, use_annual, &
431 interp_method )
result (Interp)
432 real(FMS_AMIP_INTERP_KIND_),
intent(in),
dimension(:) :: lon, lat
433 logical,
intent(in),
dimension(:,:) :: mask
434 character(len=*),
intent(in),
optional :: interp_method
435 logical,
intent(in),
optional :: use_climo, use_annual
437 type (amip_interp_type) :: Interp
439 if(.not.module_is_initialized)
call amip_interp_init
441 interp%use_climo = .false.
442 if (
present(use_climo)) interp%use_climo = use_climo
443 interp%use_annual = .false.
444 if (
present(use_annual)) interp%use_annual = use_annual
446 if ( date_out_of_range ==
'fail' .and. interp%use_climo ) &
447 call error_mesg (
'amip_interp_new_1d',
'use_climo mismatch', fatal)
449 if ( date_out_of_range ==
'fail' .and. interp%use_annual ) &
450 call error_mesg (
'amip_interp_new_1d',
'use_annual(climo) mismatch', fatal)
452 interp%Date1 = date_type( -99, -99, -99 )
453 interp%Date2 = date_type( -99, -99, -99 )
458 call horiz_interp_new ( interp%Hintrp, lon_bnd_, lat_bnd_, &
459 lon, lat, interp_method= interp_method )
461 allocate(interp%DATA1_ (
size(lon(:))-1,
size(lat(:))-1))
462 allocate(interp%DATA2_ (
size(lon(:))-1,
size(lat(:))-1))
464 interp%I_am_initialized = .true.
465 end function amip_interp_new_1d_
468 function amip_interp_new_2d_ ( lon , lat , mask , use_climo, use_annual, &
469 interp_method )
result (Interp)
470 real(FMS_AMIP_INTERP_KIND_),
intent(in),
dimension(:,:) :: lon, lat
471 logical,
intent(in),
dimension(:,:) :: mask
472 character(len=*),
intent(in),
optional :: interp_method
473 logical,
intent(in),
optional :: use_climo, use_annual
475 type (amip_interp_type) :: Interp
477 if(.not.module_is_initialized)
call amip_interp_init
479 interp%use_climo = .false.
480 if (
present(use_climo)) interp%use_climo = use_climo
481 interp%use_annual = .false.
482 if (
present(use_annual)) interp%use_annual = use_annual
484 if ( date_out_of_range ==
'fail' .and. interp%use_climo ) &
485 call error_mesg (
'amip_interp_new_2d',
'use_climo mismatch', fatal)
487 if ( date_out_of_range ==
'fail' .and. interp%use_annual ) &
488 call error_mesg (
'amip_interp_new_2d',
'use_annual(climo) mismatch', fatal)
490 interp%Date1 = date_type( -99, -99, -99 )
491 interp%Date2 = date_type( -99, -99, -99 )
496 call horiz_interp_new ( interp%Hintrp, lon_bnd_, lat_bnd_, &
497 lon, lat, interp_method = interp_method)
499 allocate(interp%DATA1_ (
size(lon,1),
size(lat,2)))
500 allocate(interp%DATA2_ (
size(lon,1),
size(lat,2)))
502 interp%I_am_initialized = .true.
503 end function amip_interp_new_2d_
506 subroutine set_sst_grid_edges_daily_ (mobs_sst, nobs_sst)
507 integer :: i, j, mobs_sst, nobs_sst
508 real(FMS_AMIP_INTERP_KIND_) :: hpie, dlon, dlat, wb, sb
509 integer,
parameter :: lkind = fms_amip_interp_kind_
511 if(
allocated(lon_bnd))
deallocate(lon_bnd)
512 if(
allocated(lat_bnd))
deallocate(lat_bnd)
514 allocate(lon_bnd(mobs_sst+1))
515 allocate(lat_bnd(nobs_sst+1))
519 hpie = pi / 2._r8_kind
520 dlon = 4._r8_kind*hpie/real(mobs_sst, r8_kind)
525 lon_bnd(i) = wb + dlon * real(i-1, r8_kind)
527 lon_bnd(mobs_sst+1) = lon_bnd(1) + 4._r8_kind*hpie
529 dlat = 2._r8_kind*hpie/real(nobs_sst, r8_kind)
533 lat_bnd(nobs_sst+1) = hpie
535 lat_bnd(j) = sb + dlat * real(j-1, r8_kind)
537 end subroutine set_sst_grid_edges_daily_
540 subroutine a2a_bilinear_ (nx, ny, dat1, n1, n2, dat2)
541 integer,
intent(in) :: nx, ny
542 integer,
intent(in) :: n1, n2
543 real(FMS_AMIP_INTERP_KIND_),
intent(in) :: dat1(nx,ny)
544 real(FMS_AMIP_INTERP_KIND_),
intent(out) :: dat2(n1,n2)
547 real(FMS_AMIP_INTERP_KIND_) :: lon1(nx), lat1(ny)
548 real(FMS_AMIP_INTERP_KIND_) :: lon2(n1), lat2(n2)
549 real(FMS_AMIP_INTERP_KIND_) :: dx1, dy1, dx2, dy2
550 real(FMS_AMIP_INTERP_KIND_) :: xc, yc
551 real(FMS_AMIP_INTERP_KIND_) :: a1, b1, c1, c2, c3, c4
552 integer :: i1, i2, jc, i0, j0, it, jt
554 integer,
parameter :: lkind = fms_amip_interp_kind_
563 dx1 = 360._lkind/real(nx, fms_amip_interp_kind_)
564 dy1 = 180._lkind/real(ny, fms_amip_interp_kind_)
567 lon1(i) = 0.5_lkind*dx1 + real(i-1, fms_amip_interp_kind_)*dx1
570 lat1(j) = -90._lkind + 0.5_lkind*dy1 + real(j-1, fms_amip_interp_kind_)*dy1
573 dx2 = 360._lkind/real(n1, fms_amip_interp_kind_)
574 dy2 = 180._lkind/real(n2, fms_amip_interp_kind_)
577 lon2(i) = 0.5_lkind*dx2 + real(i-1, fms_amip_interp_kind_)*dx2
580 lat2(j) = -90._lkind + 0.5_lkind*dy2 + real(j-1, fms_amip_interp_kind_)*dy2
587 if ( yc<lat1(1) )
then
590 elseif ( yc>lat1(ny) )
then
595 if ( yc>=lat1(j0) .and. yc<=lat1(j0+1) )
then
598 b1 = (yc-lat1(jc)) / dy1
608 if ( xc>lon1(nx) )
then
610 a1 = (xc-lon1(nx)) / dx1
611 elseif ( xc<lon1(1) )
then
613 a1 = (xc+360._lkind-lon1(nx)) / dx1
616 if ( xc>=lon1(i0) .and. xc<=lon1(i0+1) )
then
619 a1 = (xc-lon1(i1)) / dx1
627 if ( a1<-0.001_lkind .or. a1>1.001_lkind .or. b1<-0.001_lkind .or. b1>1.001_lkind )
then
628 write(*,*) i,j,a1, b1
629 call mpp_error(fatal,
'a2a bilinear interpolation')
632 c1 = (1._lkind-a1) * (1._lkind-b1)
633 c2 = a1 * (1._lkind-b1)
635 c4 = (1._lkind-a1) * b1
638 dat2(i,j) = c1*dat1(i1,jc) + c2*dat1(i2,jc) + c3*dat1(i2,jc+1) + c4*dat1(i1,jc+1)
643 end subroutine a2a_bilinear_
645 subroutine read_record_ (type, Date, Adate, dat)
646 character(len=*),
intent(in) :: type
647 type (date_type),
intent(in) :: Date
648 type (date_type),
intent(inout) :: Adate
649 real(FMS_AMIP_INTERP_KIND_),
intent(out) :: dat(mobs,nobs)
650 real(FMS_AMIP_INTERP_KIND_) :: tmp_dat(360,180)
652 integer(I2_KIND) :: idat(mobs,nobs)
653 integer :: nrecords, yr, mo, dy, ierr, k
654 integer,
dimension(:),
allocatable :: ryr, rmo, rdy
655 character(len=FMS_FILE_LEN) :: ncfilename
656 character(len=NF90_MAX_NAME) :: ncfieldname
657 type(FmsNetcdfFile_t),
pointer :: fileobj
658 integer,
parameter :: lkind = fms_amip_interp_kind_
663 if(
type(1:3) ==
'sst') then
664 ncfilename = trim(file_name_sst)
665 fileobj => fileobj_sst
666 else if(
type(1:3) ==
'ice') then
667 ncfilename = trim(file_name_ice)
668 fileobj => fileobj_ice
669 if (lowercase(trim(data_set)) ==
'amip2' .or. &
670 lowercase(trim(data_set)) ==
'hurrell' .or. &
671 lowercase(trim(data_set)) ==
'daily') ncfieldname =
'ice'
676 if (verbose > 2 .and. mpp_pe() == 0) &
677 print *,
'looking for date = ', date
680 if (mpp_pe() == mpp_root_pe())
call mpp_error (
'amip_interp_mod', &
681 'Reading NetCDF formatted input data file: '//trim(ncfilename), note)
683 call fms2_io_read_data (fileobj,
'nrecords', nrecords)
684 if (nrecords < 1)
call mpp_error(
'amip_interp_mod', &
685 'Invalid number of SST records in SST datafile: '//trim(ncfilename), fatal)
686 allocate(ryr(nrecords), rmo(nrecords), rdy(nrecords))
687 call fms2_io_read_data(fileobj,
'yr', ryr)
688 call fms2_io_read_data(fileobj,
'mo', rmo)
689 call fms2_io_read_data(fileobj,
'dy', rdy)
693 yr = ryr(k); mo = rmo(k)
694 adate = date_type( yr, mo, 0)
696 if (verbose > 2 .and. mpp_pe() == 0) &
697 print *,
'....... checking ', adate
698 if (date == adate) ierr = 0
699 if (yr == 0 .and. mo == date%month) ierr = 0
702 if (ierr .ne. 0)
call mpp_error(
'amip_interp_mod', &
703 'Model time is out of range not in SST data: '//trim(ncfilename), fatal)
704 deallocate(ryr, rmo, rdy)
709 if (yr == 0 .or. mo == 0)
then
711 if (date_out_of_range ==
'fail' ) ierr = 1
712 if (date_out_of_range ==
'initclimo' .and. &
713 date > date_end ) ierr = 1
714 if (ierr /= 0)
call error_mesg &
715 (
'read_record in amip_interp_mod', &
716 'climo data read when NO climo data requested', fatal)
721 if ( interp_oi_sst )
then
722 call fms2_io_read_data(fileobj, ncfieldname, tmp_dat, unlim_dim_level=k)
724 if ( mobs/=360 .or. nobs/=180 )
then
725 call a2a_bilinear_ (360, 180, tmp_dat, mobs, nobs, dat)
727 dat(:,:) = tmp_dat(:,:)
730 call fms2_io_read_data(fileobj, ncfieldname, dat, unlim_dim_level=k)
735 idat = nint(dat*100._lkind, i2_kind)
739 if (
type(1:3) ==
'ice') then
741 if (lowercase(trim(data_set)) /=
'amip2' .and. lowercase(trim(data_set)) /=
'hurrell')
then
742 where ( idat <= ice_crit )
750 else if (
type(1:3) ==
'sst') then
752 if (lowercase(trim(data_set)) /=
'amip2' .and. lowercase(trim(data_set)) /=
'hurrell')
then
753 dat = real(idat, fms_amip_interp_kind_)*0.01_lkind + real(tfreeze, fms_amip_interp_kind_)
758 end subroutine read_record_
760 subroutine clip_data_ (type, dat)
761 character(len=*),
intent(in) :: type
762 real(FMS_AMIP_INTERP_KIND_),
intent(inout) :: dat(:,:)
763 integer,
parameter :: lkind = fms_amip_interp_kind_
765 if (
type(1:3) ==
'ice') then
766 dat = min(max(dat,0.0_lkind), 1.0_lkind)
767 else if (
type(1:3) ==
'sst') then
768 dat = max(real(tice_crit_k, fms_amip_interp_kind_),dat)
770 end subroutine clip_data_
772subroutine zonal_sst_ (Time, ice, sst)
773 type (time_type),
intent(in) :: Time
774 real(FMS_AMIP_INTERP_KIND_),
intent(out) :: ice(mobs,nobs), sst(mobs,nobs)
775 real(FMS_AMIP_INTERP_KIND_) :: tpi, fdate, eps, ph, sph, sph2, ts
777 integer,
parameter :: lkind = fms_amip_interp_kind_
787 tpi = 2.0_lkind*real(pi, fms_amip_interp_kind_)
789 fdate = fraction_of_year(time)
791 eps = sin( tpi*(fdate-real(tlag, fms_amip_interp_kind_)) ) * real(tann, fms_amip_interp_kind_)
795 ph = 0.5_lkind * real(lat_bnd(j)+lat_bnd(j+1), fms_amip_interp_kind_)
799 ts = real(teq, fms_amip_interp_kind_) - real(tdif, fms_amip_interp_kind_)*sph2 - eps*sph
805 where ( sst < real(tice_crit_k, fms_amip_interp_kind_) )
807 sst = real(tice_crit_k, fms_amip_interp_kind_)
811end subroutine zonal_sst_