MOM6
phillips_initialization Module Reference

Detailed Description

Initialization for the "Phillips" channel configuration.

By Robert Hallberg, April 1994 - June 2002

This subroutine initializes the fields for the simulations. The one argument passed to initialize, Time, is set to the current time of the simulation. The fields which are initialized here are: u - Zonal velocity [m s-1]. v - Meridional velocity [m s-1]. h - Layer thickness in m. (Must be positive.) D - Basin depth in m. (Must be positive.) f - The Coriolis parameter [s-1]. g - The reduced gravity at each interface [m s-2] Rlay - Layer potential density (coordinate variable) [kg m-3]. If ENABLE_THERMODYNAMICS is defined: T - Temperature [degC]. S - Salinity [ppt]. If SPONGE is defined: A series of subroutine calls are made to set up the damping rates and reference profiles for all variables that are damped in the sponge. Any user provided tracer code is also first linked through this subroutine.

Forcing-related fields (taux, tauy, buoy, ustar, etc.) are set in MOM_surface_forcing.F90.

These variables are all set in the set of subroutines (in this file) Phillips_initialize_thickness, Phillips_initialize_velocity, Phillips_initialize_topography and Phillips_initialize_sponges that seet up fields that are specific to the Phillips instability test case.

Functions/Subroutines

subroutine, public phillips_initialize_thickness (h, G, GV, US, param_file, just_read_params)
 Initialize the thickness field for the Phillips model test case. More...
 
subroutine, public phillips_initialize_velocity (u, v, G, GV, US, param_file, just_read_params)
 Initialize the velocity fields for the Phillips model test case. More...
 
subroutine, public phillips_initialize_sponges (G, GV, US, tv, param_file, CSp, h)
 Sets up the 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 for the Phillips model test case. More...
 
real function sech (x)
 sech calculates the hyperbolic secant. More...
 
subroutine, public phillips_initialize_topography (D, G, param_file, max_depth, US)
 Initialize topography. More...
 

Function/Subroutine Documentation

◆ phillips_initialize_sponges()

subroutine, public phillips_initialization::phillips_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)  param_file,
type(sponge_cs), pointer  CSp,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h 
)

Sets up the 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 for the Phillips model test case.

Parameters
[in]gThe ocean's grid structure.
[in]gvVertical grid structure
[in]usA dimensional unit scaling type
[in]tvA structure containing pointers to any available thermodynamic fields, potential temperature and salinity or mixed layer density. Absent fields have NULL ptrs.
[in]param_fileA structure indicating the open file to parse for model parameter values.
cspA pointer that is set to point to the control structure for the sponge module.
[in]hThickness field [H ~> m or kg m-2].

Definition at line 198 of file Phillips_initialization.F90.

