MOM6
benchmark_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
32 
33 implicit none ; private
34 
35 #include <MOM_memory.h>
36 
40 
41 contains
42 
43 ! -----------------------------------------------------------------------------
44 !> This subroutine sets up the benchmark test case topography.
45 subroutine benchmark_initialize_topography(D, G, param_file, max_depth)
46  type(dyn_horgrid_type), intent(in) :: G !< The dynamic horizontal grid type
47  real, dimension(G%isd:G%ied,G%jsd:G%jed), &
48  intent(out) :: D !< Ocean bottom depth in m
49  type(param_file_type), intent(in) :: param_file !< Parameter file structure
50  real, intent(in) :: max_depth !< Maximum depth of model in m
51 
52 ! This subroutine sets up the benchmark test case topography
53  real :: min_depth ! The minimum and maximum depths in m.
54  real :: PI ! 3.1415926... calculated as 4*atan(1)
55  real :: D0 ! A constant to make the maximum !
56  ! basin depth MAXIMUM_DEPTH. !
57  real :: x, y
58 ! This include declares and sets the variable "version".
59 #include "version_variable.h"
60  character(len=40) :: mdl = "benchmark_initialize_topography" ! This subroutine's name.
61  integer :: i, j, is, ie, js, je, isd, ied, jsd, jed
62  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
63  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
64 
65  call mom_mesg(" benchmark_initialization.F90, benchmark_initialize_topography: setting topography", 5)
66 
67  call log_version(param_file, mdl, version, "")
68  call get_param(param_file, mdl, "MINIMUM_DEPTH", min_depth, &
69  "The minimum depth of the ocean.", units="m", default=0.0)
70 
71  pi = 4.0*atan(1.0)
72  d0 = max_depth / 0.5;
73 
74 ! Calculate the depth of the bottom.
75  do i=is,ie ; do j=js,je
76  x=(g%geoLonT(i,j)-g%west_lon)/g%len_lon
77  y=(g%geoLatT(i,j)-g%south_lat)/g%len_lat
78 ! This sets topography that has a reentrant channel to the south.
79  d(i,j) = -d0 * ( y*(1.0 + 0.6*cos(4.0*pi*x)) &
80  + 0.75*exp(-6.0*y) &
81  + 0.05*cos(10.0*pi*x) - 0.7 )
82  if (d(i,j) > max_depth) d(i,j) = max_depth
83  if (d(i,j) < min_depth) d(i,j) = 0.
84  enddo ; enddo
85 
87 ! -----------------------------------------------------------------------------
88 
89 ! -----------------------------------------------------------------------------
90 !> This subroutine initializes layer thicknesses for the benchmark test case,
91 !! by finding the depths of interfaces in a specified latitude-dependent
92 !! temperature profile with an exponentially decaying thermocline on top of a
93 !! linear stratification.
94 subroutine benchmark_initialize_thickness(h, G, GV, param_file, eqn_of_state, &
95  P_ref, just_read_params)
96  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
97  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
98  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), &
99  intent(out) :: h !< The thickness that is being initialized, in m.
100  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file
101  !! to parse for model parameter values.
102  type(eos_type), pointer :: eqn_of_state !< integer that selects the
103  !! equation of state.
104  real, intent(in) :: P_Ref !< The coordinate-density
105  !! reference pressure in Pa.
106  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
107  !! only read parameters without changing h.
108 
109  real :: e0(szk_(gv)+1) ! The resting interface heights, in m, usually !
110  ! negative because it is positive upward. !
111  real :: e_pert(szk_(gv)+1) ! Interface height perturbations, positive !
112  ! upward, in m. !
113  real :: eta1D(szk_(gv)+1) ! Interface height relative to the sea surface !
114  ! positive upward, in m. !
115  real :: SST ! The initial sea surface temperature, in deg C.
116  real :: T_int ! The initial temperature of an interface, in deg C.
117  real :: ML_depth ! The specified initial mixed layer depth, in m.
118  real :: thermocline_scale ! The e-folding scale of the thermocline, in m.
119  real, dimension(SZK_(GV)) :: T0, pres, S0, rho_guess, drho, drho_dT, drho_dS
120  real :: a_exp ! The fraction of the overall stratification that is exponential.
121  real :: I_ts, I_md ! Inverse lengthscales in m-1.
122  real :: T_frac ! A ratio of the interface temperature to the range
123  ! between SST and the bottom temperature.
124  real :: err, derr_dz ! The error between the profile's temperature and the
125  ! interface temperature for a given z and its derivative.
126  real :: pi, z
127  logical :: just_read
128  character(len=40) :: mdl = "benchmark_initialize_thickness" ! This subroutine's name.
129  integer :: i, j, k, k1, is, ie, js, je, nz, itt
130 
131  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
132 
133  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
134 
135  if (just_read) return ! This subroutine has no run-time parameters.
136 
137  call mom_mesg(" benchmark_initialization.F90, benchmark_initialize_thickness: setting thickness", 5)
138 
139  k1 = gv%nk_rho_varies + 1
140 
141  ml_depth = 50.0
142  thermocline_scale = 500.0
143  a_exp = 0.9
144 
145 ! This block calculates T0(k) for the purpose of diagnosing where the
146 ! interfaces will be found.
147  do k=1,nz
148  pres(k) = p_ref ; s0(k) = 35.0
149  enddo
150  t0(k1) = 29.0
151  call calculate_density(t0(k1),s0(k1),pres(k1),rho_guess(k1),eqn_of_state)
152  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,k1,1,eqn_of_state)
153 
154 ! A first guess of the layers' temperatures.
155  do k=1,nz
156  t0(k) = t0(k1) + (gv%Rlay(k) - rho_guess(k1)) / drho_dt(k1)
157  enddo
158 
159 ! Refine the guesses for each layer.
160  do itt=1,6
161  call calculate_density(t0,s0,pres,rho_guess,1,nz,eqn_of_state)
162  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,1,nz,eqn_of_state)
163  do k=1,nz
164  t0(k) = t0(k) + (gv%Rlay(k) - rho_guess(k)) / drho_dt(k)
165  enddo
166  enddo
167 
168  pi = 4.0*atan(1.0)
169  i_ts = 1.0 / thermocline_scale
170  i_md = 1.0 / g%max_depth
171  do j=js,je ; do i=is,ie
172  sst = 0.5*(t0(k1)+t0(nz)) - 0.9*0.5*(t0(k1)-t0(nz)) * &
173  cos(pi*(g%geoLatT(i,j)-g%south_lat)/(g%len_lat))
174 
175  do k=1,nz ; e_pert(k) = 0.0 ; enddo
176 
177 ! The remainder of this subroutine should not be changed. !
178 
179 ! This sets the initial thickness (in m) of the layers. The !
180 ! thicknesses are set to insure that: 1. each layer is at least !
181 ! Gv%Angstrom_z thick, and 2. the interfaces are where they should be !
182 ! based on the resting depths and interface height perturbations, !
183 ! as long at this doesn't interfere with 1. !
184  eta1d(nz+1) = -1.0*g%bathyT(i,j)
185 
186  do k=nz,2,-1
187  t_int = 0.5*(t0(k) + t0(k-1))
188  t_frac = (t_int - t0(nz)) / (sst - t0(nz))
189  ! Find the z such that T_frac = a exp(z/thermocline_scale) + (1-a) (z+D)/D
190  z = 0.0
191  do itt=1,6
192  err = a_exp * exp(z*i_ts) + (1.0 - a_exp) * (z*i_md + 1.0) - t_frac
193  derr_dz = a_exp * i_ts * exp(z*i_ts) + (1.0 - a_exp) * i_md
194  z = z - err / derr_dz
195  enddo
196  e0(k) = z
197 ! e0(K) = -ML_depth + thermocline_scale * log((T_int - T0(nz)) / (SST - T0(nz)))
198 
199  eta1d(k) = e0(k) + e_pert(k)
200 
201  if (eta1d(k) > -ml_depth) eta1d(k) = -ml_depth
202 
203  if (eta1d(k) < eta1d(k+1) + gv%Angstrom_z) &
204  eta1d(k) = eta1d(k+1) + gv%Angstrom_z
205 
206  h(i,j,k) = max(eta1d(k) - eta1d(k+1), gv%Angstrom_z)
207  enddo
208  h(i,j,1) = max(0.0 - eta1d(2), gv%Angstrom_z)
209 
210  enddo ; enddo
211 
212 end subroutine benchmark_initialize_thickness
213 ! -----------------------------------------------------------------------------
214 
215 ! -----------------------------------------------------------------------------
216 !> This function puts the initial layer temperatures and salinities
217 !! into T(:,:,:) and S(:,:,:).
218 subroutine benchmark_init_temperature_salinity(T, S, G, GV, param_file, &
219  eqn_of_state, P_Ref, just_read_params)
220  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
221  type(verticalgrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
222  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: T !< The potential temperature
223  !! that is being initialized.
224  real, dimension(SZI_(G),SZJ_(G), SZK_(G)), intent(out) :: S !< The salinity that is being
225  !! initialized.
226  type(param_file_type), intent(in) :: param_file !< A structure indicating the
227  !! open file to parse for
228  !! model parameter values.
229  type(eos_type), pointer :: eqn_of_state !< integer that selects the
230  !! equation of state.
231  real, intent(in) :: P_Ref !< The coordinate-density
232  !! reference pressure in Pa.
233  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
234  !! only read parameters without changing h.
235 
236  real :: T0(szk_(g)), S0(szk_(g))
237  real :: pres(szk_(g)) ! Reference pressure in kg m-3. !
238  real :: drho_dT(szk_(g)) ! Derivative of density with temperature in !
239  ! kg m-3 K-1. !
240  real :: drho_dS(szk_(g)) ! Derivative of density with salinity in !
241  ! kg m-3 PSU-1. !
242  real :: rho_guess(szk_(g)) ! Potential density at T0 & S0 in kg m-3. !
243  real :: PI ! 3.1415926... calculated as 4*atan(1)
244  real :: SST ! The initial sea surface temperature, in deg C.
245  real :: lat
246  logical :: just_read ! If true, just read parameters but set nothing.
247  character(len=40) :: mdl = "benchmark_init_temperature_salinity" ! This subroutine's name.
248  integer :: i, j, k, k1, is, ie, js, je, nz, itt
249 
250  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
251 
252  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
253 
254  if (just_read) return ! All run-time parameters have been read, so return.
255 
256  k1 = gv%nk_rho_varies + 1
257 
258  do k=1,nz
259  pres(k) = p_ref ; s0(k) = 35.0
260  enddo
261 
262  t0(k1) = 29.0
263  call calculate_density(t0(k1),s0(k1),pres(k1),rho_guess(k1),eqn_of_state)
264  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,k1,1,eqn_of_state)
265 
266 ! A first guess of the layers' temperatures. !
267  do k=1,nz
268  t0(k) = t0(k1) + (gv%Rlay(k) - rho_guess(k1)) / drho_dt(k1)
269  enddo
270 
271 ! Refine the guesses for each layer. !
272  do itt = 1,6
273  call calculate_density(t0,s0,pres,rho_guess,1,nz,eqn_of_state)
274  call calculate_density_derivs(t0,s0,pres,drho_dt,drho_ds,1,nz,eqn_of_state)
275  do k=1,nz
276  t0(k) = t0(k) + (gv%Rlay(k) - rho_guess(k)) / drho_dt(k)
277  enddo
278  enddo
279 
280  do k=1,nz ; do i=is,ie ; do j=js,je
281  t(i,j,k) = t0(k)
282  s(i,j,k) = s0(k)
283  enddo ; enddo ; enddo
284  pi = 4.0*atan(1.0)
285  do i=is,ie ; do j=js,je
286  sst = 0.5*(t0(k1)+t0(nz)) - 0.9*0.5*(t0(k1)-t0(nz)) * &
287  cos(pi*(g%geoLatT(i,j)-g%south_lat)/(g%len_lat))
288  do k=1,k1-1
289  t(i,j,k) = sst
290  enddo
291  enddo ; enddo
292 
294 ! -----------------------------------------------------------------------------
295 
296 !! \namespace benchmark_initialization
297 !!
298 !! The module configures the model for the benchmark experiment.
299 end module benchmark_initialization
subroutine, public benchmark_init_temperature_salinity(T, S, G, GV, param_file, eqn_of_state, P_Ref, just_read_params)
This function puts the initial layer temperatures and salinities into T(:,:,:) and S(:...
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
subroutine, public benchmark_initialize_topography(D, G, param_file, max_depth)
This subroutine sets up the benchmark test case topography.
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 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 ...
subroutine, public benchmark_initialize_thickness(h, G, GV, param_file, eqn_of_state, P_ref, just_read_params)
This subroutine initializes layer thicknesses for the benchmark test case, by finding the depths of i...
subroutine, public mom_error(level, message, all_print)
A control structure for the equation of state.
Definition: MOM_EOS.F90:55