Skip to content

Commit

Permalink
+Updating OBC ORLANSKI and OBLIQUE algorithms.
Browse files Browse the repository at this point in the history
- We now use u_new/v_new instead of u_old/v_old at the boundary. These
  values work because we zeroed out baroclinic accelerations at the
  boundary and added the barotropic accelerations.
- Changes affected OBC answers (for the better).
  • Loading branch information
kshedstrom committed Jul 25, 2017
1 parent 5a1ceb9 commit 3c073b6
Showing 1 changed file with 30 additions and 14 deletions.
44 changes: 30 additions & 14 deletions src/core/MOM_open_boundary.F90
Original file line number Diff line number Diff line change
Expand Up @@ -1150,9 +1150,13 @@ end subroutine open_boundary_impose_land_mask
subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
type(ocean_grid_type), intent(inout) :: G !< Ocean grid structure
type(ocean_OBC_type), pointer :: OBC !< Open boundary control structure
real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u_new !< New u values on open boundaries
real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(inout) :: u_new !< On exit, new u values on open boundaries
!! On entry, the old time-level v but
!! including barotropic accelerations.
real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), intent(in) :: u_old !< Original unadjusted u
real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v_new !< New v values on open boundaries
real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(inout) :: v_new !< On exit, new v values on open boundaries.
!! On entry, the old time-level v but
!! including barotropic accelerations.
real, dimension(SZI_(G),SZJB_(G),SZK_(G)), intent(in) :: v_old !< Original unadjusted v
real, intent(in) :: dt !< Appropriate timestep
! Local variables
Expand Down Expand Up @@ -1187,7 +1191,10 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
if (dhdt*dhdx > 0.0) rx_new = min( (dhdt/dhdx), rx_max) ! outward phase speed
rx_avg = (1.0-gamma_u)*segment%rx_normal(I,j,k) + gamma_u*rx_new
segment%rx_normal(I,j,k) = rx_avg
segment%normal_vel(I,j,k) = (u_old(I,j,k) + rx_avg*u_new(I-1,j,k)) / (1.0+rx_avg)
! The new boundary value is interpolated between future interior
! value, u_new(I-1) and past boundary value but with barotropic
! accelerations, u_new(I).
segment%normal_vel(I,j,k) = (u_new(I,j,k) + rx_avg*u_new(I-1,j,k)) / (1.0+rx_avg)
elseif (segment%oblique) then
dhdt = u_old(I-1,j,k)-u_new(I-1,j,k) !old-new
dhdx = u_new(I-1,j,k)-u_new(I-2,j,k) !in new time backward sasha for I-1
Expand All @@ -1208,7 +1215,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
cff = max(dhdx*dhdx + dhdy*dhdy, eps)
Cy = min(cff,max(dhdt*dhdy,-cff))
! endif
segment%normal_vel(I,j,k) = ((cff*u_old(I,j,k) + Cx*u_new(I-1,j,k)) - &
segment%normal_vel(I,j,k) = ((cff*u_new(I,j,k) + Cx*u_new(I-1,j,k)) - &
(max(Cy,0.0)*segment%grad_normal(J-1,2,k) + min(Cy,0.0)*segment%grad_normal(J,2,k))) / (cff + Cx)
elseif (segment%gradient) then
segment%normal_vel(I,j,k) = u_new(I-1,j,k)
Expand All @@ -1219,7 +1226,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
else
tau = segment%Tnudge_out
endif
segment%normal_vel(I,j,k) = u_new(I,j,k) + dt*tau*(segment%nudged_normal_vel(I,j,k) - u_old(I,j,k))
segment%normal_vel(I,j,k) = u_new(I,j,k) + dt*tau*(segment%nudged_normal_vel(I,j,k) - u_new(I,j,k))
endif
enddo; enddo
endif
Expand All @@ -1234,7 +1241,10 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
if (dhdt*dhdx > 0.0) rx_new = min( (dhdt/dhdx), rx_max)
rx_avg = (1.0-gamma_u)*segment%rx_normal(I,j,k) + gamma_u*rx_new
segment%rx_normal(I,j,k) = rx_avg
segment%normal_vel(I,j,k) = (u_old(I,j,k) + rx_avg*u_new(I+1,j,k)) / (1.0+rx_avg)
! The new boundary value is interpolated between future interior
! value, u_new(I+1) and past boundary value but with barotropic
! accelerations, u_new(I).
segment%normal_vel(I,j,k) = (u_new(I,j,k) + rx_avg*u_new(I+1,j,k)) / (1.0+rx_avg)
elseif (segment%oblique) then
dhdt = u_old(I+1,j,k)-u_new(I+1,j,k) !old-new
dhdx = u_new(I+1,j,k)-u_new(I+2,j,k) !in new time forward sasha for I+1
Expand All @@ -1255,7 +1265,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
cff = max(dhdx*dhdx + dhdy*dhdy, eps)
Cy = min(cff,max(dhdt*dhdy,-cff))
! endif
segment%normal_vel(I,j,k) = ((cff*u_old(I,j,k) + Cx*u_new(I+1,j,k)) - &
segment%normal_vel(I,j,k) = ((cff*u_new(I,j,k) + Cx*u_new(I+1,j,k)) - &
(max(Cy,0.0)*segment%grad_normal(J-1,2,k) + min(Cy,0.0)*segment%grad_normal(J,2,k))) / (cff + Cx)
elseif (segment%gradient) then
segment%normal_vel(I,j,k) = u_new(I+1,j,k)
Expand All @@ -1266,7 +1276,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
else
tau = segment%Tnudge_out
endif
segment%normal_vel(I,j,k) = u_new(I,j,k) + dt*tau*(segment%nudged_normal_vel(I,j,k) - u_old(I,j,k))
segment%normal_vel(I,j,k) = u_new(I,j,k) + dt*tau*(segment%nudged_normal_vel(I,j,k) - u_new(I,j,k))
endif
enddo; enddo
endif
Expand All @@ -1281,7 +1291,10 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
if (dhdt*dhdy > 0.0) ry_new = min( (dhdt/dhdy), ry_max)
ry_avg = (1.0-gamma_v)*segment%rx_normal(I,j,k) + gamma_v*ry_new
segment%rx_normal(i,J,k) = ry_avg
segment%normal_vel(i,J,k) = (v_old(i,J,k) + ry_avg*v_new(i,J-1,k)) / (1.0+ry_avg)
! The new boundary value is interpolated between future interior
! value, v_new(J-1) and past boundary value but with barotropic
! accelerations, v_new(J).
segment%normal_vel(i,J,k) = (v_new(i,J,k) + ry_avg*v_new(i,J-1,k)) / (1.0+ry_avg)
elseif (segment%oblique) then
dhdt = v_old(i,J-1,k)-v_new(i,J-1,k) !old-new
dhdy = v_new(i,J-1,k)-v_new(i,J-2,k) !in new time backward sasha for J-1
Expand All @@ -1302,7 +1315,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
cff = max(dhdx*dhdx + dhdy*dhdy, eps)
Cx = min(cff,max(dhdt*dhdx,-cff))
! endif
segment%normal_vel(i,J,k) = ((cff*v_old(i,J,k) + Cy*v_new(i,J-1,k)) - &
segment%normal_vel(i,J,k) = ((cff*v_new(i,J,k) + Cy*v_new(i,J-1,k)) - &
(max(Cx,0.0)*segment%grad_normal(I-1,2,k) + min(Cx,0.0)*segment%grad_normal(I,2,k))) / (cff + Cy)
elseif (segment%gradient) then
segment%normal_vel(i,J,k) = v_new(i,J-1,k)
Expand All @@ -1313,7 +1326,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
else
tau = segment%Tnudge_out
endif
segment%normal_vel(i,J,k) = v_new(i,J,k) + dt*tau*(segment%nudged_normal_vel(i,J,k) - v_old(i,J,k))
segment%normal_vel(i,J,k) = v_new(i,J,k) + dt*tau*(segment%nudged_normal_vel(i,J,k) - v_new(i,J,k))
endif
enddo; enddo
endif
Expand All @@ -1329,7 +1342,10 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
if (dhdt*dhdy > 0.0) ry_new = min( (dhdt/dhdy), ry_max)
ry_avg = (1.0-gamma_v)*segment%rx_normal(I,j,k) + gamma_v*ry_new
segment%rx_normal(i,J,k) = ry_avg
segment%normal_vel(i,J,k) = (v_old(i,J,k) + ry_avg*v_new(i,J+1,k)) / (1.0+ry_avg)
! The new boundary value is interpolated between future interior
! value, v_new(J+1) and past boundary value but with barotropic
! accelerations, v_new(J).
segment%normal_vel(i,J,k) = (v_new(i,J,k) + ry_avg*v_new(i,J+1,k)) / (1.0+ry_avg)
elseif (segment%oblique) then
dhdt = v_old(i,J+1,k)-v_new(i,J+1,k) !old-new
dhdy = v_new(i,J+1,k)-v_new(i,J+2,k) !in new time backward sasha for J-1
Expand All @@ -1350,7 +1366,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
cff = max(dhdx*dhdx + dhdy*dhdy, eps)
Cx = min(cff,max(dhdt*dhdx,-cff))
! endif
segment%normal_vel(i,J,k) = ((cff*v_old(i,J,k) + Cy*v_new(i,J+1,k)) - &
segment%normal_vel(i,J,k) = ((cff*v_new(i,J,k) + Cy*v_new(i,J+1,k)) - &
(max(Cx,0.0)*segment%grad_normal(I-1,2,k) + min(Cx,0.0)*segment%grad_normal(I,2,k))) / (cff + Cy)
elseif (segment%gradient) then
segment%normal_vel(i,J,k) = v_new(i,J+1,k)
Expand All @@ -1361,7 +1377,7 @@ subroutine radiation_open_bdry_conds(OBC, u_new, u_old, v_new, v_old, G, dt)
else
tau = segment%Tnudge_out
endif
segment%normal_vel(i,J,k) = v_new(i,J,k) + dt*tau*(segment%nudged_normal_vel(i,J,k) - v_old(i,J,k))
segment%normal_vel(i,J,k) = v_new(i,J,k) + dt*tau*(segment%nudged_normal_vel(i,J,k) - v_new(i,J,k))
endif
enddo; enddo
end if
Expand Down

0 comments on commit 3c073b6

Please sign in to comment.