MOM6
neverland_surface_forcing Module Reference

Detailed Description

Wind and buoyancy forcing for the Neverland configurations.

Data Types

type  neverland_surface_forcing_cs
 This control structure should be used to store any run-time variables associated with the Neverland forcing. More...
 

Functions/Subroutines

subroutine, public neverland_wind_forcing (sfc_state, forces, day, G, US, CS)
 Sets the surface wind stresses, forcestaux and forcestauy for the Neverland forcing configuration. More...
 
real function cosbell (x, L)
 Returns the value of a cosine-bell function evaluated at x/L. More...
 
real function spike (x, L)
 Returns the value of a sin-spike function evaluated at x/L. More...
 
subroutine, public neverland_buoyancy_forcing (sfc_state, fluxes, day, dt, G, US, CS)
 Surface fluxes of buoyancy for the Neverland configurations. More...
 
subroutine, public neverland_surface_forcing_init (Time, G, US, param_file, diag, CS)
 Initializes the Neverland control structure. More...
 

Function/Subroutine Documentation

◆ cosbell()

real function neverland_surface_forcing::cosbell ( real, intent(in)  x,
real, intent(in)  L 
)
private

Returns the value of a cosine-bell function evaluated at x/L.

Parameters
[in]xnon-dimensional position
[in]lnon-dimensional width

Definition at line 117 of file Neverland_surface_forcing.F90.

117 
118  real , intent(in) :: x !< non-dimensional position
119  real , intent(in) :: L !< non-dimensional width
120  real :: PI !< 3.1415926... calculated as 4*atan(1)
121 
122  pi = 4.0*atan(1.0)
123  cosbell = 0.5 * (1 + cos(pi*min(abs(x/l),1.0)))

◆ neverland_buoyancy_forcing()

subroutine, public neverland_surface_forcing::neverland_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(inout)  G,
type(unit_scale_type), intent(in)  US,
type(neverland_surface_forcing_cs), pointer  CS 
)

Surface fluxes of buoyancy for the Neverland configurations.

Parameters
[in,out]sfc_stateA structure containing fields that describe the surface state of the ocean.
[in,out]fluxesForcing fields.
[in]dayTime used for determining the fluxes.
[in]dtForcing time step (s).
[in,out]gGrid structure.
[in]usA dimensional unit scaling type
csControl structure for this module.

Definition at line 140 of file Neverland_surface_forcing.F90.

140  type(surface), intent(inout) :: sfc_state !< A structure containing fields that
141  !! describe the surface state of the ocean.
142  type(forcing), intent(inout) :: fluxes !< Forcing fields.
143  type(time_type), intent(in) :: day !< Time used for determining the fluxes.
144  real, intent(in) :: dt !< Forcing time step (s).
145  type(ocean_grid_type), intent(inout) :: G !< Grid structure.
146  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
147  type(Neverland_surface_forcing_CS), pointer :: CS !< Control structure for this module.
148  ! Local variables
149  real :: buoy_rest_const ! A constant relating density anomalies to the
150  ! restoring buoyancy flux [L2 T-3 R-1 ~> m5 s-3 kg-1].
151  real :: density_restore ! De
152  integer :: i, j, is, ie, js, je
153  integer :: isd, ied, jsd, jed
154 
155  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
156  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
157 
158  ! When modifying the code, comment out this error message. It is here
159  ! so that the original (unmodified) version is not accidentally used.
160 
161  ! Allocate and zero out the forcing arrays, as necessary. This portion is
162  ! usually not changed.
163  if (cs%use_temperature) then
164  call mom_error(fatal, "Neverland_buoyancy_forcing: " // &
165  "Temperature and salinity mode not coded!" )
166  else
167  ! This is the buoyancy only mode.
168  call safe_alloc_ptr(fluxes%buoy, isd, ied, jsd, jed)
169  endif
170 
171 
172  ! MODIFY THE CODE IN THE FOLLOWING LOOPS TO SET THE BUOYANCY FORCING TERMS.
173  if (cs%restorebuoy .and. cs%first_call) then
174  call safe_alloc_ptr(cs%buoy_restore, isd, ied, jsd, jed)
175  cs%first_call = .false.
176  ! Set CS%buoy_restore(i,j) here
177  endif
178 
179  if ( cs%use_temperature ) then
180  call mom_error(fatal, "Neverland_buoyancy_surface_forcing: " // &
181  "Temperature/salinity restoring not coded!" )
182  else ! This is the buoyancy only mode.
183  do j=js,je ; do i=is,ie
184  ! fluxes%buoy is the buoyancy flux into the ocean [L2 T-3 ~> m2 s-3]. A positive
185  ! buoyancy flux is of the same sign as heating the ocean.
186  fluxes%buoy(i,j) = 0.0 * g%mask2dT(i,j)
187  enddo ; enddo
188  endif
189 
190  if (cs%restorebuoy) then
191  if (cs%use_temperature) then
192  call mom_error(fatal, "Neverland_buoyancy_surface_forcing: " // &
193  "Temperature/salinity restoring not coded!" )
194  else
195  ! When modifying the code, comment out this error message. It is here
196  ! so that the original (unmodified) version is not accidentally used.
197 
198  ! The -1 is because density has the opposite sign to buoyancy.
199  buoy_rest_const = -1.0 * (cs%G_Earth * cs%Flux_const) / cs%Rho0
200  do j=js,je ; do i=is,ie
201  ! Set density_restore to an expression for the surface potential
202  ! density [kg m-3] that is being restored toward.
203  density_restore = 1030.0
204 
205  fluxes%buoy(i,j) = g%mask2dT(i,j) * buoy_rest_const * &
206  us%kg_m3_to_R*(density_restore - sfc_state%sfc_density(i,j))
207  enddo ; enddo
208  endif
209  endif ! end RESTOREBUOY
210 

