MOM6
meso_surface_forcing Module Reference

Detailed Description

Sets forcing for the MESO configuration.

Rewritten by Robert Hallberg, June 2009

This file contains the subroutines that a user should modify to to set the surface wind stresses and fluxes of buoyancy or temperature and fresh water. They are called when the run-time parameters WIND_CONFIG or BUOY_CONFIG are set to "USER". The standard version has simple examples, along with run-time error messages that will cause the model to abort if this code has not been modified. This code is intended for use with relatively simple specifications of the forcing. For more complicated forms, it is probably a good idea to read the forcing from input files using "file" for WIND_CONFIG and BUOY_CONFIG.

MESO_buoyancy forcing is used to set the surface buoyancy forcing, which may include a number of fresh water flux fields (evap, liq_precip, froz_precip, liq_runoff, froz_runoff, and vprec) and the surface heat fluxes (sw, lw, latent and sens) if temperature and salinity are state variables, or it may simply be the buoyancy flux if it is not. This routine also has coded a restoring to surface values of temperature and salinity.

Data Types

type  meso_surface_forcing_cs
 This control structure is used to store parameters associated with the MESO forcing. More...
 

Functions/Subroutines

subroutine, public meso_buoyancy_forcing (sfc_state, fluxes, day, dt, G, US, CS)
 This subroutine sets up the MESO buoyancy forcing, which uses control-theory style specification restorative buoyancy fluxes at large scales. More...
 
subroutine, public meso_surface_forcing_init (Time, G, US, param_file, diag, CS)
 Initialize the MESO surface forcing module. More...
 

Variables

logical first_call = .true.
 True until after the first call to the MESO forcing routines. More...
 

Function/Subroutine Documentation

◆ meso_buoyancy_forcing()

subroutine, public meso_surface_forcing::meso_buoyancy_forcing ( type(surface), intent(inout)  sfc_state,
type(forcing), intent(inout)  fluxes,
type(time_type), intent(in)  day,
real, intent(in)  dt,
type(ocean_grid_type), intent(in)  G,
type(unit_scale_type), intent(in)  US,
type(meso_surface_forcing_cs), pointer  CS 
)

This subroutine sets up the MESO buoyancy forcing, which uses control-theory style specification restorative buoyancy fluxes at large scales.

Parameters
[in,out]sfc_stateA structure containing fields that describe the surface state of the ocean.
[in,out]fluxesA structure containing thermodynamic forcing fields
[in]dayThe time of the fluxes
[in]dtThe amount of time over which the fluxes apply [s]
[in]gThe ocean's grid structure
[in]usA dimensional unit scaling type
csA pointer to the control structure returned by a previous call to MESO_surface_forcing_init

Definition at line 59 of file MESO_surface_forcing.F90.

