MOM6
mom_horizontal_regridding::horiz_interp_and_extrap_tracer Interface Reference

Detailed Description

Extrapolate and interpolate data.

Definition at line 52 of file MOM_horizontal_regridding.F90.

Private functions

subroutine horiz_interp_and_extrap_tracer_record (filename, varnam, conversion, recnum, G, tr_z, mask_z, z_in, z_edges_in, missing_value, reentrant_x, tripolar_n, homogenize, m_to_Z)
 Extrapolate and interpolate from a file record. More...
 
subroutine horiz_interp_and_extrap_tracer_fms_id (fms_id, Time, conversion, G, tr_z, mask_z, z_in, z_edges_in, missing_value, reentrant_x, tripolar_n, homogenize, m_to_Z)
 Extrapolate and interpolate using a FMS time interpolation handle. More...
 

Functions and subroutines

◆ horiz_interp_and_extrap_tracer_fms_id()

subroutine mom_horizontal_regridding::horiz_interp_and_extrap_tracer::horiz_interp_and_extrap_tracer_fms_id ( integer, intent(in)  fms_id,
type(time_type), intent(in)  Time,
real, intent(in)  conversion,
type(ocean_grid_type), intent(inout)  G,
real, dimension(:,:,:), allocatable  tr_z,
real, dimension(:,:,:), allocatable  mask_z,
real, dimension(:), allocatable  z_in,
real, dimension(:), allocatable  z_edges_in,
real, intent(out)  missing_value,
logical, intent(in)  reentrant_x,
logical, intent(in)  tripolar_n,
logical, intent(in), optional  homogenize,
real, intent(in), optional  m_to_Z 
)
private

Extrapolate and interpolate using a FMS time interpolation handle.

Parameters
[in]fms_idA unique id used by the FMS time interpolator
[in]timeA FMS time type
[in]conversionConversion factor for tracer.
[in,out]gGrid object
tr_zpointer to allocatable tracer array on local model grid and native vertical levels.
mask_zpointer to allocatable tracer mask array on local model grid and native vertical levels.
z_inCell grid values for input data.
z_edges_inCell grid edge values for input data. (Intent out)
[out]missing_valueThe missing value in the returned array.
[in]reentrant_xIf true, this grid is reentrant in the x-direction
[in]tripolar_nIf true, this is a northern tripolar grid
[in]homogenizeIf present and true, horizontally homogenize data to produce perfectly "flat" initial conditions
[in]m_to_zA conversion factor from meters to the units of depth. If missing, GbathyT must be in m.

Definition at line 604 of file MOM_horizontal_regridding.F90.