198  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
199  type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure
200  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
201  type(thermo_var_ptrs), intent(in) :: tv !< A structure containing pointers
202  !! to any available thermodynamic
203  !! fields, potential temperature and
204  !! salinity or mixed layer density.
205  !! Absent fields have NULL ptrs.
206  type(param_file_type), intent(in) :: param_file !< A structure indicating the
207  !! open file to parse for model
208  !! parameter values.
209  type(sponge_CS), pointer :: CSp !< A pointer that is set to point to
210  !! the control structure for the
211  !! sponge module.
212  real, intent(in), dimension(SZI_(G),SZJ_(G),SZK_(GV)) :: h !< Thickness field [H ~> m or kg m-2].
213 
214  ! Local variables
215  real :: eta0(SZK_(G)+1) ! The 1-d nominal positions of the interfaces.
216  real :: eta(SZI_(G),SZJ_(G),SZK_(G)+1) ! A temporary array for eta [Z ~> m].
217  real :: temp(SZI_(G),SZJ_(G),SZK_(G)) ! A temporary array for other variables.
218  real :: Idamp(SZI_(G),SZJ_(G)) ! The inverse damping rate [s-1].
219  real :: eta_im(SZJ_(G),SZK_(G)+1) ! A temporary array for zonal-mean eta [Z ~> m].
220  real :: Idamp_im(SZJ_(G)) ! The inverse zonal-mean damping rate [s-1].
221  real :: damp_rate ! The inverse zonal-mean damping rate [s-1].
222  real :: jet_width ! The width of the zonal mean jet, in km.
223  real :: jet_height ! The interface height scale associated with the zonal-mean jet [Z ~> m].
224  real :: y_2 ! The y-position relative to the channel center, in km.
225  real :: half_strat ! The fractional depth where the straficiation is centered [nondim].
226  real :: half_depth ! The depth where the stratification is centered [Z ~> m].
227  character(len=40) :: mdl = "Phillips_initialize_sponges" ! This subroutine's name.
228 
229  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
230  logical, save :: first_call = .true.
231 
232  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
233  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
234 
235  eta(:,:,:) = 0.0 ; temp(:,:,:) = 0.0 ; idamp(:,:) = 0.0
236  eta_im(:,:) = 0.0 ; idamp_im(:) = 0.0
237 
238  if (first_call) call log_version(param_file, mdl, version)
239  first_call = .false.
240  call get_param(param_file, mdl, "HALF_STRAT_DEPTH", half_strat, &
241  "The fractional depth where the stratificaiton is centered.", &
242  units="nondim", default = 0.5)
243  call get_param(param_file, mdl, "SPONGE_RATE", damp_rate, &
244  "The rate at which the zonal-mean sponges damp.", units="s-1", &
245  default = 1.0/(10.0*86400.0))
246 
247  call get_param(param_file, mdl, "JET_WIDTH", jet_width, &
248  "The width of the zonal-mean jet.", units="km", &
249  fail_if_missing=.true.)
250  call get_param(param_file, mdl, "JET_HEIGHT", jet_height, &
251  "The interface height scale associated with the "//&
252  "zonal-mean jet.", units="m", scale=us%m_to_Z, &
253  fail_if_missing=.true.)
254 
255  half_depth = g%max_depth*half_strat
256  eta0(1) = 0.0 ; eta0(nz+1) = -g%max_depth
257  do k=2,1+nz/2 ; eta0(k) = -half_depth*(2.0*(k-1)/real(nz)) ; enddo
258  do k=2+nz/2,nz+1
259  eta0(k) = -g%max_depth - 2.0*(g%max_depth-half_depth) * ((k-(nz+1))/real(nz))
260  enddo
261 
262  do j=js,je
263  idamp_im(j) = damp_rate
264  eta_im(j,1) = 0.0 ; eta_im(j,nz+1) = -g%max_depth
265  enddo
266  do k=2,nz ; do j=js,je
267  y_2 = g%geoLatT(is,j) - g%south_lat - 0.5*g%len_lat
268  eta_im(j,k) = eta0(k) + jet_height * tanh(y_2 / jet_width)
269 ! jet_height * atan(y_2 / jet_width)
270  if (eta_im(j,k) > 0.0) eta_im(j,k) = 0.0
271  if (eta_im(j,k) < -g%max_depth) eta_im(j,k) = -g%max_depth
272  enddo ; enddo
273 
274  call initialize_sponge(idamp, eta, g, param_file, csp, gv, idamp_im, eta_im)
275 

◆ phillips_initialize_thickness()

subroutine, public phillips_initialization::phillips_initialize_thickness ( real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(out)  h,
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,
logical, intent(in), optional  just_read_params 
)

Initialize the thickness field for the Phillips model test case.

