MOM6
dome_initialization Module Reference

Detailed Description

Configures the model for the "DOME" experiment. DOME = Dynamics of Overflows and Mixing Experiment.

Functions/Subroutines

subroutine, public dome_initialize_topography (D, G, param_file, max_depth, US)
 This subroutine sets up the DOME topography. More...
 
subroutine, public dome_initialize_thickness (h, G, GV, param_file, just_read_params)
 This subroutine initializes layer thicknesses for the DOME experiment. More...
 
subroutine, public dome_initialize_sponges (G, GV, US, tv, PF, CSp)
 This subroutine sets the inverse restoration time (Idamp), and ! the values towards which the interface heights and an arbitrary ! number of tracers should be restored within each sponge. The ! interface height is always subject to damping, and must always be ! the first registered field. ! More...
 
subroutine, public dome_set_obc_data (OBC, tv, G, GV, US, param_file, tr_Reg)
 This subroutine sets the properties of flow at open boundary conditions. This particular example is for the DOME inflow describe in Legg et al. 2006. More...
 

Function/Subroutine Documentation

◆ dome_initialize_sponges()

subroutine, public dome_initialization::dome_initialize_sponges ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(thermo_var_ptrs), intent(in)  tv,
type(param_file_type), intent(in)  PF,
type(sponge_cs), pointer  CSp 
)

This subroutine sets the inverse restoration time (Idamp), and ! the values towards which the interface heights and an arbitrary ! number of tracers should be restored within each sponge. The ! interface height is always subject to damping, and must always be ! the first registered field. !

Parameters
[in]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in]usA dimensional unit scaling type
[in]tvA structure containing pointers to any available thermodynamic fields, including potential temperature and salinity or mixed layer density. Absent fields have NULL ptrs.
[in]pfA structure indicating the open file to parse for model parameter values.
cspA pointer that is set to point to the control structure for this module.

Definition at line 148 of file DOME_initialization.F90.

