MOM6
user_surface_forcing Module Reference

Data Types

type  user_surface_forcing_cs
 

Functions/Subroutines

subroutine, public user_wind_forcing (state, fluxes, day, G, CS)
 
subroutine, public user_buoyancy_forcing (state, fluxes, day, dt, G, CS)
 
subroutine alloc_if_needed (ptr, isd, ied, jsd, jed)
 
subroutine, public user_surface_forcing_init (Time, G, param_file, diag, CS)
 

Function/Subroutine Documentation

◆ alloc_if_needed()

subroutine user_surface_forcing::alloc_if_needed ( real, dimension(:,:), pointer  ptr,
integer  isd,
integer  ied,
integer  jsd,
integer  jed 
)
private

Definition at line 308 of file user_surface_forcing.F90.

Referenced by user_buoyancy_forcing().

308  ! If ptr is not associated, this routine allocates it with the given size
309  ! and zeros out its contents. This is equivalent to safe_alloc_ptr in
310  ! MOM_diag_mediator, but is here so as to be completely transparent.
311  real, pointer :: ptr(:,:)
312  integer :: isd, ied, jsd, jed
313  if (.not.ASSOCIATED(ptr)) then
314  allocate(ptr(isd:ied,jsd:jed))
315  ptr(:,:) = 0.0
316  endif
Here is the caller graph for this function:

◆ user_buoyancy_forcing()

subroutine, public user_surface_forcing::user_buoyancy_forcing ( type(surface), intent(inout)  state,
type(forcing), intent(inout)  fluxes,
type(time_type), intent(in)  day,
real, intent(in)  dt,
type(ocean_grid_type), intent(in)  G,
type(user_surface_forcing_cs), pointer  CS 
)
Parameters
[in]dtThe amount of time over which the fluxes apply, in s
[in]gThe ocean's grid structure

Definition at line 166 of file user_surface_forcing.F90.

References alloc_if_needed(), and mom_error_handler::mom_error().

