19 implicit none ;
private
21 public neverland_wind_forcing
22 public neverland_buoyancy_forcing
23 public neverland_surface_forcing_init
32 logical :: use_temperature
33 logical :: restorebuoy
38 real,
dimension(:,:),
pointer :: &
39 buoy_restore(:,:) => null()
40 character(len=200) :: inputdir
43 logical :: first_call = .true.
50 subroutine neverland_wind_forcing(sfc_state, forces, day, G, US, CS)
54 type(time_type),
intent(in) :: day
60 integer :: i, j, is, ie, js, je, isq, ieq, jsq, jeq
61 integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb
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
72 call allocate_mech_forcing(g, forces, stress=.true.)
80 forces%taux(:,:) = 0.0
83 do j=js,je ;
do i=is-1,ieq
85 y = (g%geoLatT(i,j)-g%south_lat)/g%len_lat
89 forces%taux(i,j) = forces%taux(i,j) + tau_max * ( (1/0.29)*y - ( 1/(2*pi) )*sin( (2*pi*y) / 0.29 ) )
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)) )
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)) ) )
99 do j=js-1,jeq ;
do i=is,ie
100 forces%tauy(i,j) = g%mask2dCv(i,j) * 0.0
112 end subroutine neverland_wind_forcing
115 real function cosbell(x,L)
117 real ,
intent(in) :: x
118 real ,
intent(in) :: l
122 cosbell = 0.5 * (1 + cos(pi*min(abs(x/l),1.0)))
126 real function spike(x,L)
128 real ,
intent(in) :: x
129 real ,
intent(in) :: l
133 spike = (1 - sin(pi*min(abs(x/l),0.5)))
138 subroutine neverland_buoyancy_forcing(sfc_state, fluxes, day, dt, G, US, CS)
141 type(
forcing),
intent(inout) :: fluxes
142 type(time_type),
intent(in) :: day
143 real,
intent(in) :: dt
148 real :: buoy_rest_const
150 real :: density_restore
151 integer :: i, j, is, ie, js, je
152 integer :: isd, ied, jsd, jed
154 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
155 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
162 if (cs%use_temperature)
then
163 call mom_error(fatal,
"Neverland_buoyancy_forcing: " // &
164 "Temperature and salinity mode not coded!" )
167 call safe_alloc_ptr(fluxes%buoy, isd, ied, jsd, jed)
172 if (cs%restorebuoy .and. cs%first_call)
then
173 call safe_alloc_ptr(cs%buoy_restore, isd, ied, jsd, jed)
174 cs%first_call = .false.
178 if ( cs%use_temperature )
then
179 call mom_error(fatal,
"Neverland_buoyancy_surface_forcing: " // &
180 "Temperature/salinity restoring not coded!" )
182 do j=js,je ;
do i=is,ie
185 fluxes%buoy(i,j) = 0.0 * g%mask2dT(i,j)
189 if (cs%restorebuoy)
then
190 if (cs%use_temperature)
then
191 call mom_error(fatal,
"Neverland_buoyancy_surface_forcing: " // &
192 "Temperature/salinity restoring not coded!" )
198 buoy_rest_const = -1.0 * (cs%G_Earth * us%m_to_Z*us%T_to_s*cs%Flux_const) / cs%Rho0
199 do j=js,je ;
do i=is,ie
202 density_restore = 1030.0
204 fluxes%buoy(i,j) = g%mask2dT(i,j) * buoy_rest_const * &
205 (density_restore - sfc_state%sfc_density(i,j))
210 end subroutine neverland_buoyancy_forcing
213 subroutine neverland_surface_forcing_init(Time, G, US, param_file, diag, CS)
214 type(time_type),
intent(in) :: time
219 type(
diag_ctrl),
target,
intent(in) :: diag
223 #include "version_variable.h"
225 character(len=40) :: mdl =
"Neverland_surface_forcing"
227 if (
associated(cs))
then
228 call mom_error(warning,
"Neverland_surface_forcing_init called with an associated "// &
229 "control structure.")
237 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", cs%use_temperature, &
238 "If true, Temperature and salinity are used as state "//&
239 "variables.", default=.true.)
241 call get_param(param_file, mdl,
"G_EARTH", cs%G_Earth, &
242 "The gravitational acceleration of the Earth.", &
243 units=
"m s-2", default = 9.80, scale=us%m_to_L**2*us%Z_to_m*us%T_to_s**2)
244 call get_param(param_file, mdl,
"RHO_0", cs%Rho0, &
245 "The mean ocean density used with BOUSSINESQ true to "//&
246 "calculate accelerations and the mass for conservation "//&
247 "properties, or with BOUSSINSEQ false to convert some "//&
248 "parameters from vertical units of m to kg m-2.", &
249 units=
"kg m-3", default=1035.0)
254 call get_param(param_file, mdl,
"RESTOREBUOY", cs%restorebuoy, &
255 "If true, the buoyancy fluxes drive the model back "//&
256 "toward some specified surface state with a rate "//&
257 "given by FLUXCONST.", default= .false.)
259 if (cs%restorebuoy)
then
260 call get_param(param_file, mdl,
"FLUXCONST", cs%flux_const, &
261 "The constant that relates the restoring surface fluxes "//&
262 "to the relative surface anomalies (akin to a piston "//&
263 "velocity). Note the non-MKS units.", units=
"m day-1", &
264 fail_if_missing=.true.)
266 cs%flux_const = cs%flux_const / 86400.0
269 end subroutine neverland_surface_forcing_init