604 
605  integer, intent(in) :: fms_id !< A unique id used by the FMS time interpolator
606  type(time_type), intent(in) :: Time !< A FMS time type
607  real, intent(in) :: conversion !< Conversion factor for tracer.
608  type(ocean_grid_type), intent(inout) :: G !< Grid object
609  real, allocatable, dimension(:,:,:) :: tr_z !< pointer to allocatable tracer array on local
610  !! model grid and native vertical levels.
611  real, allocatable, dimension(:,:,:) :: mask_z !< pointer to allocatable tracer mask array on
612  !! local model grid and native vertical levels.
613  real, allocatable, dimension(:) :: z_in !< Cell grid values for input data.
614  real, allocatable, dimension(:) :: z_edges_in !< Cell grid edge values for input data. (Intent out)
615  real, intent(out) :: missing_value !< The missing value in the returned array.
616  logical, intent(in) :: reentrant_x !< If true, this grid is reentrant in the x-direction
617  logical, intent(in) :: tripolar_n !< If true, this is a northern tripolar grid
618  logical, optional, intent(in) :: homogenize !< If present and true, horizontally homogenize data
619  !! to produce perfectly "flat" initial conditions
620  real, optional, intent(in) :: m_to_Z !< A conversion factor from meters to the units
621  !! of depth. If missing, G%bathyT must be in m.
622 
623  ! Local variables
624  real, dimension(:,:), allocatable :: tr_in,tr_inp !< A 2-d array for holding input data on
625  !! native horizontal grid and extended grid
626  !! with poles.
627  real, dimension(:,:,:), allocatable :: data_in !< A buffer for storing the full 3-d time-interpolated array
628  !! on the original grid
629  real, dimension(:,:), allocatable :: mask_in !< A 2-d mask for extended input grid.
630 
631  real :: PI_180
632  integer :: rcode, ncid, varid, ndims, id, jd, kd, jdp
633  integer :: i,j,k
634  integer, dimension(4) :: start, count, dims, dim_id
635  real, dimension(:,:), allocatable :: x_in, y_in
636  real, dimension(:), allocatable :: lon_in, lat_in
637  real, dimension(:), allocatable :: lat_inp, last_row
638  real :: max_lat, min_lat, pole, max_depth, npole
639  real :: roundoff ! The magnitude of roundoff, usually ~2e-16.
640  logical :: add_np
641  character(len=8) :: laynum
642  type(horiz_interp_type) :: Interp
643  type(axistype), dimension(4) :: axes_data
644  integer :: is, ie, js, je ! compute domain indices
645  integer :: isc,iec,jsc,jec ! global compute domain indices
646  integer :: isg, ieg, jsg, jeg ! global extent
647  integer :: isd, ied, jsd, jed ! data domain indices
648  integer :: id_clock_read
649  integer, dimension(4) :: fld_sz
650  character(len=12) :: dim_name(4)
651  logical :: debug=.false.
652  real :: npoints,varAvg
653  real, dimension(SZI_(G),SZJ_(G)) :: lon_out, lat_out, tr_out, mask_out
654  real, dimension(SZI_(G),SZJ_(G)) :: good, fill
655  real, dimension(SZI_(G),SZJ_(G)) :: tr_outf,tr_prev
656  real, dimension(SZI_(G),SZJ_(G)) :: good2,fill2
657  real, dimension(SZI_(G),SZJ_(G)) :: nlevs
658 
659  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
660  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
661  isg = g%isg ; ieg = g%ieg ; jsg = g%jsg ; jeg = g%jeg
662 
663  id_clock_read = cpu_clock_id('(Initialize tracer from Z) read', grain=clock_loop)
664 
665 
666  pi_180=atan(1.0)/45.
667 
668  ! Open NetCDF file and if present, extract data and spatial coordinate information
669  ! The convention adopted here requires that the data be written in (i,j,k) ordering.
670 
671  call cpu_clock_begin(id_clock_read)
672 
673  fld_sz = get_external_field_size(fms_id)
674 
675  if (allocated(lon_in)) deallocate(lon_in)
676  if (allocated(lat_in)) deallocate(lat_in)
677  if (allocated(z_in)) deallocate(z_in)
678  if (allocated(z_edges_in)) deallocate(z_edges_in)
679  if (allocated(tr_z)) deallocate(tr_z)
680  if (allocated(mask_z)) deallocate(mask_z)
681 
682  axes_data = get_external_field_axes(fms_id)
683 
684  id = fld_sz(1) ; jd = fld_sz(2) ; kd = fld_sz(3)
685  allocate(lon_in(id),lat_in(jd),z_in(kd),z_edges_in(kd+1))
686  allocate(tr_z(isd:ied,jsd:jed,kd), mask_z(isd:ied,jsd:jed,kd))
687 
688  call mpp_get_axis_data(axes_data(1), lon_in)
689  call mpp_get_axis_data(axes_data(2), lat_in)
690  call mpp_get_axis_data(axes_data(3), z_in)
691 
692  if (present(m_to_z)) then ; do k=1,kd ; z_in(k) = m_to_z * z_in(k) ; enddo ; endif
693 
694  call cpu_clock_end(id_clock_read)
695 
696  missing_value = get_external_field_missing(fms_id)
697 
698 
699 ! extrapolate the input data to the north pole using the northerm-most latitude
700 
701  max_lat = maxval(lat_in)
702  add_np=.false.
703  if (max_lat < 90.0) then
704  add_np = .true.
705  jdp = jd+1
706  allocate(lat_inp(jdp))
707  lat_inp(1:jd) = lat_in(:)
708  lat_inp(jd+1) = 90.0
709  deallocate(lat_in)
710  allocate(lat_in(1:jdp))
711  lat_in(:) = lat_inp(:)
712  else
713  jdp=jd
714  endif
715 
716 ! construct level cell boundaries as the mid-point between adjacent centers
717 
718  z_edges_in(1) = 0.0
719  do k=2,kd
720  z_edges_in(k) = 0.5*(z_in(k-1)+z_in(k))
721  enddo
722  z_edges_in(kd+1) = 2.0*z_in(kd) - z_in(kd-1)
723 
724  call horiz_interp_init()
725 
726  lon_in = lon_in*pi_180
727  lat_in = lat_in*pi_180
728  allocate(x_in(id,jdp), y_in(id,jdp))
729  call meshgrid(lon_in, lat_in, x_in, y_in)
730 
731  lon_out(:,:) = g%geoLonT(:,:)*pi_180
732  lat_out(:,:) = g%geoLatT(:,:)*pi_180
733 
734  allocate(data_in(id,jd,kd)) ; data_in(:,:,:)=0.0
735  allocate(tr_in(id,jd)) ; tr_in(:,:)=0.0
736  allocate(tr_inp(id,jdp)) ; tr_inp(:,:)=0.0
737  allocate(mask_in(id,jdp)) ; mask_in(:,:)=0.0
738  allocate(last_row(id)) ; last_row(:)=0.0
739 
740  max_depth = maxval(g%bathyT)
741  call mpp_max(max_depth)
742 
743  if (z_edges_in(kd+1)<max_depth) z_edges_in(kd+1)=max_depth
744 
745  if (is_root_pe()) &
746  call time_interp_external(fms_id, time, data_in, verbose=.true.)
747 
748 ! loop through each data level and interpolate to model grid.
749 ! after interpolating, fill in points which will be needed
750 ! to define the layers
751 
752 ! roundoff = 3.0*EPSILON(missing_value)
753  roundoff = 1.e-4
754 
755  do k=1,kd
756  write(laynum,'(I8)') k ; laynum = adjustl(laynum)
757 
758  if (is_root_pe()) then
759  tr_in(1:id,1:jd) = data_in(1:id,1:jd,k)
760  if (add_np) then
761  last_row(:)=tr_in(:,jd); pole=0.0;npole=0.0
762  do i=1,id
763  if (abs(tr_in(i,jd)-missing_value) > abs(roundoff*missing_value)) then
764  pole = pole+last_row(i)
765  npole = npole+1.0
766  endif
767  enddo
768  if (npole > 0) then
769  pole=pole/npole
770  else
771  pole=missing_value
772  endif
773  tr_inp(:,1:jd) = tr_in(:,:)
774  tr_inp(:,jdp) = pole
775  else
776  tr_inp(:,:) = tr_in(:,:)
777  endif
778 
779  endif
780 
781  call mpp_sync()
782  call mpp_broadcast(tr_inp, id*jdp, root_pe())
783  call mpp_sync_self()
784 
785  mask_in=0.0
786 
787  do j=1,jdp ; do i=1,id
788  if (abs(tr_inp(i,j)-missing_value) > abs(roundoff*missing_value)) then
789  mask_in(i,j)=1.0
790  tr_inp(i,j) = tr_inp(i,j) * conversion
791  else
792  tr_inp(i,j) = missing_value
793  endif
794  enddo ; enddo
795 
796  ! call fms routine horiz_interp to interpolate input level data to model horizontal grid
797  if (k == 1) then
798  call horiz_interp_new(interp, x_in, y_in, lon_out(is:ie,js:je), lat_out(is:ie,js:je), &
799  interp_method='bilinear', src_modulo=reentrant_x)
800  endif
801 
802  if (debug) then
803  call mystats(tr_in, missing_value, 1, id, 1, jd, k, 'Tracer from file')
804  endif
805 
806  tr_out(:,:) = 0.0
807 
808  call horiz_interp(interp, tr_inp, tr_out(is:ie,js:je), missing_value=missing_value, &
809  new_missing_handle=.true.)
810 
811  mask_out(:,:) = 1.0
812  do j=js,je ; do i=is,ie
813  if (abs(tr_out(i,j)-missing_value) < abs(roundoff*missing_value)) mask_out(i,j) = 0.
814  enddo ; enddo
815 
816  fill(:,:) = 0.0 ; good(:,:) = 0.0
817 
818  npoints = 0 ; varavg = 0.
819  do j=js,je ; do i=is,ie
820  if (mask_out(i,j) < 1.0) then
821  tr_out(i,j) = missing_value
822  else
823  good(i,j) = 1.0
824  npoints = npoints + 1
825  varavg = varavg + tr_out(i,j)
826  endif
827  if ((g%mask2dT(i,j) == 1.0) .and. (z_edges_in(k) <= g%bathyT(i,j)) .and. &
828  (mask_out(i,j) < 1.0)) &
829  fill(i,j)=1.0
830  enddo ; enddo
831  call pass_var(fill, g%Domain)
832  call pass_var(good, g%Domain)
833 
834  if (debug) then
835  call mystats(tr_out, missing_value, is, ie, js, je, k, 'variable from horiz_interp()')
836  endif
837 
838  ! Horizontally homogenize data to produce perfectly "flat" initial conditions
839  if (PRESENT(homogenize)) then ; if (homogenize) then
840  call sum_across_pes(npoints)
841  call sum_across_pes(varavg)
842  if (npoints>0) then
843  varavg = varavg/real(npoints)
844  endif
845  tr_out(:,:) = varavg
846  endif ; endif
847 
848  ! tr_out contains input z-space data on the model grid with missing values
849  ! now fill in missing values using "ICE-nine" algorithm.
850 
851  tr_outf(:,:) = tr_out(:,:)
852  if (k==1) tr_prev(:,:) = tr_outf(:,:)
853  good2(:,:) = good(:,:)
854  fill2(:,:) = fill(:,:)
855 
856  call fill_miss_2d(tr_outf, good2, fill2, tr_prev, g, smooth=.true.)
857 
858 ! if (debug) then
859 ! call hchksum(tr_outf, 'field from fill_miss_2d ', G%HI)
860 ! endif
861 
862 ! call myStats(tr_outf, missing_value, is, ie, js, je, k, 'field from fill_miss_2d()')
863 
864  tr_z(:,:,k) = tr_outf(:,:)*g%mask2dT(:,:)
865  mask_z(:,:,k) = good2(:,:) + fill2(:,:)
866  tr_prev(:,:) = tr_z(:,:,k)
867 
868  if (debug) then
869  call hchksum(tr_prev,'field after fill ',g%HI)
870  endif
871 
872  enddo ! kd
873 