149  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
150  type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
151  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
152  type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any available
153  !! thermodynamic fields, including potential temperature and
154  !! salinity or mixed layer density. Absent fields have NULL ptrs.
155  type(param_file_type), intent(in) :: PF !< A structure indicating the open file to
156  !! parse for model parameter values.
157  type(sponge_CS), pointer :: CSp !< A pointer that is set to point to the control
158  !! structure for this module.
159 
160  real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta [Z ~> m].
161  real :: temp(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for other variables. !
162  real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [T-1 ~> s-1].
163 
164  real :: H0(SZK_(G)) ! Interface heights [Z ~> m].
165  real :: min_depth ! The minimum depth at which to apply damping [Z ~> m]
166  real :: damp, damp_new ! Damping rates in the sponge [days]
167  real :: e_dense ! The depth of the densest interfaces [Z ~> m]
168  character(len=40) :: mdl = "DOME_initialize_sponges" ! This subroutine's name.
169  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
170 
171  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
172  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
173 
174  eta(:,:,:) = 0.0 ; temp(:,:,:) = 0.0 ; idamp(:,:) = 0.0
175 
176 ! Here the inverse damping time [s-1], is set. Set Idamp to 0 !
177 ! wherever there is no sponge, and the subroutines that are called !
178 ! will automatically set up the sponges only where Idamp is positive!
179 ! and mask2dT is 1. !
180 
181 ! Set up sponges for DOME configuration
182  call get_param(pf, mdl, "MINIMUM_DEPTH", min_depth, &
183  "The minimum depth of the ocean.", units="m", default=0.0, scale=us%m_to_Z)
184 
185  h0(1) = 0.0
186  do k=2,nz ; h0(k) = -(real(k-1)-0.5)*g%max_depth / real(nz-1) ; enddo
187  do i=is,ie; do j=js,je
188  if (g%geoLonT(i,j) < 100.0) then ; damp = 10.0
189  elseif (g%geoLonT(i,j) < 200.0) then
190  damp = 10.0 * (200.0-g%geoLonT(i,j))/100.0
191  else ; damp=0.0
192  endif
193 
194  if (g%geoLonT(i,j) > 1400.0) then ; damp_new = 10.0
195  elseif (g%geoLonT(i,j) > 1300.0) then
196  damp_new = 10.0 * (g%geoLonT(i,j)-1300.0)/100.0
197  else ; damp_new = 0.0
198  endif
199 
200  if (damp <= damp_new) damp = damp_new
201  damp = us%T_to_s*damp
202 
203  ! These will be stretched inside of apply_sponge, so they can be in
204  ! depth space for Boussinesq or non-Boussinesq models.
205  eta(i,j,1) = 0.0
206  do k=2,nz
207 ! eta(i,j,K)=max(H0(k), -G%bathyT(i,j), GV%Angstrom_Z*(nz-k+1) - G%bathyT(i,j))
208  e_dense = -g%bathyT(i,j)
209  if (e_dense >= h0(k)) then ; eta(i,j,k) = e_dense
210  else ; eta(i,j,k) = h0(k) ; endif
211  if (eta(i,j,k) < gv%Angstrom_Z*(nz-k+1) - g%bathyT(i,j)) &
212  eta(i,j,k) = gv%Angstrom_Z*(nz-k+1) - g%bathyT(i,j)
213  enddo
214  eta(i,j,nz+1) = -g%bathyT(i,j)
215 
216  if (g%bathyT(i,j) > min_depth) then
217  idamp(i,j) = damp / 86400.0
218  else ; idamp(i,j) = 0.0 ; endif
219  enddo ; enddo
220 
221 ! This call sets up the damping rates and interface heights.
222 ! This sets the inverse damping timescale fields in the sponges. !
223  call initialize_sponge(idamp, eta, g, pf, csp, gv)
224 
225 ! Now register all of the fields which are damped in the sponge. !
226 ! By default, momentum is advected vertically within the sponge, but !
227 ! momentum is typically not damped within the sponge. !
228 
229 ! At this point, the DOME configuration is done. The following are here as a
230 ! template for other configurations.
231 
232 ! The remaining calls to set_up_sponge_field can be in any order. !
233  if ( associated(tv%T) ) then
234  call mom_error(fatal,"DOME_initialize_sponges is not set up for use with"//&
235  " a temperatures defined.")
236  ! This should use the target values of T in temp.
237  call set_up_sponge_field(temp, tv%T, g, nz, csp)
238  ! This should use the target values of S in temp.
239  call set_up_sponge_field(temp, tv%S, g, nz, csp)
240  endif
241 

◆ dome_initialize_thickness()

subroutine, public dome_initialization::dome_initialize_thickness ( real, dimension(szi_(g),szj_(g),szk_(gv)), intent(out)  h,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file,
logical, intent(in), optional  just_read_params 
)

This subroutine initializes layer thicknesses for the DOME experiment.

Parameters
[in]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[out]hThe thickness that is being initialized [H ~> m or kg m-2].
[in]param_fileA structure indicating the open file to parse for model parameter values.
[in]just_read_paramsIf present and true, this call will only read parameters without changing h.

Definition at line 90 of file DOME_initialization.F90.

91  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
92  type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
93  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
94  intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2].
95  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
96  !! to parse for model parameter values.
97  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
98  !! only read parameters without changing h.
99 
100  real :: e0(SZK_(GV)+1) ! The resting interface heights [Z ~> m], usually
101  ! negative because it is positive upward [Z ~> m].
102  real :: eta1D(SZK_(GV)+1) ! Interface height relative to the sea surface
103  ! positive upward [Z ~> m].
104  logical :: just_read ! If true, just read parameters but set nothing.
105  character(len=40) :: mdl = "DOME_initialize_thickness" ! This subroutine's name.
106  integer :: i, j, k, is, ie, js, je, nz
107 
108  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
109 
110  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
111 
112  if (just_read) return ! This subroutine has no run-time parameters.
113 
114  call mom_mesg(" DOME_initialization.F90, DOME_initialize_thickness: setting thickness", 5)
115 
116  e0(1)=0.0
117  do k=2,nz
118  e0(k) = -g%max_depth * (real(k-1)-0.5)/real(nz-1)
119  enddo
120 
121  do j=g%jsc,g%jec ; do i=g%isc,g%iec
122 ! This sets the initial thickness (in m) of the layers. The !
123 ! thicknesses are set to insure that: 1. each layer is at least an !
124 ! Angstrom thick, and 2. the interfaces are where they should be !
125 ! based on the resting depths and interface height perturbations, !
126 ! as long at this doesn't interfere with 1. !
127  eta1d(nz+1) = -g%bathyT(i,j)
128  do k=nz,1,-1
129  eta1d(k) = e0(k)
130  if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_Z)) then
131  eta1d(k) = eta1d(k+1) + gv%Angstrom_Z
132  h(i,j,k) = gv%Angstrom_H
133  else
134  h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
135  endif
136  enddo
137  enddo ; enddo
138 