Parameters
[in]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in]usA dimensional unit scaling type
[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 39 of file Phillips_initialization.F90.

39  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
40  type(verticalGrid_type), intent(in) :: GV !< The ocean's vertical grid structure.
41  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
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  real :: eta0(SZK_(G)+1) ! The 1-d nominal positions of the interfaces [Z ~> m]
50  real :: eta_im(SZJ_(G),SZK_(G)+1) ! A temporary array for zonal-mean eta [Z ~> m]
51  real :: eta1D(SZK_(G)+1) ! Interface height relative to the sea surface, positive upward [Z ~> m]
52  real :: jet_width ! The width of the zonal-mean jet [km]
53  real :: jet_height ! The interface height scale associated with the zonal-mean jet [Z ~> m]
54  real :: y_2
55  real :: half_strat ! The fractional depth where the stratification is centered [nondim]
56  real :: half_depth ! The depth where the stratification is centered [Z ~> m]
57  logical :: just_read ! If true, just read parameters but set nothing.
58  character(len=40) :: mdl = "Phillips_initialize_thickness" ! This subroutine's name.
59  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
60 
61  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
62  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
63 
64  eta_im(:,:) = 0.0
65 
66  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
67 
68  if (.not.just_read) call log_version(param_file, mdl, version)
69  call get_param(param_file, mdl, "HALF_STRAT_DEPTH", half_strat, &
70  "The fractional depth where the stratification is centered.", &
71  units="nondim", default = 0.5, do_not_log=just_read)
72  call get_param(param_file, mdl, "JET_WIDTH", jet_width, &
73  "The width of the zonal-mean jet.", units="km", &
74  fail_if_missing=.not.just_read, do_not_log=just_read)
75  call get_param(param_file, mdl, "JET_HEIGHT", jet_height, &
76  "The interface height scale associated with the "//&
77  "zonal-mean jet.", units="m", scale=us%m_to_Z, &
78  fail_if_missing=.not.just_read, do_not_log=just_read)
79 
80  if (just_read) return ! All run-time parameters have been read, so return.
81 
82  half_depth = g%max_depth*half_strat
83  eta0(1) = 0.0 ; eta0(nz+1) = -g%max_depth
84  do k=2,1+nz/2 ; eta0(k) = -half_depth*(2.0*(k-1)/real(nz)) ; enddo
85  do k=2+nz/2,nz+1
86  eta0(k) = -g%max_depth - 2.0*(g%max_depth-half_depth) * ((k-(nz+1))/real(nz))
87  enddo
88 
89  do j=js,je
90  eta_im(j,1) = 0.0 ; eta_im(j,nz+1) = -g%max_depth
91  enddo
92  do k=2,nz ; do j=js,je
93  y_2 = g%geoLatT(is,j) - g%south_lat - 0.5*g%len_lat
94  eta_im(j,k) = eta0(k) + jet_height * tanh(y_2 / jet_width)
95  ! or ... + jet_height * atan(y_2 / jet_width)
96  if (eta_im(j,k) > 0.0) eta_im(j,k) = 0.0
97  if (eta_im(j,k) < -g%max_depth) eta_im(j,k) = -g%max_depth
98  enddo ; enddo
99 
100  do j=js,je ; do i=is,ie
101  ! This sets the initial thickness in [H ~> m or kg m-2] of the layers. The
102  ! thicknesses are set to insure that: 1. each layer is at least an Angstrom thick, and
103  ! 2. the interfaces are where they should be based on the resting depths and interface
104  ! height perturbations, as long at this doesn't interfere with 1.
105  eta1d(nz+1) = -g%bathyT(i,j)
106  do k=nz,1,-1
107  eta1d(k) = eta_im(j,k)
108  if (eta1d(k) < (eta1d(k+1) + gv%Angstrom_Z)) then
109  eta1d(k) = eta1d(k+1) + gv%Angstrom_Z
110  h(i,j,k) = gv%Angstrom_H
111  else
112  h(i,j,k) = gv%Z_to_H * (eta1d(k) - eta1d(k+1))
113  endif
114  enddo
115  enddo ; enddo
116 

◆ phillips_initialize_topography()

subroutine, public phillips_initialization::phillips_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 
)

Initialize 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 293 of file Phillips_initialization.F90.