59  type(surface), intent(inout) :: sfc_state !< A structure containing fields that
60  !! describe the surface state of the ocean.
61  type(forcing), intent(inout) :: fluxes !< A structure containing thermodynamic forcing fields
62  type(time_type), intent(in) :: day !< The time of the fluxes
63  real, intent(in) :: dt !< The amount of time over which
64  !! the fluxes apply [s]
65  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure
66  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
67  type(MESO_surface_forcing_CS), pointer :: CS !< A pointer to the control structure returned by
68  !! a previous call to MESO_surface_forcing_init
69 
70 ! When temperature is used, there are long list of fluxes that need to be
71 ! set - essentially the same as for a full coupled model, but most of these
72 ! can be simply set to zero. The net fresh water flux should probably be
73 ! set in fluxes%evap and fluxes%lprec, with any salinity restoring
74 ! appearing in fluxes%vprec, and the other water flux components
75 ! (fprec, lrunoff and frunoff) left as arrays full of zeros.
76 ! Evap is usually negative and precip is usually positive. All heat fluxes
77 ! are in W m-2 and positive for heat going into the ocean. All fresh water
78 ! fluxes are in kg m-2 s-1 and positive for water moving into the ocean.
79 
80  real :: Temp_restore ! The temperature that is being restored toward [degC].
81  real :: Salin_restore ! The salinity that is being restored toward [ppt]
82  real :: density_restore ! The potential density that is being restored
83  ! toward [kg m-3].
84  real :: rhoXcp ! The mean density times the heat capacity [J m-3 degC-1].
85  real :: buoy_rest_const ! A constant relating density anomalies to the
86  ! restoring buoyancy flux [L2 T-3 R-1 ~> m5 s-3 kg-1].
87 
88  integer :: i, j, is, ie, js, je
89  integer :: isd, ied, jsd, jed
90 
91  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
92  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
93 
94  ! When modifying the code, comment out this error message. It is here
95  ! so that the original (unmodified) version is not accidentally used.
96 
97  ! Allocate and zero out the forcing arrays, as necessary. This portion is
98  ! usually not changed.
99  if (cs%use_temperature) then
100  call safe_alloc_ptr(fluxes%evap, isd, ied, jsd, jed)
101  call safe_alloc_ptr(fluxes%lprec, isd, ied, jsd, jed)
102  call safe_alloc_ptr(fluxes%fprec, isd, ied, jsd, jed)
103  call safe_alloc_ptr(fluxes%lrunoff, isd, ied, jsd, jed)
104  call safe_alloc_ptr(fluxes%frunoff, isd, ied, jsd, jed)
105  call safe_alloc_ptr(fluxes%vprec, isd, ied, jsd, jed)
106 
107  call safe_alloc_ptr(fluxes%sw, isd, ied, jsd, jed)
108  call safe_alloc_ptr(fluxes%lw, isd, ied, jsd, jed)
109  call safe_alloc_ptr(fluxes%latent, isd, ied, jsd, jed)
110  call safe_alloc_ptr(fluxes%sens, isd, ied, jsd, jed)
111  call safe_alloc_ptr(fluxes%heat_content_lprec, isd, ied, jsd, jed)
112  else ! This is the buoyancy only mode.
113  call safe_alloc_ptr(fluxes%buoy, isd, ied, jsd, jed)
114  endif
115 
116 
117  ! MODIFY THE CODE IN THE FOLLOWING LOOPS TO SET THE BUOYANCY FORCING TERMS.
118  if (cs%restorebuoy .and. first_call) then !#CTRL# .or. associated(CS%ctrl_forcing_CSp)) then
119  call safe_alloc_ptr(cs%T_Restore, isd, ied, jsd, jed)
120  call safe_alloc_ptr(cs%S_Restore, isd, ied, jsd, jed)
121  call safe_alloc_ptr(cs%Heat, isd, ied, jsd, jed)
122  call safe_alloc_ptr(cs%PmE, isd, ied, jsd, jed)
123  call safe_alloc_ptr(cs%Solar, isd, ied, jsd, jed)
124 
125  call mom_read_data(trim(cs%inputdir)//trim(cs%SSTrestore_file), "SST", &
126  cs%T_Restore(:,:), g%Domain)
127  call mom_read_data(trim(cs%inputdir)//trim(cs%salinityrestore_file), "SAL", &
128  cs%S_Restore(:,:), g%Domain)
129  call mom_read_data(trim(cs%inputdir)//trim(cs%heating_file), "Heat", &
130  cs%Heat(:,:), g%Domain)
131  call mom_read_data(trim(cs%inputdir)//trim(cs%PmE_file), "PmE", &
132  cs%PmE(:,:), g%Domain)
133  call mom_read_data(trim(cs%inputdir)//trim(cs%Solar_file), "NET_SOL", &
134  cs%Solar(:,:), g%Domain)
135  first_call = .false.
136  endif
137 
138  if ( cs%use_temperature ) then
139  ! Set whichever fluxes are to be used here. Any fluxes that
140  ! are always zero do not need to be changed here.
141  do j=js,je ; do i=is,ie
142  ! Fluxes of fresh water through the surface are in units of [kg m-2 s-1]
143  ! and are positive downward - i.e. evaporation should be negative.
144  fluxes%evap(i,j) = -0.0 * g%mask2dT(i,j)
145  fluxes%lprec(i,j) = us%m_to_Z*us%T_to_s * cs%PmE(i,j) * cs%Rho0 * g%mask2dT(i,j)
146 
147  ! vprec will be set later, if it is needed for salinity restoring.
148  fluxes%vprec(i,j) = 0.0
149 
150  ! Heat fluxes are in units of [W m-2] and are positive into the ocean.
151  fluxes%lw(i,j) = 0.0 * g%mask2dT(i,j)
152  fluxes%latent(i,j) = 0.0 * g%mask2dT(i,j)
153  fluxes%sens(i,j) = cs%Heat(i,j) * g%mask2dT(i,j)
154  fluxes%sw(i,j) = cs%Solar(i,j) * g%mask2dT(i,j)
155  enddo ; enddo
156  else ! This is the buoyancy only mode.
157  do j=js,je ; do i=is,ie
158  ! fluxes%buoy is the buoyancy flux into the ocean [L2 T-3 ~> m2 s-3]. A positive
159  ! buoyancy flux is of the same sign as heating the ocean.
160  fluxes%buoy(i,j) = 0.0 * g%mask2dT(i,j)
161  enddo ; enddo
162  endif
163 
164  if (cs%restorebuoy) then
165  if (cs%use_temperature) then
166  call safe_alloc_ptr(fluxes%heat_added, isd, ied, jsd, jed)
167  ! When modifying the code, comment out this error message. It is here
168  ! so that the original (unmodified) version is not accidentally used.
169 ! call MOM_error(FATAL, "MESO_buoyancy_surface_forcing: " // &
170 ! "Temperature and salinity restoring used without modification." )
171 
172  rhoxcp = us%R_to_kg_m3*cs%Rho0 * fluxes%C_p
173  do j=js,je ; do i=is,ie
174  ! Set Temp_restore and Salin_restore to the temperature (in degC) and
175  ! salinity (in ppt or PSU) that are being restored toward.
176  if (g%mask2dT(i,j) > 0) then
177  fluxes%heat_added(i,j) = g%mask2dT(i,j) * &
178  ((cs%T_Restore(i,j) - sfc_state%SST(i,j)) * rhoxcp * us%Z_to_m*us%s_to_T*cs%Flux_const)
179  fluxes%vprec(i,j) = - (cs%Rho0 * cs%Flux_const) * &
180  (cs%S_Restore(i,j) - sfc_state%SSS(i,j)) / &
181  (0.5*(sfc_state%SSS(i,j) + cs%S_Restore(i,j)))
182  else
183  fluxes%heat_added(i,j) = 0.0
184  fluxes%vprec(i,j) = 0.0
185  endif
186  enddo ; enddo
187  else
188  ! When modifying the code, comment out this error message. It is here
189  ! so that the original (unmodified) version is not accidentally used.
190  call mom_error(fatal, "MESO_buoyancy_surface_forcing: " // &
191  "Buoyancy restoring used without modification." )
192 
193  ! The -1 is because density has the opposite sign to buoyancy.
194  buoy_rest_const = -1.0 * (cs%G_Earth * cs%Flux_const) / cs%Rho0
195  do j=js,je ; do i=is,ie
196  ! Set density_restore to an expression for the surface potential
197  ! density [kg m-3] that is being restored toward.
198  density_restore = 1030.0
199 
200  fluxes%buoy(i,j) = g%mask2dT(i,j) * buoy_rest_const * &
201  us%kg_m3_to_R * (density_restore - sfc_state%sfc_density(i,j))
202  enddo ; enddo
203  endif
204  endif ! end RESTOREBUOY
205 