◆ horiz_interp_and_extrap_tracer_record()

subroutine mom_horizontal_regridding::horiz_interp_and_extrap_tracer::horiz_interp_and_extrap_tracer_record ( character(len=*), intent(in)  filename,
character(len=*), intent(in)  varnam,
real, intent(in)  conversion,
integer, intent(in)  recnum,
type(ocean_grid_type), intent(inout)  G,
real, dimension(:,:,:), allocatable  tr_z,
real, dimension(:,:,:), allocatable  mask_z,
real, dimension(:), allocatable  z_in,
real, dimension(:), allocatable  z_edges_in,
real, intent(out)  missing_value,
logical, intent(in)  reentrant_x,
logical, intent(in)  tripolar_n,
logical, intent(in), optional  homogenize,
real, intent(in), optional  m_to_Z 
)
private

Extrapolate and interpolate from a file record.

Parameters
[in]filenamePath to file containing tracer to be interpolated.
[in]varnamName of tracer in filee.
[in]conversionConversion factor for tracer.
[in]recnumRecord number of tracer to be read.
[in,out]gGrid object
tr_zpointer to allocatable tracer array on local model grid and input-file vertical levels.
mask_zpointer to allocatable tracer mask array on local model grid and input-file vertical levels.
z_inCell grid values for input data.
z_edges_inCell grid edge values for input data.
[out]missing_valueThe missing value in the returned array.
[in]reentrant_xIf true, this grid is reentrant in the x-direction
[in]tripolar_nIf true, this is a northern tripolar grid
[in]homogenizeIf present and true, horizontally homogenize data to produce perfectly "flat" initial conditions
[in]m_to_zA conversion factor from meters to the units of depth. If missing, GbathyT must be in m.