166  type(surface), intent(inout) :: state
167  type(forcing), intent(inout) :: fluxes
168  type(time_type), intent(in) :: day
169  real, intent(in) :: dt !< The amount of time over which
170  !! the fluxes apply, in s
171  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
172  type(user_surface_forcing_cs), pointer :: cs
173 
174 ! This subroutine specifies the current surface fluxes of buoyancy or
175 ! temperature and fresh water. It may also be modified to add
176 ! surface fluxes of user provided tracers.
177 
178 ! When temperature is used, there are long list of fluxes that need to be
179 ! set - essentially the same as for a full coupled model, but most of these
180 ! can be simply set to zero. The net fresh water flux should probably be
181 ! set in fluxes%evap and fluxes%lprec, with any salinity restoring
182 ! appearing in fluxes%vprec, and the other water flux components
183 ! (fprec, lrunoff and frunoff) left as arrays full of zeros.
184 ! Evap is usually negative and precip is usually positive. All heat fluxes
185 ! are in W m-2 and positive for heat going into the ocean. All fresh water
186 ! fluxes are in kg m-2 s-1 and positive for water moving into the ocean.
187 
188 ! Arguments: state - A structure containing fields that describe the
189 ! surface state of the ocean.
190 ! (out) fluxes - A structure containing pointers to any possible
191 ! forcing fields. Unused fields have NULL ptrs.
192 ! (in) day_start - Start time of the fluxes.
193 ! (in) day_interval - Length of time over which these fluxes
194 ! will be applied.
195 ! (in) G - The ocean's grid structure.
196 ! (in) CS - A pointer to the control structure returned by a previous
197 ! call to user_surface_forcing_init
198 
199  real :: temp_restore ! The temperature that is being restored toward, in C.
200  real :: salin_restore ! The salinity that is being restored toward, in PSU.
201  real :: density_restore ! The potential density that is being restored
202  ! toward, in kg m-3.
203  real :: rhoxcp ! The mean density times the heat capacity, in J m-3 K-1.
204  real :: buoy_rest_const ! A constant relating density anomalies to the
205  ! restoring buoyancy flux, in m5 s-3 kg-1.
206 
207  integer :: i, j, is, ie, js, je
208  integer :: isd, ied, jsd, jed
209 
210  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
211  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
212 
213  ! When modifying the code, comment out this error message. It is here
214  ! so that the original (unmodified) version is not accidentally used.
215  call mom_error(fatal, "User_buoyancy_surface_forcing: " // &
216  "User forcing routine called without modification." )
217 
218  ! Allocate and zero out the forcing arrays, as necessary. This portion is
219  ! usually not changed.
220  if (cs%use_temperature) then
221  call alloc_if_needed(fluxes%evap, isd, ied, jsd, jed)
222  call alloc_if_needed(fluxes%lprec, isd, ied, jsd, jed)
223  call alloc_if_needed(fluxes%fprec, isd, ied, jsd, jed)
224  call alloc_if_needed(fluxes%lrunoff, isd, ied, jsd, jed)
225  call alloc_if_needed(fluxes%frunoff, isd, ied, jsd, jed)
226  call alloc_if_needed(fluxes%vprec, isd, ied, jsd, jed)
227 
228  call alloc_if_needed(fluxes%sw, isd, ied, jsd, jed)
229  call alloc_if_needed(fluxes%lw, isd, ied, jsd, jed)
230  call alloc_if_needed(fluxes%latent, isd, ied, jsd, jed)
231  call alloc_if_needed(fluxes%sens, isd, ied, jsd, jed)
232  else ! This is the buoyancy only mode.
233  call alloc_if_needed(fluxes%buoy, isd, ied, jsd, jed)
234  endif
235 
236 
237  ! MODIFY THE CODE IN THE FOLLOWING LOOPS TO SET THE BUOYANCY FORCING TERMS.
238 
239  if ( cs%use_temperature ) then
240  ! Set whichever fluxes are to be used here. Any fluxes that
241  ! are always zero do not need to be changed here.
242  do j=js,je ; do i=is,ie
243  ! Fluxes of fresh water through the surface are in units of kg m-2 s-1
244  ! and are positive downward - i.e. evaporation should be negative.
245  fluxes%evap(i,j) = -0.0 * g%mask2dT(i,j)
246  fluxes%lprec(i,j) = 0.0 * g%mask2dT(i,j)
247 
248  ! vprec will be set later, if it is needed for salinity restoring.
249  fluxes%vprec(i,j) = 0.0
250 
251  ! Heat fluxes are in units of W m-2 and are positive into the ocean.
252  fluxes%lw(i,j) = 0.0 * g%mask2dT(i,j)
253  fluxes%latent(i,j) = 0.0 * g%mask2dT(i,j)
254  fluxes%sens(i,j) = 0.0 * g%mask2dT(i,j)
255  fluxes%sw(i,j) = 0.0 * g%mask2dT(i,j)
256  enddo ; enddo
257  else ! This is the buoyancy only mode.
258  do j=js,je ; do i=is,ie
259  ! fluxes%buoy is the buoyancy flux into the ocean in m2 s-3. A positive
260  ! buoyancy flux is of the same sign as heating the ocean.
261  fluxes%buoy(i,j) = 0.0 * g%mask2dT(i,j)
262  enddo ; enddo
263  endif
264 
265  if (cs%restorebuoy) then
266  if (cs%use_temperature) then
267  call alloc_if_needed(fluxes%heat_added, isd, ied, jsd, jed)
268  ! When modifying the code, comment out this error message. It is here
269  ! so that the original (unmodified) version is not accidentally used.
270  call mom_error(fatal, "User_buoyancy_surface_forcing: " // &
271  "Temperature and salinity restoring used without modification." )
272 
273  rhoxcp = cs%Rho0 * fluxes%C_p
274  do j=js,je ; do i=is,ie
275  ! Set Temp_restore and Salin_restore to the temperature (in C) and
276  ! salinity (in PSU) that are being restored toward.
277  temp_restore = 0.0
278  salin_restore = 0.0
279 
280  fluxes%heat_added(i,j) = (g%mask2dT(i,j) * (rhoxcp * cs%Flux_const)) * &
281  (temp_restore - state%SST(i,j))
282  fluxes%vprec(i,j) = - (g%mask2dT(i,j) * (cs%Rho0*cs%Flux_const)) * &
283  ((salin_restore - state%SSS(i,j)) / &
284  (0.5 * (salin_restore + state%SSS(i,j))))
285  enddo ; enddo
286  else
287  ! When modifying the code, comment out this error message. It is here
288  ! so that the original (unmodified) version is not accidentally used.
289  call mom_error(fatal, "User_buoyancy_surface_forcing: " // &
290  "Buoyancy restoring used without modification." )
291 
292  ! The -1 is because density has the opposite sign to buoyancy.
293  buoy_rest_const = -1.0 * (cs%G_Earth * cs%Flux_const) / cs%Rho0
294  do j=js,je ; do i=is,ie
295  ! Set density_restore to an expression for the surface potential
296  ! density in kg m-3 that is being restored toward.
297  density_restore = 1030.0
298 
299  fluxes%buoy(i,j) = g%mask2dT(i,j) * buoy_rest_const * &
300  (density_restore - state%sfc_density(i,j))
301  enddo ; enddo
302  endif
303  endif ! end RESTOREBUOY
304 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:

◆ user_surface_forcing_init()

subroutine, public user_surface_forcing::user_surface_forcing_init ( type(time_type), intent(in)  Time,
type(ocean_grid_type), intent(in)  G,
type(param_file_type), intent(in)  param_file,
type(diag_ctrl), intent(in), target  diag,
type(user_surface_forcing_cs), pointer  CS 
)
Parameters
[in]gThe ocean's grid structure
[in]param_fileA structure to parse for run-time parameters

Definition at line 320 of file user_surface_forcing.F90.

References mom_error_handler::mom_error().

320  type(time_type), intent(in) :: time
321  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
322  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters
323  type(diag_ctrl), target, intent(in) :: diag
324  type(user_surface_forcing_cs), pointer :: cs
325 ! Arguments: Time - The current model time.
326 ! (in) G - The ocean's grid structure.
327 ! (in) param_file - A structure indicating the open file to parse for
328 ! model parameter values.
329 ! (in) diag - A structure that is used to regulate diagnostic output.
330 ! (in/out) CS - A pointer that is set to point to the control structure
331 ! for this module
332 
333 ! This include declares and sets the variable "version".
334 #include "version_variable.h"
335  character(len=40) :: mdl = "user_surface_forcing" ! This module's name.
336 
337  if (associated(cs)) then
338  call mom_error(warning, "USER_surface_forcing_init called with an associated "// &
339  "control structure.")
340  return
341  endif
342  allocate(cs)
343  cs%diag => diag
344 
345  ! Read all relevant parameters and write them to the model log.
346  call log_version(param_file, mdl, version, "")
347  call get_param(param_file, mdl, "ENABLE_THERMODYNAMICS", cs%use_temperature, &
348  "If true, Temperature and salinity are used as state \n"//&
349  "variables.", default=.true.)
350 
351  call get_param(param_file, mdl, "G_EARTH", cs%G_Earth, &
352  "The gravitational acceleration of the Earth.", &
353  units="m s-2", default = 9.80)
354  call get_param(param_file, mdl, "RHO_0", cs%Rho0, &
355  "The mean ocean density used with BOUSSINESQ true to \n"//&
356  "calculate accelerations and the mass for conservation \n"//&
357  "properties, or with BOUSSINSEQ false to convert some \n"//&
358  "parameters from vertical units of m to kg m-2.", &
359  units="kg m-3", default=1035.0)
360  call get_param(param_file, mdl, "GUST_CONST", cs%gust_const, &
361  "The background gustiness in the winds.", units="Pa", &
362  default=0.02)
363 
364  call get_param(param_file, mdl, "RESTOREBUOY", cs%restorebuoy, &
365  "If true, the buoyancy fluxes drive the model back \n"//&
366  "toward some specified surface state with a rate \n"//&
367  "given by FLUXCONST.", default= .false.)
368  if (cs%restorebuoy) then
369  call get_param(param_file, mdl, "FLUXCONST", cs%Flux_const, &
370  "The constant that relates the restoring surface fluxes \n"//&
371  "to the relative surface anomalies (akin to a piston \n"//&
372  "velocity). Note the non-MKS units.", units="m day-1", &
373  fail_if_missing=.true.)
374  ! Convert CS%Flux_const from m day-1 to m s-1.
375  cs%Flux_const = cs%Flux_const / 86400.0
376  endif
377 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:

◆ user_wind_forcing()

subroutine, public user_surface_forcing::user_wind_forcing ( type(surface), intent(inout)  state,
type(forcing), intent(inout)  fluxes,
type(time_type), intent(in)  day,
type(ocean_grid_type), intent(inout)  G,
type(user_surface_forcing_cs), pointer  CS 
)
Parameters
[in,out]gThe ocean's grid structure

Definition at line 105 of file user_surface_forcing.F90.

References mom_forcing_type::allocate_forcing_type(), and mom_error_handler::mom_error().

105  type(surface), intent(inout) :: state
106  type(forcing), intent(inout) :: fluxes
107  type(time_type), intent(in) :: day
108  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure
109  type(user_surface_forcing_cs), pointer :: cs
110 
111 ! This subroutine sets the surface wind stresses, fluxes%taux and fluxes%tauy.
112 ! These are the stresses in the direction of the model grid (i.e. the same
113 ! direction as the u- and v- velocities.) They are both in Pa.
114 ! In addition, this subroutine can be used to set the surface friction
115 ! velocity, fluxes%ustar, in m s-1. This is needed with a bulk mixed layer.
116 !
117 ! Arguments: state - A structure containing fields that describe the
118 ! surface state of the ocean.
119 ! (out) fluxes - A structure containing pointers to any possible
120 ! forcing fields. Unused fields have NULL ptrs.
121 ! (in) day - Time of the fluxes.
122 ! (in) G - The ocean's grid structure.
123 ! (in) CS - A pointer to the control structure returned by a previous
124 ! call to user_surface_forcing_init
125 
126  integer :: i, j, is, ie, js, je, isq, ieq, jsq, jeq
127  integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb
128 
129  ! When modifying the code, comment out this error message. It is here
130  ! so that the original (unmodified) version is not accidentally used.
131  call mom_error(fatal, "User_wind_surface_forcing: " // &
132  "User forcing routine called without modification." )
133 
134  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
135  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
136  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
137  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
138 
139  ! Allocate the forcing arrays, if necessary.
140  call allocate_forcing_type(g, fluxes, stress=.true., ustar=.true.)
141 
142  ! Set the surface wind stresses, in units of Pa. A positive taux
143  ! accelerates the ocean to the (pseudo-)east.
144 
145  ! The i-loop extends to is-1 so that taux can be used later in the
146  ! calculation of ustar - otherwise the lower bound would be Isq.
147  do j=js,je ; do i=is-1,ieq
148  fluxes%taux(i,j) = g%mask2dCu(i,j) * 0.0 ! Change this to the desired expression.
149  enddo ; enddo
150  do j=js-1,jeq ; do i=is,ie
151  fluxes%tauy(i,j) = g%mask2dCv(i,j) * 0.0 ! Change this to the desired expression.
152  enddo ; enddo
153 
154  ! Set the surface friction velocity, in units of m s-1. ustar
155  ! is always positive.
156  if (associated(fluxes%ustar)) then ; do j=js,je ; do i=is,ie
157  ! This expression can be changed if desired, but need not be.
158  fluxes%ustar(i,j) = g%mask2dT(i,j) * sqrt(cs%gust_const/cs%Rho0 + &
159  sqrt(0.5*(fluxes%taux(i-1,j)**2 + fluxes%taux(i,j)**2) + &
160  0.5*(fluxes%tauy(i,j-1)**2 + fluxes%tauy(i,j)**2))/cs%Rho0)
161  enddo ; enddo ; endif
162 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function: