MOM6
Rossby_front_2d_initialization.F90
1 !> Initial conditions for the 2D Rossby front test
3 
4 ! This file is part of MOM6. See LICENSE.md for the license.
5 
6 use mom_error_handler, only : mom_mesg, mom_error, fatal, is_root_pe
8 use mom_get_input, only : directories
9 use mom_grid, only : ocean_grid_type
14 use regrid_consts, only : coordinatemode, default_coordinate_mode
15 use regrid_consts, only : regridding_layer, regridding_zstar
16 use regrid_consts, only : regridding_rho, regridding_sigma
17 
18 implicit none ; private
19 
20 #include <MOM_memory.h>
21 
22 ! Private (module-wise) parameters
23 character(len=40) :: mdl = "Rossby_front_2d_initialization" !< This module's name.
24 ! This include declares and sets the variable "version".
25 #include "version_variable.h"
26 
27 public rossby_front_initialize_thickness
28 public rossby_front_initialize_temperature_salinity
29 public rossby_front_initialize_velocity
30 
31 ! Parameters defining the initial conditions of this test case
32 real, parameter :: frontfractionalwidth = 0.5 !< Width of front as fraction of domain [nondim]
33 real, parameter :: hmlmin = 0.25 !< Shallowest ML as fractional depth of ocean [nondim]
34 real, parameter :: hmlmax = 0.75 !< Deepest ML as fractional depth of ocean [nondim]
35 
36 contains
37 
38 !> Initialization of thicknesses in 2D Rossby front test
39 subroutine rossby_front_initialize_thickness(h, G, GV, param_file, just_read_params)
40  type(ocean_grid_type), intent(in) :: g !< Grid structure
41  type(verticalgrid_type), intent(in) :: gv !< Vertical grid structure
42  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
43  intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2]
44  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
45  !! to parse for model parameter values.
46  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
47  !! only read parameters without changing h.
48 
49  integer :: i, j, k, is, ie, js, je, nz
50  real :: tz, dml, eta, stretch, h0
51  real :: min_thickness, t_range, drho_dt
52  logical :: just_read ! If true, just read parameters but set nothing.
53  character(len=40) :: verticalcoordinate
54 
55  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
56 
57  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
58 
59  if (.not.just_read) &
60  call mom_mesg("Rossby_front_2d_initialization.F90, Rossby_front_initialize_thickness: setting thickness")
61 
62  if (.not.just_read) call log_version(param_file, mdl, version, "")
63  ! Read parameters needed to set thickness
64  call get_param(param_file, mdl, "MIN_THICKNESS", min_thickness, &
65  'Minimum layer thickness',units='m',default=1.e-3, do_not_log=just_read)
66  call get_param(param_file, mdl, "REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
67  default=default_coordinate_mode, do_not_log=just_read)
68  call get_param(param_file, mdl, "T_RANGE", t_range, 'Initial temperature range', &
69  units='C', default=0.0, do_not_log=just_read)
70  call get_param(param_file, mdl, "DRHO_DT", drho_dt, default=-0.2, do_not_log=.true.)
71 
72  if (just_read) return ! All run-time parameters have been read, so return.
73 
74  tz = t_range / g%max_depth
75 
76  select case ( coordinatemode(verticalcoordinate) )
77 
78  case (regridding_layer, regridding_rho)
79  do j = g%jsc,g%jec ; do i = g%isc,g%iec
80  dml = hml( g, g%geoLatT(i,j) )
81  eta = -( -drho_dt / gv%Rho0 ) * tz * 0.5 * ( dml * dml )
82  stretch = ( ( g%max_depth + eta ) / g%max_depth )
83  h0 = ( g%max_depth / real(nz) ) * stretch
84  do k = 1, nz
85  h(i,j,k) = h0 * gv%Z_to_H
86  enddo
87  enddo ; enddo
88 
89  case (regridding_zstar, regridding_sigma)
90  do j = g%jsc,g%jec ; do i = g%isc,g%iec
91  dml = hml( g, g%geoLatT(i,j) )
92  eta = -( -drho_dt / gv%Rho0 ) * tz * 0.5 * ( dml * dml )
93  stretch = ( ( g%max_depth + eta ) / g%max_depth )
94  h0 = ( g%max_depth / real(nz) ) * stretch
95  do k = 1, nz
96  h(i,j,k) = h0 * gv%Z_to_H
97  enddo
98  enddo ; enddo
99 
100  case default
101  call mom_error(fatal,"Rossby_front_initialize: "// &
102  "Unrecognized i.c. setup - set REGRIDDING_COORDINATE_MODE")
103 
104  end select
105 
106 end subroutine rossby_front_initialize_thickness
107 
108 
109 !> Initialization of temperature and salinity in the Rossby front test
110 subroutine rossby_front_initialize_temperature_salinity(T, S, h, G, GV, &
111  param_file, eqn_of_state, just_read_params)
112  type(ocean_grid_type), intent(in) :: g !< Grid structure
113  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
114  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: t !< Potential temperature [degC]
115  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: s !< Salinity [ppt]
116  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Thickness [H ~> m or kg m-2]
117  type(param_file_type), intent(in) :: param_file !< Parameter file handle
118  type(eos_type), pointer :: eqn_of_state !< Equation of state structure
119  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
120  !! only read parameters without changing T & S.
121 
122  integer :: i, j, k, is, ie, js, je, nz
123  real :: t_ref, s_ref ! Reference salinity and temerature within surface layer
124  real :: t_range ! Range of salinities and temperatures over the vertical
125  real :: y, zc, zi, dtdz
126  logical :: just_read ! If true, just read parameters but set nothing.
127  character(len=40) :: verticalcoordinate
128  real :: pi ! 3.1415926... calculated as 4*atan(1)
129 
130  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
131 
132  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
133 
134  call get_param(param_file, mdl,"REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
135  default=default_coordinate_mode, do_not_log=just_read)
136  call get_param(param_file, mdl,"S_REF",s_ref,'Reference salinity', units='1e-3', &
137  fail_if_missing=.not.just_read, do_not_log=just_read)
138  call get_param(param_file, mdl,"T_REF",t_ref,'Reference temperature',units='C',&
139  fail_if_missing=.not.just_read, do_not_log=just_read)
140  call get_param(param_file, mdl,"T_RANGE",t_range,'Initial temperature range',&
141  units='C', default=0.0, do_not_log=just_read)
142 
143  if (just_read) return ! All run-time parameters have been read, so return.
144 
145  t(:,:,:) = 0.0
146  s(:,:,:) = s_ref
147  dtdz = t_range / g%max_depth
148 
149  do j = g%jsc,g%jec ; do i = g%isc,g%iec
150  zi = 0.
151  do k = 1, nz
152  zi = zi - h(i,j,k) ! Bottom interface position
153  zc = gv%H_to_Z * (zi - 0.5*h(i,j,k)) ! Position of middle of cell
154  zc = min( zc, -hml(g, g%geoLatT(i,j)) ) ! Bound by depth of mixed layer
155  t(i,j,k) = t_ref + dtdz * zc ! Linear temperature profile
156  enddo
157  enddo ; enddo
158 
159 end subroutine rossby_front_initialize_temperature_salinity
160 
161 
162 !> Initialization of u and v in the Rossby front test
163 subroutine rossby_front_initialize_velocity(u, v, h, G, GV, US, param_file, just_read_params)
164  type(ocean_grid_type), intent(in) :: g !< Grid structure
165  type(verticalgrid_type), intent(in) :: gv !< Vertical grid structure
166  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
167  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
168  intent(out) :: u !< i-component of velocity [m s-1]
169  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
170  intent(out) :: v !< j-component of velocity [m s-1]
171  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), &
172  intent(in) :: h !< Thickness [H ~> m or kg m-2]
173  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
174  !! to parse for model parameter values.
175  logical, optional, intent(in) :: just_read_params !< If present and true, this call
176  !! will only read parameters without setting u & v.
177 
178  real :: y ! Non-dimensional coordinate across channel, 0..pi
179  real :: t_range ! Range of salinities and temperatures over the vertical
180  real :: dudt ! Factor to convert dT/dy into dU/dz, g*alpha/f [L2 Z-1 T-1 degC-1 ~> m s-1 degC-1]
181  real :: drho_dt
182  real :: dml, zi, zc, zm ! Depths [Z ~> m].
183  real :: f ! The local Coriolis parameter [T-1 ~> s-1]
184  real :: ty ! The meridional temperature gradient [degC L-1 ~> degC m-1]
185  real :: hatu ! Interpolated layer thickness [Z ~> m].
186  integer :: i, j, k, is, ie, js, je, nz
187  logical :: just_read ! If true, just read parameters but set nothing.
188  character(len=40) :: verticalcoordinate
189 
190  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
191 
192  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
193 
194  call get_param(param_file, mdl, "REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
195  default=default_coordinate_mode, do_not_log=just_read)
196  call get_param(param_file, mdl, "T_RANGE", t_range, 'Initial temperature range', &
197  units='C', default=0.0, do_not_log=just_read)
198  call get_param(param_file, mdl, "DRHO_DT", drho_dt, default=-0.2, do_not_log=.true.)
199 
200  if (just_read) return ! All run-time parameters have been read, so return.
201 
202  v(:,:,:) = 0.0
203  u(:,:,:) = 0.0
204 
205  do j = g%jsc,g%jec ; do i = g%isc-1,g%iec+1
206  f = 0.5* (g%CoriolisBu(i,j) + g%CoriolisBu(i,j-1) )
207  dudt = 0.0 ; if (abs(f) > 0.0) &
208  dudt = ( gv%g_Earth*drho_dt ) / ( f * gv%Rho0 )
209  dml = hml( g, g%geoLatT(i,j) )
210  ty = us%L_to_m*dtdy( g, t_range, g%geoLatT(i,j) )
211  zi = 0.
212  do k = 1, nz
213  hatu = 0.5*(h(i,j,k)+h(i+1,j,k)) * gv%H_to_Z
214  zi = zi - hatu ! Bottom interface position
215  zc = zi - 0.5*hatu ! Position of middle of cell
216  zm = max( zc + dml, 0. ) ! Height above bottom of mixed layer
217  u(i,j,k) = us%L_T_to_m_s * dudt * ty * zm ! Thermal wind starting at base of ML
218  enddo
219  enddo ; enddo
220 
221 end subroutine rossby_front_initialize_velocity
222 
223 !> Pseudo coordinate across domain used by Hml() and dTdy()
224 !! returns a coordinate from -PI/2 .. PI/2 squashed towards the
225 !! center of the domain.
226 real function ypseudo( G, lat )
227  type(ocean_grid_type), intent(in) :: g !< Grid structure
228  real, intent(in) :: lat !< Latitude
229  ! Local
230  real :: y, pi
231 
232  pi = 4.0 * atan(1.0)
233  ypseudo = ( ( lat - g%south_lat ) / g%len_lat ) - 0.5 ! -1/2 .. 1/.2
234  ypseudo = pi * max(-0.5, min(0.5, ypseudo / frontfractionalwidth))
235 end function ypseudo
236 
237 
238 !> Analytic prescription of mixed layer depth in 2d Rossby front test,
239 !! in the same units as G%max_depth
240 real function hml( G, lat )
241  type(ocean_grid_type), intent(in) :: g !< Grid structure
242  real, intent(in) :: lat !< Latitude
243  ! Local
244  real :: dhml, hmlmean
245 
246  dhml = 0.5 * ( hmlmax - hmlmin ) * g%max_depth
247  hmlmean = 0.5 * ( hmlmin + hmlmax ) * g%max_depth
248  hml = hmlmean + dhml * sin( ypseudo(g, lat) )
249 end function hml
250 
251 
252 !> Analytic prescription of mixed layer temperature gradient in 2d Rossby front test
253 real function dtdy( G, dT, lat )
254  type(ocean_grid_type), intent(in) :: g !< Grid structure
255  real, intent(in) :: dt !< Top to bottom temperature difference
256  real, intent(in) :: lat !< Latitude
257  ! Local
258  real :: pi, dhml, dhdy
259  real :: km = 1.e3 ! AXIS_UNITS = 'k' (1000 m)
260 
261  pi = 4.0 * atan(1.0)
262  dhml = 0.5 * ( hmlmax - hmlmin ) * g%max_depth
263  dhdy = dhml * ( pi / ( frontfractionalwidth * g%len_lat * km ) ) * cos( ypseudo(g, lat) )
264  dtdy = -( dt / g%max_depth ) * dhdy
265 
266 end function dtdy
267 
268 
269 !> \namespace rossby_front_2d_initialization
270 !!
271 !! \section section_Rossby_front_2d Description of the 2d Rossby front initial conditions
272 !!
273 !! Consistent with a linear equation of state, the system has a constant stratification
274 !! below the mixed layer, stratified in temperature only. Isotherms are flat below the
275 !! mixed layer and vertical within. Salinity is constant. The mixed layer has a half sine
276 !! form so that there are no mixed layer or temperature gradients at the side walls.
277 !!
278 !! Below the mixed layer the potential temperature, \f$\theta(z)\f$, is given by
279 !! \f[ \theta(z) = \theta_0 - \Delta \theta \left( z + h_{ML} \right) \f]
280 !! where \f$ \theta_0 \f$ and \f$ \Delta \theta \f$ are external model parameters.
281 !!
282 !! The depth of the mixed layer, \f$H_{ML}\f$ is
283 !! \f[ h_{ML}(y) = h_{min} + \left( h_{max} - h_{min} \right) \cos{\pi y/L} \f].
284 !! The temperature in mixed layer is given by the reference temperature at \f$z=h_{ML}\f$
285 !! so that
286 !! \f[ \theta(y,z) =
287 !! \theta_0 - \Delta \theta \left( z + h_{ML} \right) & \forall & z < h_{ML}(y) T.B.D.
288 !! \f]
289 
rossby_front_2d_initialization
Initial conditions for the 2D Rossby front test.
Definition: Rossby_front_2d_initialization.F90:2
mom_verticalgrid
Provides a transparent vertical ocean grid type and supporting routines.
Definition: MOM_verticalGrid.F90:2
mom_file_parser::log_version
An overloaded interface to log version information about modules.
Definition: MOM_file_parser.F90:109
mom_variables::thermo_var_ptrs
Pointers to an assortment of thermodynamic fields that may be available, including potential temperat...
Definition: MOM_variables.F90:82
mom_get_input::directories
Container for paths and parameter file names.
Definition: MOM_get_input.F90:20
mom_eos
Provides subroutines for quantities specific to the equation of state.
Definition: MOM_EOS.F90:2
mom_file_parser::param_file_type
A structure that can be parsed to read and document run-time parameters.
Definition: MOM_file_parser.F90:54
mom_file_parser::get_param
An overloaded interface to read and log the values of various types of parameters.
Definition: MOM_file_parser.F90:102
mom_get_input
Reads the only Fortran name list needed to boot-strap the model.
Definition: MOM_get_input.F90:6
mom_unit_scaling::unit_scale_type
Describes various unit conversion factors.
Definition: MOM_unit_scaling.F90:14
regrid_consts
Contains constants for interpreting input parameters that control regridding.
Definition: regrid_consts.F90:2
mom_eos::eos_type
A control structure for the equation of state.
Definition: MOM_EOS.F90:86
mom_verticalgrid::verticalgrid_type
Describes the vertical ocean grid, including unit conversion factors.
Definition: MOM_verticalGrid.F90:24
mom_variables
Provides transparent structures with groups of MOM6 variables and supporting routines.
Definition: MOM_variables.F90:2
mom_file_parser
The MOM6 facility to parse input files for runtime parameters.
Definition: MOM_file_parser.F90:2
mom_eos::calculate_density_derivs
Calculate the derivatives of density with temperature and salinity from T, S, and P.
Definition: MOM_EOS.F90:70
mom_grid
Provides the ocean grid type.
Definition: MOM_grid.F90:2
mom_unit_scaling
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Definition: MOM_unit_scaling.F90:2
mom_error_handler
Routines for error handling and I/O management.
Definition: MOM_error_handler.F90:2
mom_grid::ocean_grid_type
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:25
mom_eos::calculate_density
Calculates density of sea water from T, S and P.
Definition: MOM_EOS.F90:60