This subroutine calls any of the other subroutines in this file that are needed to specify the current surface forcing fields.
83 type(ocean_grid_type),
intent(inout) :: G
84 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: SST_anom
86 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: SSS_anom
88 real,
dimension(SZI_(G),SZJ_(G)),
intent(in) :: SSS_mean
90 real,
dimension(SZI_(G),SZJ_(G)),
intent(inout) :: virt_heat
93 real,
dimension(SZI_(G),SZJ_(G)),
intent(inout) :: virt_precip
97 type(time_type),
intent(in) :: day_start
98 real,
intent(in) :: dt
100 type(unit_scale_type),
intent(in) :: US
101 type(ctrl_forcing_CS),
pointer :: CS
105 real,
dimension(SZIB_(G),SZJ_(G)) :: &
108 real,
dimension(SZI_(G),SZJB_(G)) :: &
111 type(time_type) :: day_end
113 real :: mr_st, mr_end, mr_mid, mr_prev, mr_next
114 real :: dt_wt, dt_heat_rate, dt_prec_rate
115 real :: dt1_heat_rate, dt1_prec_rate, dt2_heat_rate, dt2_prec_rate
116 real :: wt_per1, wt_st, wt_end, wt_mid
117 integer :: m_st, m_end, m_mid, m_u1, m_u2, m_u3
118 integer :: yr, mon, day, hr, min, sec
119 integer :: i, j, is, ie, js, je
121 is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec
123 if (.not.
associated(cs))
return
124 if ((cs%num_cycle <= 0) .and. (.not.cs%do_integrated))
return
126 day_end = day_start + real_to_time(dt)
128 do j=js,je ;
do i=is,ie
129 virt_heat(i,j) = 0.0 ; virt_precip(i,j) = 0.0
132 if (cs%do_integrated)
then
133 dt_heat_rate = dt * cs%heat_int_rate
134 dt_prec_rate = dt * cs%prec_int_rate
135 call pass_var(cs%heat_0, g%Domain, complete=.false.)
136 call pass_var(cs%precip_0, g%Domain)
138 do j=js,je ;
do i=is-1,ie
139 coef = cs%Len2 * (g%dy_Cu(i,j)*g%IdxCu(i,j))
140 flux_heat_x(i,j) = coef * (cs%heat_0(i,j) - cs%heat_0(i+1,j))
141 flux_prec_x(i,j) = coef * (cs%precip_0(i,j) - cs%precip_0(i+1,j))
143 do j=js-1,je ;
do i=is,ie
144 coef = cs%Len2 * (g%dx_Cv(i,j)*g%IdyCv(i,j))
145 flux_heat_y(i,j) = coef * (cs%heat_0(i,j) - cs%heat_0(i,j+1))
146 flux_prec_y(i,j) = coef * (cs%precip_0(i,j) - cs%precip_0(i,j+1))
148 do j=js,je ;
do i=is,ie
149 cs%heat_0(i,j) = cs%heat_0(i,j) + dt_heat_rate * ( &
150 -cs%lam_heat*g%mask2dT(i,j)*sst_anom(i,j) + &
151 (us%m_to_L**2*g%IareaT(i,j) * ((flux_heat_x(i-1,j) - flux_heat_x(i,j)) + &
152 (flux_heat_y(i,j-1) - flux_heat_y(i,j))) ) )
154 cs%precip_0(i,j) = cs%precip_0(i,j) + dt_prec_rate * ( &
155 cs%lam_prec * g%mask2dT(i,j)*(sss_anom(i,j) / sss_mean(i,j)) + &
156 (us%m_to_L**2*g%IareaT(i,j) * ((flux_prec_x(i-1,j) - flux_prec_x(i,j)) + &
157 (flux_prec_y(i,j-1) - flux_prec_y(i,j))) ) )
159 virt_heat(i,j) = virt_heat(i,j) + cs%heat_0(i,j)
160 virt_precip(i,j) = virt_precip(i,j) + cs%precip_0(i,j)
164 if (cs%num_cycle > 0)
then
166 call get_date(day_start, yr, mon, day, hr, min, sec)
167 mr_st = cs%num_cycle * (time_type_to_real(day_start - set_date(yr, 1, 1)) / &
168 time_type_to_real(set_date(yr+1, 1, 1) - set_date(yr, 1, 1)))
170 call get_date(day_end, yr, mon, day, hr, min, sec)
171 mr_end = cs%num_cycle * (time_type_to_real(day_end - set_date(yr, 1, 1)) / &
172 time_type_to_real(set_date(yr+1, 1, 1) - set_date(yr, 1, 1)))
180 m_end = periodic_int(real(ceiling(mr_end)), cs%num_cycle)
181 m_mid = periodic_int(real(ceiling(mr_st)), cs%num_cycle)
182 m_st = periodic_int(mr_st, cs%num_cycle)
184 mr_st = periodic_real(mr_st, cs%num_cycle)
185 mr_end = periodic_real(mr_end, cs%num_cycle)
187 mr_prev = periodic_real(real(floor(mr_st)), cs%num_cycle)
188 mr_next = periodic_real(real(m_end), cs%num_cycle)
189 if (m_mid == m_end)
then ; mr_mid = mr_end
190 else ; mr_mid = periodic_real(real(m_mid), cs%num_cycle) ;
endif
197 if (mr_st < mr_prev) mr_prev = mr_prev - cs%num_cycle
198 if (mr_mid < mr_st) mr_mid = mr_mid + cs%num_cycle
199 if (mr_end < mr_st) mr_end = mr_end + cs%num_cycle
200 if (mr_next < mr_prev) mr_next = mr_next + cs%num_cycle
203 if ((mr_mid < mr_st) .or. (mr_mid > mr_prev + 1.))
call mom_error(fatal, &
204 "apply ctrl_forcing: m_mid interpolation out of bounds; fix the code.")
205 if ((mr_end < mr_st) .or. (mr_end > mr_prev + 2.))
call mom_error(fatal, &
206 "apply ctrl_forcing: m_end interpolation out of bounds; fix the code.")
207 if (mr_end > mr_next)
call mom_error(fatal, &
208 "apply ctrl_forcing: mr_next interpolation out of bounds; fix the code.")
211 if (mr_mid < mr_end) wt_per1 = (mr_mid - mr_st) / (mr_end - mr_st)
214 wt_st = wt_per1 * (1. + (mr_prev - 0.5*(mr_st + mr_mid)))
215 wt_end = (1.0-wt_per1) * (1. + (0.5*(mr_end + mr_mid) - mr_next))
216 wt_mid = 1.0 - (wt_st + wt_end)
217 if ((wt_st < 0.0) .or. (wt_end < 0.0) .or. (wt_mid < 0.0)) &
218 call mom_error(fatal,
"apply_ctrl_forcing: Negative m weights")
219 if ((wt_st > 1.0) .or. (wt_end > 1.0) .or. (wt_mid > 1.0)) &
220 call mom_error(fatal,
"apply_ctrl_forcing: Excessive m weights")
223 do j=js,je ;
do i=is,ie
224 virt_heat(i,j) = virt_heat(i,j) + (wt_st * cs%heat_cyc(i,j,m_st) + &
225 (wt_mid * cs%heat_cyc(i,j,m_mid) + &
226 wt_end * cs%heat_cyc(i,j,m_end)))
227 virt_precip(i,j) = virt_precip(i,j) + (wt_st * cs%precip_cyc(i,j,m_st) + &
228 (wt_mid * cs%precip_cyc(i,j,m_mid) + &
229 wt_end * cs%precip_cyc(i,j,m_end)))
242 if (cs%avg_time(m_end) <= 0.0)
then
243 cs%avg_time(m_end) = 0.0
244 do j=js,je ;
do i=is,ie
245 cs%avg_SST_anom(i,j,m_end) = 0.0
246 cs%avg_SSS_anom(i,j,m_end) = 0.0 ; cs%avg_SSS(i,j,m_end) = 0.0
249 if (cs%avg_time(m_mid) <= 0.0)
then
250 cs%avg_time(m_mid) = 0.0
251 do j=js,je ;
do i=is,ie
252 cs%avg_SST_anom(i,j,m_mid) = 0.0
253 cs%avg_SSS_anom(i,j,m_mid) = 0.0 ; cs%avg_SSS(i,j,m_mid) = 0.0
259 cs%avg_time(m_mid) = cs%avg_time(m_mid) + dt_wt
260 do j=js,je ;
do i=is,ie
261 cs%avg_SST_anom(i,j,m_mid) = cs%avg_SST_anom(i,j,m_mid) + &
262 dt_wt * g%mask2dT(i,j) * sst_anom(i,j)
263 cs%avg_SSS_anom(i,j,m_mid) = cs%avg_SSS_anom(i,j,m_mid) + &
264 dt_wt * g%mask2dT(i,j) * sss_anom(i,j)
265 cs%avg_SSS(i,j,m_mid) = cs%avg_SSS(i,j,m_mid) + dt_wt * sss_mean(i,j)
267 if (wt_per1 < 1.0)
then
268 dt_wt = (1.0-wt_per1) * dt
269 cs%avg_time(m_end) = cs%avg_time(m_end) + dt_wt
270 do j=js,je ;
do i=is,ie
271 cs%avg_SST_anom(i,j,m_end) = cs%avg_SST_anom(i,j,m_end) + &
272 dt_wt * g%mask2dT(i,j) * sst_anom(i,j)
273 cs%avg_SSS_anom(i,j,m_end) = cs%avg_SSS_anom(i,j,m_end) + &
274 dt_wt * g%mask2dT(i,j) * sss_anom(i,j)
275 cs%avg_SSS(i,j,m_end) = cs%avg_SSS(i,j,m_end) + dt_wt * sss_mean(i,j)
280 m_u1 = periodic_int(m_st - 4.0, cs%num_cycle)
281 m_u2 = periodic_int(m_st - 3.0, cs%num_cycle)
282 m_u3 = periodic_int(m_st - 2.0, cs%num_cycle)
284 if (cs%avg_time(m_u1) > 0.0)
then
285 do j=js,je ;
do i=is,ie
286 cs%avg_SST_anom(i,j,m_u1) = cs%avg_SST_anom(i,j,m_u1) / cs%avg_time(m_u1)
287 cs%avg_SSS_anom(i,j,m_u1) = cs%avg_SSS_anom(i,j,m_u1) / cs%avg_time(m_u1)
288 cs%avg_SSS(i,j,m_u1) = cs%avg_SSS(i,j,m_u1) / cs%avg_time(m_u1)
290 cs%avg_time(m_u1) = -1.0
292 if (cs%avg_time(m_u2) > 0.0)
then
293 do j=js,je ;
do i=is,ie
294 cs%avg_SST_anom(i,j,m_u2) = cs%avg_SST_anom(i,j,m_u2) / cs%avg_time(m_u2)
295 cs%avg_SSS_anom(i,j,m_u2) = cs%avg_SSS_anom(i,j,m_u2) / cs%avg_time(m_u2)
296 cs%avg_SSS(i,j,m_u2) = cs%avg_SSS(i,j,m_u2) / cs%avg_time(m_u2)
298 cs%avg_time(m_u2) = -1.0
300 if (cs%avg_time(m_u3) > 0.0)
then
301 do j=js,je ;
do i=is,ie
302 cs%avg_SST_anom(i,j,m_u3) = cs%avg_SST_anom(i,j,m_u3) / cs%avg_time(m_u3)
303 cs%avg_SSS_anom(i,j,m_u3) = cs%avg_SSS_anom(i,j,m_u3) / cs%avg_time(m_u3)
304 cs%avg_SSS(i,j,m_u3) = cs%avg_SSS(i,j,m_u3) / cs%avg_time(m_u3)
306 cs%avg_time(m_u3) = -1.0
309 dt1_heat_rate = wt_per1 * dt * cs%heat_cyc_rate
310 dt1_prec_rate = wt_per1 * dt * cs%prec_cyc_rate
311 dt2_heat_rate = (1.0-wt_per1) * dt * cs%heat_cyc_rate
312 dt2_prec_rate = (1.0-wt_per1) * dt * cs%prec_cyc_rate
314 if (wt_per1 < 1.0)
then
315 call pass_var(cs%heat_cyc(:,:,m_u2), g%Domain, complete=.false.)
316 call pass_var(cs%precip_cyc(:,:,m_u2), g%Domain, complete=.false.)
318 call pass_var(cs%heat_cyc(:,:,m_u1), g%Domain, complete=.false.)
319 call pass_var(cs%precip_cyc(:,:,m_u1), g%Domain)
321 if ((cs%avg_time(m_u1) == -1.0) .and. (cs%avg_time(m_u2) == -1.0))
then
322 do j=js,je ;
do i=is-1,ie
323 coef = cs%Len2 * (g%dy_Cu(i,j)*g%IdxCu(i,j))
324 flux_heat_x(i,j) = coef * (cs%heat_cyc(i,j,m_u1) - cs%heat_cyc(i+1,j,m_u1))
325 flux_prec_x(i,j) = coef * (cs%precip_cyc(i,j,m_u1) - cs%precip_cyc(i+1,j,m_u1))
327 do j=js-1,je ;
do i=is,ie
328 coef = cs%Len2 * (g%dx_Cv(i,j)*g%IdyCv(i,j))
329 flux_heat_y(i,j) = coef * (cs%heat_cyc(i,j,m_u1) - cs%heat_cyc(i,j+1,m_u1))
330 flux_prec_y(i,j) = coef * (cs%precip_cyc(i,j,m_u1) - cs%precip_cyc(i,j+1,m_u1))
332 do j=js,je ;
do i=is,ie
333 cs%heat_cyc(i,j,m_u1) = cs%heat_cyc(i,j,m_u1) + dt1_heat_rate * ( &
334 -cs%lam_cyc_heat*(cs%avg_SST_anom(i,j,m_u2) - cs%avg_SST_anom(i,j,m_u1)) + &
335 (us%m_to_L**2*g%IareaT(i,j) * ((flux_heat_x(i-1,j) - flux_heat_x(i,j)) + &
336 (flux_heat_y(i,j-1) - flux_heat_y(i,j))) ) )
338 cs%precip_cyc(i,j,m_u1) = cs%precip_cyc(i,j,m_u1) + dt1_prec_rate * ( &
339 cs%lam_cyc_prec * (cs%avg_SSS_anom(i,j,m_u2) - cs%avg_SSS_anom(i,j,m_u1)) / &
340 (0.5*(cs%avg_SSS(i,j,m_u2) + cs%avg_SSS(i,j,m_u1))) + &
341 (us%m_to_L**2*g%IareaT(i,j) * ((flux_prec_x(i-1,j) - flux_prec_x(i,j)) + &
342 (flux_prec_y(i,j-1) - flux_prec_y(i,j))) ) )
346 if ((wt_per1 < 1.0) .and. (cs%avg_time(m_u1) == -1.0) .and. (cs%avg_time(m_u2) == -1.0))
then
347 do j=js,je ;
do i=is-1,ie
348 coef = cs%Len2 * (g%dy_Cu(i,j)*g%IdxCu(i,j))
349 flux_heat_x(i,j) = coef * (cs%heat_cyc(i,j,m_u2) - cs%heat_cyc(i+1,j,m_u2))
350 flux_prec_x(i,j) = coef * (cs%precip_cyc(i,j,m_u2) - cs%precip_cyc(i+1,j,m_u2))
352 do j=js-1,je ;
do i=is,ie
353 coef = cs%Len2 * (g%dx_Cv(i,j)*g%IdyCv(i,j))
354 flux_heat_y(i,j) = coef * (cs%heat_cyc(i,j,m_u2) - cs%heat_cyc(i,j+1,m_u2))
355 flux_prec_y(i,j) = coef * (cs%precip_cyc(i,j,m_u2) - cs%precip_cyc(i,j+1,m_u2))
357 do j=js,je ;
do i=is,ie
358 cs%heat_cyc(i,j,m_u2) = cs%heat_cyc(i,j,m_u2) + dt1_heat_rate * ( &
359 -cs%lam_cyc_heat*(cs%avg_SST_anom(i,j,m_u3) - cs%avg_SST_anom(i,j,m_u2)) + &
360 (us%m_to_L**2*g%IareaT(i,j) * ((flux_heat_x(i-1,j) - flux_heat_x(i,j)) + &
361 (flux_heat_y(i,j-1) - flux_heat_y(i,j))) ) )
363 cs%precip_cyc(i,j,m_u2) = cs%precip_cyc(i,j,m_u2) + dt1_prec_rate * ( &
364 cs%lam_cyc_prec * (cs%avg_SSS_anom(i,j,m_u3) - cs%avg_SSS_anom(i,j,m_u2)) / &
365 (0.5*(cs%avg_SSS(i,j,m_u3) + cs%avg_SSS(i,j,m_u2))) + &
366 (us%m_to_L**2*g%IareaT(i,j) * ((flux_prec_x(i-1,j) - flux_prec_x(i,j)) + &
367 (flux_prec_y(i,j-1) - flux_prec_y(i,j))) ) )