MOM6
DOME_initialization.F90
Go to the documentation of this file.
2 !***********************************************************************
3 !* GNU General Public License *
4 !* This file is a part of MOM. *
5 !* *
6 !* MOM is free software; you can redistribute it and/or modify it and *
7 !* are expected to follow the terms of the GNU General Public License *
8 !* as published by the Free Software Foundation; either version 2 of *
9 !* the License, or (at your option) any later version. *
10 !* *
11 !* MOM is distributed in the hope that it will be useful, but WITHOUT *
12 !* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
13 !* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public *
14 !* License for more details. *
15 !* *
16 !* For the full text of the GNU General Public License, *
17 !* write to: Free Software Foundation, Inc., *
18 !* 675 Mass Ave, Cambridge, MA 02139, USA. *
19 !* or see: http://www.gnu.org/licenses/gpl.html *
20 !***********************************************************************
21 
26 use mom_get_input, only : directories
27 use mom_grid, only : ocean_grid_type
34 
35 implicit none ; private
36 
37 #include <MOM_memory.h>
38 
42 public dome_set_obc_data
43 
44 contains
45 
46 ! -----------------------------------------------------------------------------
47 !> This subroutine sets up the DOME topography
48 subroutine dome_initialize_topography(D, G, param_file, max_depth)
49  type(dyn_horgrid_type), intent(in) :: G !< The dynamic horizontal grid type
50  real, dimension(G%isd:G%ied,G%jsd:G%jed), &
51  intent(out) :: D !< Ocean bottom depth in m
52  type(param_file_type), intent(in) :: param_file !< Parameter file structure
53  real, intent(in) :: max_depth !< Maximum depth of model in m
54 
55  real :: min_depth ! The minimum and maximum depths in m.
56 ! This include declares and sets the variable "version".
57 #include "version_variable.h"
58  character(len=40) :: mdl = "DOME_initialize_topography" ! This subroutine's name.
59  integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
60  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
61  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
62 
63  call mom_mesg(" DOME_initialization.F90, DOME_initialize_topography: setting topography", 5)
64 
65  call log_version(param_file, mdl, version, "")
66  call get_param(param_file, mdl, "MINIMUM_DEPTH", min_depth, &
67  "The minimum depth of the ocean.", units="m", default=0.0)
68 
69  do j=js,je ; do i=is,ie
70  if (g%geoLatT(i,j) < 600.0) then
71  if (g%geoLatT(i,j) < 300.0) then
72  d(i,j)=max_depth
73  else
74  d(i,j)=max_depth-10.0*(g%geoLatT(i,j)-300.0)
75  endif
76  else
77  if ((g%geoLonT(i,j) > 1000.0).AND.(g%geoLonT(i,j) < 1100.0)) then
78  d(i,j)=600.0
79  else
80  d(i,j)=0.5*min_depth
81  endif
82  endif
83 
84  if (d(i,j) > max_depth) d(i,j) = max_depth
85  if (d(i,j) < min_depth) d(i,j) = 0.5*min_depth
86  enddo ; enddo
87 
88 end subroutine dome_initialize_topography
89 ! -----------------------------------------------------------------------------
90 
91 ! -----------------------------------------------------------------------------
92 !> This subroutine initializes layer thicknesses for the DOME experiment
93 subroutine dome_initialize_thickness(h, G, GV, param_file, just_read_params)
94  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
95  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
96  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
97  intent(out) :: h !< The thickness that is being initialized, in m.
98  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
99  !! to parse for model parameter values.
100  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
101  !! only read parameters without changing h.
102 
103  real :: e0(szk_(gv)+1) ! The resting interface heights, in m, usually !
104  ! negative because it is positive upward. !
105  real :: eta1D(szk_(gv)+1) ! Interface height relative to the sea surface !
106  ! positive upward, in m. !
107  logical :: just_read ! If true, just read parameters but set nothing.
108  character(len=40) :: mdl = "DOME_initialize_thickness" ! This subroutine's name.
109  integer :: i, j, k, is, ie, js, je, nz
110 
111  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
112 
113  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
114 
115  if (just_read) return ! This subroutine has no run-time parameters.
116 
117  call mom_mesg(" DOME_initialization.F90, DOME_initialize_thickness: setting thickness", 5)
118 
119  e0(1)=0.0
120  do k=2,nz
121  e0(k) = -g%max_depth * (real(k-1)-0.5)/real(nz-1)
122  enddo
123 
124  do j=g%jsc,g%jec ; do i=g%isc,g%iec
125 ! This sets the initial thickness (in m) of the layers. The !
126 ! thicknesses are set to insure that: 1. each layer is at least an !
127 ! Angstrom thick, and 2. the interfaces are where they should be !
128 ! based on the resting depths and interface height perturbations, !
129 ! as long at this doesn't interfere with 1. !
130  eta1d(nz+1) = -1.0*g%bathyT(i,j)
131  do k=nz,1,-1
132  eta1d(k) = e0(k)
133  if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_z)) then
134  eta1d(k) = eta1d(k+1) + gv%Angstrom_z
135  h(i,j,k) = gv%Angstrom_z
136  else
137  h(i,j,k) = eta1d(k) - eta1d(k+1)
138  endif
139  enddo
140  enddo ; enddo
141 
142 end subroutine dome_initialize_thickness
143 ! -----------------------------------------------------------------------------
144 
145 ! -----------------------------------------------------------------------------
146 !> This subroutine sets the inverse restoration time (Idamp), and !
147 !! the values towards which the interface heights and an arbitrary !
148 !! number of tracers should be restored within each sponge. The !
149 !! interface height is always subject to damping, and must always be !
150 !! the first registered field. !
151 subroutine dome_initialize_sponges(G, GV, tv, PF, CSp)
152  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
153  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
154  type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any available
155  !! thermodynamic fields, including potential temperature and
156  !! salinity or mixed layer density. Absent fields have NULL ptrs.
157  type(param_file_type), intent(in) :: PF !< A structure indicating the open file to
158  !! parse for model parameter values.
159  type(sponge_cs), pointer :: CSp !< A pointer that is set to point to the control
160  !! structure for this module.
161 
162  real :: eta(szi_(g),szj_(g),szk_(g)+1) ! A temporary array for eta.
163  real :: temp(szi_(g),szj_(g),szk_(g)) ! A temporary array for other variables. !
164  real :: Idamp(szi_(g),szj_(g)) ! The inverse damping rate, in s-1.
165 
166  real :: H0(szk_(g))
167  real :: min_depth
168  real :: damp, e_dense, damp_new
169  character(len=40) :: mdl = "DOME_initialize_sponges" ! This subroutine's name.
170  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
171 
172  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
173  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
174 
175  eta(:,:,:) = 0.0 ; temp(:,:,:) = 0.0 ; idamp(:,:) = 0.0
176 
177 ! Here the inverse damping time, in s-1, is set. Set Idamp to 0 !
178 ! wherever there is no sponge, and the subroutines that are called !
179 ! will automatically set up the sponges only where Idamp is positive!
180 ! and mask2dT is 1. !
181 
182 ! Set up sponges for DOME configuration
183  call get_param(pf, mdl, "MINIMUM_DEPTH", min_depth, &
184  "The minimum depth of the ocean.", units="m", default=0.0)
185 
186  h0(1) = 0.0
187  do k=2,nz ; h0(k) = -(real(k-1)-0.5)*g%max_depth/real(nz-1) ; enddo
188  do i=is,ie; do j=js,je
189  if (g%geoLonT(i,j) < 100.0) then ; damp = 10.0
190  elseif (g%geoLonT(i,j) < 200.0) then
191  damp = 10.0*(200.0-g%geoLonT(i,j))/100.0
192  else ; damp=0.0
193  endif
194 
195  if (g%geoLonT(i,j) > 1400.0) then ; damp_new = 10.0
196  elseif (g%geoLonT(i,j) > 1300.0) then
197  damp_new = 10.0*(g%geoLonT(i,j)-1300.0)/100.0
198  else ; damp_new = 0.0
199  endif
200 
201  if (damp <= damp_new) damp=damp_new
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)
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 
242 end subroutine dome_initialize_sponges
243 
244 !> This subroutine sets the properties of flow at open boundary conditions.
245 !! This particular example is for the DOME inflow describe in Legg et al. 2006.
246 subroutine dome_set_obc_data(OBC, tv, G, GV, param_file, tr_Reg)
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(param_file_type), intent(in) :: param_file !< A structure indicating the open file
257  !! to parse for model parameter values.
258  type(tracer_registry_type), pointer :: tr_Reg !< Tracer registry.
259 
260  real, pointer, dimension(:,:,:) :: &
261  OBC_T_v => null(), & ! specify the values of T and S that should come
262  obc_s_v => null() ! boundary conditions, in C and psu.
263  ! The following variables are used to set the target temperature and salinity.
264  real :: T0(szk_(g)), S0(szk_(g))
265  real :: pres(szk_(g)) ! An array of the reference pressure in Pa.
266  real :: drho_dT(szk_(g)) ! Derivative of density with temperature in kg m-3 K-1. !
267  real :: drho_dS(szk_(g)) ! Derivative of density with salinity in kg m-3 PSU-1. !
268  real :: rho_guess(szk_(g)) ! Potential density at T0 & S0 in kg m-3.
269  ! The following variables are used to set up the transport in the DOME example.
270  real :: tr_0, y1, y2, tr_k, rst, rsb, rc, v_k, lon_im1
271  real :: D_edge ! The thickness in m of the dense fluid at the
272  ! inner edge of the inflow.
273  real :: g_prime_tot ! The reduced gravity across all layers, m s-2.
274  real :: Def_Rad ! The deformation radius, based on fluid of
275  ! thickness D_edge, in the same units as lat.
276  real :: Ri_trans ! The shear Richardson number in the transition
277  ! region of the specified shear profile.
278  character(len=40) :: mdl = "DOME_set_OBC_data" ! This subroutine's name.
279  integer :: i, j, k, itt, is, ie, js, je, isd, ied, jsd, jed, nz
280  integer :: IsdB, IedB, JsdB, JedB
281  type(obc_segment_type), pointer :: segment
282 
283  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
284  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
285  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
286 
287  ! The following variables should be transformed into runtime parameters.
288  d_edge = 300.0 ! The thickness of dense fluid in the inflow.
289  ri_trans = 1.0/3.0 ! The shear Richardson number in the transition region
290  ! region of the specified shear profile.
291 
292  if (.not.associated(obc)) return
293 
294  g_prime_tot = (gv%g_Earth/gv%Rho0)*2.0
295  def_rad = sqrt(d_edge*g_prime_tot) / (1.0e-4*1000.0)
296  tr_0 = (-d_edge*sqrt(d_edge*g_prime_tot)*0.5e3*def_rad) * gv%m_to_H
297 
298  if (obc%number_of_segments .ne. 1) then
299  print *, 'Error in DOME OBC segment setup'
300  return !!! Need a better error message here
301  endif
302  segment => obc%segment(1)
303  if (.not. segment%on_pe) return
304 
305  do k=1,nz
306  rst = -1.0
307  if (k>1) rst = -1.0 + (real(k-1)-0.5)/real(nz-1)
308 
309  rsb = 0.0
310  if (k<nz) rsb = -1.0 + (real(k-1)+0.5)/real(nz-1)
311  rc = -1.0 + real(k-1)/real(nz-1)
312 
313  ! These come from assuming geostrophy and a constant Ri profile.
314  y1 = (2.0*ri_trans*rst + ri_trans + 2.0)/(2.0 - ri_trans)
315  y2 = (2.0*ri_trans*rsb + ri_trans + 2.0)/(2.0 - ri_trans)
316  tr_k = tr_0 * (2.0/(ri_trans*(2.0-ri_trans))) * &
317  ((log(y1)+1.0)/y1 - (log(y2)+1.0)/y2)
318  v_k = -sqrt(d_edge*g_prime_tot)*log((2.0 + ri_trans*(1.0 + 2.0*rc)) / &
319  (2.0 - ri_trans))
320  if (k == nz) tr_k = tr_k + tr_0 * (2.0/(ri_trans*(2.0+ri_trans))) * &
321  log((2.0+ri_trans)/(2.0-ri_trans))
322  ! New way
323  isd = segment%HI%isd ; ied = segment%HI%ied
324  jsdb = segment%HI%JsdB ; jedb = segment%HI%JedB
325  do j=jsdb,jedb ; do i=isd,ied
326  lon_im1 = 2.0*g%geoLonCv(i,j) - g%geoLonBu(i,j)
327  segment%normal_trans(i,j,k) = tr_k * (exp(-2.0*(lon_im1 - 1000.0)/def_rad) -&
328  exp(-2.0*(g%geoLonBu(i,j) - 1000.0)/def_rad))
329  segment%normal_vel(i,j,k) = v_k * exp(-2.0*(g%geoLonCv(i,j) - 1000.0)/def_rad)
330  enddo ; enddo
331  enddo
332 
333  ! The inflow values of temperature and salinity also need to be set here if
334  ! these variables are used. The following code is just a naive example.
335  if (associated(tv%S)) then
336  ! In this example, all S inflows have values of 35 psu.
337  call add_tracer_obc_values("S", tr_reg, obc_inflow=35.0)
338  endif
339  if (associated(tv%T)) then
340  ! In this example, the T values are set to be consistent with the layer
341  ! target density and a salinity of 35 psu. This code is taken from
342  ! USER_initialize_temp_sal.
343  pres(:) = tv%P_Ref ; s0(:) = 35.0 ; t0(1) = 25.0
344  call calculate_density(t0(1),s0(1),pres(1),rho_guess(1),tv%eqn_of_state)
345  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,1,1,tv%eqn_of_state)
346 
347  do k=1,nz ; t0(k) = t0(1) + (gv%Rlay(k)-rho_guess(1)) / drho_dt(1) ; enddo
348  do itt=1,6
349  call calculate_density(t0,s0,pres,rho_guess,1,nz,tv%eqn_of_state)
350  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,1,nz,tv%eqn_of_state)
351  do k=1,nz ; t0(k) = t0(k) + (gv%Rlay(k)-rho_guess(k)) / drho_dt(k) ; enddo
352  enddo
353 
354  allocate(obc_t_v(isd:ied,jsdb:jedb,nz))
355  do k=1,nz ; do j=jsdb,jedb ; do i=isd,ied
356  obc_t_v(i,j,k) = t0(k)
357  enddo ; enddo ; enddo
358  call add_tracer_obc_values("T", tr_reg, obc_in_v=obc_t_v)
359  endif
360 
361 end subroutine dome_set_obc_data
362 
363 !> \namespace dome_initialization
364 !!
365 !! The module configures the model for the "DOME" experiment.
366 !! DOME = Dynamics of Overflows and Mixing Experiment
367 end module dome_initialization
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Calculates density of sea water from T, S and P.
Definition: MOM_EOS.F90:45
Provides the ocean grid type.
Definition: MOM_grid.F90:2
Open boundary segment data structure.
subroutine, public dome_initialize_thickness(h, G, GV, param_file, just_read_params)
This subroutine initializes layer thicknesses for the DOME experiment.
integer, parameter, public obc_simple
This module contains the tracer_registry_type and the subroutines that handle registration of tracers...
subroutine, public calculate_density_derivs(T, S, pressure, drho_dT, drho_dS, start, npts, EOS)
Calls the appropriate subroutine to calculate density derivatives for 1-D array inputs.
Definition: MOM_EOS.F90:214
subroutine, public initialize_sponge(Iresttime, int_height, G, param_file, CS, Iresttime_i_mean, int_height_i_mean)
Definition: MOM_sponge.F90:142
subroutine, public set_up_sponge_field(sp_val, f_ptr, G, nlay, CS, sp_val_i_mean)
Definition: MOM_sponge.F90:271
Type to carry basic tracer information.
logical function, public is_root_pe()
subroutine, public add_tracer_obc_values(name, Reg, OBC_inflow, OBC_in_u, OBC_in_v)
This subroutine adds open boundary condition concentrations for a tracer that has previously been reg...
subroutine, public dome_initialize_topography(D, G, param_file, max_depth)
This subroutine sets up the DOME topography.
subroutine, public dome_initialize_sponges(G, GV, tv, PF, CSp)
This subroutine sets the inverse restoration time (Idamp), and ! the values towards which the interfa...
subroutine, public mom_mesg(message, verb, all_print)
Provides subroutines for quantities specific to the equation of state.
Definition: MOM_EOS.F90:2
The thermo_var_ptrs structure contains pointers to an assortment of thermodynamic fields that may be ...
integer, parameter, public obc_none
Controls where open boundary conditions are applied.
subroutine, public dome_set_obc_data(OBC, tv, G, GV, param_file, tr_Reg)
This subroutine sets the properties of flow at open boundary conditions. This particular example is f...
The module configures the model for the "DOME" experiment. DOME = Dynamics of Overflows and Mixing Ex...
subroutine, public mom_error(level, message, all_print)
A control structure for the equation of state.
Definition: MOM_EOS.F90:55