◆ dome_initialize_topography()

subroutine, public dome_initialization::dome_initialize_topography ( real, dimension(g%isd:g%ied,g%jsd:g%jed), intent(out)  D,
type(dyn_horgrid_type), intent(in)  G,
type(param_file_type), intent(in)  param_file,
real, intent(in)  max_depth,
type(unit_scale_type), intent(in), optional  US 
)

This subroutine sets up the DOME topography.

Parameters
[in]gThe dynamic horizontal grid type
[out]dOcean bottom depth in m or Z if US is present
[in]param_fileParameter file structure
[in]max_depthMaximum model depth in the units of D
[in]usA dimensional unit scaling type

Definition at line 40 of file DOME_initialization.F90.

41  type(dyn_horgrid_type), intent(in) :: G !< The dynamic horizontal grid type
42  real, dimension(G%isd:G%ied,G%jsd:G%jed), &
43  intent(out) :: D !< Ocean bottom depth in m or Z if US is present
44  type(param_file_type), intent(in) :: param_file !< Parameter file structure
45  real, intent(in) :: max_depth !< Maximum model depth in the units of D
46  type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type
47 
48  ! Local variables
49  real :: m_to_Z ! A dimensional rescaling factor.
50  real :: min_depth ! The minimum and maximum depths [Z ~> m].
51  ! This include declares and sets the variable "version".
52 # include "version_variable.h"
53  character(len=40) :: mdl = "DOME_initialize_topography" ! This subroutine's name.
54  integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
55  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
56  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
57 
58  call mom_mesg(" DOME_initialization.F90, DOME_initialize_topography: setting topography", 5)
59 
60  m_to_z = 1.0 ; if (present(us)) m_to_z = us%m_to_Z
61 
62  call log_version(param_file, mdl, version, "")
63  call get_param(param_file, mdl, "MINIMUM_DEPTH", min_depth, &
64  "The minimum depth of the ocean.", units="m", default=0.0, scale=m_to_z)
65 
66  do j=js,je ; do i=is,ie
67  if (g%geoLatT(i,j) < 600.0) then
68  if (g%geoLatT(i,j) < 300.0) then
69  d(i,j) = max_depth
70  else
71  d(i,j) = max_depth - 10.0*m_to_z * (g%geoLatT(i,j)-300.0)
72  endif
73  else
74  if ((g%geoLonT(i,j) > 1000.0) .AND. (g%geoLonT(i,j) < 1100.0)) then
75  d(i,j) = 600.0*m_to_z
76  else
77  d(i,j) = 0.5*min_depth
78  endif
79  endif
80 
81  if (d(i,j) > max_depth) d(i,j) = max_depth
82  if (d(i,j) < min_depth) d(i,j) = 0.5*min_depth
83  enddo ; enddo
84 

◆ dome_set_obc_data()

subroutine, public dome_initialization::dome_set_obc_data ( type(ocean_obc_type), pointer  OBC,
type(thermo_var_ptrs), intent(in)  tv,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
type(unit_scale_type), intent(in)  US,
type(param_file_type), intent(in)  param_file,
type(tracer_registry_type), pointer  tr_Reg 
)

This subroutine sets the properties of flow at open boundary conditions. This particular example is for the DOME inflow describe in Legg et al. 2006.

Parameters
obcThis open boundary condition type specifies whether, where, and what open boundary conditions are used.
[in]tvA structure containing pointers to any available thermodynamic fields, including potential temperature and salinity or mixed layer density. Absent fields have NULL ptrs.
[in]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in]usA dimensional unit scaling type
[in]param_fileA structure indicating the open file to parse for model parameter values.
tr_regTracer registry.

Definition at line 246 of file DOME_initialization.F90.

