20 use mom_time_manager,
only : time_type,
operator(+),
operator(/),
operator(-)
26 implicit none ;
private 28 #include <MOM_memory.h> 30 public apply_ctrl_forcing, register_ctrl_forcing_restarts
31 public controlled_forcing_init, controlled_forcing_end
35 logical :: use_temperature
37 logical :: do_integrated
60 real,
pointer,
dimension(:) :: &
62 real,
pointer,
dimension(:,:) :: &
65 real,
pointer,
dimension(:,:,:) :: &
67 precip_cyc => null(), &
68 avg_sst_anom => null(), &
69 avg_sss_anom => null(), &
74 integer :: id_heat_0 = -1
81 subroutine apply_ctrl_forcing(SST_anom, SSS_anom, SSS_mean, virt_heat, virt_precip, &
82 day_start, dt, G, US, CS)
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
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))) ) )
373 end subroutine apply_ctrl_forcing
376 function periodic_int(rval, num_period)
result (m)
377 real,
intent(in) :: rval
378 integer,
intent(in) :: num_period
383 m = m + num_period * (1 + (abs(m) / num_period))
384 elseif (m > num_period)
then 385 m = m - num_period * ((m-1) / num_period)
391 function periodic_real(rval, num_period)
result(val_out)
392 real,
intent(in) :: rval
393 integer,
intent(in) :: num_period
397 if (rval < 0)
then ; nshft = floor(abs(rval) / num_period) + 1
398 elseif (rval < num_period)
then ; nshft = 0
399 else ; nshft = -1*floor(rval / num_period) ;
endif 401 val_out = rval + nshft * num_period
407 subroutine register_ctrl_forcing_restarts(G, param_file, CS, restart_CS)
416 logical :: controlled, use_temperature
417 character (len=8) :: period_str
419 integer :: isd, ied, jsd, jed, isdb, iedb, jsdb, jedb
420 isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
421 isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
423 if (
associated(cs))
then 424 call mom_error(warning,
"register_ctrl_forcing_restarts called "//&
425 "with an associated control structure.")
430 call read_param(param_file,
"CONTROLLED_FORCING", controlled)
431 if (.not.controlled)
return 433 use_temperature = .true.
434 call read_param(param_file,
"ENABLE_THERMODYNAMICS", use_temperature)
435 if (.not.use_temperature)
call mom_error(fatal, &
436 "register_ctrl_forcing_restarts: CONTROLLED_FORCING only works with "//&
437 "ENABLE_THERMODYNAMICS defined.")
441 cs%do_integrated = .true. ; cs%num_cycle = 0
442 call read_param(param_file,
"CTRL_FORCE_INTEGRATED", cs%do_integrated)
443 call read_param(param_file,
"CTRL_FORCE_NUM_CYCLE", cs%num_cycle)
445 if (cs%do_integrated)
then 446 call safe_alloc_ptr(cs%heat_0,isd,ied,jsd,jed) ; cs%heat_0(:,:) = 0.0
447 call safe_alloc_ptr(cs%precip_0,isd,ied,jsd,jed) ; cs%precip_0(:,:) = 0.0
448 vd = var_desc(
"Ctrl_heat",
"W m-2",
"Control Integrative Heating",z_grid=
'1')
450 vd = var_desc(
"Ctrl_precip",
"kg m-2 s-1",
"Control Integrative Precipitation",z_grid=
'1')
454 if (cs%num_cycle > 0)
then 455 write (period_str,
'(i8)') cs%num_cycle
456 period_str = trim(
'p ')//trim(adjustl(period_str))
457 call safe_alloc_ptr(cs%heat_cyc,isd,ied,jsd,jed,cs%num_cycle) ; cs%heat_cyc(:,:,:) = 0.0
458 call safe_alloc_ptr(cs%precip_cyc,isd,ied,jsd,jed,cs%num_cycle) ; cs%precip_cyc(:,:,:) = 0.0
459 vd = var_desc(
"Ctrl_heat_cycle",
"W m-2",
"Cyclical Control Heating",&
460 z_grid=
'1', t_grid=period_str)
462 vd = var_desc(
"Ctrl_precip_cycle",
"kg m-2 s-1",
"Cyclical Control Precipitation", &
463 z_grid=
'1', t_grid=period_str)
466 call safe_alloc_ptr(cs%avg_time,cs%num_cycle) ; cs%avg_time(:) = 0.0
467 vd = var_desc(
"avg_time",
"sec",
"Cyclical accumulated averaging time", &
468 '1',z_grid=
'1',t_grid=period_str)
471 call safe_alloc_ptr(cs%avg_SST_anom,isd,ied,jsd,jed,cs%num_cycle) ; cs%avg_SST_anom(:,:,:) = 0.0
472 call safe_alloc_ptr(cs%avg_SSS_anom,isd,ied,jsd,jed,cs%num_cycle) ; cs%avg_SSS_anom(:,:,:) = 0.0
473 vd = var_desc(
"avg_SST_anom",
"deg C",
"Cyclical average SST Anomaly", &
474 z_grid=
'1',t_grid=period_str)
476 vd = var_desc(
"avg_SSS_anom",
"g kg-1",
"Cyclical average SSS Anomaly", &
477 z_grid=
'1',t_grid=period_str)
481 end subroutine register_ctrl_forcing_restarts
484 subroutine controlled_forcing_init(Time, G, param_file, diag, CS)
485 type(time_type),
intent(in) :: time
490 type(
diag_ctrl),
target,
intent(in) :: diag
495 logical :: do_integrated
498 #include "version_variable.h" 499 character(len=40) :: mdl =
"MOM_controlled_forcing" 505 if (
associated(cs))
then 506 do_integrated = cs%do_integrated ; num_cycle = cs%num_cycle
508 do_integrated = .false. ; num_cycle = 0
513 call log_param(param_file, mdl,
"CTRL_FORCE_INTEGRATED", do_integrated, &
514 "If true, use a PI controller to determine the surface "//&
515 "forcing that is consistent with the observed mean properties.", &
517 call log_param(param_file, mdl,
"CTRL_FORCE_NUM_CYCLE", num_cycle, &
518 "The number of cycles per year in the controlled forcing, "//&
519 "or 0 for no cyclic forcing.", default=0)
521 if (.not.
associated(cs))
return 525 call get_param(param_file, mdl,
"CTRL_FORCE_HEAT_INT_RATE", cs%heat_int_rate, &
526 "The integrated rate at which heat flux anomalies are "//&
527 "accumulated.", units=
"s-1", default=0.0)
528 call get_param(param_file, mdl,
"CTRL_FORCE_PREC_INT_RATE", cs%prec_int_rate, &
529 "The integrated rate at which precipitation anomalies "//&
530 "are accumulated.", units=
"s-1", default=0.0)
531 call get_param(param_file, mdl,
"CTRL_FORCE_HEAT_CYC_RATE", cs%heat_cyc_rate, &
532 "The integrated rate at which cyclical heat flux "//&
533 "anomalies are accumulated.", units=
"s-1", default=0.0)
534 call get_param(param_file, mdl,
"CTRL_FORCE_PREC_CYC_RATE", cs%prec_cyc_rate, &
535 "The integrated rate at which cyclical precipitation "//&
536 "anomalies are accumulated.", units=
"s-1", default=0.0)
537 call get_param(param_file, mdl,
"CTRL_FORCE_SMOOTH_LENGTH", smooth_len, &
538 "The length scales over which controlled forcing "//&
539 "anomalies are smoothed.", units=
"m", default=0.0)
540 call get_param(param_file, mdl,
"CTRL_FORCE_LAMDA_HEAT", cs%lam_heat, &
541 "A constant of proportionality between SST anomalies "//&
542 "and controlling heat fluxes",
"W m-2 K-1", default=0.0)
543 call get_param(param_file, mdl,
"CTRL_FORCE_LAMDA_PREC", cs%lam_prec, &
544 "A constant of proportionality between SSS anomalies "//&
545 "(normalised by mean SSS) and controlling precipitation.", &
546 "kg m-2", default=0.0)
547 call get_param(param_file, mdl,
"CTRL_FORCE_LAMDA_CYC_HEAT", cs%lam_cyc_heat, &
548 "A constant of proportionality between SST anomalies "//&
549 "and cyclical controlling heat fluxes",
"W m-2 K-1", default=0.0)
550 call get_param(param_file, mdl,
"CTRL_FORCE_LAMDA_CYC_PREC", cs%lam_cyc_prec, &
551 "A constant of proportionality between SSS anomalies "//&
552 "(normalised by mean SSS) and cyclical controlling "//&
553 "precipitation.",
"kg m-2", default=0.0)
555 cs%Len2 = smooth_len**2
561 end subroutine controlled_forcing_init
564 subroutine controlled_forcing_end(CS)
570 if (
associated(cs))
then 571 if (
associated(cs%heat_0))
deallocate(cs%heat_0)
572 if (
associated(cs%precip_0))
deallocate(cs%precip_0)
573 if (
associated(cs%heat_cyc))
deallocate(cs%heat_cyc)
574 if (
associated(cs%precip_cyc))
deallocate(cs%precip_cyc)
575 if (
associated(cs%avg_SST_anom))
deallocate(cs%avg_SST_anom)
576 if (
associated(cs%avg_SSS_anom))
deallocate(cs%avg_SSS_anom)
577 if (
associated(cs%avg_SSS))
deallocate(cs%avg_SSS)
583 end subroutine controlled_forcing_end
Pointers to various fields which may be used describe the surface state of MOM, and which will be ret...
Wraps the FMS time manager functions.
Control structure for MOM_controlled_forcing.
This module implements boundary forcing for MOM6.
Ocean grid type. See mom_grid for details.
A structure that can be parsed to read and document run-time parameters.
Provides the ocean grid type.
Register fields for restarts.
This module contains I/O framework code.
The MOM6 facility to parse input files for runtime parameters.
An overloaded interface to log the values of various types of parameters.
Do a halo update on a pair of arrays representing the two components of a vector. ...
Use control-theory to adjust the surface heat flux and precipitation.
Make a diagnostic available for averaging or output.
A restart registry and the control structure for restarts.
Describes various unit conversion factors.
Provides a transparent unit rescaling type to facilitate dimensional consistency testing.
Describes the decomposed MOM domain and has routines for communications across PEs.
Routines for error handling and I/O management.
The MOM6 facility for reading and writing restart files, and querying what has been read...
Structure that contains pointers to the boundary forcing used to drive the liquid ocean simulated by ...
Type for describing a variable, typically a tracer.
An overloaded interface to log version information about modules.
An overloaded interface to read various types of parameters.
Provides transparent structures with groups of MOM6 variables and supporting routines.
Do a halo update on an array.
An overloaded interface to read and log the values of various types of parameters.