21 implicit none ;
private
23 public dumbbell_dynamic_forcing, dumbbell_buoyancy_forcing, dumbbell_surface_forcing_init
27 logical :: use_temperature
28 logical :: restorebuoy
37 real,
dimension(:,:),
allocatable :: &
39 real,
dimension(:,:),
allocatable :: &
48 subroutine dumbbell_buoyancy_forcing(sfc_state, fluxes, day, dt, G, US, CS)
51 type(
forcing),
intent(inout) :: fluxes
54 type(time_type),
intent(in) :: day
55 real,
intent(in) :: dt
64 integer :: i, j, is, ie, js, je
65 integer :: isd, ied, jsd, jed
67 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
68 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
72 if (cs%use_temperature)
then
91 if ( cs%use_temperature )
then
94 do j=js,je ;
do i=is,ie
97 fluxes%evap(i,j) = -0.0 * g%mask2dT(i,j)
98 fluxes%lprec(i,j) = 0.0 * g%mask2dT(i,j)
101 fluxes%vprec(i,j) = 0.0
104 fluxes%lw(i,j) = 0.0 * g%mask2dT(i,j)
105 fluxes%latent(i,j) = 0.0 * g%mask2dT(i,j)
106 fluxes%sens(i,j) = 0.0 * g%mask2dT(i,j)
107 fluxes%sw(i,j) = 0.0 * g%mask2dT(i,j)
110 do j=js,je ;
do i=is,ie
113 fluxes%buoy(i,j) = 0.0 * g%mask2dT(i,j)
117 if (cs%use_temperature .and. cs%restorebuoy)
then
118 do j=js,je ;
do i=is,ie
119 if (cs%forcing_mask(i,j)>0.)
then
120 fluxes%vprec(i,j) = - (g%mask2dT(i,j) * (cs%Rho0*cs%Flux_const)) * &
121 ((cs%S_restore(i,j) - sfc_state%SSS(i,j)) / (0.5 * (cs%S_restore(i,j) + sfc_state%SSS(i,j))))
127 end subroutine dumbbell_buoyancy_forcing
130 subroutine dumbbell_dynamic_forcing(sfc_state, fluxes, day, dt, G, CS)
133 type(
forcing),
intent(inout) :: fluxes
136 type(time_type),
intent(in) :: day
137 real,
intent(in) :: dt
143 integer :: i, j, is, ie, js, je
144 integer :: isd, ied, jsd, jed
145 integer :: idays, isecs
146 real :: deg_rad, rdays
149 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
150 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
152 deg_rad = atan(1.0)*4.0/180.
154 call get_time(day,isecs,idays)
155 rdays = real(idays) + real(isecs)/8.64e4
162 do j=js,je ;
do i=is,ie
163 fluxes%p_surf(i,j) = cs%forcing_mask(i,j)* cs%slp_amplitude * &
164 g%mask2dT(i,j) * sin(deg_rad*(rdays/cs%slp_period))
165 fluxes%p_surf_full(i,j) = cs%forcing_mask(i,j) * cs%slp_amplitude * &
166 g%mask2dT(i,j) * sin(deg_rad*(rdays/cs%slp_period))
169 end subroutine dumbbell_dynamic_forcing
172 subroutine dumbbell_surface_forcing_init(Time, G, US, param_file, diag, CS)
173 type(time_type),
intent(in) :: time
177 type(
diag_ctrl),
target,
intent(in) :: diag
182 real :: s_surf, s_range
186 #include "version_variable.h"
187 character(len=40) :: mdl =
"dumbbell_surface_forcing"
189 if (
associated(cs))
then
190 call mom_error(warning,
"dumbbell_surface_forcing_init called with an associated "// &
191 "control structure.")
199 call get_param(param_file, mdl,
"ENABLE_THERMODYNAMICS", cs%use_temperature, &
200 "If true, Temperature and salinity are used as state variables.", default=.true.)
202 call get_param(param_file, mdl,
"G_EARTH", cs%G_Earth, &
203 "The gravitational acceleration of the Earth.", &
204 units=
"m s-2", default = 9.80, scale=us%m_to_L**2*us%Z_to_m*us%T_to_s**2)
205 call get_param(param_file, mdl,
"RHO_0", cs%Rho0, &
206 "The mean ocean density used with BOUSSINESQ true to "//&
207 "calculate accelerations and the mass for conservation "//&
208 "properties, or with BOUSSINSEQ false to convert some "//&
209 "parameters from vertical units of m to kg m-2.", &
210 units=
"kg m-3", default=1035.0, scale=us%kg_m3_to_R)
211 call get_param(param_file, mdl,
"DUMBBELL_SLP_AMP", cs%slp_amplitude, &
212 "Amplitude of SLP forcing in reservoirs.", &
213 units=
"Pa", default = 10000.0, scale=us%kg_m3_to_R*us%m_s_to_L_T**2)
214 call get_param(param_file, mdl,
"DUMBBELL_SLP_PERIOD", cs%slp_period, &
215 "Periodicity of SLP forcing in reservoirs.", &
216 units=
"days", default = 1.0)
217 call get_param(param_file, mdl,
"DUMBBELL_ROTATION", dbrotate, &
218 'Logical for rotation of dumbbell domain.',&
219 units=
'nondim', default=.false., do_not_log=.true.)
220 call get_param(param_file, mdl,
"INITIAL_SSS", s_surf, &
221 "Initial surface salinity", units=
"1e-3", default=34.0, do_not_log=.true.)
222 call get_param(param_file, mdl,
"INITIAL_S_RANGE", s_range, &
223 "Initial salinity range (bottom - surface)", units=
"1e-3", &
224 default=2., do_not_log=.true.)
226 call get_param(param_file, mdl,
"RESTOREBUOY", cs%restorebuoy, &
227 "If true, the buoyancy fluxes drive the model back "//&
228 "toward some specified surface state with a rate "//&
229 "given by FLUXCONST.", default= .false.)
230 if (cs%restorebuoy)
then
231 call get_param(param_file, mdl,
"FLUXCONST", cs%Flux_const, &
232 "The constant that relates the restoring surface fluxes to the relative "//&
233 "surface anomalies (akin to a piston velocity). Note the non-MKS units.", &
234 default=0.0, units=
"m day-1", scale=us%m_to_Z*us%T_to_s)
236 cs%Flux_const = cs%Flux_const / 86400.0
239 allocate(cs%forcing_mask(g%isd:g%ied, g%jsd:g%jed)); cs%forcing_mask(:,:)=0.0
240 allocate(cs%S_restore(g%isd:g%ied, g%jsd:g%jed))
249 x = ( g%geoLatT(i,j) - g%south_lat ) / g%len_lat - 0.5
251 x = ( g%geoLonT(i,j) - g%west_lon ) / g%len_lon - 0.5
253 cs%forcing_mask(i,j)=0
254 cs%S_restore(i,j) = s_surf
256 cs%forcing_mask(i,j) = 1
257 cs%S_restore(i,j) = s_surf + s_range
258 elseif ((x<-0.25))
then
259 cs%forcing_mask(i,j) = 1
260 cs%S_restore(i,j) = s_surf - s_range
266 end subroutine dumbbell_surface_forcing_init