@@ -67,6 +67,9 @@ module MOM_set_visc
6767 ! ! actual velocity in the bottommost `HBBL`, depending
6868 ! ! on whether linear_drag is true.
6969 ! ! Runtime parameter `BOTTOMDRAGLAW`.
70+ logical :: body_force_drag ! < If true, the bottom stress is imposed as an explicit body force
71+ ! ! applied over a fixed distance from the bottom, rather than as an
72+ ! ! implicit calculation based on an enhanced near-bottom viscosity.
7073 logical :: BBL_use_EOS ! < If true, use the equation of state in determining
7174 ! ! the properties of the bottom boundary layer.
7275 logical :: linear_drag ! < If true, the drag law is cdrag*`DRAG_BG_VEL`*u.
@@ -146,7 +149,9 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, pbv)
146149 ! layer with temperature [R C-1 ~> kg m-3 degC-1].
147150 dR_dS, & ! Partial derivative of the density in the bottom boundary
148151 ! layer with salinity [R S-1 ~> kg m-3 ppt-1].
149- press ! The pressure at which dR_dT and dR_dS are evaluated [R L2 T-2 ~> Pa].
152+ press, & ! The pressure at which dR_dT and dR_dS are evaluated [R L2 T-2 ~> Pa].
153+ umag_avg, & ! The average magnitude of velocities in the bottom boundary layer [L T-1 ~> m s-1].
154+ h_bbl_drag ! The thickness over which to apply drag as a body force [H ~> m or kg m-2].
150155 real :: htot ! Sum of the layer thicknesses up to some point [H ~> m or kg m-2].
151156 real :: htot_vel ! Sum of the layer thicknesses up to some point [H ~> m or kg m-2].
152157
@@ -199,6 +204,7 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, pbv)
199204 ! quadratic bottom drag [L2 T-2 ~> m2 s-2].
200205 real :: hwtot ! Sum of the thicknesses used to calculate
201206 ! the near-bottom velocity magnitude [H ~> m or kg m-2].
207+ real :: I_hwtot ! The Adcroft reciprocal of hwtot [H-1 ~> m-1 or m2 kg-1].
202208 real :: hutot ! Running sum of thicknesses times the velocity
203209 ! magnitudes [H L T-1 ~> m2 s-1 or kg m-1 s-1].
204210 real :: Thtot ! Running sum of thickness times temperature [C H ~> degC m or degC kg m-2].
@@ -265,6 +271,9 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, pbv)
265271 ! viscous bottom boundary layer [nondim].
266272 real :: BBL_visc_frac ! The fraction of all the drag that is expressed as
267273 ! a viscous bottom boundary layer [nondim].
274+ real :: h_bbl_fr ! The fraction of the bottom boundary layer in a layer [nondim].
275+ real :: h_sum ! The sum of the thicknesses of the layers below the one being
276+ ! worked on [H ~> m or kg m-2].
268277 real , parameter :: C1_3 = 1.0 / 3.0 , C1_6 = 1.0 / 6.0 , C1_12 = 1.0 / 12.0
269278 real :: C2pi_3 ! An irrational constant, 2/3 pi.
270279 real :: tmp ! A temporary variable.
@@ -508,7 +517,7 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, pbv)
508517 endif
509518 endif ; endif
510519
511- if (use_BBL_EOS .or. .not. CS% linear_drag) then
520+ if (use_BBL_EOS .or. CS % body_force_drag .or. .not. CS% linear_drag) then
512521 ! Calculate the mean velocity magnitude over the bottommost CS%Hbbl of
513522 ! the water column for determining the quadratic bottom drag.
514523 ! Used in ustar(i)
@@ -554,6 +563,12 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, pbv)
554563 ustar(i) = cdrag_sqrt_Z* CS% drag_bg_vel
555564 endif
556565
566+ ! Find the Adcroft reciprocal of the total thickness weights
567+ I_hwtot = 0.0 ; if (hwtot > 0.0 ) I_hwtot = 1.0 / hwtot
568+
569+ umag_avg(i) = hutot * I_hwtot
570+ h_bbl_drag(i) = hwtot
571+
557572 if (use_BBL_EOS) then ; if (hwtot > 0.0 ) then
558573 T_EOS(i) = Thtot/ hwtot ; S_EOS(i) = Shtot/ hwtot
559574 else
@@ -995,6 +1010,24 @@ subroutine set_viscous_BBL(u, v, h, tv, visc, G, GV, US, CS, pbv)
9951010 endif
9961011 endif
9971012
1013+ if (CS% body_force_drag .and. (h_bbl_drag(i) > 0.0 )) then
1014+ ! Increment the Rayleigh drag as a way introduce the bottom drag as a body force.
1015+ h_sum = 0.0
1016+ I_hwtot = 1.0 / h_bbl_drag(i)
1017+ do k= nz,1 ,- 1
1018+ h_bbl_fr = min (h_bbl_drag(i) - h_sum, h_at_vel(i,k)) * I_hwtot
1019+ if (m== 1 ) then
1020+ visc% Ray_u(I,j,k) = visc% Ray_u(I,j,k) + (CS% cdrag* US% L_to_Z* umag_avg(I)) * h_bbl_fr
1021+ else
1022+ visc% Ray_v(i,J,k) = visc% Ray_v(i,J,k) + (CS% cdrag* US% L_to_Z* umag_avg(i)) * h_bbl_fr
1023+ endif
1024+ h_sum = h_sum + h_at_vel(i,k)
1025+ if (h_sum >= bbl_thick) exit ! The top of this layer is above the drag zone.
1026+ enddo
1027+ ! Do not enhance the near-bottom viscosity in this case.
1028+ Kv_bbl = CS% Kv_BBL_min
1029+ endif
1030+
9981031 kv_bbl = max (CS% Kv_BBL_min, kv_bbl)
9991032 if (m== 1 ) then
10001033 visc% bbl_thick_u(I,j) = bbl_thick_Z
@@ -1967,6 +2000,11 @@ subroutine set_visc_init(Time, G, GV, US, param_file, diag, visc, CS, restart_CS
19672000 " may be an assumed value or it may be based on the " // &
19682001 " actual velocity in the bottommost HBBL, depending on " // &
19692002 " LINEAR_DRAG." , default= .true. )
2003+ call get_param(param_file, mdl, " DRAG_AS_BODY_FORCE" , CS% body_force_drag, &
2004+ " If true, the bottom stress is imposed as an explicit body force " // &
2005+ " applied over a fixed distance from the bottom, rather than as an " // &
2006+ " implicit calculation based on an enhanced near-bottom viscosity" , &
2007+ default= .false. , do_not_log= .not. CS% bottomdraglaw)
19702008 call get_param(param_file, mdl, " CHANNEL_DRAG" , CS% Channel_drag, &
19712009 " If true, the bottom drag is exerted directly on each " // &
19722010 " layer proportional to the fraction of the bottom it " // &
@@ -2178,7 +2216,7 @@ subroutine set_visc_init(Time, G, GV, US, param_file, diag, visc, CS, restart_CS
21782216 call pass_var(CS% tideamp,G% domain)
21792217 endif
21802218 endif
2181- if (CS% Channel_drag) then
2219+ if (CS% Channel_drag .or. CS % body_force_drag ) then
21822220 allocate (visc% Ray_u(IsdB:IedB,jsd:jed,nz), source= 0.0 )
21832221 allocate (visc% Ray_v(isd:ied,JsdB:JedB,nz), source= 0.0 )
21842222 CS% id_Ray_u = register_diag_field(' ocean_model' , ' Rayleigh_u' , diag% axesCuL, &
0 commit comments