Definition at line 270 of file MOM_horizontal_regridding.F90.

270 
271  character(len=*), intent(in) :: filename !< Path to file containing tracer to be
272  !! interpolated.
273  character(len=*), intent(in) :: varnam !< Name of tracer in filee.
274  real, intent(in) :: conversion !< Conversion factor for tracer.
275  integer, intent(in) :: recnum !< Record number of tracer to be read.
276  type(ocean_grid_type), intent(inout) :: G !< Grid object
277  real, allocatable, dimension(:,:,:) :: tr_z !< pointer to allocatable tracer array on local
278  !! model grid and input-file vertical levels.
279  real, allocatable, dimension(:,:,:) :: mask_z !< pointer to allocatable tracer mask array on
280  !! local model grid and input-file vertical levels.
281  real, allocatable, dimension(:) :: z_in !< Cell grid values for input data.
282  real, allocatable, dimension(:) :: z_edges_in !< Cell grid edge values for input data.
283  real, intent(out) :: missing_value !< The missing value in the returned array.
284  logical, intent(in) :: reentrant_x !< If true, this grid is reentrant in the x-direction
285  logical, intent(in) :: tripolar_n !< If true, this is a northern tripolar grid
286  logical, optional, intent(in) :: homogenize !< If present and true, horizontally homogenize data
287  !! to produce perfectly "flat" initial conditions
288  real, optional, intent(in) :: m_to_Z !< A conversion factor from meters to the units
289  !! of depth. If missing, G%bathyT must be in m.
290 
291  ! Local variables
292  real, dimension(:,:), allocatable :: tr_in, tr_inp ! A 2-d array for holding input data on
293  ! native horizontal grid and extended grid
294  ! with poles.
295  real, dimension(:,:), allocatable :: mask_in ! A 2-d mask for extended input grid.
296 
297  real :: PI_180
298  integer :: rcode, ncid, varid, ndims, id, jd, kd, jdp
299  integer :: i,j,k
300  integer, dimension(4) :: start, count, dims, dim_id
301  real, dimension(:,:), allocatable :: x_in, y_in
302  real, dimension(:), allocatable :: lon_in, lat_in
303  real, dimension(:), allocatable :: lat_inp, last_row
304  real :: max_lat, min_lat, pole, max_depth, npole
305  real :: roundoff ! The magnitude of roundoff, usually ~2e-16.
306  real :: add_offset, scale_factor
307  logical :: add_np
308  character(len=8) :: laynum
309  type(horiz_interp_type) :: Interp
310  integer :: is, ie, js, je ! compute domain indices
311  integer :: isc,iec,jsc,jec ! global compute domain indices
312  integer :: isg, ieg, jsg, jeg ! global extent
313  integer :: isd, ied, jsd, jed ! data domain indices
314  integer :: id_clock_read
315  character(len=12) :: dim_name(4)
316  logical :: debug=.false.
317  real :: npoints,varAvg
318  real, dimension(SZI_(G),SZJ_(G)) :: lon_out, lat_out, tr_out, mask_out
319  real, dimension(SZI_(G),SZJ_(G)) :: good, fill
320  real, dimension(SZI_(G),SZJ_(G)) :: tr_outf,tr_prev
321  real, dimension(SZI_(G),SZJ_(G)) :: good2,fill2
322  real, dimension(SZI_(G),SZJ_(G)) :: nlevs
323 
324  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
325  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
326  isg = g%isg ; ieg = g%ieg ; jsg = g%jsg ; jeg = g%jeg
327 
328  id_clock_read = cpu_clock_id('(Initialize tracer from Z) read', grain=clock_loop)
329 
330 
331  if (allocated(tr_z)) deallocate(tr_z)
332  if (allocated(mask_z)) deallocate(mask_z)
333  if (allocated(z_edges_in)) deallocate(z_edges_in)
334 
335  pi_180=atan(1.0)/45.
336 
337  ! Open NetCDF file and if present, extract data and spatial coordinate information
338  ! The convention adopted here requires that the data be written in (i,j,k) ordering.
339 
340  call cpu_clock_begin(id_clock_read)
341 
342 
343  rcode = nf90_open(filename, nf90_nowrite, ncid)
344  if (rcode /= 0) call mom_error(fatal,"error opening file "//trim(filename)//&
345  " in hinterp_extrap")
346  rcode = nf90_inq_varid(ncid, varnam, varid)
347  if (rcode /= 0) call mom_error(fatal,"error finding variable "//trim(varnam)//&
348  " in file "//trim(filename)//" in hinterp_extrap")
349 
350  rcode = nf90_inquire_variable(ncid, varid, ndims=ndims, dimids=dims)
351  if (rcode /= 0) call mom_error(fatal,'error inquiring dimensions hinterp_extrap')
352  if (ndims < 3) call mom_error(fatal,"Variable "//trim(varnam)//" in file "// &
353  trim(filename)//" has too few dimensions.")
354 
355  rcode = nf90_inquire_dimension(ncid, dims(1), dim_name(1), len=id)
356  if (rcode /= 0) call mom_error(fatal,"error reading dimension 1 data for "// &
357  trim(varnam)//" in file "// trim(filename)//" in hinterp_extrap")
358  rcode = nf90_inq_varid(ncid, dim_name(1), dim_id(1))
359  if (rcode /= 0) call mom_error(fatal,"error finding variable "//trim(dim_name(1))//&
360  " in file "//trim(filename)//" in hinterp_extrap")
361  rcode = nf90_inquire_dimension(ncid, dims(2), dim_name(2), len=jd)
362  if (rcode /= 0) call mom_error(fatal,"error reading dimension 2 data for "// &
363  trim(varnam)//" in file "// trim(filename)//" in hinterp_extrap")
364  rcode = nf90_inq_varid(ncid, dim_name(2), dim_id(2))
365  if (rcode /= 0) call mom_error(fatal,"error finding variable "//trim(dim_name(2))//&
366  " in file "//trim(filename)//" in hinterp_extrap")
367  rcode = nf90_inquire_dimension(ncid, dims(3), dim_name(3), len=kd)
368  if (rcode /= 0) call mom_error(fatal,"error reading dimension 3 data for "// &
369  trim(varnam)//" in file "// trim(filename)//" in hinterp_extrap")
370  rcode = nf90_inq_varid(ncid, dim_name(3), dim_id(3))
371  if (rcode /= 0) call mom_error(fatal,"error finding variable "//trim(dim_name(3))//&
372  " in file "//trim(filename)//" in hinterp_extrap")
373 
374 
375  missing_value=0.0
376  rcode = nf90_get_att(ncid, varid, "_FillValue", missing_value)
377  if (rcode /= 0) call mom_error(fatal,"error finding missing value for "//&
378  trim(varnam)//" in file "// trim(filename)//" in hinterp_extrap")
379 
380  rcode = nf90_get_att(ncid, varid, "add_offset", add_offset)
381  if (rcode /= 0) add_offset = 0.0
382 
383  rcode = nf90_get_att(ncid, varid, "scale_factor", scale_factor)
384  if (rcode /= 0) scale_factor = 1.0
385 
386 
387  if (allocated(lon_in)) deallocate(lon_in)
388  if (allocated(lat_in)) deallocate(lat_in)
389  if (allocated(z_in)) deallocate(z_in)
390  if (allocated(z_edges_in)) deallocate(z_edges_in)
391  if (allocated(tr_z)) deallocate(tr_z)
392  if (allocated(mask_z)) deallocate(mask_z)
393 
394 
395  allocate(lon_in(id),lat_in(jd),z_in(kd),z_edges_in(kd+1))
396  allocate(tr_z(isd:ied,jsd:jed,kd), mask_z(isd:ied,jsd:jed,kd))
397 
398  start = 1; count = 1; count(1) = id
399  rcode = nf90_get_var(ncid, dim_id(1), lon_in, start, count)
400  if (rcode /= 0) call mom_error(fatal,"error reading dimension 1 values for var_name "// &
401  trim(varnam)//",dim_name "//trim(dim_name(1))//" in file "// trim(filename)//" in hinterp_extrap")
402  start = 1; count = 1; count(1) = jd
403  rcode = nf90_get_var(ncid, dim_id(2), lat_in, start, count)
404  if (rcode /= 0) call mom_error(fatal,"error reading dimension 2 values for var_name "// &
405  trim(varnam)//",dim_name "//trim(dim_name(2))//" in file "// trim(filename)//" in hinterp_extrap")
406  start = 1; count = 1; count(1) = kd
407  rcode = nf90_get_var(ncid, dim_id(3), z_in, start, count)
408  if (rcode /= 0) call mom_error(fatal,"error reading dimension 3 values for var_name "// &
409  trim(varnam//",dim_name "//trim(dim_name(3)))//" in file "// trim(filename)//" in hinterp_extrap")
410 
411  call cpu_clock_end(id_clock_read)
412 
413  if (present(m_to_z)) then ; do k=1,kd ; z_in(k) = m_to_z * z_in(k) ; enddo ; endif
414 
415 ! extrapolate the input data to the north pole using the northerm-most latitude
416 
417  max_lat = maxval(lat_in)
418  add_np=.false.
419  if (max_lat < 90.0) then
420  add_np=.true.
421  jdp=jd+1
422  allocate(lat_inp(jdp))
423  lat_inp(1:jd)=lat_in(:)
424  lat_inp(jd+1)=90.0
425  deallocate(lat_in)
426  allocate(lat_in(1:jdp))
427  lat_in(:)=lat_inp(:)
428  else
429  jdp=jd
430  endif
431 
432 ! construct level cell boundaries as the mid-point between adjacent centers
433 
434  z_edges_in(1) = 0.0
435  do k=2,kd
436  z_edges_in(k)=0.5*(z_in(k-1)+z_in(k))
437  enddo
438  z_edges_in(kd+1)=2.0*z_in(kd) - z_in(kd-1)
439 
440  call horiz_interp_init()
441 
442  lon_in = lon_in*pi_180
443  lat_in = lat_in*pi_180
444  allocate(x_in(id,jdp),y_in(id,jdp))
445  call meshgrid(lon_in,lat_in, x_in, y_in)
446 
447  lon_out(:,:) = g%geoLonT(:,:)*pi_180
448  lat_out(:,:) = g%geoLatT(:,:)*pi_180
449 
450 
451  allocate(tr_in(id,jd)) ; tr_in(:,:)=0.0
452  allocate(tr_inp(id,jdp)) ; tr_inp(:,:)=0.0
453  allocate(mask_in(id,jdp)) ; mask_in(:,:)=0.0
454  allocate(last_row(id)) ; last_row(:)=0.0
455 
456  max_depth = maxval(g%bathyT)
457  call mpp_max(max_depth)
458 
459  if (z_edges_in(kd+1)<max_depth) z_edges_in(kd+1)=max_depth
460 
461 
462 ! loop through each data level and interpolate to model grid.
463 ! after interpolating, fill in points which will be needed
464 ! to define the layers
465 
466  roundoff = 3.0*epsilon(missing_value)
467 
468 
469  do k=1,kd
470  write(laynum,'(I8)') k ; laynum = adjustl(laynum)
471 
472  if (is_root_pe()) then
473  start = 1 ; start(3) = k ; count(:) = 1 ; count(1) = id ; count(2) = jd
474  rcode = nf90_get_var(ncid,varid, tr_in, start, count)
475  if (rcode /= 0) call mom_error(fatal,"hinterp_and_extract_from_Fie: "//&
476  "error reading level "//trim(laynum)//" of variable "//&
477  trim(varnam)//" in file "// trim(filename))
478 
479  if (add_np) then
480  last_row(:)=tr_in(:,jd); pole=0.0;npole=0.0
481  do i=1,id
482  if (abs(tr_in(i,jd)-missing_value) > abs(roundoff*missing_value)) then
483  pole = pole+last_row(i)
484  npole = npole+1.0
485  endif
486  enddo
487  if (npole > 0) then
488  pole=pole/npole
489  else
490  pole=missing_value
491  endif
492  tr_inp(:,1:jd) = tr_in(:,:)
493  tr_inp(:,jdp) = pole
494  else
495  tr_inp(:,:) = tr_in(:,:)
496  endif
497 
498  endif
499 
500  call mpp_sync()
501  call mpp_broadcast(tr_inp, id*jdp, root_pe())
502  call mpp_sync_self()
503 
504  mask_in=0.0
505 
506  do j=1,jdp
507  do i=1,id
508  if (abs(tr_inp(i,j)-missing_value) > abs(roundoff*missing_value)) then
509  mask_in(i,j) = 1.0
510  tr_inp(i,j) = (tr_inp(i,j)*scale_factor+add_offset) * conversion
511  else
512  tr_inp(i,j) = missing_value
513  endif
514  enddo
515  enddo
516 
517 
518 ! call fms routine horiz_interp to interpolate input level data to model horizontal grid
519 
520 
521  if (k == 1) then
522  call horiz_interp_new(interp,x_in,y_in,lon_out(is:ie,js:je),lat_out(is:ie,js:je), &
523  interp_method='bilinear',src_modulo=reentrant_x)
524  endif
525 
526  if (debug) then
527  call mystats(tr_inp,missing_value, is,ie,js,je,k,'Tracer from file')
528  endif
529 
530  tr_out(:,:) = 0.0
531 
532  call horiz_interp(interp,tr_inp,tr_out(is:ie,js:je), missing_value=missing_value, new_missing_handle=.true.)
533 
534  mask_out=1.0
535  do j=js,je
536  do i=is,ie
537  if (abs(tr_out(i,j)-missing_value) < abs(roundoff*missing_value)) mask_out(i,j)=0.
538  enddo
539  enddo
540 
541  fill = 0.0; good = 0.0
542 
543  npoints = 0 ; varavg = 0.
544  do j=js,je
545  do i=is,ie
546  if (mask_out(i,j) < 1.0) then
547  tr_out(i,j)=missing_value
548  else
549  good(i,j)=1.0
550  npoints = npoints + 1
551  varavg = varavg + tr_out(i,j)
552  endif
553  if (g%mask2dT(i,j) == 1.0 .and. z_edges_in(k) <= g%bathyT(i,j) .and. mask_out(i,j) < 1.0) &
554  fill(i,j)=1.0
555  enddo
556  enddo
557  call pass_var(fill,g%Domain)
558  call pass_var(good,g%Domain)
559 
560  if (debug) then
561  call mystats(tr_out,missing_value, is,ie,js,je,k,'variable from horiz_interp()')
562  endif
563 
564  ! Horizontally homogenize data to produce perfectly "flat" initial conditions
565  if (PRESENT(homogenize)) then
566  if (homogenize) then
567  call sum_across_pes(npoints)
568  call sum_across_pes(varavg)
569  if (npoints>0) then
570  varavg = varavg/real(npoints)
571  endif
572  tr_out(:,:) = varavg
573  endif
574  endif
575 
576 ! tr_out contains input z-space data on the model grid with missing values
577 ! now fill in missing values using "ICE-nine" algorithm.
578 
579  tr_outf(:,:) = tr_out(:,:)
580  if (k==1) tr_prev(:,:) = tr_outf(:,:)
581  good2(:,:) = good(:,:)
582  fill2(:,:) = fill(:,:)
583 
584  call fill_miss_2d(tr_outf, good2, fill2, tr_prev, g, smooth=.true.)
585  call mystats(tr_outf, missing_value, is, ie, js, je, k, 'field from fill_miss_2d()')
586 
587  tr_z(:,:,k) = tr_outf(:,:) * g%mask2dT(:,:)
588  mask_z(:,:,k) = good2(:,:) + fill2(:,:)
589 
590  tr_prev(:,:) = tr_z(:,:,k)
591 
592  if (debug) then
593  call hchksum(tr_prev,'field after fill ',g%HI)
594  endif
595 
596  enddo ! kd
597 

The documentation for this interface was generated from the following file: