!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! !!
!! GNU General Public License !!
!! !!
!! This file is part of the Flexible Modeling System (FMS). !!
!! !!
!! FMS is free software; you can redistribute it and/or modify !!
!! it and are expected to follow the terms of the GNU General Public !!
!! License as published by the Free Software Foundation. !!
!! !!
!! FMS is distributed in the hope that it will be useful, !!
!! but WITHOUT ANY WARRANTY; without even the implied warranty of !!
!! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the !!
!! GNU General Public License for more details. !!
!! !!
!! You should have received a copy of the GNU General Public License !!
!! along with FMS; if not, write to: !!
!! Free Software Foundation, Inc. !!
!! 59 Temple Place, Suite 330 !!
!! Boston, MA 02111-1307 USA !!
!! or see: !!
!! http://www.gnu.org/licenses/gpl.txt !!
!! !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
module ocean_tracer_util_mod
!
! Ron Pacanowski
!
!
!
! S. M. Griffies
!
!
!
! This module contains many routines of use for tracer diagnostics in mom4.
!
!
!
! Tracer utility module for mom4. Of use for tracer diagnostics.
!
!
use mpp_mod, only: stdout, stdlog, FATAL
use mpp_mod, only: mpp_error, mpp_chksum, mpp_pe, mpp_min, mpp_max
use platform_mod, only: i8_kind
use ocean_domains_mod, only: get_local_indices
use ocean_parameters_mod, only: ADVECT_PSOM
use ocean_types_mod, only: ocean_grid_type, ocean_domain_type
use ocean_types_mod, only: ocean_prog_tracer_type, ocean_diag_tracer_type
use ocean_types_mod, only: ocean_time_type, ocean_thickness_type
use ocean_util_mod, only: write_timestamp
use ocean_workspace_mod, only: wrk1
implicit none
private
character(len=256) :: version='CVS $Id'
character(len=256) :: tagname='Tag $Name'
! for output
integer :: unit=6
#include
logical :: module_is_initialized = .false.
type(ocean_domain_type), pointer :: Dom =>NULL()
type(ocean_grid_type), pointer :: Grd =>NULL()
public ocean_tracer_util_init
public tracer_min_max
public dzt_min_max
public tracer_prog_chksum
public tracer_diag_chksum
public tracer_psom_chksum
public sort_pick_array
public sort_shell_array
contains
!#######################################################################
!
!
!
! Initialize mom4 tracer utilities.
!
!
subroutine ocean_tracer_util_init (Grid, Domain)
type(ocean_grid_type), intent(in), target :: Grid
type(ocean_domain_type), intent(in), target :: Domain
integer :: stdlogunit
if (module_is_initialized) then
call mpp_error(FATAL,&
'==>Error in ocean_tracer_util_mod (ocean_tracer_util_init): module already initialized')
endif
module_is_initialized = .true.
stdlogunit=stdlog()
write( stdlogunit,'(/a/)') trim(version)
Dom => Domain
Grd => Grid
#ifndef MOM4_STATIC_ARRAYS
call get_local_indices(Domain, isd, ied, jsd, jed, isc, iec, jsc, jec)
nk=Grd%nk
#endif
end subroutine ocean_tracer_util_init
! NAME="ocean_tracer_util_init">
!#######################################################################
!
!
!
! Compute the global min and max for tracers.
!
! Vectorized using maxloc() and minloc() intrinsic functions by
! Russell.Fiedler@csiro.au (May 2005).
!
! Modified by Zhi.Liang@noaa.gov (July 2005)
!
!
!
subroutine tracer_min_max(Time, Thickness, Tracer)
type(ocean_time_type), intent(in) :: Time
type(ocean_thickness_type), intent(in) :: Thickness
type(ocean_prog_tracer_type), intent(in) :: Tracer
real :: tmax, tmin, tmax0, tmin0
integer :: itmax, jtmax, ktmax, itmin, jtmin, ktmin
integer :: tau
real :: fudge
! arrays to enable vectorization
integer :: iminarr(3),imaxarr(3)
if (.not. module_is_initialized) then
call mpp_error(FATAL,&
'==>Error from ocean_tracer_util_mod (tracer_min_max): module not initialized')
endif
tmax=-1.e10;tmin=1.e10
itmax=0;jtmax=0;ktmax=0
itmin=0;jtmin=0;ktmin=0
tau = Time%tau
call write_timestamp(Time%model_time)
wrk1(isc:iec,jsc:jec,:) = Tracer%field(isc:iec,jsc:jec,:,tau)
if(ANY(Grd%tmask(isc:iec,jsc:jec,:) > 0.)) then
iminarr=minloc(wrk1(isc:iec,jsc:jec,:),Grd%tmask(isc:iec,jsc:jec,:) > 0.)
imaxarr=maxloc(wrk1(isc:iec,jsc:jec,:),Grd%tmask(isc:iec,jsc:jec,:) > 0.)
itmin=iminarr(1)+isc-1
jtmin=iminarr(2)+jsc-1
ktmin=iminarr(3)
itmax=imaxarr(1)+isc-1
jtmax=imaxarr(2)+jsc-1
ktmax=imaxarr(3)
tmin=wrk1(itmin,jtmin,ktmin)
tmax=wrk1(itmax,jtmax,ktmax)
end if
! use "fudge" to distinguish processors when tracer extreme is independent of processor
fudge = 1.0 + 1.e-12*mpp_pe()
tmax = tmax*fudge
tmin = tmin*fudge
if(tmax == 0.0) then
tmax = tmax + 1.e-12*mpp_pe()
endif
if(tmin == 0.0) then
tmin = tmin + 1.e-12*mpp_pe()
endif
tmax0=tmax;tmin0=tmin
call mpp_max(tmax)
call mpp_min(tmin)
if (tmax0 == tmax) then
if (trim(Tracer%name) == 'temp') then
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The maximum T is ', tmax,&
' deg C at (i,j,k) = (',itmax+Dom%ioff,',',jtmax+Dom%joff,',',ktmax,&
'), (lon,lat,dpt) = (',Grd%xt(itmax,jtmax),',', &
Grd%yt(itmax,jtmax),',', Grd%zt(ktmax),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12,a)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmax,jtmax),',', Grd%dyt(itmax,jtmax),',', Thickness%dzt(itmax,jtmax,ktmax),' m)'
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmax,jtmax,ktmax),', ',Thickness%rho_dzt(itmax,jtmax,ktmax,tau)
write(unit,'(a,i6)') ' And the number of cells in the column are kmt = ', Grd%kmt(itmax,jtmax)
if (tmax > Tracer%max_tracer) then
call mpp_error(FATAL, &
'==>Error from ocean_tracer_util_mod: The maximum temperature is outside allowable range')
endif
else if (trim(Tracer%name) == 'salt') then
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The maximum S is ', tmax,&
' psu at (i,j,k) = (',itmax+Dom%ioff,',',jtmax+Dom%joff,',',ktmax,&
'), (lon,lat,dpt) = (',Grd%xt(itmax,jtmax),',', &
Grd%yt(itmax,jtmax),',', Grd%zt(ktmax),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12,a)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmax,jtmax),',', Grd%dyt(itmax,jtmax),',', Thickness%dzt(itmax,jtmax,ktmax),' m)'
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmax,jtmax,ktmax),', ',Thickness%rho_dzt(itmax,jtmax,ktmax,tau)
write(unit,'(a,i6)') ' And the number of cells in the column are kmt = ', Grd%kmt(itmax,jtmax)
if (tmax > Tracer%max_tracer) then
call mpp_error(FATAL,&
'==>Error from ocean_tracer_util_mod: The maximum salinity is outside allowable range')
endif
else
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The maximum '//trim(Tracer%name)// ' is ', tmax,&
' '// trim(Tracer%units)// ' at (i,j,k) = (',itmax+Dom%ioff,',',jtmax+Dom%joff,','&
,ktmax,'), (lon,lat,dpt) = (',Grd%xt(itmax,jtmax),',', &
Grd%yt(itmax,jtmax),',', Grd%zt(ktmax),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12,a)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmax,jtmax),',', Grd%dyt(itmax,jtmax),',', Thickness%dzt(itmax,jtmax,ktmax),' m)'
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmin,jtmin,ktmin),', ',Thickness%rho_dzt(itmin,jtmin,ktmin,tau)
write(unit,'(a,i6)') ' And the number of cells in the column are kmt = ', Grd%kmt(itmax,jtmax)
if (tmax > Tracer%max_tracer) then
call mpp_error(FATAL, &
'==>Error from ocean_tracer_util_mod: The maximum tracer is outside allowable range')
endif
endif
endif
if (tmin0 == tmin) then
if (trim(Tracer%name) == 'temp') then
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The minimum T is ', tmin,&
' deg C at (i,j,k) = (',itmin+Dom%ioff,',',jtmin+Dom%joff,',',ktmin,&
'), (lon,lat,dpt) = (',Grd%xt(itmin,jtmin),',', &
Grd%yt(itmin,jtmin),',', Grd%zt(ktmin),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12,a)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmin,jtmin),',', Grd%dyt(itmin,jtmin),',', Thickness%dzt(itmin,jtmin,ktmin),' m)'
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmin,jtmin,ktmin),', ',Thickness%rho_dzt(itmin,jtmin,ktmin,tau)
write(unit,'(a,i6)') ' And the number of cells in the column are kmt = ', Grd%kmt(itmin,jtmin)
if (tmin < Tracer%min_tracer) then
call mpp_error(FATAL, &
'==>Error from ocean_tracer_util_mod (tracer_min_max): minimum temp outside allowable range')
endif
else if (trim(Tracer%name) == 'salt') then
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The minimum S is ', tmin,&
' psu at (i,j,k) = (',itmin+Dom%ioff,',',jtmin+Dom%joff,',',ktmin,&
'), (lon,lat,dpt) = (',Grd%xt(itmin,jtmin),',', &
Grd%yt(itmin,jtmin),',', Grd%zt(ktmin),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12,a)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmin,jtmin),',', Grd%dyt(itmin,jtmin),',', Thickness%dzt(itmin,jtmin,ktmin),' m)'
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmin,jtmin,ktmin),', ',Thickness%rho_dzt(itmin,jtmin,ktmin,tau)
write(unit,'(a,i6)') ' And the number of cells in the column are kmt = ', Grd%kmt(itmin,jtmin)
if (tmin < Tracer%min_tracer) then
call mpp_error(FATAL, &
'==>Error from ocean_tracer_util_mod: The minimum salinity is outside allowable range')
endif
else
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The minimum '//trim(Tracer%name)// ' is ', tmin,&
' '// trim(Tracer%units)// ' at (i,j,k) = (',itmin+Dom%ioff,',',jtmin+Dom%joff,','&
,ktmin,'), (lon,lat,dpt) = (',Grd%xt(itmin,jtmin),',', &
Grd%yt(itmin,jtmin),',', Grd%zt(ktmin),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12,a)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmin,jtmin),',', Grd%dyt(itmin,jtmin),',', Thickness%dzt(itmin,jtmin,ktmin),' m)'
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmin,jtmin,ktmin),', ',Thickness%rho_dzt(itmin,jtmin,ktmin,tau)
write(unit,'(a,i6)') ' And the number of cells in the column are kmt = ', Grd%kmt(itmin,jtmin)
if (tmin < Tracer%min_tracer) then
call mpp_error(FATAL, &
'==>Error from ocean_tracer_util_mod (tracer_min_max): minimum tracer outside allowable range')
endif
endif
endif
return
end subroutine tracer_min_max
! NAME="tracer_min_max"
!#######################################################################
!
!
!
! Compute the global min and max for dzt.
!
! Modified by Stephen.Griffies@noaa.gov from subroutine tracer_min_max
!
!
!
subroutine dzt_min_max(Time, Thickness, filecaller)
type(ocean_time_type), intent(in) :: Time
type(ocean_thickness_type), intent(in) :: Thickness
character(len=*), intent(in) :: filecaller
real :: dztmax, dztmin, dztmax0, dztmin0
integer :: itmax, jtmax, ktmax, itmin, jtmin, ktmin
integer :: tau
real :: fudge
! arrays to enable vectorization
integer :: iminarr(3),imaxarr(3)
tau = Time%tau
dztmax=-1.e10;dztmin=1.e10
itmax=0;jtmax=0;ktmax=0
itmin=0;jtmin=0;ktmin=0
call write_timestamp(Time%model_time)
wrk1(isc:iec,jsc:jec,:) = Thickness%dzt(isc:iec,jsc:jec,:)
if(ANY(Grd%tmask(isc:iec,jsc:jec,:) > 0.)) then
iminarr=minloc(wrk1(isc:iec,jsc:jec,:),Grd%tmask(isc:iec,jsc:jec,:) > 0.)
imaxarr=maxloc(wrk1(isc:iec,jsc:jec,:),Grd%tmask(isc:iec,jsc:jec,:) > 0.)
itmin=iminarr(1)+isc-1
jtmin=iminarr(2)+jsc-1
ktmin=iminarr(3)
itmax=imaxarr(1)+isc-1
jtmax=imaxarr(2)+jsc-1
ktmax=imaxarr(3)
dztmin=wrk1(itmin,jtmin,ktmin)
dztmax=wrk1(itmax,jtmax,ktmax)
end if
! use "fudge" to distinguish processors when extreme is independent of processor
fudge = 1.0 + 1.e-12*mpp_pe()
dztmax = dztmax*fudge
dztmin = dztmin*fudge
if(dztmax == 0.0) then
dztmax = dztmax + 1.e-12*mpp_pe()
endif
if(dztmin == 0.0) then
dztmin = dztmin + 1.e-12*mpp_pe()
endif
dztmax0=dztmax;dztmin0=dztmin
call mpp_max(dztmax)
call mpp_min(dztmin)
if (dztmax0 == dztmax) then
write(unit,'(/a)') trim(filecaller)
call write_timestamp(Time%model_time)
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The maximum dzt is ', dztmax,&
' metre at (i,j,k) = (',itmax+Dom%ioff,',',jtmax+Dom%joff,',',ktmax,&
'), (lon,lat,dpt) = (',Grd%xt(itmax,jtmax),',', &
Grd%yt(itmax,jtmax),',', Thickness%depth_zt(itmax,jtmax,ktmax),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmax,jtmax),',', Grd%dyt(itmax,jtmax),',', Thickness%dzt(itmax,jtmax,ktmax),' m)'
write(unit,'(a,i6)') ' The number of cells in the column are kmt = ', Grd%kmt(itmax,jtmax)
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmax,jtmax,ktmax),', ',Thickness%rho_dzt(itmax,jtmax,ktmax,tau)
endif
if (dztmin0 == dztmin) then
write(unit,'(/,a,es22.12,a,i4,a1,i4,a1,i3,a,f10.4,a,f10.4,a,f10.4,a)') &
' The minimum dzt is ', dztmin,&
' metre at (i,j,k) = (',itmin+Dom%ioff,',',jtmin+Dom%joff,',',ktmin,&
'), (lon,lat,dpt) = (',Grd%xt(itmin,jtmin),',', &
Grd%yt(itmin,jtmin),',', Thickness%depth_zt(itmin,jtmin,ktmin),' m)'
write(unit,'(a,es22.12,a,es22.12,a,es22.12,a)') &
' The grid dimensions are (dxt, dyt, dzt) = (', &
Grd%dxt(itmin,jtmin),',', Grd%dyt(itmin,jtmin),',', Thickness%dzt(itmin,jtmin,ktmin),' m)'
write(unit,'(a,i6)') ' And the number of cells in the column are kmt = ', Grd%kmt(itmin,jtmin)
write(unit,'(a,es22.12,a,es22.12)') ' The grid dimensions (dst,rho_dzt) = ', &
Thickness%dst(itmin,jtmin,ktmin),', ',Thickness%rho_dzt(itmin,jtmin,ktmin,tau)
if(dztmin < 0.0) then
write(unit,'(a)') '==>Error in ocean_tracer_util_mod (dzt_min_max): dzt < 0 detected.'
call mpp_error(FATAL,&
'==>Error in ocean_tracer_util_mod (dzt_min_max): dzt < 0 detected.')
endif
endif
return
end subroutine dzt_min_max
! NAME="dzt_min_max"
!#######################################################################
!
!
!
! Compute checksums for prognostic tracers
!
subroutine tracer_prog_chksum(Time, Tracer, index, chksum)
type(ocean_time_type), intent(in) :: Time
type(ocean_prog_tracer_type), intent(in) :: Tracer
integer, intent(in) :: index
integer(i8_kind), optional, intent(inout) :: chksum
integer(i8_kind) :: chk_sum
integer :: stdoutunit
stdoutunit=stdout()
if (.not. module_is_initialized) then
call mpp_error(FATAL,&
'==>Error from ocean_tracer_util_mod (tracer_prog_chksum): module not initialized ')
endif
write(stdoutunit,*) ' '
write(stdoutunit,*) '=== Prognostic tracer checksum follows ==='
write(stdoutunit,*) 'Tracer name = ', Tracer%name
call write_timestamp(Time%model_time)
wrk1(isc:iec,jsc:jec,:) = Tracer%field(isc:iec,jsc:jec,:,index)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer chksum = ', chk_sum
if (PRESENT(chksum)) chksum = chk_sum
end subroutine tracer_prog_chksum
! NAME="tracer_prog_chksum"
!#######################################################################
!
!
!
! Compute checksums for diagnostic tracers
!
subroutine tracer_diag_chksum(Time, Tracer, chksum)
type(ocean_time_type), intent(in) :: Time
type(ocean_diag_tracer_type), intent(in) :: Tracer
integer(i8_kind), optional, intent(inout) :: chksum
integer(i8_kind) :: chk_sum
integer :: stdoutunit
stdoutunit=stdout()
if (.not. module_is_initialized) then
call mpp_error(FATAL,&
'==>Error from ocean_tracer_util_mod (tracer_diag_chksum): module not initialized ')
endif
write(stdoutunit,*) '=== Diagnostic tracer checksum follows ==='
write(stdoutunit,*) 'Tracer name = ', Tracer%name
call write_timestamp(Time%model_time)
wrk1(isc:iec,jsc:jec,:) = Tracer%field(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer chksum = ', chk_sum
if (PRESENT(chksum)) chksum = chk_sum
end subroutine tracer_diag_chksum
! NAME="tracer_diag_chksum"
!#######################################################################
!
!
!
! Compute checksums for PSOM advection second order moments.
!
subroutine tracer_psom_chksum(Time, Tracer)
type(ocean_time_type), intent(in) :: Time
type(ocean_prog_tracer_type), intent(in) :: Tracer
integer(i8_kind) :: chk_sum
integer :: stdoutunit
stdoutunit=stdout()
if (.not. module_is_initialized) then
call mpp_error(FATAL,&
'==>Error from ocean_tracer_util_mod (tracer_psom_chksum): module not initialized ')
endif
write(stdoutunit,*) ' '
write (stdoutunit,*) 'Writing psom moments for tracer ',trim(Tracer%name)
call write_timestamp(Time%model_time)
wrk1(isc:iec,jsc:jec,:) = Tracer%s0(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%s0 chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%sx(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%sx chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%sxx(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%sxx chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%sy(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%sy chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%syy(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%syy chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%sz(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%sz chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%szz(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%szz chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%sxy(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%sxy chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%sxy(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%sxz chksum = ', chk_sum
wrk1(isc:iec,jsc:jec,:) = Tracer%syz(isc:iec,jsc:jec,:)*Grd%tmask(isc:iec,jsc:jec,:)
chk_sum = mpp_chksum(wrk1(isc:iec,jsc:jec,:))
write(stdoutunit,*) 'Tracer%syz chksum = ', chk_sum
end subroutine tracer_psom_chksum
! NAME="tracer_psom_chksum"
!#######################################################################
!
!
!
! Simplest, and slowest, sorting algorithm from Numerical Recipes.
! Called "sort_pick" in Numerical Recipes.
!
! Input are two arrays, first array defines the ascending sort
! and second is a slave to the sort.
!
! Typical example is sorting a vector of water parcels lightest
! to densest, with slave being volume of the parcels.
!
! More sophisticated sorting algorithms exist, and may need to
! be coded should this method prove too slow.
!
! This scheme has order N^2 operations, which is a lot.
!
! output has array(1) smallest and a(nsortpts) largest
! with corresponding slave array.
!
! coded Stephen.Griffies@noaa.gov June 2005
!
!
!
subroutine sort_pick_array(array, slave)
real, dimension(:), intent(inout) :: array
real, dimension(:), intent(inout) :: slave
real :: tmp_a, tmp_s
integer :: m, n, nsortpts
if (.not.module_is_initialized) then
call mpp_error(FATAL,&
'==>Error from ocean_tracer_util_mod (sort_pick_array): module not initialized')
endif
nsortpts = size(array)
do n=2,nsortpts
tmp_a = array(n)
tmp_s = slave(n)
do m=n-1,1,-1
if(array(m) <= tmp_a) exit
array(m+1)=array(m)
slave(m+1)=slave(m)
enddo
array(m+1) = tmp_a
slave(m+1) = tmp_s
enddo
end subroutine sort_pick_array
! NAME="sort_pick_array"
!#######################################################################
!
!
!
! Shell (or diminishing increment) sort from Numerical Recipes.
! Called "sort_shell" in Numerical Recipes.
!
! Input are two arrays, first array defines the ascending sort
! and second is a slave to the sort array.
!
! Typical example is sorting a vector of water parcels lightest
! to densest, with slave being volume of the parcels.
!
! More sophisticated sorting algorithms exist, and may need to
! be coded should this method prove too slow.
!
! This scheme has order N^(5/4) operations.
!
! output has array(1) smallest and a(nsortpts) largest,
! with corresponding ordering for slave array.
!
! coded Stephen.Griffies@noaa.gov June 2005
!
!
!
subroutine sort_shell_array(array, slave)
real, dimension(:), intent(inout) :: array
real, dimension(:), intent(inout) :: slave
real :: tmp_a, tmp_s
integer :: m, n, inc, nsortpts
if (.not.module_is_initialized) then
call mpp_error(FATAL,&
'==>Error from ocean_tracer_util_mod (sort_shell_array): module not initialized')
endif
nsortpts = size(array)
inc=1
do
inc=3*inc+1
if(inc > nsortpts) exit
enddo
do
inc=inc/3
do m=inc+1,nsortpts
tmp_a = array(m)
tmp_s = slave(m)
n=m
do
if(array(n-inc) <= tmp_a) exit
array(n) = array(n-inc)
slave(n) = slave(n-inc)
n=n-inc
if(n <= inc) exit
enddo
array(n)=tmp_a
slave(n)=tmp_s
enddo
if(inc <=1) exit
enddo
end subroutine sort_shell_array
! NAME="sort_shell_array"
end module ocean_tracer_util_mod