247  type(ocean_OBC_type), pointer :: OBC !< This open boundary condition type specifies
248  !! whether, where, and what open boundary
249  !! conditions are used.
250  type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any
251  !! available thermodynamic fields, including potential
252  !! temperature and salinity or mixed layer density. Absent
253  !! fields have NULL ptrs.
254  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
255  type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
256  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
257  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
258  !! to parse for model parameter values.
259  type(tracer_registry_type), pointer :: tr_Reg !< Tracer registry.
260 
261 ! Local variables
262  ! The following variables are used to set the target temperature and salinity.
263  real :: T0(SZK_(G)), S0(SZK_(G))
264  real :: pres(SZK_(G)) ! An array of the reference pressure [R L2 T-2 ~> Pa].
265  real :: drho_dT(SZK_(G)) ! Derivative of density with temperature [R degC-1 ~> kg m-3 degC-1].
266  real :: drho_dS(SZK_(G)) ! Derivative of density with salinity [R ppt-1 ~> kg m-3 ppt-1].
267  real :: rho_guess(SZK_(G)) ! Potential density at T0 & S0 [R ~> kg m-3].
268  ! The following variables are used to set up the transport in the DOME example.
269  real :: tr_0, y1, y2, tr_k, rst, rsb, rc, v_k, lon_im1
270  real :: D_edge ! The thickness [Z ~> m], of the dense fluid at the
271  ! inner edge of the inflow.
272  real :: g_prime_tot ! The reduced gravity across all layers [L2 Z-1 T-2 ~> m s-2].
273  real :: Def_Rad ! The deformation radius, based on fluid of
274  ! thickness D_edge, in the same units as lat [m].
275  real :: Ri_trans ! The shear Richardson number in the transition
276  ! region of the specified shear profile.
277  character(len=40) :: mdl = "DOME_set_OBC_data" ! This subroutine's name.
278  character(len=32) :: name
279  integer :: i, j, k, itt, is, ie, js, je, isd, ied, jsd, jed, m, nz, NTR
280  integer :: IsdB, IedB, JsdB, JedB
281  type(OBC_segment_type), pointer :: segment => null()
282  type(tracer_type), pointer :: tr_ptr => null()
283 
284  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
285  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
286  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
287 
288  ! The following variables should be transformed into runtime parameters.
289  d_edge = 300.0*us%m_to_Z ! The thickness of dense fluid in the inflow.
290  ri_trans = 1.0/3.0 ! The shear Richardson number in the transition region
291  ! region of the specified shear profile.
292 
293  if (.not.associated(obc)) return
294 
295  g_prime_tot = (gv%g_Earth / gv%Rho0) * 2.0*us%kg_m3_to_R
296  def_rad = us%L_to_m*sqrt(d_edge*g_prime_tot) / (1.0e-4*us%T_to_s * 1000.0)
297  tr_0 = (-d_edge*sqrt(d_edge*g_prime_tot)*0.5e3*us%m_to_L*def_rad) * gv%Z_to_H
298 
299  if (obc%number_of_segments /= 1) then
300  call mom_error(warning, 'Error in DOME OBC segment setup', .true.)
301  return !!! Need a better error message here
302  endif
303 
304  ntr = tr_reg%NTR
305 
306  ! Stash this information away for the messy tracer restarts.
307  obc%ntr = ntr
308  if (.not. associated(obc%tracer_x_reservoirs_used)) then
309  allocate(obc%tracer_x_reservoirs_used(ntr))
310  allocate(obc%tracer_y_reservoirs_used(ntr))
311  obc%tracer_x_reservoirs_used(:) = .false.
312  obc%tracer_y_reservoirs_used(:) = .false.
313  obc%tracer_y_reservoirs_used(1) = .true.
314  endif
315 
316  segment => obc%segment(1)
317  if (.not. segment%on_pe) return
318 
319  allocate(segment%field(ntr))
320 
321  do k=1,nz
322  rst = -1.0
323  if (k>1) rst = -1.0 + (real(k-1)-0.5)/real(nz-1)
324 
325  rsb = 0.0
326  if (k<nz) rsb = -1.0 + (real(k-1)+0.5)/real(nz-1)
327  rc = -1.0 + real(k-1)/real(nz-1)
328 
329  ! These come from assuming geostrophy and a constant Ri profile.
330  y1 = (2.0*ri_trans*rst + ri_trans + 2.0)/(2.0 - ri_trans)
331  y2 = (2.0*ri_trans*rsb + ri_trans + 2.0)/(2.0 - ri_trans)
332  tr_k = tr_0 * (2.0/(ri_trans*(2.0-ri_trans))) * &
333  ((log(y1)+1.0)/y1 - (log(y2)+1.0)/y2)
334  v_k = -sqrt(d_edge*g_prime_tot)*log((2.0 + ri_trans*(1.0 + 2.0*rc)) / &
335  (2.0 - ri_trans))
336  if (k == nz) tr_k = tr_k + tr_0 * (2.0/(ri_trans*(2.0+ri_trans))) * &
337  log((2.0+ri_trans)/(2.0-ri_trans))
338  ! New way
339  isd = segment%HI%isd ; ied = segment%HI%ied
340  jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
341  do j=jsdb,jedb ; do i=isd,ied
342  lon_im1 = 2.0*g%geoLonCv(i,j) - g%geoLonBu(i,j)
343  segment%normal_trans(i,j,k) = tr_k * (exp(-2.0*(lon_im1 - 1000.0)/def_rad) -&
344  exp(-2.0*(g%geoLonBu(i,j) - 1000.0)/def_rad))
345  segment%normal_vel(i,j,k) = v_k * exp(-2.0*(g%geoLonCv(i,j) - 1000.0)/def_rad)
346  enddo ; enddo
347  enddo
348 
349  ! The inflow values of temperature and salinity also need to be set here if
350  ! these variables are used. The following code is just a naive example.
351  if (associated(tv%S)) then
352  ! In this example, all S inflows have values of 35 psu.
353  name = 'salt'
354  call tracer_name_lookup(tr_reg, tr_ptr, name)
355  call register_segment_tracer(tr_ptr, param_file, gv, segment, obc_scalar=35.0)
356  endif
357  if (associated(tv%T)) then
358  ! In this example, the T values are set to be consistent with the layer
359  ! target density and a salinity of 35 psu. This code is taken from
360  ! USER_initialize_temp_sal.
361  pres(:) = tv%P_Ref ; s0(:) = 35.0 ; t0(1) = 25.0
362  call calculate_density(t0(1), s0(1), pres(1), rho_guess(1), tv%eqn_of_state)
363  call calculate_density_derivs(t0, s0, pres, drho_dt, drho_ds, tv%eqn_of_state, (/1,1/) )
364 
365  do k=1,nz ; t0(k) = t0(1) + (gv%Rlay(k)-rho_guess(1)) / drho_dt(1) ; enddo
366  do itt=1,6
367  call calculate_density(t0, s0, pres, rho_guess, tv%eqn_of_state)
368  call calculate_density_derivs(t0, s0, pres, drho_dt, drho_ds, tv%eqn_of_state)
369  do k=1,nz ; t0(k) = t0(k) + (gv%Rlay(k)-rho_guess(k)) / drho_dt(k) ; enddo
370  enddo
371 
372  ! Temperature on tracer 1???
373  allocate(segment%field(1)%buffer_src(segment%HI%isd:segment%HI%ied,segment%HI%JsdB:segment%HI%JedB,nz))
374  do k=1,nz ; do j=jsdb,jedb ; do i=isd,ied
375  segment%field(1)%buffer_src(i,j,k) = t0(k)
376  enddo ; enddo ; enddo
377  name = 'temp'
378  call tracer_name_lookup(tr_reg, tr_ptr, name)
379  call register_segment_tracer(tr_ptr, param_file, gv, segment, obc_array=.true.)
380  endif
381 
382  ! Dye tracers - fight with T,S???
383  ! First dye - only one with OBC values
384  ! This field(1) requires tr_D1 to be the first tracer.
385  allocate(segment%field(1)%buffer_src(segment%HI%isd:segment%HI%ied,segment%HI%JsdB:segment%HI%JedB,nz))
386  do k=1,nz ; do j=segment%HI%jsd,segment%HI%jed ; do i=segment%HI%isd,segment%HI%ied
387  if (k < nz/2) then ; segment%field(1)%buffer_src(i,j,k) = 0.0
388  else ; segment%field(1)%buffer_src(i,j,k) = 1.0 ; endif
389  enddo ; enddo ; enddo
390  name = 'tr_D1'
391  call tracer_name_lookup(tr_reg, tr_ptr, name)
392  call register_segment_tracer(tr_ptr, param_file, gv, &
393  obc%segment(1), obc_array=.true.)
394 
395  ! All tracers but the first have 0 concentration in their inflows. As this
396  ! is the default value, the following calls are unnecessary.
397  do m=2,ntr
398  if (m < 10) then ; write(name,'("tr_D",I1.1)') m
399  else ; write(name,'("tr_D",I2.2)') m ; endif
400  call tracer_name_lookup(tr_reg, tr_ptr, name)
401  call register_segment_tracer(tr_ptr, param_file, gv, &
402  obc%segment(1), obc_scalar=0.0)
403  enddo
404