293  type(dyn_horgrid_type), intent(in) :: G !< The dynamic horizontal grid type
294  real, dimension(G%isd:G%ied,G%jsd:G%jed), &
295  intent(out) :: D !< Ocean bottom depth in m or Z if US is present
296  type(param_file_type), intent(in) :: param_file !< Parameter file structure
297  real, intent(in) :: max_depth !< Maximum model depth in the units of D
298  type(unit_scale_type), optional, intent(in) :: US !< A dimensional unit scaling type
299 
300  ! Local variables
301  real :: m_to_Z ! A dimensional rescaling factor.
302  real :: PI, Htop, Wtop, Ltop, offset, dist
303  real :: x1, x2, x3, x4, y1, y2
304  integer :: i,j,is,ie,js,je
305  character(len=40) :: mdl = "Phillips_initialize_topography" ! This subroutine's name.
306 
307  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
308 
309  pi = 4.0*atan(1.0)
310  m_to_z = 1.0 ; if (present(us)) m_to_z = us%m_to_Z
311 
312  call get_param(param_file, mdl, "PHILLIPS_HTOP", htop, &
313  "The maximum height of the topography.", units="m", scale=m_to_z, &
314  fail_if_missing=.true.)
315 ! Htop=0.375*max_depth ! max height of topog. above max_depth
316  wtop = 0.5*g%len_lat ! meridional width of drake and mount
317  ltop = 0.25*g%len_lon ! zonal width of topographic features
318  offset = 0.1*g%len_lat ! meridional offset from center
319  dist = 0.333*g%len_lon ! distance between drake and mount
320  ! should be longer than Ltop/2
321 
322  y1=g%south_lat+0.5*g%len_lat+offset-0.5*wtop; y2=y1+wtop
323  x1=g%west_lon+0.1*g%len_lon; x2=x1+ltop; x3=x1+dist; x4=x3+3.0/2.0*ltop
324 
325  do i=is,ie ; do j=js,je
326  d(i,j)=0.0
327  if (g%geoLonT(i,j)>x1 .and. g%geoLonT(i,j)<x2) then
328  d(i,j) = htop*sin(pi*(g%geoLonT(i,j)-x1)/(x2-x1))**2
329  if (g%geoLatT(i,j)>y1 .and. g%geoLatT(i,j)<y2) then
330  d(i,j) = d(i,j)*(1-sin(pi*(g%geoLatT(i,j)-y1)/(y2-y1))**2)
331  endif
332  elseif (g%geoLonT(i,j)>x3 .and. g%geoLonT(i,j)<x4 .and. &
333  g%geoLatT(i,j)>y1 .and. g%geoLatT(i,j)<y2) then
334  d(i,j) = 2.0/3.0*htop*sin(pi*(g%geoLonT(i,j)-x3)/(x4-x3))**2 &
335  *sin(pi*(g%geoLatT(i,j)-y1)/(y2-y1))**2
336  endif
337  d(i,j) = max_depth - d(i,j)
338  enddo ; enddo
339 

◆ phillips_initialize_velocity()

subroutine, public phillips_initialization::phillips_initialize_velocity ( real, dimension( g %isdb: g %iedb, g %jsd: g %jed, g %ke), intent(out)  u,
real, dimension( g %isd: g %ied, g %jsdb: g %jedb, g %ke), intent(out)  v,
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,
logical, intent(in), optional  just_read_params 
)

Initialize the velocity fields for the Phillips model test case.

Parameters
[in]gGrid structure
[in]gvVertical grid structure
[in]usA dimensional unit scaling type
[out]ui-component of velocity [m s-1]
[out]vj-component of velocity [m s-1]
[in]param_fileA structure indicating the open file to parse for modelparameter values.
[in]just_read_paramsIf present and true, this call will only read parameters without changing h.

Definition at line 121 of file Phillips_initialization.F90.

