GFDL - Geophysical Fluid Dynamics Laboratory

module barotropic_dynamics_mod

Contact: Isaac Held

Reviewers: Peter Phillipps


The dynamical core of the spectral transform model for two-dimensional, non-divergent
flow on the surface of the sphere.


Integrates the barotropic vorticity equation for nondivergent flow on the sphere
using the spectral transform technique. Also allows for the inclusion of a passive
tracer advected by the same spectral advection algorithm as the vorticity, and a
gridpoint tracer advected with a finite volume algorithm on the transform grid.
The default initial condition provided as an example is a zonal flow resembling
that in the Northern winter, plus a sinusoidal disturbance localized in midlatitudes.
For a full description of the model and algorithms used, see
barotropic.pdf For higher level routines for running
this barotropic spectral model, see atmosphere_mod


  • fms_mod
  • constants_mod
  • time_manager_mod
  • transforms_mod
  • spectral_damping_mod
  • leapfrog_mod
  • fv_advection_mod


  use barotropic_dynamics_mod [,only: barotropic_dynamics_init,       


type grid_type
   real, pointer, dimension(:,:,:) :: u, v, vor, trs, tr, pv
   real, pointer, dimension(:,:)   :: stream
end type

   allocated space for grid fields

   (:,:,:) => (lon, lat, time_level)
   (:,:)   => (lon, lat)
      (lon, lat) on local computational domain
      time_level stores the two time levels needed for the
          leapfrog step
   u      -- eastward velocity (m/s)
   v      -- northward velocity (m/s)
   vor    -- vorticity (1/s)
   trs    -- tracer advected spectrally
   tr     -- tracer advected on grid
   pv     -- absolute vorticity, f + vor, where f = 2*omega*sin(lat) (1/s)
   stream -- streamfunction (m^2/s) at current time

type spectral_type
   complex, pointer, dimension(:,:,:) :: vor, trs
end type

   allocated space for spectral fields
      (:,:,:) => (zonal, meridional, time_level)

   vor -- spectral vorticity
   trs -- spectral tracer

type tendency_type
    real, pointer, dimension(:,:) :: u, v, trs, tr
end type

   allocated space for accumulating tendencies, d/dt, in grid space, 
           for prognostic variables
      (:,:,:) => (lon, lat)

type dynamics_type
   type(grid_type)     :: grid
   type(spectral_type) :: spec
   type(tendency_type) :: tend
   integer             :: num_lon, num_lat  ! size of global domain
   logical             :: grid_tracer, spec_tracer 
end type

   grid_tracer = .true. => tracer with gridpoint advection is beign integrated
   similarly for spec_tracer


subroutine  barotropic_dynamics_init
subroutine barotropic _dynamics
subroutine barotropic_dynamics_end
type (grid_type)
type (spectral_type)
type (tendency_type)
type (dynamics_type)
 subroutine barotropic_dynamics_init(Dyn,  Time, Time_init)
   type(dynamics_type), intent(inout)  :: Dyn
         type containing all dynamical fields and related information
	 (see type (dynamics_type))
type(time_type) , intent(in) :: Time, Time_init
current time and time at which integeration began
time_type defined by time_manager_mod
Initializes the module;
Reads restart from 'INPUT/barotropic_dynamics.res' if Time = Time_init;
otherwise uses default initial conditions

  subroutine barotropic_dynamics &
     (Time, Time_init, Dyn, previous, current, future, delta_t)
     type(time_type)    , intent(inout)  :: Time, Time_init
     type(dynamics_type), intent(inout)  :: Dyn
     integer            , intent(in   )  :: previous, current, future
     real               , intent(in   )  :: delta_t
     previous, current and future = 1 or 2
       these integers refer to the third dimension of the 
         three-dimensional fields in Dyn
       the fields at time t - delta_t are assumed to be in (:,:,previous)
       the fields at time t           are assumed to be in (:,:,current)
       the fields at time t + delta_t are placed        in (:,:,future)
          overwriting whatever is already there

     delta_t = time step in seconds
     updates dynamical fields by one time step

   subroutine barotropic_dynamics_end(Dyn, previous, current)
     type(dynamics_type), intent(inout)  :: Dyn
     integer, intent(in) :: previous, current
    Terminates module; 
     writes restart file to 'RESTART/barotropic_dynamics.res'


integer :: num_lat = 128 number of latitudes in global grid
integer :: num_lon = 256 number of longitudes in global grid should equal 2*num_lat for Triangular truncation
integer :: num_fourier = 85 the retained fourier wavenumber are n*fourier_inc, where n ranges from 0 to num_fourier
integer :: num_spherical = 86 the maximum number of meridional modes for any zonal wavenumber for triangular truncation, set num_spherical = num_fourier +1
integer :: fourier_inc = 1 creates a "sector" model if fourier_inc > 1; integration domain is (360 degrees longitude)/fourier_inc (the default values for num_lat, num_lon, num_fourier and num_spherical define a standard T85 resolution)
logical :: check_fourier_imag = .false. if true, checks to see if fields to be transformed to grid domain have zero imaginary part to their zonally symmetric modes; useful for debugging
logical :: south_to_north = .true. true => grid runs from south to north false => grid runs from north to south
logical :: triangular_trunc = .true. true => shape of truncation is triangular false => shape of truncation is rhomboidal
real :: robert_coeff = 0.04 x(current) => (1-2r)*x(current) + r*(x(future)+x(previous)) where r = robert_coeff (non-dimensional)
real :: longitude_origin = 0.0 longitude of first longitude, in degrees (if you want the western boundary of first grid box to be at 0.0, set longitude_origin = 0.5*360./float(num_lon))
character :: damping_option = 'resolution_dependent' integer :: damping_order = 4 real :: damping_coeff = 1.e-04 damping = nu*(del^2)^n where n = damping order damping_option = 'resolution_dependent' or 'resolution_independent' = 'resolution_dependent' => nu is set so that the damping rate for the mode (m=0,n=num_spherical-1) equals damping_coeff (in 1/s) For triangular truncation, damping_coeff is then the rate of damping of the highest retained mode = 'resolution_independent' => nu = damping_coef
real :: zeta_0 = 8.e-05 (1/sec) integer :: m_0 = 4 real :: eddy_width = 15.0 (degrees longitude) real :: eddy_lat = 45.0 (degrees latitude) eddy component of the initial condition is sinusoidal with wavenumber m_0 and with a gaussian distribution of vorticity in latitude, centered at eddy_lat with half-width logical :: spec_tracer = .true. logical :: grid_tracer = .true. spec_tracer = true => a passive tracer is carried that is advected spectrally, with the same algorithm as the vorticity grid_tracer = true => a passive tracer is carried that is advected on the spectral transform grid by a finite-volume algorithm Both tracers can be carried simultaeneously. The vorticity and the tracers are initialized within subroutine barotropic_dynamics_init
real, dimension(2) :: valid_range_v = -1000., 1000. A valid range for meridional wind. Model terminates if meridional wind goes outside the valid range. Allows model to terminate gracefully when, for example, the model becomes numerically unstable.
character :: initial_zonal_wind = 'two_jets' initial_zonal_wind = 'two_jets' => A jet in each hemisphere centered near 30 deg latitude initial_zonal_wind = 'zero' => Zero zonal wind


   "Dynamics has not been initialized"
      -- barotropic_dynamics_init must be called before any other
         routines in the module are called
   "restart does not exist" 
      -- Time is not equal to Time_init at initalization, but the file
          'INPUT/barotropic_dynamics.res' does not exit