References first_call, and mom_error_handler::mom_error().

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(unit_scale_type), intent(in)  US,
type(param_file_type), intent(in)  param_file,
type(diag_ctrl), intent(inout), target  diag,
type(meso_surface_forcing_cs), pointer  CS 
)

Initialize the MESO surface forcing module.

Parameters
[in]timeThe current model time
[in]gThe ocean's grid structure
[in]usA dimensional unit scaling type
[in]param_fileA structure to parse for run-time parameters
[in,out]diagstructure used to regulate diagnostic output
csA pointer that is set to point to the control structure for this module

Definition at line 210 of file MESO_surface_forcing.F90.

210 
211  type(time_type), intent(in) :: Time !< The current model time
212  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure
213  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
214  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time parameters
215  type(diag_ctrl), target, intent(inout) :: diag !< structure used to regulate diagnostic output
216  type(MESO_surface_forcing_CS), pointer :: CS !< A pointer that is set to point to the
217  !! control structure for this module
218 
219 ! This include declares and sets the variable "version".
220 #include "version_variable.h"
221  character(len=40) :: mdl = "MESO_surface_forcing" ! This module's name.
222 
223  if (associated(cs)) then
224  call mom_error(warning, "MESO_surface_forcing_init called with an associated "// &
225  "control structure.")
226  return
227  endif
228  allocate(cs)
229  cs%diag => diag
230 
231  ! Read all relevant parameters and write them to the model log.
232  call log_version(param_file, mdl, version, "")
233  call get_param(param_file, mdl, "ENABLE_THERMODYNAMICS", cs%use_temperature, &
234  "If true, Temperature and salinity are used as state "//&
235  "variables.", default=.true.)
236 
237  call get_param(param_file, mdl, "G_EARTH", cs%G_Earth, &
238  "The gravitational acceleration of the Earth.", &
239  units="m s-2", default = 9.80, scale=us%m_to_L**2*us%Z_to_m*us%T_to_s**2)
240  call get_param(param_file, mdl, "RHO_0", cs%Rho0, &
241  "The mean ocean density used with BOUSSINESQ true to "//&
242  "calculate accelerations and the mass for conservation "//&
243  "properties, or with BOUSSINSEQ false to convert some "//&
244  "parameters from vertical units of m to kg m-2.", &
245  units="kg m-3", default=1035.0, scale=us%kg_m3_to_R)
246  call get_param(param_file, mdl, "GUST_CONST", cs%gust_const, &
247  "The background gustiness in the winds.", units="Pa", &
248  default=0.02)
249 
250  call get_param(param_file, mdl, "RESTOREBUOY", cs%restorebuoy, &
251  "If true, the buoyancy fluxes drive the model back "//&
252  "toward some specified surface state with a rate "//&
253  "given by FLUXCONST.", default= .false.)
254 
255  if (cs%restorebuoy) then
256  call get_param(param_file, mdl, "FLUXCONST", cs%Flux_const, &
257  "The constant that relates the restoring surface fluxes "//&
258  "to the relative surface anomalies (akin to a piston "//&
259  "velocity). Note the non-MKS units.", &
260  units="m day-1", scale=us%m_to_Z/(86400.0*us%s_to_T), &
261  fail_if_missing=.true.)
262 
263  call get_param(param_file, mdl, "SSTRESTORE_FILE", cs%SSTrestore_file, &
264  "The file with the SST toward which to restore in "//&
265  "variable TEMP.", fail_if_missing=.true.)
266  call get_param(param_file, mdl, "SALINITYRESTORE_FILE", cs%salinityrestore_file, &
267  "The file with the surface salinity toward which to "//&
268  "restore in variable SALT.", fail_if_missing=.true.)
269  call get_param(param_file, mdl, "SENSIBLEHEAT_FILE", cs%heating_file, &
270  "The file with the non-shortwave heat flux in "//&
271  "variable Heat.", fail_if_missing=.true.)
272  call get_param(param_file, mdl, "PRECIP_FILE", cs%PmE_file, &
273  "The file with the net precipiation minus evaporation "//&
274  "in variable PmE.", fail_if_missing=.true.)
275  call get_param(param_file, mdl, "SHORTWAVE_FILE", cs%Solar_file, &
276  "The file with the shortwave heat flux in "//&
277  "variable NET_SOL.", fail_if_missing=.true.)
278  call get_param(param_file, mdl, "INPUTDIR", cs%inputdir, default=".")
279  cs%inputdir = slasher(cs%inputdir)
280 
281  endif
282 

References mom_error_handler::mom_error().

Referenced by mom_surface_forcing::surface_forcing_init().

Here is the call graph for this function:
Here is the caller graph for this function:

Variable Documentation

◆ first_call

logical meso_surface_forcing::first_call = .true.

True until after the first call to the MESO forcing routines.

Definition at line 52 of file MESO_surface_forcing.F90.

52 logical :: first_call = .true. !< True until after the first call to the MESO forcing routines

Referenced by meso_buoyancy_forcing().