References mom_error_handler::mom_error().

Here is the call graph for this function:

◆ neverland_surface_forcing_init()

subroutine, public neverland_surface_forcing::neverland_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(in), target  diag,
type(neverland_surface_forcing_cs), pointer  CS 
)

Initializes the Neverland control structure.

Parameters
[in]timeThe current model time.
[in]gThe ocean's grid structure.
[in]usA dimensional unit scaling type
[in]param_fileA structure indicating the open file to parse for model parameter values.
[in]diagA structure that is used to regulate diagnostic output.
csA pointer that is set to point to the control structure for this module

Definition at line 215 of file Neverland_surface_forcing.F90.

215  type(time_type), intent(in) :: Time !< The current model time.
216  type(ocean_grid_type), intent(in) :: G !< The ocean's grid structure.
217  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
218  type(param_file_type), intent(in) :: param_file !< A structure indicating the open file to parse for
219  !! model parameter values.
220  type(diag_ctrl), target, intent(in) :: diag !< A structure that is used to regulate diagnostic output.
221  type(Neverland_surface_forcing_CS), pointer :: CS !< A pointer that is set to point to the control structure
222  !! for this module
223  ! This include declares and sets the variable "version".
224 #include "version_variable.h"
225  ! Local variables
226  character(len=40) :: mdl = "Neverland_surface_forcing" ! This module's name.
227 
228  if (associated(cs)) then
229  call mom_error(warning, "Neverland_surface_forcing_init called with an associated "// &
230  "control structure.")
231  return
232  endif
233  allocate(cs)
234  cs%diag => diag
235 
236  ! Read all relevant parameters and write them to the model log.
237  call log_version(param_file, mdl, version, "")
238  call get_param(param_file, mdl, "ENABLE_THERMODYNAMICS", cs%use_temperature, &
239  "If true, Temperature and salinity are used as state "//&
240  "variables.", default=.true.)
241 
242  call get_param(param_file, mdl, "G_EARTH", cs%G_Earth, &
243  "The gravitational acceleration of the Earth.", &
244  units="m s-2", default = 9.80, scale=us%m_to_L**2*us%Z_to_m*us%T_to_s**2)
245  call get_param(param_file, mdl, "RHO_0", cs%Rho0, &
246  "The mean ocean density used with BOUSSINESQ true to "//&
247  "calculate accelerations and the mass for conservation "//&
248  "properties, or with BOUSSINSEQ false to convert some "//&
249  "parameters from vertical units of m to kg m-2.", &
250  units="kg m-3", default=1035.0, scale=us%kg_m3_to_R)
251 ! call get_param(param_file, mdl, "GUST_CONST", CS%gust_const, &
252 ! "The background gustiness in the winds.", units="Pa", &
253 ! default=0.02)
254 
255  call get_param(param_file, mdl, "RESTOREBUOY", cs%restorebuoy, &
256  "If true, the buoyancy fluxes drive the model back "//&
257  "toward some specified surface state with a rate "//&
258  "given by FLUXCONST.", default= .false.)
259 
260  if (cs%restorebuoy) then
261  call get_param(param_file, mdl, "FLUXCONST", cs%flux_const, &
262  "The constant that relates the restoring surface fluxes "//&
263  "to the relative surface anomalies (akin to a piston "//&
264  "velocity). Note the non-MKS units.", &
265  units="m day-1", scale=us%m_to_Z*us%T_to_s, fail_if_missing=.true.)
266  ! Convert CS%flux_const from m day-1 to m s-1.
267  cs%flux_const = cs%flux_const / 86400.0
268  endif
269 

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:

◆ neverland_wind_forcing()

subroutine, public neverland_surface_forcing::neverland_wind_forcing ( type(surface), intent(inout)  sfc_state,
type(mech_forcing), intent(inout)  forces,
type(time_type), intent(in)  day,
type(ocean_grid_type), intent(inout)  G,
type(unit_scale_type), intent(in)  US,
type(neverland_surface_forcing_cs), pointer  CS 
)

