PUBLIC ROUTINES
==========================================================================
subroutine gcm_vert_diff_init(Tri_surf, idim, jdim, kdim, &
conserve_energy,
use_virtual_temp_vert_diff,
do_mcm_plev)
integer, intent(in) :: idim, jdim, kdim
the three "global" dimensions of the fields to be diffused,
with kdim being the number of vertical levels;
"global" refers to the entire field residing on a processor
type(surf_diff_type), intent(inout) :: Tri_surf
where data needed outside of module is stored
logical, intent(in) :: conserve_energy
.true. => kinetic energy that is lost due to vertical diffusion
is returned as heat in the temperature tendency so as to
conserve energy
logical, intent(in) :: use_virtual_temp_vert_diff
logical, intent(in) :: do_mcm_plev
==========================================================================
subroutine gcm_vert_diff_end()
no arguments
==========================================================================
subroutine vert_diff(delt, xi, t, q, diff, p_half, z_full, &
flux, dflux_datmos, factor, dt_xi, kbot)
input:
delt -- real
time step , seconds
if using leapfrog step, set equal to 2*dt = time(i+1) - time(i-1)
xi -- real, dimension(:,:,:)
field to be diffused,
at time step i for two-time level schemes
at time step i-1 for three-time level (leapfrog) schemes
units up to user
t -- real, dimension(:,:,:)
temperature ( degrees K)
used only for computation of density
shape must conform to that of xi
q -- real, dimension(:,:,:)
specific humidity (dimensionless)
used only for computation of density
shape must conform to that of xi
(set = 0 to ignore effects of vapor on density)
diff -- real, dimension(:,:,:)
kinematic diffusivity (m*2/s)
shape must conform to that of xi
diff(:,:,k) is the diffusivity evaluated at the interface
between the k-1 and k levels
the value diff(:,:,1) is not used
p_half -- real, dimension(:,:,:)
pressure at interface between model levels
size(p_half,3) must = 1 + size(xi,3)
units = Pascals
z_full -- real, dimension(:,:,:)
height of the level where xi is defined
shape must conform to that of xi
units = meters
factor -- real
used if one wants to modify the units of the flux input
The units for flux are [factor]*[xi]*kg/(m**2 s)
where [xi} is the unit for the field xi
Thus, if xi = temperature in K, and if you want to input the
flux in W/(m**2) set factor = heat capacity per unit mass
in (J/(kg K))
dflux_datmos -- real, dimension(:,:)
shape must conform to first two dimensions of xi.
Set = 0.0 if the surface flux is treated explicitly.
If dependence of flux on lowest level of atmosphere is
treated implicitly, set equal to derivative of flux
with respect to value of xi in lowest model layer.
Units = [factor]*kg/(m**2 s)
input/output:
flux -- real, dimension(:,:)
Surface flux (positive upwards)
shape must conform to first two dimensions of xi
Units = [factor]*[xi]*kg/(m**2 s)
Flux should be evaluated with atmospheric fields
from time i for two-time level schemes
from time i-1 for leapgrog
If dflux_datmos is non-zero, input flux is modified by
the implicit correction
flux(i+1) = flux(i or i-1) + delt*dflux_datmos*dt_xi(:,:,N)
where dt_xi is the final (output) tendency and
N = size(dt_xi,3) is the lowest model level
dt_xi -- real, dimension(:,:,:)
Tendency of xi
shape must conform to that of xi
input is the tendency due to all other processes
that have been added prior to this call
output will be the tendency modified by the effects of diffusion
Because the algorithm is implicit, the final tendency
depends on which other processes contribute to
the tendency before, and which after, this call
optional input:
kbot -- integer,dimension(:,:)
shape must conform to first two dimensions of xi
For use with models in which different columns
have different number of levels above the surface.
The levels k <= kbot are assumed to be above the surface.
If kbot is present, the module will function properly
if diff = 0 for levels below the surface. Also, to avoid
division by zero, be sure that the underground
input temperatures are non-zero and that the pressure
thicknesses of the underground layers are non-zero as well.
==========================================================================
subroutine gcm_vert_diff(delt, u, v, t, q, tr, diff_m, diff_t, &
p_half, z_full, &
dtau_datmos, dsens_datmos, devap_datmos, &
sens, evap, tau_u, tau_v, flux_tr, &
dt_u, dt_v, dt_t, dt_q, dt_tr, dissipative_heat, &
kbot)
input:
delt -- real
time step , seconds
if using leapfrog step, set equal to 2*dt = time(i+1) - time(i-1)
u -- real, dimension(:,:,:) zonal wind (m/sec)
v -- real, dimension(:,:,:) meridional wind (m/sec)
T -- real, dimension(:,:,:) temperature (K)
q -- real, dimension(:,:,:) specific humidity
(non-dimensional -- Kg water/Kg air)
tr -- real, dimension(:,:,:,:) tracers
(units arbitrary)
size(tr,4) = number of tracers
fields to be diffused,
at time step i for two-time level schemes
at time step i-1 for three-time level (leapfrog) schemes
(t and q also used to compute density)
diff_m -- real, dimension(:,:,:)
kinematic diffusivity for momentum (m*2/s)
diff_t -- real, dimension(:,:,:)
kinematic diffusivity for heat, water vapor, tracers (m*2/s)
shape must conform to those of u, v, t, q
diff_m(:,:,k) and dsiff_t(:,:,k) are the diffusivities
evaluated at the interface between the k-1 and k levels
the values diff_m(:,:,1) and diff_m(:,:,1) are not used
p_half -- real, dimension(:,:,:)
pressure at interface between model levels
size(p_half,3) must = 1 + size(t,3)
units = Pascals
z_full -- real, dimension(:,:,:)
height of the levels where t, q, u, v, tr are defined
shape must conform to that of xi
units = meters
dtau_datmos -- real, dimension(:,:)
dsens_datmos -- real, dimension(:,:)
devap_datmos -- real, dimension(:,:)
shape must conform to first two dimensions of input fields
Set = 0.0 if the surface flux is treated explicitly
If dependence of flux on lowest level of atmosphere is
treated implicitly, set
dtau_datmos = derivative of surface stress with respect to
wind component in lowest model layer.
Units = kg/(m**2 s)
dsens_datmos = derivative of surface sensible heat flux
with respect to temperature in lowest model layer.
Units = W/(m**2 K)
devap_datmos = derivative of surface flux of water vapor
with respect to specific humidity in lowest model layer.
Units = kg/(m**2 s)
input/output:
sens, evap, tau_u, tau_v -- real, dimension(:,:)
Surface fluxes (positive upwards)
shape must conform to first two dimensions of input fields
Units: sens : W/(m**2) = J /(m**2 s)
evap : Kg/(m**2 s)
tau_u : Kg/(m s**2) = (Kg m/s)/(m**2 s)
= (Kg/(m**3))((m/s)**2) = Pascals
tau_v : as above
Flux should be evaluated with atmospheric fields
from time i for two-time level schemes
from time i-1 for leapgrog
If dflux_datmos is non-zero, input flux is modified by
the implicit correction to be
flux(i+1) = flux(i or i-1) + delt*dflux_datmos*dt_xi(:,:,N)
where dt_xi is the final (output) tendency and
N is the lowest model level
flux_tr -- real, dimension(:,:,:)
with size(flux,tr_3) = number of tracers
(although listed as inout, the implicit treatment of
tracer fluxes is not implemented here, so the
ouput tracer flux will be identical to the input flux
dt_u, dt_v, dt_t, dt_q -- real, dimension(:,:,:)
Tendency of u, v, t, q
shape must conform to that of u, v etc
input is the tendency due to all other processes
that have been added prior to this call
output will be the tendency modified by the effects of diffusion
Because the algorithm is implicit, the final tendency
depends on which other processes have contributed to
the tendency before, and which after, this call
Units of dt_xi are [xi]/s where [xi] are units of xi
dt_tr -- real, dimension(:,:,:,:)
Tracer tendency (see above) size(dt_tr,4) = number of tracers
output:
dissipative_heat -- real, dimension(:,:,:)
shape must conform to that of u, v, t, etc
units: deg_K/s
(computed when do_conserve_energy = .true.
and added to dt_t before temperature is diffused)
optional input:
kbot -- integer,dimension(:,:)
shape must conform to first two dimensions of xi
For use with models in which different columns
have different number of levels above the surface.
The levels k <= kbot are assumed to be above the surface.
If kbot is present, the interface will function properly
if diff = 0 for levels below the surface. Also, to avoid
division by zero, be sure that the underground
input temperatures are non-zero and that the pressure
thicknesses of the underground layers are non-zero as well.
==========================================================================
type surf_diff_type
a public type used to store data needed by the
multi-step version of the diffusion algorithm
real, pointer, dimension(:,:) :: dtmass, &
dflux_t, &
dflux_q, &
delta_t, &
delta_q
for full description of these fields, and the rationale for
saving these particular fields,
see vert_diff.tech.ps
dtmass = dt/mass, where dt = atmospheric time step (sec)
((i+1)-(i-1), not (i+1)-i, if atmos model is leapfrog)
mass = mass of lowest atmospheric layer (Kg/m2)
(defined in gcm_vert_diff_down -- not used elsewhere)
dflux_t = derivative of the temperature flux at the top of the lowest
atmospheric layer with respect to the temperature
of that layer (J/(m2 K))
(defined in gcm_vert_diff_down -- not used elsewhere)
dflux_q = derivative of the flux of specific humidity
at the top of the lowest atmospheric layer with respect to
the specific humidity of that layer (--/(m2 K))
(defined in gcm_vert_diff_down -- not used elsewhere)
delta_t = the increment in temperature in the lowest atmospheric
layer (((i+1)-(i-1) if atmos model is leapfrog) (K)
(defined in gcm_vert_diff_down as the increment computed up
to this point in model, including effect of vertical
diffusive flux at top of lowest model level, presumed
to be modified to include effects of surface fluxes
outside of this module, then used to start upward
tridiagonal sweep,
see vert_diff.tech.ps
delta_q = similarly for the increment in specific humidity
(non-dimensional = Kg/Kg)
==========================================================================
subroutine gcm_vert_diff_down (is, js, delt, &
u, v, t, q, tr, &
diff_m, diff_t, p_half, p_full, z_full, &
tau_u, tau_v, dtau_datmos, &
flux_tr, &
dt_u, dt_v, dt_t, dt_q, dt_tr, &
dissipative_heat, Tri_surf, &
kbot)
input:
is, js -- integers
the location in the global lon-lat grid of the rectangular
domain on which diffusion is to be performed
the size of the domain is determined by the size ofthe input
i.e, longitude index ranges from is to is + size(t,1) -1
latitude index ranges from js to js + size(t,2) -1
delt -- real
time step , seconds
if using leapfrog step, set equal to 2*dt = time(i+1) - time(i-1)
u -- real, dimension(:,:,:) zonal wind (m/sec)
v -- real, dimension(:,:,:) meridional wind (m/sec)
T -- real, dimension(:,:,:) temperature (K)
q -- real, dimension(:,:,:) specific humidity
(non-dimensional -- Kg water/Kg air)
tr -- real, dimension(:,:,:,:) tracers
(units arbitrary)
size(tr,4) = number of tracers
input fields to be diffused,
values at time step i for two-time level schemes
at time step i-1 for three-time level (leapfrog) schemes
(t and q also used to compute density)
diff_m -- real, dimension(:,:,:)
kinematic diffusivity for momentum (m*2/s)
diff_t -- real, dimension(:,:,:)
kinematic diffusivity for heat, water vapor, tracers (m*2/s)
shape must conform to those of u, v, t, q
diff_m(:,:,k) and dsiff_t(:,:,k) are the diffusivities
evaluated at the interface between the k-1 and k levels
the values diff_m(:,:,1) and diff_m(:,:,1) are not used
p_half -- real, dimension(:,:,:)
pressure at interface between model levels
size(p_half,3) must = 1 + size(t,3)
units = Pascals
p_full -- real, dimension(:,:,:)
pressure at full model levels
size(p_half,3) must = size(t,3)
units = Pascals
z_full -- real, dimension(:,:,:)
height of the levels where t, q, u, v, tr are defined
shape must conform to that of xi
units = meters
dtau_datmos -- real, dimension(:,:)
shape must conform to first two dimensions of input fields
Set = 0.0 if the surface flux is treated explicitly. If
dependence of flux on lowest level of atmosphere is
treated implicitly, set = derivative of surface stress
with respect to wind component in lowest model layer.
Units = kg/(m**2 s)
dt_t, dt_q -- real, dimension(:,:,:)
Tendency of t, q up to this point
(The final value of dt_t and dt_q are output by
gcm_vert_diff_up)
Units are [xi]/s where [xi] = [T], [q]
input/output:
tau_u, tau_v -- real, dimension(:,:)
Surface stresses (positive upwards)
shape must conform to first two dimensions of input fields
Units: Kg/(m s**2) = (Kg m/s)/(m**2 s)
= (Kg/(m**3))((m/s)**2) = Pascals
Flux should be evaluated at time i for two-time level schemes
and at time i-1 for leapgrog
If dtau_datmos is non-zero, input stress is modified by
the implicit correction
tau_u(i+1) = tau_u(i or i-1) + delt*dtau_datmos*dt_u(:,:,N)
where dt_u is the final (output) tendency and
N is the lowest model level; similarly for tau_v
flux_tr -- real, dimension(:,:,:)
with size(flux,tr_3) = number of tracers
(although listed as inout, the implicit treatment of
tracer fluxes is not implemented here, so the
ouput tracer flux will be identical to the input flux
dt_u, dt_v, -- real, dimension(:,:,:)
Tendency of u and v
shape must conform to that of u, v etc
input is the tendency due to all other processes
that have been added prior to this call
output will be the tendency modified by the
effects of diffusion
Units are [xi]/s where [xi] = [u], [v] etc
dt_tr -- real, dimension(:,:,:,:)
Tracer tendency (see above) size(dt_tr,4) = number of tracer
Tri_surf -- type(surf_diff_type)
information needed to pass
=> surface modules => gcm_vert_diff_up
output:
dissipative_heat -- real, dimension(:,:,:)
shape must conform to that of u, v, t, etc
units: deg_K/s
(computed when do_conserve_energy = .true.
and added to dt_t before temperature is diffused)
optional input:
kbot -- integer,dimension(:,:)
shape must conform to first two dimensions of xi
For use with models in which different columns
have different number of levels above the surface.
The levels k <= kbot are assumed to be above the surface.
If kbot is present, the interface will function properly
if diff = 0 for levels below the surface. Also, to avoid
division by zero, be sure that the underground
input temperatures are non-zero and that the pressure
thicknesses of the underground layers are non-zero as well.
==========================================================================
subroutine gcm_vert_diff_up (is, js, delt, Tri_surf, dt_t, dt_q, kbot)
input:
is, js -- integers
the location in the global lon-lat grid of the rectangular
domain on which diffusion is to be performed
the size of the domain is determined by the size ofthe input
i.e, longitude index ranges from is to is + size(dt_t,1) -1
latitude index ranges from js to js + size(dt_t,2) -1
delt -- real
time step , seconds
if using leapfrog step, set equal to 2*dt = time(i+1) - time(i-1)
Tri_surf -- type(surf_diff_type)
information passed from information
surface modules and gcm_vert_diff_down
dt_t, dt_q -- real, dimension(:,:,:)
The tendencies modified by the effects of diffusion
Because the algorithm is implicit, the final tendency
depends on which other processes have contributed to
the tendency before, and which after, this call
Units of dt_xi are [xi]/s where [xi] are units of xi
optional input:
kbot -- integer,dimension(:,:)
shape must conform to first two dimensions of xi
For use with models in which different columns
have different number of levels above the surface.
The levels k <= kbot are assumed to be above the surface.
If kbot is present, the interface will function properly
if diff = 0 for levels below the surface. Also, to avoid
division by zero, be sure that the underground
input temperatures are non-zero and that the pressure
thicknesses of the underground layers are non-zero as well.
==========================================================================
subroutine gcm_vert_diff_end