MOM6
meso_surface_forcing Module Reference

Data Types

type  meso_surface_forcing_cs
 

Functions/Subroutines

subroutine, public meso_wind_forcing (state, fluxes, day, G, CS)
 
subroutine, public meso_buoyancy_forcing (state, fluxes, day, dt, G, CS)
 
subroutine alloc_if_needed (ptr, isd, ied, jsd, jed)
 
subroutine, public meso_surface_forcing_init (Time, G, param_file, diag, CS)
 

Variables

logical first_call = .true.
 

Function/Subroutine Documentation

◆ alloc_if_needed()

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

Definition at line 340 of file MESO_surface_forcing.F90.

Referenced by meso_buoyancy_forcing().

340  ! If ptr is not associated, this routine allocates it with the given size
341  ! and zeros out its contents. This is equivalent to safe_alloc_ptr in
342  ! MOM_diag_mediator, but is here so as to be completely transparent.
343  real, pointer :: ptr(:,:)
344  integer :: isd, ied, jsd, jed
345  if (.not.ASSOCIATED(ptr)) then
346  allocate(ptr(isd:ied,jsd:jed))
347  ptr(:,:) = 0.0
348  endif
Here is the caller graph for this function:

◆ meso_buoyancy_forcing()

subroutine, public meso_surface_forcing::meso_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(meso_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 178 of file MESO_surface_forcing.F90.

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

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

◆ meso_surface_forcing_init()

subroutine, public meso_surface_forcing::meso_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(meso_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 352 of file MESO_surface_forcing.F90.

References mom_error_handler::mom_error().

352  type(time_type), intent(in) :: time
353  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
354  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters
355  type(diag_ctrl), target, intent(in) :: diag
356  type(meso_surface_forcing_cs), pointer :: cs
357 ! Arguments: Time - The current model time.
358 ! (in) G - The ocean's grid structure.
359 ! (in) param_file - A structure indicating the open file to parse for
360 ! model parameter values.
361 ! (in) diag - A structure that is used to regulate diagnostic output.
362 ! (in/out) CS - A pointer that is set to point to the control structure
363 ! for this module
364 
365 ! This include declares and sets the variable "version".
366 #include "version_variable.h"
367  character(len=40) :: mdl = "MESO_surface_forcing" ! This module's name.
368 
369  if (associated(cs)) then
370  call mom_error(warning, "MESO_surface_forcing_init called with an associated "// &
371  "control structure.")
372  return
373  endif
374  allocate(cs)
375  cs%diag => diag
376 
377  ! Read all relevant parameters and write them to the model log.
378  call log_version(param_file, mdl, version, "")
379  call get_param(param_file, mdl, "ENABLE_THERMODYNAMICS", cs%use_temperature, &
380  "If true, Temperature and salinity are used as state \n"//&
381  "variables.", default=.true.)
382 
383  call get_param(param_file, mdl, "G_EARTH", cs%G_Earth, &
384  "The gravitational acceleration of the Earth.", &
385  units="m s-2", default = 9.80)
386  call get_param(param_file, mdl, "RHO_0", cs%Rho0, &
387  "The mean ocean density used with BOUSSINESQ true to \n"//&
388  "calculate accelerations and the mass for conservation \n"//&
389  "properties, or with BOUSSINSEQ false to convert some \n"//&
390  "parameters from vertical units of m to kg m-2.", &
391  units="kg m-3", default=1035.0)
392  call get_param(param_file, mdl, "GUST_CONST", cs%gust_const, &
393  "The background gustiness in the winds.", units="Pa", &
394  default=0.02)
395 
396  call get_param(param_file, mdl, "RESTOREBUOY", cs%restorebuoy, &
397  "If true, the buoyancy fluxes drive the model back \n"//&
398  "toward some specified surface state with a rate \n"//&
399  "given by FLUXCONST.", default= .false.)
400 
401  if (cs%restorebuoy) then
402  call get_param(param_file, mdl, "FLUXCONST", cs%Flux_const, &
403  "The constant that relates the restoring surface fluxes \n"//&
404  "to the relative surface anomalies (akin to a piston \n"//&
405  "velocity). Note the non-MKS units.", units="m day-1", &
406  fail_if_missing=.true.)
407  ! Convert CS%Flux_const from m day-1 to m s-1.
408  cs%Flux_const = cs%Flux_const / 86400.0
409 
410  call get_param(param_file, mdl, "SSTRESTORE_FILE", cs%SSTrestore_file, &
411  "The file with the SST toward which to restore in \n"//&
412  "variable TEMP.", fail_if_missing=.true.)
413  call get_param(param_file, mdl, "SALINITYRESTORE_FILE", cs%salinityrestore_file, &
414  "The file with the surface salinity toward which to \n"//&
415  "restore in variable SALT.", fail_if_missing=.true.)
416  call get_param(param_file, mdl, "SENSIBLEHEAT_FILE", cs%heating_file, &
417  "The file with the non-shortwave heat flux in \n"//&
418  "variable Heat.", fail_if_missing=.true.)
419  call get_param(param_file, mdl, "PRECIP_FILE", cs%PmE_file, &
420  "The file with the net precipiation minus evaporation \n"//&
421  "in variable PmE.", fail_if_missing=.true.)
422  call get_param(param_file, mdl, "SHORTWAVE_FILE", cs%Solar_file, &
423  "The file with the shortwave heat flux in \n"//&
424  "variable NET_SOL.", fail_if_missing=.true.)
425  call get_param(param_file, mdl, "INPUTDIR", cs%inputdir, default=".")
426  cs%inputdir = slasher(cs%inputdir)
427 
428  endif
429 
Here is the call graph for this function:

◆ meso_wind_forcing()

subroutine, public meso_surface_forcing::meso_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(meso_surface_forcing_cs), pointer  CS 
)
Parameters
[in,out]gThe ocean's grid structure

Definition at line 117 of file MESO_surface_forcing.F90.

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

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

Variable Documentation

◆ first_call

logical meso_surface_forcing::first_call = .true.

Definition at line 112 of file MESO_surface_forcing.F90.

Referenced by meso_buoyancy_forcing().

112 logical :: first_call = .true.