!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! !!
!! 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_rivermix_mod
!
! S.M. Griffies
!
!
! M.J. Harrison
!
!
! K.W. Dixon
!
!
!
! Tracer source from discharging river with depth or
! mixing rivers with depth.
!
!
!
! Compute thickness weighted tendency [tracer*rho*meter/sec]
! associated with discharge of river tracer content
! over a user defined column of ocean points. Points are
! selected based on whether river flow into a point is nonzero.
! Contribution added to tracer source array.
!
!
!
!
!
! S.M. Griffies, M.J. Harrison, R. C. Pacanowski, and A. Rosati
! A Guide to MOM4 (2003)
! NOAA/Geophysical Fluid Dynamics Laboratory
!
!
!
! Algorithm ensures total tracer is conserved. Note that volume/mass is
! modified by river water within the eta-equation using the big leap-frog.
!
!
!
!
!
!
! Must be true to enable this module. Default=.true., since
! this is the only way that tracer in river water enters the ocean.
!
!
!
! Set discharge_combine_runoff_calve=.true. to discharge combined tracer carried
! by liquid and solid runoff. This approach is sensible when ocean
! assigns a tracer content to the liquid and solid runoff fields.
! The alternative is to have a land model that provides information about
! the tracer coming into the ocean from land water, in which case it is
! preferable to set discharge_combine_runoff_calve=.false., so to do the runoff
! and calving separately.
! Default discharge_combine_runoff_calve=.true.
!
!
!
! Thickness of the column over which to insert tracers from
! rivers. Default river_insertion_thickness=0.0 (all in top).
!
!
! Thickness of the column over which to insert tracers carried by
! liquid runoff. Default runoff_insertion_thickness=0.0 (all in top).
!
!
! Thickness of the column over which to insert tracers carried by
! solid runoff. Default calving_insertion_thickness=0.0 (all in top).
!
!
!
! Thickness of the column over which to diffuse tracers from
! rivers.
!
!
! Vertical diffusivity enhancement at river mouths which is applied
! to a depth of river_diffusion_thickness, with linear tapering to zero
! enhancement from the ocean surface to river_diffusion_thickness.
!
!
! Logical to determine if enhance vertical diffusion of temp at river mouths
!
!
! Logical to determine if enhance vertical diffusion of salt and all other
! passive tracers at river mouths
!
!
!
! For debugging
!
!
! For debugging, by placing all in top cell, regardless value of
! river_insertion_thickness.
!
!
! For debugging, print global sum of heating rate by river water.
!
!
!
use axis_utils_mod, only: frac_index, nearest_index
use constants_mod, only: epsln
use diag_manager_mod, only: register_diag_field, send_data
use fms_mod, only: write_version_number, open_namelist_file, check_nml_error, close_file
use fms_mod, only: FATAL, NOTE, stdout, stdlog
use mpp_domains_mod, only: domain2D, mpp_global_sum, BITWISE_EXACT_SUM
use mpp_mod, only: mpp_error
use ocean_domains_mod, only: get_local_indices
use ocean_parameters_mod, only: missing_value
use ocean_types_mod, only: ocean_domain_type, ocean_grid_type, ocean_thickness_type
use ocean_types_mod, only: ocean_time_type, ocean_time_steps_type, ocean_options_type
use ocean_types_mod, only: ocean_prog_tracer_type, ocean_external_mode_type, ocean_density_type
use ocean_workspace_mod, only: wrk1, wrk1_2d
implicit none
private
public ocean_rivermix_init
public rivermix
private river_discharge_tracer
private runoff_calving_discharge_tracer
private river_kappa
private river_diagnostics
type(ocean_domain_type), pointer :: Dom => NULL()
type(ocean_grid_type), pointer :: Grd => NULL()
real :: river_insertion_thickness=0.0 ! static thickness (m) of ocean column where discharge rivers.
! actual thickness is based on model grid spacing. min thickness=dtz(1).
real :: runoff_insertion_thickness=0.0 ! static thickness (m) of ocean column where discharge liquid runoff.
! actual thickness is based on model grid spacing. min thickness=dtz(1).
real :: calving_insertion_thickness=0.0 ! static thickness (m) of ocean column where discharge solid runoff.
! actual thickness is based on model grid spacing. min thickness=dtz(1).
real :: river_diffusion_thickness=0.0 ! static thickness (m) of ocean column where diffuse tracer at river mouths.
! actual thickness is based on model grid spacing. min thickness=dtz(1).
real :: river_diffusivity=5.0e-3 ! enhancement to the vertical diffusivity (m^2/s) at river mouths
logical :: river_diffuse_temp=.false. ! to enhance diffusivity of temp at river mouths over river_thickness column
logical :: river_diffuse_salt=.false. ! to enhance diffusivity of salt at river mouths over river_thickness column
logical :: discharge_combine_runoff_calve=.true. ! to discharge liquid+solid together
real, dimension(:,:), allocatable :: tracer_flux
! for diagnostics
logical :: used
integer, dimension(:), allocatable :: id_rivermix
integer, dimension(:), allocatable :: id_runoffmix
integer, dimension(:), allocatable :: id_calvingmix
integer :: id_diff_cbt_river_t =-1
integer :: id_diff_cbt_river_s =-1
integer :: id_neutral_rho_rivermix =-1
integer :: id_neutral_rho_runoffmix =-1
integer :: id_neutral_rho_calvingmix =-1
integer :: id_wdian_rho_rivermix =-1
integer :: id_wdian_rho_runoffmix =-1
integer :: id_wdian_rho_calvingmix =-1
integer :: unit=6 ! processor zero writes to unit 6
! time step (sec)
real :: dtime
integer :: num_prog_tracers=0
integer :: index_temp=-1
integer :: index_salt=-1
character(len=128) :: version=&
'$Id: ocean_rivermix.F90,v 16.0.2.1.10.1.2.1.52.1 2009/10/10 00:42:46 nnz Exp $'
character (len=128) :: tagname=&
'$Name: mom4p1_pubrel_dec2009_nnz $'
integer :: isd, ied, jsd, jed, isc, iec, jsc, jec, nk
logical :: debug_this_module = .false.
logical :: debug_all_in_top_cell = .false.
logical :: debug_this_module_heat=.false.
logical :: module_is_initialized = .FALSE.
logical :: use_this_module = .true.
namelist /ocean_rivermix_nml/ use_this_module, debug_this_module, &
debug_all_in_top_cell, debug_this_module_heat, &
river_diffuse_temp, river_diffuse_salt, &
river_diffusion_thickness, river_diffusivity, &
discharge_combine_runoff_calve, river_insertion_thickness, &
runoff_insertion_thickness, calving_insertion_thickness
contains
!#######################################################################
!
!
!
! Initial set up for mixing of tracers at runoff points.
!
!
subroutine ocean_rivermix_init(Grid, Domain, Time, Time_steps, T_prog, Ocean_options, debug)
type(ocean_grid_type), target, intent(in) :: Grid
type(ocean_domain_type), target, intent(in) :: Domain
type(ocean_time_type), intent(in) :: Time
type(ocean_time_steps_type), intent(in) :: Time_steps
type(ocean_prog_tracer_type), intent(inout) :: T_prog(:)
type(ocean_options_type), intent(inout) :: Ocean_options
logical, optional, intent(in) :: debug
integer :: n, nz_insert, nz_diffuse
integer :: io_status, ioun, ierr
integer :: stdoutunit,stdlogunit
stdoutunit=stdout();stdlogunit=stdlog()
if ( module_is_initialized ) then
call mpp_error(FATAL, &
'==>Error from ocean_rivermix_mod (ocean_rivermix_init): module already initialized')
endif
module_is_initialized = .TRUE.
call write_version_number( version, tagname )
call get_local_indices(Domain,isd,ied,jsd,jed,isc,iec,jsc,jec)
nk = Grid%nk
Dom => Domain
Grd => Grid
dtime = Time_steps%dtts
num_prog_tracers = size(T_prog(:))
do n=1,num_prog_tracers
if (T_prog(n)%name == 'temp') index_temp = n
if (T_prog(n)%name == 'salt') index_salt = n
enddo
if (PRESENT(debug)) debug_this_module = debug
! provide for namelist over-ride of default values
ioun = open_namelist_file()
read (ioun,ocean_rivermix_nml,IOSTAT=io_status)
write (stdlogunit,ocean_rivermix_nml)
write (stdoutunit,'(/)')
write (stdoutunit,ocean_rivermix_nml)
ierr = check_nml_error(io_status,'ocean_rivermix_nml')
call close_file (ioun)
if(use_this_module) then
call mpp_error(NOTE,&
'==>From ocean_rivermix_mod: Using rivermix module to mix liquid and/or solid runoff into the ocean.')
Ocean_options%rivermix = 'Used rivermix module to mix liquid and/or solid runoff into ocean.'
else
call mpp_error(NOTE,&
'==>From ocean_rivermix_mod: NOT using rivermix module. Will NOT mix river tracers into ocean. Is this what you wish?')
Ocean_options%rivermix = 'Did NOT use rivermix module. River tracers NOT mixed into the ocean. '
return
endif
! allocate for tracer flux in runoff or calving
allocate (tracer_flux(isd:ied,jsd:jed))
tracer_flux=0.0
if(discharge_combine_runoff_calve) then
write(stdoutunit,'(a)')'==>Note: discharging calving+runoff together. The alternative is to separately discharge. '
! get nominal thickness
nz_insert = nearest_index(river_insertion_thickness,Grd%zw)
nz_insert = max(1,nz_insert)
if(river_insertion_thickness==0.0) then
call mpp_error(NOTE, &
'==>Note: resetting river_insertion_thickness to dzt(1). Discharge all river into top cell')
else
write(stdoutunit,'(a)')'==>Note: if using waterflux and rivers, then will'
write(stdoutunit,'(a,i3,a)')' discharge river tracer over ',nz_insert,' grid points in vertical'
endif
else
! get nominal thickness
nz_insert = nearest_index(runoff_insertion_thickness,Grd%zw)
nz_insert = max(1,nz_insert)
if(runoff_insertion_thickness==0.0) then
call mpp_error(NOTE, &
'==>Note: resetting runoff_insertion_thickness to dzt(1). Discharge all liquid runoff into top cell')
else
write(stdoutunit,'(a)')'==>Note: if using waterflux and liquid runoff, then will'
write(stdoutunit,'(a,i3,a)')' discharge liquid runoff tracer over ',nz_insert,' grid points in vertical'
endif
! get nominal thickness
nz_insert = nearest_index(calving_insertion_thickness,Grd%zw)
nz_insert = max(1,nz_insert)
if(calving_insertion_thickness==0.0) then
call mpp_error(NOTE, &
'==>Note: resetting calving_insertion_thickness to dzt(1). Discharge all solid runoff into top cell')
else
write(stdoutunit,'(a)')'==>Note: if using waterflux and solid runoff, then will'
write(stdoutunit,'(a,i3,a)')' discharge solid runoff tracer over ',nz_insert,' grid points in vertical'
endif
endif
! get nominal thickness over which to diffuse river
nz_diffuse = nearest_index(river_diffusion_thickness,Grd%zw)
nz_diffuse = max(1,nz_diffuse)
if(river_diffuse_temp) then
if(Time_steps%aidif==0.0) then
call mpp_error(FATAL, &
'==>Error: aidif=1.0 must be set to allow stable time stepping with river_diffuse_temp=.true.')
endif
if(river_diffusion_thickness==0.0) then
call mpp_error(NOTE, &
'==>Note: resetting river_diffusion_thickness=dzt(1) for enhanced diff_cbt of temperature.')
else
write(stdoutunit,'(a,i3,a)') &
' ==>Note: enhance temp diff_cbt at rivers over ',nz_diffuse,' points in vertical'
write(stdoutunit,'(a,e12.5,a)')&
' Do so by adding diffusivity of ',river_diffusivity,' m^2/s to diff_cbt(temp)'
endif
endif
if(river_diffuse_salt) then
if(Time_steps%aidif==0.0) then
call mpp_error(FATAL, &
' ==>Error: aidif=1.0 must be set to allow stable time stepping with river_diffuse_salt=.true.')
endif
if(river_diffusion_thickness==0.0) then
call mpp_error(NOTE, &
'==>Note: resetting river_diffusion_thickness=dzt(1) for enhanced diff_cbt of salt and passive')
else
write(stdoutunit,'(a,i3,a)') &
' ==>Note: enhance salt/passive diff_cbt at rivers over ',nz_diffuse,' points in vertical'
write(stdoutunit,'(a,e12.5,a)') &
' Do so by adding diffusivity of ',river_diffusivity,' m^2/s to diff_cbt(salt)'
endif
endif
! register for diag_manager
allocate (id_rivermix(num_prog_tracers))
allocate (id_runoffmix(num_prog_tracers))
allocate (id_calvingmix(num_prog_tracers))
id_rivermix = -1
id_runoffmix = -1
id_calvingmix = -1
do n=1,num_prog_tracers
if(T_prog(n)%name == 'temp') then
id_rivermix(n) = register_diag_field ('ocean_model', trim(T_prog(n)%name)//'_rivermix', &
Grd%tracer_axes(1:3), Time%model_time, &
'cp*rivermix*rho_dzt*temp', 'Watt/m^2', &
missing_value=missing_value, range=(/-1.e10,1.e10/))
id_runoffmix(n) = register_diag_field ('ocean_model', trim(T_prog(n)%name)//'_runoffmix',&
Grd%tracer_axes(1:3), Time%model_time, &
'cp*runoffmix*rho_dzt*temp', 'Watt/m^2', &
missing_value=missing_value, range=(/-1.e10,1.e10/))
id_calvingmix(n) = register_diag_field ('ocean_model', trim(T_prog(n)%name)//'_calvingmix',&
Grd%tracer_axes(1:3), Time%model_time, &
'cp*calvingmix*rho_dzt*temp', 'Watt/m^2', &
missing_value=missing_value, range=(/-1.e10,1.e10/))
else
id_rivermix(n) = register_diag_field ('ocean_model', trim(T_prog(n)%name)//'_rivermix', &
Grd%tracer_axes(1:3), Time%model_time, &
'rivermix*rho_dzt*tracer for '//trim(T_prog(n)%name), &
trim(T_prog(n)%flux_units), &
missing_value=missing_value, range=(/-1.e10,1.e10/))
id_runoffmix(n) = register_diag_field ('ocean_model', trim(T_prog(n)%name)//'_runoffmix',&
Grd%tracer_axes(1:3), Time%model_time, &
'runoffmix*rho_dzt*tracer for '//trim(T_prog(n)%name), &
trim(T_prog(n)%flux_units), &
missing_value=missing_value, range=(/-1.e10,1.e10/))
id_calvingmix(n) = register_diag_field ('ocean_model', trim(T_prog(n)%name)//'_calvingmix',&
Grd%tracer_axes(1:3), Time%model_time, &
'calvingmix*rho_dzt*tracer for '//trim(T_prog(n)%name), &
trim(T_prog(n)%flux_units), &
missing_value=missing_value, range=(/-1.e10,1.e10/))
endif
enddo
if(debug_all_in_top_cell) then
call mpp_error(NOTE, &
'==>Note: in rivermix module, debug_all_in_top_cell=.true., so placing all river water to top cell.')
endif
id_diff_cbt_river_t = -1
id_diff_cbt_river_t = register_diag_field ('ocean_model', 'diff_cbt_river_t', &
Grid%tracer_axes(1:3), Time%model_time, &
'diff_cbt(temp) enhancement at rivers', 'm^2/s', &
missing_value=missing_value, range=(/-10.0,1e6/))
id_diff_cbt_river_s = -1
id_diff_cbt_river_s = register_diag_field ('ocean_model', 'diff_cbt_river_s', &
Grid%tracer_axes(1:3), Time%model_time, &
'diff_cbt(salt) enhancement at rivers', 'm^2/s', &
missing_value=missing_value,range=(/-10.0,1e6/))
id_neutral_rho_rivermix = register_diag_field ('ocean_model', 'neutral_rho_rivermix', &
Grd%tracer_axes(1:3), Time%model_time, &
'update of neutral density from rivermix scheme', &
'rho*rho_dz/sec', missing_value=missing_value, range=(/-1.e10,1.e10/))
id_neutral_rho_runoffmix = register_diag_field ('ocean_model', 'neutral_rho_runoffmix', &
Grd%tracer_axes(1:3), Time%model_time, &
'update of neutral density from runoffmix scheme', &
'rho*rho_dz/sec', missing_value=missing_value, range=(/-1.e10,1.e10/))
id_neutral_rho_calvingmix = register_diag_field ('ocean_model', 'neutral_rho_calvingmix', &
Grd%tracer_axes(1:3), Time%model_time, &
'update of neutral density from calvingmix scheme', &
'rho*rho_dz/sec', missing_value=missing_value, range=(/-1.e10,1.e10/))
id_wdian_rho_rivermix = register_diag_field ('ocean_model', 'wdian_rho_rivermix', &
Grd%tracer_axes(1:3), Time%model_time, &
'dianeutral velocity component due to rivermix scheme', &
'm/sec', missing_value=missing_value, range=(/-1.e10,1.e10/))
id_wdian_rho_runoffmix = register_diag_field ('ocean_model', 'wdian_rho_runoffmix', &
Grd%tracer_axes(1:3), Time%model_time, &
'dianeutral velocity component due to runoffmix scheme', &
'm/sec', missing_value=missing_value, range=(/-1.e10,1.e10/))
id_wdian_rho_calvingmix = register_diag_field ('ocean_model', 'wdian_rho_calvingmix',&
Grd%tracer_axes(1:3), Time%model_time, &
'dianeutral velocity component due to calvingmix scheme', &
'm/sec', missing_value=missing_value, range=(/-1.e10,1.e10/))
end subroutine ocean_rivermix_init
! NAME="ocean_rivermix_init"
!#######################################################################
!
!
!
! This subroutine computes one or all of the following:
!
! (1) Thickness weighted and rho weighted tracer source associated
! with river tracer content discharged into a vertical column of ocean
! tracer cells. This is done if river_discharge=.true.
!
! (2) Enhance vertical diffusivity at river mouths.
! This is done if river_diffuse_temp=.true. or
! river_diffuse_salt=.true.
!
! Doing one or both are useful for models with fine vertical
! resolution, where discharging river content to top cell
! is often not numerically suitable nor physically relevant.
!
!
!
subroutine rivermix (Time, Thickness, Dens, T_prog, river, runoff, calving, &
diff_cbt, index_temp, index_salt)
type(ocean_time_type), intent(in) :: Time
type(ocean_thickness_type), intent(in) :: Thickness
type(ocean_density_type), intent(in) :: Dens
type(ocean_prog_tracer_type), intent(inout) :: T_prog(:)
integer, intent(in) :: index_temp
integer, intent(in) :: index_salt
real, dimension(isd:,jsd:), intent(in) :: river
real, dimension(isd:,jsd:), intent(in) :: runoff
real, dimension(isd:,jsd:), intent(in) :: calving
real, dimension(isd:,jsd:,:,:), intent(inout) :: diff_cbt
integer :: i,j,n
logical :: river_discharge =.false.
logical :: runoff_discharge =.false.
logical :: calving_discharge=.false.
if(.not. use_this_module) return
if(.not. module_is_initialized ) then
call mpp_error(FATAL, &
'==>Error from ocean_rivermix_mod (rivermix): module must be initialized')
endif
! for discharging the combined runoff+calving fields
if(discharge_combine_runoff_calve) then
do n=1,num_prog_tracers
T_prog(n)%wrk1(:,:,:) = 0.0
enddo
river_discharge=.false.
do j=jsc,jec
do i=isc,iec
if(river(i,j) > 0.0 .and. Grd%kmt(i,j) > 0) river_discharge=.true.
enddo
enddo
if(river_discharge) then
call river_discharge_tracer(Time, Thickness, Dens, T_prog(1:num_prog_tracers), river)
endif
do n=1,num_prog_tracers
if(id_rivermix(n) > 0) then
used = send_data (id_rivermix(n), T_prog(n)%wrk1(:,:,:)*T_prog(n)%conversion, &
Time%model_time, rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
enddo
call river_diagnostics(Time, Thickness, Dens, &
T_prog(index_temp)%wrk1(:,:,:),T_prog(index_salt)%wrk1(:,:,:),3)
! for separately discharging liquid runoff and solid calving
else
do n=1,num_prog_tracers
T_prog(n)%wrk1(:,:,:) = 0.0
enddo
runoff_discharge=.false.
do j=jsc,jec
do i=isc,iec
if(runoff(i,j) > 0.0 .and. Grd%kmt(i,j) > 0) runoff_discharge=.true.
enddo
enddo
if(runoff_discharge) then
call runoff_calving_discharge_tracer(Time, Thickness, Dens, &
T_prog(1:num_prog_tracers), runoff, runoff_insertion_thickness, 1)
endif
do n=1,num_prog_tracers
if(id_runoffmix(n) > 0) then
used = send_data (id_runoffmix(n), T_prog(n)%wrk1(:,:,:)*T_prog(n)%conversion, &
Time%model_time, rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
enddo
call river_diagnostics(Time, Thickness, Dens, &
T_prog(index_temp)%wrk1(:,:,:),T_prog(index_salt)%wrk1(:,:,:),1)
do n=1,num_prog_tracers
T_prog(n)%wrk1(:,:,:) = 0.0
enddo
calving_discharge=.false.
do j=jsc,jec
do i=isc,iec
if(calving(i,j) > 0.0 .and. Grd%kmt(i,j) > 0) calving_discharge=.true.
enddo
enddo
if(calving_discharge) then
call runoff_calving_discharge_tracer(Time, Thickness, Dens, &
T_prog(1:num_prog_tracers), calving, calving_insertion_thickness, 2)
endif
do n=1,num_prog_tracers
if(id_calvingmix(n) > 0) then
used = send_data (id_calvingmix(n), T_prog(n)%wrk1(:,:,:)*T_prog(n)%conversion, &
Time%model_time, rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
enddo
call river_diagnostics(Time, Thickness, Dens, &
T_prog(index_temp)%wrk1(:,:,:),T_prog(index_salt)%wrk1(:,:,:),2)
endif ! discharge_combine_runoff_calve
if(river_diffuse_temp) then
call river_kappa(Time, Thickness, T_prog(index_temp), diff_cbt(isd:ied,jsd:jed,:,1))
endif
if(river_diffuse_salt) then
call river_kappa(Time, Thickness, T_prog(index_salt), diff_cbt(isd:ied,jsd:jed,:,2))
endif
end subroutine rivermix
! NAME="rivermix"
!#######################################################################
!
!
!
! Compute thickness weighted tracer source [tracer*m/s]
! associated with the discharge of tracer from a river over
! a vertical column whose thickness is set by River_insertion_thickness
! and whose horizontal location is given by the river array.
!
! Jan 2005: converted to mass weighting for use with non-Boussinesq
! pressure-like coodinates.
!
! This subroutine is maintained for legacy purposes.
!
!
!
subroutine river_discharge_tracer (Time, Thickness, Dens, T_prog, river)
type(ocean_time_type), intent(in) :: Time
type(ocean_thickness_type), intent(in) :: Thickness
type(ocean_density_type), intent(in) :: Dens
type(ocean_prog_tracer_type), intent(inout) :: T_prog(:)
real, dimension(isd:,jsd:), intent(in) :: river
integer :: i, j, k, n, nz
integer :: tau
real :: depth, thkocean
real :: delta(nk), delta_rho_tocean(nk), delta_rho0_triver(nk)
real :: zextra, zinsert, tracerextra, tracernew(nk)
real :: temporary, tracer_input
integer :: stdoutunit
stdoutunit=stdout()
if(.not. use_this_module) return
if(.not. module_is_initialized ) then
call mpp_error(FATAL, &
'==>Error in ocean_rivermix_mod (river_discharge_tracer): module must be initialized')
endif
tau = Time%tau
do n=1,num_prog_tracers
T_prog(n)%wrk1(:,:,:) = 0.0
enddo
delta = 0.0
delta_rho_tocean = 0.0
delta_rho0_triver = 0.0
wrk1 = 0.0
do j=jsc,jec
do i=isc,iec
if (river(i,j) > 0.0 .and. Grd%kmt(i,j) > 0) then
! the array "river" contains the volume rate (m/s) or mass
! rate (kg/m2/sec) of fluid with tracer concentration triver
! that is to be distributed in the vertical.
depth = min(Grd%ht(i,j),river_insertion_thickness) ! be sure not to discharge river content into rock
nz = min(Grd%kmt(i,j),floor(frac_index(depth,Grd%zw))) ! number of k-levels into which discharge rivers
nz = max(1,nz) ! make sure have at least one cell to discharge into
! determine fractional thicknesses of grid cells
thkocean = 0.0
do k=1,nz
thkocean = thkocean + Thickness%rho_dzt(i,j,k,tau)
enddo
do k=1,nz
delta(k) = Thickness%rho_dzt(i,j,k,tau)/(epsln+thkocean)
enddo
do n=1,num_prog_tracers
! mix a portion of the river mass(volume) inserted over the course of a tracer timestep
! into each model level from k=1:nz, in proportion to the fractional cell thickness.
! The mixing scheme used here follows scheme devised by Keith Dixon to handle hydraulic
! control across xland mixing points
!
! The following schematic illustrates the scheme, assuming constant layer thickness
! neglecting free surface height variations and assuming the river insertion depth
! extends to the base of the third model level. Each of these assumptions are for
! purposes of this schematic only. The scheme that is implemented works in general
! for non-constant cell thicknesses.
!
! Total depth = H; cell thickness = dz; River mass flux/timestep = R
! x--------x
! ! !
! ! ! < === Insert zinsert = R*dz/H meters of riverwater at a temperature of
! ! ! Triver + 2*zinsert meters of water at T*(2)
! ! ! T*(1) = (T(1).dz + 3.T*(2).zinsert + Triver.zinsert ) / (dz + 3.zinsert)
! x--------x
! ! !
! ! ! < === Insert zinsert = R*dz/H meters of riverwater at a temperature of
! ! ! Triver + zinsert meters of water at T*(3)
! ! ! T*(2) = (T(2).dz + 2.T*(3).zinsert + Triver.zinsert ) / (dz + 2.zinsert)
! ! !
! x--------x
! ! !
! ! ! < === Insert zinsert = R*dz/H meters of riverwater at a temperature of Triver
! ! ! T*(3) = (T(3).dz + Triver.zinsert ) / (dz + zinsert)
! ! !
! xxxxxxxxxx
zextra=0.0
do k=nz,1,-1
tracernew(k) = 0.0
if (k.eq.nz) then
tracerextra=0.0
else
tracerextra = tracernew(k+1)
endif
zinsert = river(i,j)*dtime*delta(k)
tracernew(k) = (tracerextra*zextra + T_prog(n)%field(i,j,k,tau)*Thickness%rho_dzt(i,j,k,tau) + &
T_prog(n)%triver(i,j)*zinsert) / (zextra+Thickness%rho_dzt(i,j,k,tau)+zinsert)
zextra=zextra+zinsert
enddo
k=1
T_prog(n)%wrk1(i,j,k) = (tracernew(k)*(Thickness%rho_dzt(i,j,k,tau)+river(i,j)*dtime) -&
T_prog(n)%field(i,j,k,tau)*Thickness%rho_dzt(i,j,k,tau))/dtime
do k=2,nz
T_prog(n)%wrk1(i,j,k) = Thickness%rho_dzt(i,j,k,tau)*(tracernew(k) - T_prog(n)%field(i,j,k,tau))/dtime
enddo
if(debug_all_in_top_cell) then
k=1
T_prog(n)%wrk1(i,j,:) = 0.0
T_prog(n)%wrk1(i,j,k) = Grd%tmask(i,j,k)*river(i,j)*T_prog(n)%triver(i,j)
endif
do k=1,nz
T_prog(n)%th_tendency(i,j,k) = T_prog(n)%th_tendency(i,j,k) + T_prog(n)%wrk1(i,j,k)
enddo
if (debug_this_module) then
write(6,*) 'i,j,n,river((kg/m^3)*m/sec),triver= ',i,j,n,river(i,j),T_prog(n)%triver(i,j)
do k=1,nz
write(6,*) 'i,j,k,tracer(k),tracernew(k),tendency(tracer*rho*thickness/sec)= ',&
i,j,k,T_prog(n)%field(i,j,k,tau),tracernew(k),T_prog(n)%wrk1(i,j,k)
enddo
endif
enddo ! n end
endif ! river > 0
enddo ! i end
enddo ! j end
if (debug_this_module_heat) then
wrk1_2d(:,:) = 0.0
do j=jsc,jec
do i=isc,iec
wrk1_2d(i,j) = Grd%tmask(i,j,1)*Grd%dat(i,j)*T_prog(index_temp)%conversion &
*river(i,j)*T_prog(index_temp)%triver(i,j)*dtime
enddo
enddo
tracer_input = mpp_global_sum(Dom%domain2d,wrk1_2d(:,:), BITWISE_EXACT_SUM)
write(stdoutunit,'(a)')
write (stdoutunit,'(a,es24.17,a)') ' Heat input via river (runoff+calving) in rivermix = ',&
tracer_input,' Joule'
write(stdoutunit,'(a)')
endif
end subroutine river_discharge_tracer
! NAME="river_discharge_tracer"
!#######################################################################
!
!
!
! Compute thickness weighted tracer source [tracer*m/s]
! associated with the discharge of tracer from runoff or calving over
! a vertical column whose thickness is set by either runoff_insertion_thickness
! or calving_insertion_thickness, and whose horizontal location is given
! by the runoff or calving array.
!
! Jan 2005: converted to mass weighting for use with non-Boussinesq
! pressure-like coodinates.
!
! Feb 2009: now use calving_tracer_flux and runoff_tracer_flux, as the
! land model carries information about the tracer content in the
! liquid and solid runoff.
!
!
!
subroutine runoff_calving_discharge_tracer (Time, Thickness, Dens, T_prog, &
river, insertion_thickness, runoff_type)
type(ocean_time_type), intent(in) :: Time
type(ocean_thickness_type), intent(in) :: Thickness
type(ocean_density_type), intent(in) :: Dens
type(ocean_prog_tracer_type), intent(inout) :: T_prog(:)
real, dimension(isd:,jsd:), intent(in) :: river
real, intent(in) :: insertion_thickness
integer, intent(in) :: runoff_type
integer :: i, j, k, n, nz
integer :: tau
real :: depth, thkocean
real :: delta(nk), delta_rho_tocean(nk), delta_rho0_triver(nk)
real :: zextra, zinsert, tracerextra, tracernew(nk)
real :: temporary, tracer_input
integer :: stdoutunit
stdoutunit=stdout()
if(.not. use_this_module) return
if(.not. module_is_initialized ) then
call mpp_error(FATAL, &
'==>Error in ocean_rivermix_mod (runoff_calving_discharge_tracer): module must be initialized')
endif
tau = Time%tau
do n=1,num_prog_tracers
T_prog(n)%wrk1(:,:,:) = 0.0
enddo
delta = 0.0
delta_rho_tocean = 0.0
delta_rho0_triver = 0.0
wrk1 = 0.0
tracer_flux = 0.0
do j=jsc,jec
do i=isc,iec
if (river(i,j) > 0.0 .and. Grd%kmt(i,j) > 0) then
! the array "river" contains the volume rate (m/s) or mass
! rate (kg/m2/sec) of fluid with tracer
! that is to be distributed in the vertical.
depth = min(Grd%ht(i,j),insertion_thickness) ! be sure not to discharge river content into rock
nz = min(Grd%kmt(i,j),floor(frac_index(depth,Grd%zw))) ! number of k-levels into which discharge rivers
nz = max(1,nz) ! make sure have at least one cell to discharge into
! determine fractional thicknesses of grid cells
thkocean = 0.0
do k=1,nz
thkocean = thkocean + Thickness%rho_dzt(i,j,k,tau)
enddo
do k=1,nz
delta(k) = Thickness%rho_dzt(i,j,k,tau)/(epsln+thkocean)
enddo
do n=1,num_prog_tracers
! mix a portion of the river mass(volume) inserted over the course of a tracer timestep
! into each model level from k=1:nz, in proportion to the fractional cell thickness.
! The mixing scheme used here follows scheme devised by Keith Dixon to handle hydraulic
! control across xland mixing points
!
! The following schematic illustrates the scheme, assuming constant layer thickness
! neglecting free surface height variations and assuming the river insertion depth
! extends to the base of the third model level. Each of these assumptions are for
! purposes of this schematic only. The scheme that is implemented works in general
! for non-constant cell thicknesses.
!
! Total depth = H; cell thickness = dz; River mass flux/timestep = R
! x--------x
! ! !
! ! ! < === Insert zinsert = R*dz/H meters of riverwater at a temperature of
! ! ! Triver + 2*zinsert meters of water at T*(2)
! ! ! T*(1) = (T(1).dz + 3.T*(2).zinsert + Triver.zinsert ) / (dz + 3.zinsert)
! x--------x
! ! !
! ! ! < === Insert zinsert = R*dz/H meters of riverwater at a temperature of
! ! ! Triver + zinsert meters of water at T*(3)
! ! ! T*(2) = (T(2).dz + 2.T*(3).zinsert + Triver.zinsert ) / (dz + 2.zinsert)
! ! !
! x--------x
! ! !
! ! ! < === Insert zinsert = R*dz/H meters of riverwater at a temperature of Triver
! ! ! T*(3) = (T(3).dz + Triver.zinsert ) / (dz + zinsert)
! ! !
! xxxxxxxxxx
if(runoff_type==1) then
tracer_flux(i,j) = T_prog(n)%runoff_tracer_flux(i,j)
else
tracer_flux(i,j) = T_prog(n)%calving_tracer_flux(i,j)
endif
zextra=0.0
do k=nz,1,-1
tracernew(k) = 0.0
if (k.eq.nz) then
tracerextra=0.0
else
tracerextra = tracernew(k+1)
endif
zinsert = river(i,j)*dtime*delta(k)
tracernew(k) = (tracerextra*zextra + T_prog(n)%field(i,j,k,tau)*Thickness%rho_dzt(i,j,k,tau) + &
tracer_flux(i,j)*dtime*delta(k)) / (zextra+Thickness%rho_dzt(i,j,k,tau)+zinsert)
zextra=zextra+zinsert
enddo
k=1
T_prog(n)%wrk1(i,j,k) = (tracernew(k)*(Thickness%rho_dzt(i,j,k,tau)+river(i,j)*dtime) -&
T_prog(n)%field(i,j,k,tau)*Thickness%rho_dzt(i,j,k,tau))/dtime
do k=2,nz
T_prog(n)%wrk1(i,j,k) = Thickness%rho_dzt(i,j,k,tau)*(tracernew(k) - T_prog(n)%field(i,j,k,tau))/dtime
enddo
if(debug_all_in_top_cell) then
k=1
T_prog(n)%wrk1(i,j,:) = 0.0
T_prog(n)%wrk1(i,j,k) = Grd%tmask(i,j,k)*river(i,j)*T_prog(n)%triver(i,j)
endif
do k=1,nz
T_prog(n)%th_tendency(i,j,k) = T_prog(n)%th_tendency(i,j,k) + T_prog(n)%wrk1(i,j,k)
enddo
if (debug_this_module) then
write(6,*) 'i,j,n,river((kg/m^3)*m/sec),tracer_flux= ',i,j,n,river(i,j),tracer_flux(i,j)
do k=1,nz
write(6,*) 'i,j,k,tracer(k),tracernew(k),tendency(tracer*rho*thickness/sec)= ',&
i,j,k,T_prog(n)%field(i,j,k,tau),tracernew(k),T_prog(n)%wrk1(i,j,k)
enddo
endif
enddo ! n end for number of prognostic tracers
endif ! river > 0
enddo ! i end
enddo ! j end
if (debug_this_module_heat) then
if(runoff_type==1) then
wrk1_2d(:,:) = 0.0
do j=jsc,jec
do i=isc,iec
wrk1_2d(i,j) = Grd%tmask(i,j,1)*Grd%dat(i,j)*T_prog(index_temp)%conversion &
*T_prog(index_temp)%runoff_tracer_flux(i,j)*dtime
enddo
enddo
tracer_input = mpp_global_sum(Dom%domain2d,wrk1_2d(:,:), BITWISE_EXACT_SUM)
write(stdoutunit,'(a)')
write (stdoutunit,'(a,es24.17,a)') ' Heat input via runoff in rivermix = ',&
tracer_input,' Joule'
write(stdoutunit,'(a)')
endif
if(runoff_type==2) then
wrk1_2d(:,:) = 0.0
do j=jsc,jec
do i=isc,iec
wrk1_2d(i,j) = Grd%tmask(i,j,1)*Grd%dat(i,j)*T_prog(index_temp)%conversion &
*T_prog(index_temp)%calving_tracer_flux(i,j)*dtime
enddo
enddo
tracer_input = mpp_global_sum(Dom%domain2d,wrk1_2d(:,:), BITWISE_EXACT_SUM)
write(stdoutunit,'(a)')
write (stdoutunit,'(a,es24.17,a)') ' Heat input via calving in rivermix = ',&
tracer_input,' Joule'
write(stdoutunit,'(a)')
endif
endif
end subroutine runoff_calving_discharge_tracer
! NAME="runoff_calving_discharge_tracer"
!#######################################################################
!
!
!
! This subroutine enhances the vertical diffusivity kappa over
! a vertical column whose thickness is set by river_diffusion_thickness
! and whose horizontal location is given by the rmask array.
! Note that rmask can be > 0 even if river=0 in the case when
! use virtual salt flux.
! The enhanced diffusivity is maximum at the top cell and is linearly
! interpolated to the normal diffusivity at the depth set by
! river_diffusion_thickness
!
!
subroutine river_kappa (Time, Thickness, Tracer, kappa)
type(ocean_time_type), intent(in) :: Time
type(ocean_thickness_type), intent(in) :: Thickness
type(ocean_prog_tracer_type), intent(in) :: Tracer
real, dimension(isd:,jsd:,:), intent(inout) :: kappa
integer :: i, j, k, nz
real :: depth
real, dimension(nk) :: zw_ij
if(.not. module_is_initialized ) then
call mpp_error(FATAL, &
'==>Error in ocean_rivermix_mod (river_kappa): module must be initialized')
endif
wrk1=0.0
do j=jsc,jec
do i=isc,iec
do k=1,nk
zw_ij(k) = Thickness%depth_zwt(i,j,k)
enddo
if (Tracer%riverdiffuse(i,j) > 0.0 .and. Grd%kmt(i,j) > 0) then
depth = min(Grd%ht(i,j),river_diffusion_thickness)
nz = min(Grd%kmt(i,j),floor(frac_index(depth,zw_ij)))
nz = max(1,nz)
do k=1,nz
wrk1(i,j,k) = river_diffusivity*(1.0 - Thickness%depth_zt(i,j,k)/Thickness%depth_zt(i,j,nk))
kappa(i,j,k) = kappa(i,j,k) + wrk1(i,j,k)
enddo
endif
enddo
enddo
if (id_diff_cbt_river_t > 0 .and. Tracer%name=='temp') then
used = send_data (id_diff_cbt_river_t, wrk1(:,:,:), &
Time%model_time, rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
if (id_diff_cbt_river_s > 0 .and. Tracer%name=='salt') then
used = send_data (id_diff_cbt_river_s, wrk1(:,:,:), &
Time%model_time, rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
end subroutine river_kappa
! NAME="river_kappa"
!#######################################################################
!
!
!
! For sending some diagnostics.
!
!
subroutine river_diagnostics (Time, Thickness, Dens, temp_wrk, salt_wrk, mix_type)
type(ocean_time_type), intent(in) :: Time
type(ocean_thickness_type), intent(in) :: Thickness
type(ocean_density_type), intent(in) :: Dens
real, dimension(isd:,jsd:,:), intent(in) :: temp_wrk
real, dimension(isd:,jsd:,:), intent(in) :: salt_wrk
integer, intent(in) :: mix_type
integer :: i,j,k,n,tau
real :: temporary
! runoff
if(mix_type==1) then
if (id_neutral_rho_runoffmix > 0) then
wrk1(:,:,:) = 0.0
do k=1,nk
do j=jsc,jec
do i=isc,iec
wrk1(i,j,k) = Grd%tmask(i,j,k) &
*(Dens%drhodT(i,j,k)*temp_wrk(i,j,k) &
+Dens%drhodS(i,j,k)*salt_wrk(i,j,k))
enddo
enddo
enddo
used = send_data (id_neutral_rho_runoffmix, wrk1(:,:,:), &
Time%model_time,rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
if (id_wdian_rho_runoffmix > 0) then
wrk1(:,:,:) = 0.0
do k=1,nk
do j=jsc,jec
do i=isc,iec
temporary = Dens%drhodz_zt(i,j,k)*Thickness%rho_dzt(i,j,k,tau)
wrk1(i,j,k) = Grd%tmask(i,j,k) &
*(Dens%drhodT(i,j,k)*temp_wrk(i,j,k) &
+Dens%drhodS(i,j,k)*salt_wrk(i,j,k)) &
/(epsln+temporary)
enddo
enddo
enddo
used = send_data (id_wdian_rho_runoffmix, wrk1(:,:,:),&
Time%model_time,rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
! calving
elseif(mix_type==2) then
if (id_neutral_rho_calvingmix > 0) then
wrk1(:,:,:) = 0.0
do k=1,nk
do j=jsc,jec
do i=isc,iec
wrk1(i,j,k) = Grd%tmask(i,j,k) &
*(Dens%drhodT(i,j,k)*temp_wrk(i,j,k) &
+Dens%drhodS(i,j,k)*salt_wrk(i,j,k))
enddo
enddo
enddo
used = send_data (id_neutral_rho_calvingmix, wrk1(:,:,:),&
Time%model_time,rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
if (id_wdian_rho_calvingmix > 0) then
wrk1(:,:,:) = 0.0
do k=1,nk
do j=jsc,jec
do i=isc,iec
temporary = Dens%drhodz_zt(i,j,k)*Thickness%rho_dzt(i,j,k,tau)
wrk1(i,j,k) = Grd%tmask(i,j,k) &
*(Dens%drhodT(i,j,k)*temp_wrk(i,j,k) &
+Dens%drhodS(i,j,k)*salt_wrk(i,j,k)) &
/(epsln+temporary)
enddo
enddo
enddo
used = send_data (id_wdian_rho_calvingmix, wrk1(:,:,:),&
Time%model_time,rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
! river=runoff+calving
elseif(mix_type==3) then
if (id_neutral_rho_rivermix > 0) then
wrk1(:,:,:) = 0.0
do k=1,nk
do j=jsc,jec
do i=isc,iec
wrk1(i,j,k) = Grd%tmask(i,j,k) &
*(Dens%drhodT(i,j,k)*temp_wrk(i,j,k) &
+Dens%drhodS(i,j,k)*salt_wrk(i,j,k))
enddo
enddo
enddo
used = send_data (id_neutral_rho_rivermix, wrk1(:,:,:),&
Time%model_time,rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
if (id_wdian_rho_rivermix > 0) then
wrk1(:,:,:) = 0.0
do k=1,nk
do j=jsc,jec
do i=isc,iec
temporary = Dens%drhodz_zt(i,j,k)*Thickness%rho_dzt(i,j,k,tau)
wrk1(i,j,k) = Grd%tmask(i,j,k) &
*(Dens%drhodT(i,j,k)*temp_wrk(i,j,k) &
+Dens%drhodS(i,j,k)*salt_wrk(i,j,k)) &
/(epsln+temporary)
enddo
enddo
enddo
used = send_data (id_wdian_rho_rivermix, wrk1(:,:,:), &
Time%model_time,rmask=Grd%tmask(:,:,:), &
is_in=isc, js_in=jsc, ks_in=1, ie_in=iec, je_in=jec, ke_in=nk)
endif
endif
end subroutine river_diagnostics
! NAME="river_diagnostics"
end module ocean_rivermix_mod