121  type(ocean_grid_type), intent(in) :: G !< Grid structure
122  type(verticalGrid_type), intent(in) :: GV !< Vertical grid structure
123  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
124  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
125  intent(out) :: u !< i-component of velocity [m s-1]
126  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
127  intent(out) :: v !< j-component of velocity [m s-1]
128  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to
129  !! parse for modelparameter values.
130  logical, optional, intent(in) :: just_read_params !< If present and true, this call will
131  !! only read parameters without changing h.
132 
133  real :: jet_width, jet_height, x_2, y_2
134  real :: velocity_amplitude, pi
135  integer :: i, j, k, is, ie, js, je, nz, m
136  logical :: just_read ! If true, just read parameters but set nothing.
137  character(len=40) :: mdl = "Phillips_initialize_velocity" ! This subroutine's name.
138  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
139 
140  just_read = .false. ; if (present(just_read_params)) just_read = just_read_params
141 
142  if (.not.just_read) call log_version(param_file, mdl, version)
143  call get_param(param_file, mdl, "VELOCITY_IC_PERTURB_AMP", velocity_amplitude, &
144  "The magnitude of the initial velocity perturbation.", &
145  units="m s-1", default=0.001, do_not_log=just_read)
146  call get_param(param_file, mdl, "JET_WIDTH", jet_width, &
147  "The width of the zonal-mean jet.", units="km", &
148  fail_if_missing=.not.just_read, do_not_log=just_read)
149  call get_param(param_file, mdl, "JET_HEIGHT", jet_height, &
150  "The interface height scale associated with the "//&
151  "zonal-mean jet.", units="m", scale=us%m_to_Z, &
152  fail_if_missing=.not.just_read, do_not_log=just_read)
153 
154  if (just_read) return ! All run-time parameters have been read, so return.
155 
156  u(:,:,:) = 0.0
157  v(:,:,:) = 0.0
158 
159  pi = 4.0*atan(1.0)
160 
161  ! Use thermal wind shear to give a geostrophically balanced flow.
162  do k=nz-1,1 ; do j=js,je ; do i=is-1,ie
163  y_2 = g%geoLatCu(i,j) - g%south_lat - 0.5*g%len_lat
164 ! This uses d/d y_2 atan(y_2 / jet_width)
165 ! u(I,j,k) = u(I,j,k+1) + (1e-3 * jet_height / &
166 ! (jet_width * (1.0 + (y_2 / jet_width)**2))) * &
167 ! (2.0 * US%L_to_m**2*US%s_to_T**2*GV%g_prime(K+1) * US%T_to_s / (G%CoriolisBu(I,J) + G%CoriolisBu(I,J-1)))
168 ! This uses d/d y_2 tanh(y_2 / jet_width)
169  u(i,j,k) = u(i,j,k+1) + (1e-3 * (jet_height / jet_width) * &
170  (sech(y_2 / jet_width))**2 ) * &
171  (2.0 * us%L_to_m**2*us%s_to_T**2*gv%g_prime(k+1) * us%T_to_s / (g%CoriolisBu(i,j) + g%CoriolisBu(i,j-1)))
172  enddo ; enddo ; enddo
173 
174  do k=1,nz ; do j=js,je ; do i=is-1,ie
175  y_2 = (g%geoLatCu(i,j) - g%south_lat - 0.5*g%len_lat) / g%len_lat
176  x_2 = (g%geoLonCu(i,j) - g%west_lon - 0.5*g%len_lon) / g%len_lon
177  if (g%geoLonCu(i,j) == g%west_lon) then
178  ! This modification is required so that the perturbations are identical for
179  ! symmetric and non-symmetric memory. It is exactly equivalent to
180  ! taking the longitude at the eastern edge of the domain, so that x_2 ~= 0.5.
181  x_2 = ((g%west_lon + g%len_lon*real(g%ieg-(g%isg-1))/real(g%Domain%niglobal)) - &
182  g%west_lon - 0.5*g%len_lon) / g%len_lon
183  endif
184  u(i,j,k) = u(i,j,k) + velocity_amplitude * ((real(k)-0.5)/real(nz)) * &
185  (0.5 - abs(2.0*x_2) + 0.1*abs(cos(10.0*pi*x_2)) - abs(sin(5.0*pi*y_2)))
186  do m=1,10
187  u(i,j,k) = u(i,j,k) + 0.2*velocity_amplitude * ((real(k)-0.5)/real(nz)) * &
188  cos(2.0*m*pi*x_2 + 2*m) * cos(6.0*pi*y_2)
189  enddo
190  enddo ; enddo ; enddo
191 

◆ sech()

real function phillips_initialization::sech ( real, intent(in)  x)
private

sech calculates the hyperbolic secant.

Parameters
[in]xInput value.
Returns
Result.

Definition at line 280 of file Phillips_initialization.F90.

280  real, intent(in) :: x !< Input value.
281  real :: sech !< Result.
282 
283  ! This is here to prevent overflows or underflows.
284  if (abs(x) > 228.) then
285  sech = 0.0
286  else
287  sech = 2.0 / (exp(x) + exp(-x))
288  endif