MOM6
ISOMIP_initialization.F90
1 !> Configures the ISOMIP test case.
3 
4 ! This file is part of MOM6. See LICENSE.md for the license.
5 
7 use mom_sponge, only : sponge_cs, set_up_sponge_field, initialize_sponge
9 use mom_error_handler, only : mom_mesg, mom_error, fatal, is_root_pe, warning
11 use mom_get_input, only : directories
12 use mom_grid, only : ocean_grid_type
13 use mom_io, only : file_exists
14 use mom_io, only : mom_read_data
15 use mom_io, only : slasher
20 use regrid_consts, only : coordinatemode, default_coordinate_mode
21 use regrid_consts, only : regridding_layer, regridding_zstar
22 use regrid_consts, only : regridding_rho, regridding_sigma
23 use regrid_consts, only : regridding_sigma_shelf_zstar
24 implicit none ; private
25 
26 #include <MOM_memory.h>
27 
28 character(len=40) :: mdl = "ISOMIP_initialization" !< This module's name.
29 
30 ! The following routines are visible to the outside world
31 public isomip_initialize_topography
32 public isomip_initialize_thickness
33 public isomip_initialize_temperature_salinity
34 public isomip_initialize_sponges
35 
36 ! A note on unit descriptions in comments: MOM6 uses units that can be rescaled for dimensional
37 ! consistency testing. These are noted in comments with units like Z, H, L, and T, along with
38 ! their mks counterparts with notation like "a velocity [Z T-1 ~> m s-1]". If the units
39 ! vary with the Boussinesq approximation, the Boussinesq variant is given first.
40 
41 contains
42 
43 !> Initialization of topography for the ISOMIP configuration
44 subroutine isomip_initialize_topography(D, G, param_file, max_depth, US)
45  type(dyn_horgrid_type), intent(in) :: g !< The dynamic horizontal grid type
46  real, dimension(G%isd:G%ied,G%jsd:G%jed), &
47  intent(out) :: d !< Ocean bottom depth in m or Z if US is present
48  type(param_file_type), intent(in) :: param_file !< Parameter file structure
49  real, intent(in) :: max_depth !< Maximum model depth in the units of D
50  type(unit_scale_type), optional, intent(in) :: us !< A dimensional unit scaling type
51 
52  ! Local variables
53  real :: min_depth ! The minimum and maximum depths [Z ~> m].
54  real :: m_to_z ! A dimensional rescaling factor.
55  ! The following variables are used to set up the bathymetry in the ISOMIP example.
56  real :: bmax ! max depth of bedrock topography
57  real :: b0,b2,b4,b6 ! first, second, third and fourth bedrock topography coeff
58  real :: xbar ! characteristic along-flow lenght scale of the bedrock
59  real :: dc ! depth of the trough compared with side walls [Z ~> m].
60  real :: fc ! characteristic width of the side walls of the channel
61  real :: wc ! half-width of the trough
62  real :: ly ! domain width (across ice flow)
63  real :: bx, by ! dummy vatiables [Z ~> m].
64  real :: xtil ! dummy vatiable
65  logical :: is_2d ! If true, use 2D setup
66 ! This include declares and sets the variable "version".
67 #include "version_variable.h"
68  character(len=40) :: mdl = "ISOMIP_initialize_topography" ! This subroutine's name.
69  integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
70  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
71  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
72 
73  call mom_mesg(" ISOMIP_initialization.F90, ISOMIP_initialize_topography: setting topography", 5)
74 
75  m_to_z = 1.0 ; if (present(us)) m_to_z = us%m_to_Z
76 
77  call log_version(param_file, mdl, version, "")
78  call get_param(param_file, mdl, "MINIMUM_DEPTH", min_depth, &
79  "The minimum depth of the ocean.", units="m", default=0.0, scale=m_to_z)
80  call get_param(param_file, mdl, "ISOMIP_2D",is_2d,'If true, use a 2D setup.', default=.false.)
81 
82  ! The following variables should be transformed into runtime parameters?
83  bmax = 720.0*m_to_z ; dc = 500.0*m_to_z
84  b0 = -150.0*m_to_z ; b2 = -728.8*m_to_z ; b4 = 343.91*m_to_z ; b6 = -50.57*m_to_z
85  xbar = 300.0e3 ; fc = 4.0e3 ; wc = 24.0e3 ; ly = 80.0e3
86  bx = 0.0 ; by = 0.0 ; xtil = 0.0
87 
88 
89  if (is_2d) then
90  do j=js,je ; do i=is,ie
91  ! 2D setup
92  xtil = g%geoLonT(i,j)*1.0e3/xbar
93  !xtil = 450*1.0e3/xbar
94  bx = b0 + b2*xtil**2 + b4*xtil**4 + b6*xtil**6
95  !by = (dc/(1.+exp(-2.*(G%geoLatT(i,j)*1.0e3- ly/2. - wc)/fc))) + &
96  ! (dc/(1.+exp(2.*(G%geoLatT(i,j)*1.0e3- ly/2. + wc)/fc)))
97 
98  ! slice at y = 40 km
99  by = (dc / (1.+exp(-2.*(40.0*1.0e3- ly/2. - wc)/fc))) + &
100  (dc / (1.+exp(2.*(40.0*1.0e3- ly/2. + wc)/fc)))
101 
102  d(i,j) = -max(bx+by, -bmax)
103  if (d(i,j) > max_depth) d(i,j) = max_depth
104  if (d(i,j) < min_depth) d(i,j) = 0.5*min_depth
105  enddo ; enddo
106 
107  else
108  do j=js,je ; do i=is,ie
109  ! 3D setup
110  ! ===== TEST =====
111  !if (G%geoLonT(i,j)<500.) then
112  ! xtil = 500.*1.0e3/xbar
113  !else
114  ! xtil = G%geoLonT(i,j)*1.0e3/xbar
115  !endif
116  ! ===== TEST =====
117 
118  xtil = g%geoLonT(i,j)*1.0e3/xbar
119 
120  bx = b0 + b2*xtil**2 + b4*xtil**4 + b6*xtil**6
121  by = (dc / (1.+exp(-2.*(g%geoLatT(i,j)*1.0e3- ly/2. - wc)/fc))) + &
122  (dc / (1.+exp(2.*(g%geoLatT(i,j)*1.0e3- ly/2. + wc)/fc)))
123 
124  d(i,j) = -max(bx+by, -bmax)
125  if (d(i,j) > max_depth) d(i,j) = max_depth
126  if (d(i,j) < min_depth) d(i,j) = 0.5*min_depth
127  enddo ; enddo
128  endif
129 
130 end subroutine isomip_initialize_topography
131 
132 !> Initialization of thicknesses
133 subroutine isomip_initialize_thickness ( h, G, GV, US, param_file, tv, just_read_params)
134  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
135  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
136  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
137  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
138  intent(out) :: h !< The thickness that is being initialized [H ~> m or kg m-2].
139  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
140  !! to parse for model parameter values.
141  type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers to any
142  !! available thermodynamic fields, including
143  !! the eqn. of state.
144  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
145  !! only read parameters without changing h.
146  ! Local variables
147  real :: e0(szk_(g)+1) ! The resting interface heights, in depth units [Z ~> m],
148  ! usually negative because it is positive upward.
149  real :: eta1d(szk_(g)+1)! Interface height relative to the sea surface
150  ! positive upward, in depth units [Z ~> m].
151  integer :: i, j, k, is, ie, js, je, nz, tmp1
152  real :: x
153  real :: rho_range
154  real :: min_thickness, s_sur, s_bot, t_sur, t_bot, rho_sur, rho_bot
155  logical :: just_read ! If true, just read parameters but set nothing.
156  character(len=256) :: mesg ! The text of an error message
157  character(len=40) :: verticalcoordinate
158 
159  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
160 
161  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
162 
163  if (.not.just_read) &
164  call mom_mesg("MOM_initialization.F90, initialize_thickness_uniform: setting thickness")
165 
166  call get_param(param_file, mdl,"MIN_THICKNESS", min_thickness, &
167  'Minimum layer thickness', units='m', default=1.e-3, do_not_log=just_read, scale=us%m_to_Z)
168  call get_param(param_file, mdl,"REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
169  default=default_coordinate_mode, do_not_log=just_read)
170 
171  select case ( coordinatemode(verticalcoordinate) )
172 
173  case ( regridding_layer, regridding_rho ) ! Initial thicknesses for isopycnal coordinates
174  call get_param(param_file, mdl, "ISOMIP_T_SUR",t_sur, &
175  'Temperature at the surface (interface)', default=-1.9, do_not_log=just_read)
176  call get_param(param_file, mdl, "ISOMIP_S_SUR", s_sur, &
177  'Salinity at the surface (interface)', default=33.8, do_not_log=just_read)
178  call get_param(param_file, mdl, "ISOMIP_T_BOT", t_bot, &
179  'Temperature at the bottom (interface)', default=-1.9, do_not_log=just_read)
180  call get_param(param_file, mdl, "ISOMIP_S_BOT", s_bot,&
181  'Salinity at the bottom (interface)', default=34.55, do_not_log=just_read)
182 
183  if (just_read) return ! All run-time parameters have been read, so return.
184 
185  ! Compute min/max density using T_SUR/S_SUR and T_BOT/S_BOT
186  call calculate_density(t_sur, s_sur, 0.0, rho_sur, tv%eqn_of_state)
187  ! write(mesg,*) 'Surface density is:', rho_sur
188  ! call MOM_mesg(mesg,5)
189  call calculate_density(t_bot, s_bot, 0.0, rho_bot, tv%eqn_of_state)
190  ! write(mesg,*) 'Bottom density is:', rho_bot
191  ! call MOM_mesg(mesg,5)
192  rho_range = rho_bot - rho_sur
193  ! write(mesg,*) 'Density range is:', rho_range
194  ! call MOM_mesg(mesg,5)
195 
196  ! Construct notional interface positions
197  e0(1) = 0.
198  do k=2,nz
199  e0(k) = -g%max_depth * ( 0.5 * ( gv%Rlay(k-1) + gv%Rlay(k) ) - rho_sur ) / rho_range
200  e0(k) = min( 0., e0(k) ) ! Bound by surface
201  e0(k) = max( -g%max_depth, e0(k) ) ! Bound by possible deepest point in model
202  ! write(mesg,*) 'G%max_depth,GV%Rlay(k-1),GV%Rlay(k),e0(k)',G%max_depth,GV%Rlay(k-1),GV%Rlay(k),e0(k)
203  ! call MOM_mesg(mesg,5)
204  enddo
205  e0(nz+1) = -g%max_depth
206 
207  ! Calculate thicknesses
208  do j=js,je ; do i=is,ie
209  eta1d(nz+1) = -g%bathyT(i,j)
210  do k=nz,1,-1
211  eta1d(k) = e0(k)
212  if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_Z)) then
213  eta1d(k) = eta1d(k+1) + gv%Angstrom_Z
214  h(i,j,k) = gv%Angstrom_H
215  else
216  h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
217  endif
218  enddo
219  enddo ; enddo
220 
221  case ( regridding_zstar, regridding_sigma_shelf_zstar ) ! Initial thicknesses for z coordinates
222  if (just_read) return ! All run-time parameters have been read, so return.
223  do j=js,je ; do i=is,ie
224  eta1d(nz+1) = -g%bathyT(i,j)
225  do k=nz,1,-1
226  eta1d(k) = -g%max_depth * real(k-1) / real(nz)
227  if (eta1d(k) < (eta1d(k+1) + min_thickness)) then
228  eta1d(k) = eta1d(k+1) + min_thickness
229  h(i,j,k) = gv%Z_to_H * min_thickness
230  else
231  h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
232  endif
233  enddo
234  enddo ; enddo
235 
236  case ( regridding_sigma ) ! Initial thicknesses for sigma coordinates
237  if (just_read) return ! All run-time parameters have been read, so return.
238  do j=js,je ; do i=is,ie
239  h(i,j,:) = gv%Z_to_H * g%bathyT(i,j) / dfloat(nz)
240  enddo ; enddo
241 
242  case default
243  call mom_error(fatal,"isomip_initialize: "// &
244  "Unrecognized i.c. setup - set REGRIDDING_COORDINATE_MODE")
245 
246  end select
247 
248 end subroutine isomip_initialize_thickness
249 
250 !> Initial values for temperature and salinity
251 subroutine isomip_initialize_temperature_salinity ( T, S, h, G, GV, param_file, &
252  eqn_of_state, just_read_params)
253  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
254  type(verticalgrid_type), intent(in) :: gv !< Vertical grid structure
255  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: t !< Potential temperature [degC]
256  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: s !< Salinity [ppt]
257  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(in) :: h !< Layer thickness [H ~> m or kg m-2]
258  type(param_file_type), intent(in) :: param_file !< Parameter file structure
259  type(eos_type), pointer :: eqn_of_state !< Equation of state structure
260  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
261  !! only read parameters without changing T & S.
262  ! Local variables
263  integer :: i, j, k, is, ie, js, je, nz, itt
264  real :: x, ds, dt, rho_sur, rho_bot
265  real :: xi0, xi1 ! Heights in depth units [Z ~> m].
266  real :: s_sur, s_bot ! Salinity at the surface and bottom [ppt]
267  real :: t_sur, t_bot ! Temperature at the bottom [degC]
268  real :: dt_dz ! Vertical gradient of temperature [degC Z-1 ~> degC m-1].
269  real :: ds_dz ! Vertical gradient of salinity [ppt Z-1 ~> ppt m-1].
270  real :: z ! vertical position in z space [Z ~> m]
271  character(len=256) :: mesg ! The text of an error message
272  character(len=40) :: verticalcoordinate, density_profile
273  real :: rho_tmp
274  logical :: just_read ! If true, just read parameters but set nothing.
275  logical :: fit_salin ! If true, accept the prescribed temperature and fit the salinity.
276  real :: t0(szk_(g)), s0(szk_(g))
277  real :: drho_dt(szk_(g)) ! Derivative of density with temperature [kg m-3 degC-1].
278  real :: drho_ds(szk_(g)) ! Derivative of density with salinity [kg m-3 ppt-1].
279  real :: rho_guess(szk_(g)) ! Potential density at T0 & S0 [kg m-3].
280  real :: pres(szk_(g)) ! An array of the reference pressure [Pa]. (zero here)
281  real :: drho_dt1, drho_ds1, t_ref, s_ref
282  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
283  pres(:) = 0.0
284 
285  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
286 
287  call get_param(param_file, mdl, "REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
288  default=default_coordinate_mode, do_not_log=just_read)
289  call get_param(param_file, mdl, "ISOMIP_T_SUR",t_sur, &
290  'Temperature at the surface (interface)', default=-1.9, do_not_log=just_read)
291  call get_param(param_file, mdl, "ISOMIP_S_SUR", s_sur, &
292  'Salinity at the surface (interface)', default=33.8, do_not_log=just_read)
293  call get_param(param_file, mdl, "ISOMIP_T_BOT", t_bot, &
294  'Temperature at the bottom (interface)', default=-1.9, do_not_log=just_read)
295  call get_param(param_file, mdl, "ISOMIP_S_BOT", s_bot, &
296  'Salinity at the bottom (interface)', default=34.55, do_not_log=just_read)
297 
298  call calculate_density(t_sur,s_sur,0.0,rho_sur,eqn_of_state)
299  ! write(mesg,*) 'Density in the surface layer:', rho_sur
300  ! call MOM_mesg(mesg,5)
301  call calculate_density(t_bot,s_bot,0.0,rho_bot,eqn_of_state)
302  ! write(mesg,*) 'Density in the bottom layer::', rho_bot
303  ! call MOM_mesg(mesg,5)
304 
305  select case ( coordinatemode(verticalcoordinate) )
306 
307  case ( regridding_rho, regridding_zstar, regridding_sigma_shelf_zstar, regridding_sigma )
308  if (just_read) return ! All run-time parameters have been read, so return.
309 
310  ds_dz = (s_sur - s_bot) / g%max_depth
311  dt_dz = (t_sur - t_bot) / g%max_depth
312  do j=js,je ; do i=is,ie
313  xi0 = -g%bathyT(i,j)
314  do k = nz,1,-1
315  xi0 = xi0 + 0.5 * h(i,j,k) * gv%H_to_Z ! Depth in middle of layer
316  s(i,j,k) = s_sur + ds_dz * xi0
317  t(i,j,k) = t_sur + dt_dz * xi0
318  xi0 = xi0 + 0.5 * h(i,j,k) * gv%H_to_Z ! Depth at top of layer
319  enddo
320  enddo ; enddo
321 
322  case ( regridding_layer )
323  call get_param(param_file, mdl, "FIT_SALINITY", fit_salin, &
324  "If true, accept the prescribed temperature and fit the "//&
325  "salinity; otherwise take salinity and fit temperature.", &
326  default=.false., do_not_log=just_read)
327  call get_param(param_file, mdl, "DRHO_DS", drho_ds1, &
328  "Partial derivative of density with salinity.", &
329  units="kg m-3 PSU-1", fail_if_missing=.not.just_read, do_not_log=just_read)
330  call get_param(param_file, mdl, "DRHO_DT", drho_dt1, &
331  "Partial derivative of density with temperature.", &
332  units="kg m-3 K-1", fail_if_missing=.not.just_read, do_not_log=just_read)
333  call get_param(param_file, mdl, "T_REF", t_ref, &
334  "A reference temperature used in initialization.", &
335  units="degC", fail_if_missing=.not.just_read, do_not_log=just_read)
336  call get_param(param_file, mdl, "S_REF", s_ref, &
337  "A reference salinity used in initialization.", units="PSU", &
338  default=35.0, do_not_log=just_read)
339  if (just_read) return ! All run-time parameters have been read, so return.
340 
341  ! write(mesg,*) 'read drho_dS, drho_dT', drho_dS1, drho_dT1
342  ! call MOM_mesg(mesg,5)
343 
344  ds_dz = (s_sur - s_bot) / g%max_depth
345  dt_dz = (t_sur - t_bot) / g%max_depth
346 
347  do j=js,je ; do i=is,ie
348  xi0 = 0.0
349  do k = 1,nz
350  !T0(k) = T_Ref; S0(k) = S_Ref
351  xi1 = xi0 + 0.5 * h(i,j,k) * gv%H_to_Z
352  s0(k) = s_sur - ds_dz * xi1
353  t0(k) = t_sur - dt_dz * xi1
354  xi0 = xi0 + h(i,j,k) * gv%H_to_Z
355  ! write(mesg,*) 'S,T,xi0,xi1,k',S0(k),T0(k),xi0,xi1,k
356  ! call MOM_mesg(mesg,5)
357  enddo
358 
359  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,1,1,eqn_of_state)
360  ! write(mesg,*) 'computed drho_dS, drho_dT', drho_dS(1), drho_dT(1)
361  ! call MOM_mesg(mesg,5)
362  call calculate_density(t0(1),s0(1),0.,rho_guess(1),eqn_of_state)
363 
364  if (fit_salin) then
365  ! A first guess of the layers' salinity.
366  do k=nz,1,-1
367  s0(k) = max(0.0, s0(1) + (gv%Rlay(k) - rho_guess(1)) / drho_ds1)
368  enddo
369  ! Refine the guesses for each layer.
370  do itt=1,6
371  call calculate_density(t0,s0,pres,rho_guess,1,nz,eqn_of_state)
372  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,1,nz,eqn_of_state)
373  do k=1,nz
374  s0(k) = max(0.0, s0(k) + (gv%Rlay(k) - rho_guess(k)) / drho_ds1)
375  enddo
376  enddo
377 
378  else
379  ! A first guess of the layers' temperatures.
380  do k=nz,1,-1
381  t0(k) = t0(1) + (gv%Rlay(k) - rho_guess(1)) / drho_dt1
382  enddo
383 
384  do itt=1,6
385  call calculate_density(t0,s0,pres,rho_guess,1,nz,eqn_of_state)
386  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,1,nz,eqn_of_state)
387  do k=1,nz
388  t0(k) = t0(k) + (gv%Rlay(k) - rho_guess(k)) / drho_dt(k)
389  enddo
390  enddo
391  endif
392 
393  do k=1,nz
394  t(i,j,k) = t0(k) ; s(i,j,k) = s0(k)
395  enddo
396 
397  enddo ; enddo
398 
399  case default
400  call mom_error(fatal,"isomip_initialize: "// &
401  "Unrecognized i.c. setup - set REGRIDDING_COORDINATE_MODE")
402 
403  end select
404 
405  ! for debugging
406  !i=G%iec; j=G%jec
407  !do k = 1,nz
408  ! call calculate_density(T(i,j,k),S(i,j,k),0.0,rho_tmp,eqn_of_state)
409  ! write(mesg,*) 'k,h,T,S,rho,Rlay',k,h(i,j,k),T(i,j,k),S(i,j,k),rho_tmp,GV%Rlay(k)
410  ! call MOM_mesg(mesg,5)
411  !enddo
412 
413 end subroutine isomip_initialize_temperature_salinity
414 
415 !> Sets up the the inverse restoration time (Idamp), and
416 ! the values towards which the interface heights and an arbitrary
417 ! number of tracers should be restored within each sponge.
418 subroutine isomip_initialize_sponges(G, GV, US, tv, PF, use_ALE, CSp, ACSp)
419  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure.
420  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
421  type(unit_scale_type), intent(in) :: us !< A dimensional unit scaling type
422  type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers
423  !! to any available thermodynamic
424  !! fields, potential temperature and
425  !! salinity or mixed layer density.
426  !! Absent fields have NULL ptrs.
427  type(param_file_type), intent(in) :: pf !< A structure indicating the
428  !! open file to parse for model
429  !! parameter values.
430  logical, intent(in) :: use_ale !< If true, indicates model is in ALE mode
431  type(sponge_cs), pointer :: csp !< Layer-mode sponge structure
432  type(ale_sponge_cs), pointer :: acsp !< ALE-mode sponge structure
433  ! Local variables
434  real :: t(szi_(g),szj_(g),szk_(g)) ! A temporary array for temp
435  real :: s(szi_(g),szj_(g),szk_(g)) ! A temporary array for salt
436  real :: rho(szi_(g),szj_(g),szk_(g)) ! A temporary array for RHO
437  real :: h(szi_(g),szj_(g),szk_(g)) ! A temporary array for thickness
438  real :: idamp(szi_(g),szj_(g)) ! The inverse damping rate [s-1].
439  real :: tnudg ! Nudging time scale, days
440  real :: s_sur, t_sur ! Surface salinity and temerature in sponge
441  real :: s_bot, t_bot ! Bottom salinity and temerature in sponge
442  real :: t_ref, s_ref ! reference T and S
443  real :: rho_sur, rho_bot, rho_range
444  real :: dt_dz, ds_dz ! Gradients of T and S in degC/Z and PPT/Z.
445 
446  real :: e0(szk_(g)+1) ! The resting interface heights [Z ~> m], usually
447  ! negative because it is positive upward.
448  real :: eta1d(szk_(g)+1) ! Interface height relative to the sea surface, positive upward [Z ~> m].
449  real :: eta(szi_(g),szj_(g),szk_(g)+1) ! A temporary array for eta [Z ~> m].
450  real :: min_depth, dummy1, z
451  real :: damp, rho_dummy, min_thickness, rho_tmp, xi0
452  character(len=40) :: verticalcoordinate, filename, state_file
453  character(len=40) :: temp_var, salt_var, eta_var, inputdir
454 
455  character(len=40) :: mdl = "ISOMIP_initialize_sponges" ! This subroutine's name.
456  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
457 
458  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
459  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
460 
461  call get_param(pf, mdl, "MIN_THICKNESS", min_thickness, "Minimum layer thickness", &
462  units="m", default=1.e-3, scale=us%m_to_Z)
463 
464  call get_param(pf, mdl, "REGRIDDING_COORDINATE_MODE", verticalcoordinate, &
465  default=default_coordinate_mode)
466 
467  call get_param(pf, mdl, "ISOMIP_TNUDG", tnudg, "Nudging time scale for sponge layers (days)", default=0.0)
468 
469  call get_param(pf, mdl, "T_REF", t_ref, "Reference temperature", default=10.0,&
470  do_not_log=.true.)
471 
472  call get_param(pf, mdl, "S_REF", s_ref, "Reference salinity", default=35.0,&
473  do_not_log=.true.)
474 
475  call get_param(pf, mdl, "ISOMIP_S_SUR_SPONGE", s_sur, &
476  'Surface salinity in sponge layer.', default=s_ref) ! units="ppt")
477 
478  call get_param(pf, mdl, "ISOMIP_S_BOT_SPONGE", s_bot, &
479  'Bottom salinity in sponge layer.', default=s_ref) ! units="ppt")
480 
481  call get_param(pf, mdl, "ISOMIP_T_SUR_SPONGE", t_sur, &
482  'Surface temperature in sponge layer.', default=t_ref) ! units="degC")
483 
484  call get_param(pf, mdl, "ISOMIP_T_BOT_SPONGE", t_bot, &
485  'Bottom temperature in sponge layer.', default=t_ref) ! units="degC")
486 
487  t(:,:,:) = 0.0 ; s(:,:,:) = 0.0 ; idamp(:,:) = 0.0; rho(:,:,:) = 0.0
488 
489 ! Set up sponges for ISOMIP configuration
490  call get_param(pf, mdl, "MINIMUM_DEPTH", min_depth, &
491  "The minimum depth of the ocean.", units="m", default=0.0, scale=us%m_to_Z)
492 
493  if (associated(csp)) call mom_error(fatal, &
494  "ISOMIP_initialize_sponges called with an associated control structure.")
495  if (associated(acsp)) call mom_error(fatal, &
496  "ISOMIP_initialize_sponges called with an associated ALE-sponge control structure.")
497 
498  ! Here the inverse damping time [s-1], is set. Set Idamp to 0 !
499  ! wherever there is no sponge, and the subroutines that are called !
500  ! will automatically set up the sponges only where Idamp is positive!
501  ! and mask2dT is 1.
502 
503  do i=is,ie; do j=js,je
504  if (g%geoLonT(i,j) >= 790.0 .AND. g%geoLonT(i,j) <= 800.0) then
505 
506  ! 1 / day
507  dummy1=(g%geoLonT(i,j)-790.0)/(800.0-790.0)
508  damp = 1.0/tnudg * max(0.0,dummy1)
509 
510  else ; damp=0.0
511  endif
512 
513  ! convert to 1 / seconds
514  if (g%bathyT(i,j) > min_depth) then
515  idamp(i,j) = damp/86400.0
516  else ; idamp(i,j) = 0.0 ; endif
517 
518  enddo ; enddo
519 
520  ! Compute min/max density using T_SUR/S_SUR and T_BOT/S_BOT
521  call calculate_density(t_sur, s_sur, 0.0, rho_sur, tv%eqn_of_state)
522  !write (mesg,*) 'Surface density in sponge:', rho_sur
523  ! call MOM_mesg(mesg,5)
524  call calculate_density(t_bot, s_bot, 0.0, rho_bot, tv%eqn_of_state)
525  !write (mesg,*) 'Bottom density in sponge:', rho_bot
526  ! call MOM_mesg(mesg,5)
527  rho_range = rho_bot - rho_sur
528  !write (mesg,*) 'Density range in sponge:', rho_range
529  ! call MOM_mesg(mesg,5)
530 
531  if (use_ale) then
532 
533  select case ( coordinatemode(verticalcoordinate) )
534 
535  case ( regridding_rho )
536  ! Construct notional interface positions
537  e0(1) = 0.
538  do k=2,nz
539  e0(k) = -g%max_depth * ( 0.5 * ( gv%Rlay(k-1) + gv%Rlay(k) ) - rho_sur ) / rho_range
540  e0(k) = min( 0., e0(k) ) ! Bound by surface
541  e0(k) = max( -g%max_depth, e0(k) ) ! Bound by possible deepest point in model
542  ! write(mesg,*) 'G%max_depth,GV%Rlay(k-1),GV%Rlay(k),e0(k)',G%max_depth,GV%Rlay(k-1),GV%Rlay(k),e0(k)
543  ! call MOM_mesg(mesg,5)
544  enddo
545  e0(nz+1) = -g%max_depth
546 
547  ! Calculate thicknesses
548  do j=js,je ; do i=is,ie
549  eta1d(nz+1) = -g%bathyT(i,j)
550  do k=nz,1,-1
551  eta1d(k) = e0(k)
552  if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_Z)) then
553  eta1d(k) = eta1d(k+1) + gv%Angstrom_Z
554  h(i,j,k) = gv%Angstrom_H
555  else
556  h(i,j,k) = gv%Z_to_H*(eta1d(k) - eta1d(k+1))
557  endif
558  enddo
559  enddo ; enddo
560 
561  case ( regridding_zstar, regridding_sigma_shelf_zstar ) ! Initial thicknesses for z coordinates
562  do j=js,je ; do i=is,ie
563  eta1d(nz+1) = -g%bathyT(i,j)
564  do k=nz,1,-1
565  eta1d(k) = -g%max_depth * real(k-1) / real(nz)
566  if (eta1d(k) < (eta1d(k+1) + min_thickness)) then
567  eta1d(k) = eta1d(k+1) + min_thickness
568  h(i,j,k) = min_thickness * gv%Z_to_H
569  else
570  h(i,j,k) = gv%Z_to_H*(eta1d(k) - eta1d(k+1))
571  endif
572  enddo
573  enddo ; enddo
574 
575  case ( regridding_sigma ) ! Initial thicknesses for sigma coordinates
576  do j=js,je ; do i=is,ie
577  h(i,j,:) = gv%Z_to_H * (g%bathyT(i,j) / dfloat(nz))
578  enddo ; enddo
579 
580  case default
581  call mom_error(fatal,"ISOMIP_initialize_sponges: "// &
582  "Unrecognized i.c. setup - set REGRIDDING_COORDINATE_MODE")
583 
584  end select
585 
586  ! This call sets up the damping rates and interface heights.
587  ! This sets the inverse damping timescale fields in the sponges.
588  call initialize_ale_sponge(idamp, g, pf, acsp, h, nz)
589 
590  ds_dz = (s_sur - s_bot) / g%max_depth
591  dt_dz = (t_sur - t_bot) / g%max_depth
592  do j=js,je ; do i=is,ie
593  xi0 = -g%bathyT(i,j)
594  do k = nz,1,-1
595  xi0 = xi0 + 0.5 * h(i,j,k) * gv%H_to_Z ! Depth in middle of layer
596  s(i,j,k) = s_sur + ds_dz * xi0
597  t(i,j,k) = t_sur + dt_dz * xi0
598  xi0 = xi0 + 0.5 * h(i,j,k) * gv%H_to_Z ! Depth at top of layer
599  enddo
600  enddo ; enddo
601  ! for debugging
602  !i=G%iec; j=G%jec
603  !do k = 1,nz
604  ! call calculate_density(T(i,j,k),S(i,j,k),0.0,rho_tmp,tv%eqn_of_state)
605  ! write(mesg,*) 'Sponge - k,h,T,S,rho,Rlay',k,h(i,j,k),T(i,j,k),S(i,j,k),rho_tmp,GV%Rlay(k)
606  ! call MOM_mesg(mesg,5)
607  !enddo
608 
609  ! Now register all of the fields which are damped in the sponge. !
610  ! By default, momentum is advected vertically within the sponge, but !
611  ! momentum is typically not damped within the sponge. !
612 
613  ! The remaining calls to set_up_sponge_field can be in any order. !
614  if ( associated(tv%T) ) then
615  call set_up_ale_sponge_field(t, g, tv%T, acsp)
616  endif
617  if ( associated(tv%S) ) then
618  call set_up_ale_sponge_field(s, g, tv%S, acsp)
619  endif
620 
621  else ! layer mode
622  ! 1) Read eta, salt and temp from IC file
623  call get_param(pf, mdl, "INPUTDIR", inputdir, default=".")
624  inputdir = slasher(inputdir)
625  ! GM: get two different files, one with temp and one with salt values
626  ! this is work around to avoid having wrong values near the surface
627  ! because of the FIT_SALINITY option. To get salt values right in the
628  ! sponge, FIT_SALINITY=False. The oposite is true for temp. One can
629  ! combined the *correct* temp and salt values in one file instead.
630  call get_param(pf, mdl, "ISOMIP_SPONGE_FILE", state_file, &
631  "The name of the file with temps., salts. and interfaces to "//&
632  "damp toward.", fail_if_missing=.true.)
633  call get_param(pf, mdl, "SPONGE_PTEMP_VAR", temp_var, &
634  "The name of the potential temperature variable in "//&
635  "SPONGE_STATE_FILE.", default="Temp")
636  call get_param(pf, mdl, "SPONGE_SALT_VAR", salt_var, &
637  "The name of the salinity variable in "//&
638  "SPONGE_STATE_FILE.", default="Salt")
639  call get_param(pf, mdl, "SPONGE_ETA_VAR", eta_var, &
640  "The name of the interface height variable in "//&
641  "SPONGE_STATE_FILE.", default="eta")
642 
643  !read temp and eta
644  filename = trim(inputdir)//trim(state_file)
645  if (.not.file_exists(filename, g%Domain)) call mom_error(fatal, &
646  "ISOMIP_initialize_sponges: Unable to open "//trim(filename))
647  call mom_read_data(filename, eta_var, eta(:,:,:), g%Domain, scale=us%m_to_Z)
648  call mom_read_data(filename, temp_var, t(:,:,:), g%Domain)
649  call mom_read_data(filename, salt_var, s(:,:,:), g%Domain)
650 
651  ! for debugging
652  !i=G%iec; j=G%jec
653  !do k = 1,nz
654  ! call calculate_density(T(i,j,k),S(i,j,k),0.0,rho_tmp,tv%eqn_of_state)
655  ! write(mesg,*) 'Sponge - k,eta,T,S,rho,Rlay',k,eta(i,j,k),T(i,j,k),&
656  ! S(i,j,k),rho_tmp,GV%Rlay(k)
657  ! call MOM_mesg(mesg,5)
658  !enddo
659 
660  ! Set the inverse damping rates so that the model will know where to
661  ! apply the sponges, along with the interface heights.
662  call initialize_sponge(idamp, eta, g, pf, csp, gv)
663  ! Apply sponge in tracer fields
664  call set_up_sponge_field(t, tv%T, g, nz, csp)
665  call set_up_sponge_field(s, tv%S, g, nz, csp)
666 
667  endif
668 
669 end subroutine isomip_initialize_sponges
670 
671 !> \namespace isomip_initialization
672 !!
673 !! See this paper for details: http://www.geosci-model-dev-discuss.net/8/9859/2015/gmdd-8-9859-2015.pdf
674 end module isomip_initialization
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_ale_sponge::initialize_ale_sponge
Ddetermine the number of points which are within sponges in this computational domain.
Definition: MOM_ALE_sponge.F90:49
mom_dyn_horgrid
Contains a shareable dynamic type for describing horizontal grids and metric data and utilty routines...
Definition: MOM_dyn_horgrid.F90:3
mom_ale_sponge::ale_sponge_cs
ALE sponge control structure.
Definition: MOM_ALE_sponge.F90:85
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_ale_sponge
This module contains the routines used to apply sponge layers when using the ALE mode.
Definition: MOM_ALE_sponge.F90:11
mom_io
This module contains I/O framework code.
Definition: MOM_io.F90:2
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_ale_sponge::set_up_ale_sponge_field
Store the reference profile at h points for a variable.
Definition: MOM_ALE_sponge.F90:34
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_io::mom_read_data
Read a data field from a file.
Definition: MOM_io.F90:74
mom_file_parser
The MOM6 facility to parse input files for runtime parameters.
Definition: MOM_file_parser.F90:2
mom_sponge
Implements sponge regions in isopycnal mode.
Definition: MOM_sponge.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_sponge::sponge_cs
This control structure holds memory and parameters for the MOM_sponge module.
Definition: MOM_sponge.F90:40
mom_unit_scaling
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Definition: MOM_unit_scaling.F90:2
mom_io::file_exists
Indicate whether a file exists, perhaps with domain decomposition.
Definition: MOM_io.F90:68
mom_error_handler
Routines for error handling and I/O management.
Definition: MOM_error_handler.F90:2
mom_dyn_horgrid::dyn_horgrid_type
Describes the horizontal ocean grid with only dynamic memory arrays.
Definition: MOM_dyn_horgrid.F90:22
mom_grid::ocean_grid_type
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:25
isomip_initialization
Configures the ISOMIP test case.
Definition: ISOMIP_initialization.F90:2
mom_eos::calculate_density
Calculates density of sea water from T, S and P.
Definition: MOM_EOS.F90:60