Sets the surface wind stresses, forcestaux and forcestauy for the Neverland forcing configuration.

Parameters
[in,out]sfc_stateA structure containing fields that describe the surface state of the ocean.
[in,out]forcesA structure with the driving mechanical forces
[in]dayTime used for determining the fluxes.
[in,out]gGrid structure.
[in]usA dimensional unit scaling type
csControl structure for this module.

Definition at line 50 of file Neverland_surface_forcing.F90.

50  type(surface), intent(inout) :: sfc_state !< A structure containing fields that
51  !! describe the surface state of the ocean.
52  type(mech_forcing), intent(inout) :: forces !< A structure with the driving mechanical forces
53  type(time_type), intent(in) :: day !< Time used for determining the fluxes.
54  type(ocean_grid_type), intent(inout) :: G !< Grid structure.
55  type(unit_scale_type), intent(in) :: US !< A dimensional unit scaling type
56  type(Neverland_surface_forcing_CS), pointer :: CS !< Control structure for this module.
57 
58  ! Local variables
59  integer :: i, j, is, ie, js, je, Isq, Ieq, Jsq, Jeq
60  integer :: isd, ied, jsd, jed, IsdB, IedB, JsdB, JedB
61  real :: x, y
62  real :: PI
63  real :: tau_max ! The magnitude of the wind stress [R Z L T-2 ~> Pa]
64  real :: off
65 
66  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
67  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
68  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
69  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
70 
71  ! Allocate the forcing arrays, if necessary.
72  call allocate_mech_forcing(g, forces, stress=.true.)
73 
74  ! Set the surface wind stresses, in units of Pa. A positive taux
75  ! accelerates the ocean to the (pseudo-)east.
76 
77  ! The i-loop extends to is-1 so that taux can be used later in the
78  ! calculation of ustar - otherwise the lower bound would be Isq.
79  pi = 4.0*atan(1.0)
80  forces%taux(:,:) = 0.0
81  tau_max = 0.2 * us%kg_m3_to_R*us%m_s_to_L_T**2*us%L_to_Z
82  off = 0.02
83  do j=js,je ; do i=is-1,ieq
84 ! x = (G%geoLonT(i,j)-G%west_lon)/G%len_lon
85  y = (g%geoLatT(i,j)-g%south_lat)/g%len_lat
86 ! forces%taux(I,j) = G%mask2dCu(I,j) * 0.0
87 
88  if (y <= 0.29) then
89  forces%taux(i,j) = forces%taux(i,j) + tau_max * ( (1/0.29)*y - ( 1/(2*pi) )*sin( (2*pi*y) / 0.29 ) )
90  endif
91  if ((y > 0.29) .and. (y <= (0.8-off))) then
92  forces%taux(i,j) = forces%taux(i,j) + tau_max *(0.35+0.65*cos(pi*(y-0.29)/(0.51-off)) )
93  endif
94  if ((y > (0.8-off)) .and. (y <= (1-off))) then
95  forces%taux(i,j) = forces%taux(i,j) + tau_max *( 1.5*( (y-1+off) - (0.1/pi)*sin(10.0*pi*(y-0.8+off)) ) )
96  endif
97  enddo ; enddo
98 
99  do j=js-1,jeq ; do i=is,ie
100  forces%tauy(i,j) = g%mask2dCv(i,j) * 0.0 ! Change this to the desired expression.
101  enddo ; enddo
102 
103  ! Set the surface friction velocity, in units of m s-1. ustar
104  ! is always positive.
105 ! if (associated(forces%ustar)) then ; do j=js,je ; do i=is,ie
106 ! ! This expression can be changed if desired, but need not be.
107 ! forces%ustar(i,j) = G%mask2dT(i,j) * sqrt((CS%gust_const + &
108 ! sqrt(0.5*(forces%taux(I-1,j)**2 + forces%taux(I,j)**2) + &
109 ! 0.5*(forces%tauy(i,J-1)**2 + forces%tauy(i,J)**2))) * &
110 ! (US%L_to_Z / CS%Rho0) )
111 ! enddo ; enddo ; endif
112 

References mom_forcing_type::allocate_mech_forcing().

Here is the call graph for this function:

◆ spike()

real function neverland_surface_forcing::spike ( real, intent(in)  x,
real, intent(in)  L 
)
private

Returns the value of a sin-spike function evaluated at x/L.

Parameters
[in]xnon-dimensional position
[in]lnon-dimensional width

Definition at line 128 of file Neverland_surface_forcing.F90.

128 
129  real , intent(in) :: x !< non-dimensional position
130  real , intent(in) :: L !< non-dimensional width
131  real :: PI !< 3.1415926... calculated as 4*atan(1)
132 
133  pi = 4.0*atan(1.0)
134  spike = (1 - sin(pi*min(abs(x/l),0.5)))