MOM6
mom_dynamics_legacy_split Module Reference

Data Types

type  mom_dyn_legacy_split_cs
 

Functions/Subroutines

subroutine, public step_mom_dyn_legacy_split (u, v, h, tv, visc, Time_local, dt, fluxes, p_surf_begin, p_surf_end, dt_since_flux, dt_therm, uh, vh, uhtr, vhtr, eta_av, G, GV, CS, calc_dtbt, VarMix, MEKE)
 
subroutine, public adjustments_dyn_legacy_split (u, v, h, dt, G, GV, CS)
 
subroutine, public register_restarts_dyn_legacy_split (HI, GV, param_file, CS, restart_CS, uh, vh)
 
subroutine, public initialize_dyn_legacy_split (u, v, h, uh, vh, eta, Time, G, GV, param_file, diag, CS, restart_CS, dt, Accel_diag, Cont_diag, MIS, VarMix, MEKE, OBC, update_OBC_CSp, ALE_CSp, setVisc_CSp, visc, dirs, ntrunc)
 
subroutine, public end_dyn_legacy_split (CS)
 

Variables

integer id_clock_cor
 
integer id_clock_pres
 
integer id_clock_vertvisc
 
integer id_clock_horvisc
 
integer id_clock_mom_update
 
integer id_clock_continuity
 
integer id_clock_thick_diff
 
integer id_clock_btstep
 
integer id_clock_btcalc
 
integer id_clock_btforce
 
integer id_clock_pass
 
integer id_clock_pass_init
 

Function/Subroutine Documentation

◆ adjustments_dyn_legacy_split()

subroutine, public mom_dynamics_legacy_split::adjustments_dyn_legacy_split ( real, dimension(szib_(g),szj_(g),szk_(g)), intent(inout)  u,
real, dimension(szi_(g),szjb_(g),szk_(g)), intent(inout)  v,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(inout)  h,
real, intent(in)  dt,
type(ocean_grid_type), intent(inout)  G,
type(verticalgrid_type), intent(in)  GV,
type(mom_dyn_legacy_split_cs), pointer  CS 
)
Parameters
[in,out]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in,out]uThe zonal velocity, in m s-1.
[in,out]vThe meridional velocity, in m s-1.
[in,out]hLayer thicknesses, in H
[in]dtThe baroclinic dynamics time step, in s.
csThe control structure set up by initialize_dyn_legacy_split.

Definition at line 1044 of file MOM_dynamics_legacy_split.F90.

References id_clock_continuity.

Referenced by mom::step_mom().

1044  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure.
1045  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
1046  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1047  intent(inout) :: u !< The zonal velocity, in m s-1.
1048  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1049  intent(inout) :: v !< The meridional velocity, in m s-1.
1050  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
1051  intent(inout) :: h !< Layer thicknesses, in H
1052  !! (usually m or kg m-2).
1053  real, intent(in) :: dt !< The baroclinic dynamics time step, in s.
1054  type(mom_dyn_legacy_split_cs), pointer :: cs !< The control structure set up by
1055  !! initialize_dyn_legacy_split.
1056 
1057 ! Arguments: u - The zonal velocity, in m s-1.
1058 ! (in) v - The meridional velocity, in m s-1.
1059 ! (in) h - The layer thicknesses, in m or kg m-2, depending on
1060 ! whether the Boussinesq approximation is made.
1061 ! (in) dt - The time step in s.
1062 ! (in) G - The ocean's grid structure.
1063 ! (in) GV - The ocean's vertical grid structure.
1064 ! (in) CS - The control structure set up by initialize_dyn_legacy_split.
1065 
1066  ! Temporary arrays to contain layer thickness fluxes in m3 s-1 or kg s-1.
1067  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: uh_temp
1068  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: vh_temp
1069  ! A temporary array to contain layer projected thicknesses in m or kg m-2.
1070  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_temp
1071  integer :: i, j, k, is, ie, js, je, nz
1072  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1073 
1074  if (cs%readjust_BT_trans) then
1075  call cpu_clock_begin(id_clock_continuity)
1076  call continuity(u, v, h, h_temp, uh_temp, vh_temp, dt, g, gv, &
1077  cs%continuity_CSp, obc=cs%OBC)
1078  call cpu_clock_end(id_clock_continuity)
1079 !$OMP parallel default(none) shared(is,ie,js,je,nz,CS,uh_temp,vh_temp)
1080 !$OMP do
1081  do j=js,je
1082  do i=is-1,ie ; cs%uhbt_in(i,j) = uh_temp(i,j,1) ; enddo
1083  do k=2,nz ; do i=is-1,ie
1084  cs%uhbt_in(i,j) = cs%uhbt_in(i,j) + uh_temp(i,j,k)
1085  enddo ; enddo
1086  enddo
1087 !$OMP do
1088  do j=js-1,je
1089  do i=is,ie ; cs%vhbt_in(i,j) = vh_temp(i,j,1) ; enddo
1090  do k=2,nz ; do i=is,ie
1091  cs%vhbt_in(i,j) = cs%vhbt_in(i,j) + vh_temp(i,j,k)
1092  enddo ; enddo
1093  enddo
1094 !$OMP end parallel
1095  cs%readjust_velocity = .true.
1096  endif
1097 
Here is the caller graph for this function:

◆ end_dyn_legacy_split()

subroutine, public mom_dynamics_legacy_split::end_dyn_legacy_split ( type(mom_dyn_legacy_split_cs), pointer  CS)

Definition at line 1540 of file MOM_dynamics_legacy_split.F90.

1540  type(mom_dyn_legacy_split_cs), pointer :: cs
1541 ! (inout) CS - The control structure set up by initialize_dyn_legacy_split.
1542 
1543  dealloc_(cs%diffu) ; dealloc_(cs%diffv)
1544  dealloc_(cs%CAu) ; dealloc_(cs%CAv)
1545  dealloc_(cs%PFu) ; dealloc_(cs%PFv)
1546 
1547  if (associated(cs%taux_bot)) deallocate(cs%taux_bot)
1548  if (associated(cs%tauy_bot)) deallocate(cs%tauy_bot)
1549  dealloc_(cs%uhbt) ; dealloc_(cs%vhbt)
1550  dealloc_(cs%u_accel_bt) ; dealloc_(cs%v_accel_bt)
1551  dealloc_(cs%visc_rem_u) ; dealloc_(cs%visc_rem_v)
1552 
1553  dealloc_(cs%eta) ; dealloc_(cs%eta_PF) ; dealloc_(cs%pbce)
1554  dealloc_(cs%h_av) ; dealloc_(cs%u_av) ; dealloc_(cs%v_av)
1555  dealloc_(cs%uhbt_in) ; dealloc_(cs%vhbt_in)
1556 
1557  call dealloc_bt_cont_type(cs%BT_cont)
1558 
1559  deallocate(cs)

◆ initialize_dyn_legacy_split()

subroutine, public mom_dynamics_legacy_split::initialize_dyn_legacy_split ( real, dimension(szib_(g),szj_(g),szk_(g)), intent(inout)  u,
real, dimension(szi_(g),szjb_(g),szk_(g)), intent(inout)  v,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(inout)  h,
real, dimension(szib_(g),szj_(g),szk_(g)), intent(inout), target  uh,
real, dimension(szi_(g),szjb_(g),szk_(g)), intent(inout), target  vh,
real, dimension(szi_(g),szj_(g)), intent(inout)  eta,
type(time_type), intent(in), target  Time,
type(ocean_grid_type), intent(inout)  G,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file,
type(diag_ctrl), intent(inout), target  diag,
type(mom_dyn_legacy_split_cs), pointer  CS,
type(mom_restart_cs), pointer  restart_CS,
real, intent(in)  dt,
type(accel_diag_ptrs), intent(inout), target  Accel_diag,
type(cont_diag_ptrs), intent(inout), target  Cont_diag,
type(ocean_internal_state), intent(inout)  MIS,
type(varmix_cs), pointer  VarMix,
type(meke_type), pointer  MEKE,
type(ocean_obc_type), pointer  OBC,
type(update_obc_cs), pointer  update_OBC_CSp,
type(ale_cs), pointer  ALE_CSp,
type(set_visc_cs), pointer  setVisc_CSp,
type(vertvisc_type), intent(inout)  visc,
type(directories), intent(in)  dirs,
integer, intent(inout), target  ntrunc 
)
Parameters
[in,out]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in,out]uThe zonal velocity, in m s-1.
[in,out]vThe meridional velocity, in m s-1.
[in,out]hLayer thicknesses, in H
[in,out]uhThe zonal volume or mass transport,
[in,out]vhThe meridional volume or mass transport,
[in,out]etaThe free surface height or column mass,
[in]timeThe current model time.
[in]param_fileA structure to parse for run-time parameters.
[in,out]diagA structure that is used to regulate diagnostic output.
csThe control structure set up by initialize_dyn_legacy_split.
restart_csA pointer to the restart control structure.
[in]dtThe baroclinic dynamics time step, in s.
[in,out]accel_diagA set of pointers to the various accelerations in the momentum equations, which can be used for later derived diagnostics, like energy budgets.
[in,out]cont_diagA structure with pointers to various terms in the continuity equations.
[in,out]misThe "MOM6 Internal State" structure, used to pass around pointers to various arrays for diagnostic purposes.
varmixA pointer to a structure with fields that specify the spatially variable viscosities.
mekeA pointer to a structure containing fields related to the Mesoscale Eddy Kinetic Energy.
obcIf open boundary conditions are used, this points to the ocean_OBC_type that was set up in MOM_initialization.
update_obc_cspIf open boundary condition updates are used, this points to the appropriate control structure.
ale_cspThis points to the ALE control structure.
setvisc_cspThis points to the set_visc control structure.
[in,out]viscA structure containing vertical viscosities, bottom drag viscosities, and related fields.
[in]dirsA structure containing several relevant directory paths.
[in,out]ntruncA target for the variable that records the number of times the velocity is truncated (this should be 0).

Definition at line 1214 of file MOM_dynamics_legacy_split.F90.

References id_clock_btcalc, id_clock_btforce, id_clock_btstep, id_clock_continuity, id_clock_cor, id_clock_horvisc, id_clock_mom_update, id_clock_pass, id_clock_pass_init, id_clock_pres, and id_clock_vertvisc.

1214  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure.
1215  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
1216  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1217  intent(inout) :: u !< The zonal velocity, in m s-1.
1218  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1219  intent(inout) :: v !< The meridional velocity, in m s-1.
1220  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) , &
1221  intent(inout) :: h !< Layer thicknesses, in H
1222  !! (usually m or kg m-2).
1223  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
1224  target, intent(inout) :: uh !< The zonal volume or mass transport,
1225  !! in m3 s-1 or kg s-1.
1226  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
1227  target, intent(inout) :: vh !< The meridional volume or mass transport,
1228  !! in m3 s-1 or kg s-1.
1229  real, dimension(SZI_(G),SZJ_(G)), &
1230  intent(inout) :: eta !< The free surface height or column mass,
1231  !! in m or kg m-2.
1232  type(time_type), target, intent(in) :: time !< The current model time.
1233  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time
1234  !! parameters.
1235  type(diag_ctrl), target, intent(inout) :: diag !< A structure that is used to
1236  !! regulate diagnostic output.
1237  type(mom_dyn_legacy_split_cs), pointer :: cs !< The control structure set up by
1238  !! initialize_dyn_legacy_split.
1239  type(mom_restart_cs), pointer :: restart_cs !< A pointer to the restart control
1240  !! structure.
1241  real, intent(in) :: dt !< The baroclinic dynamics time step,
1242  !! in s.
1243  type(accel_diag_ptrs), target, intent(inout) :: accel_diag !<A set of pointers to the various
1244  !! accelerations in the momentum equations, which can be
1245  !! used for later derived diagnostics, like energy budgets.
1246  type(cont_diag_ptrs), target, intent(inout) :: cont_diag !< A structure with pointers to various
1247  !! terms in the continuity equations.
1248  type(ocean_internal_state), intent(inout) :: mis !< The "MOM6 Internal State"
1249  !! structure, used to pass around pointers to
1250  !! various arrays for diagnostic purposes.
1251  type(varmix_cs), pointer :: varmix !< A pointer to a structure with
1252  !! fields that specify the spatially variable viscosities.
1253  type(meke_type), pointer :: meke !< A pointer to a structure containing
1254  !! fields related to the Mesoscale Eddy Kinetic Energy.
1255  type(ocean_obc_type), pointer :: obc !< If open boundary conditions are
1256  !! used, this points to the ocean_OBC_type
1257  !! that was set up in MOM_initialization.
1258  type(update_obc_cs), pointer :: update_obc_csp !< If open boundary condition
1259  !! updates are used, this points to
1260  !! the appropriate control structure.
1261  type(ale_cs), pointer :: ale_csp !< This points to the ALE control
1262  !! structure.
1263  type(set_visc_cs), pointer :: setvisc_csp !< This points to the set_visc control
1264  !! structure.
1265  type(vertvisc_type), intent(inout) :: visc !< A structure containing vertical
1266  !! viscosities, bottom drag viscosities, and related fields.
1267  type(directories), intent(in) :: dirs !< A structure containing several
1268  !! relevant directory paths.
1269  integer, target, intent(inout) :: ntrunc !< A target for the variable that
1270  !! records the number of times the velocity is truncated (this should be 0).
1271 
1272 ! Arguments: u - The zonal velocity, in m s-1.
1273 ! (inout) v - The meridional velocity, in m s-1.
1274 ! (inout) h - The layer thicknesses, in m or kg m-2, depending on whether
1275 ! the Boussinesq approximation is made.
1276 ! (inout) uh - The zonal volume or mass transport, in m3 s-1 or kg s-1.
1277 ! (inout) vh - The meridional volume or mass transport, in m3 s-1 or kg s-1.
1278 ! (out) eta - The free surface height or column mass, in m or kg m-2.
1279 ! (in) Time - The current model time.
1280 ! (in) G - The ocean's grid structure.
1281 ! (in) param_file - A structure indicating the open file to parse for
1282 ! model parameter values.
1283 ! (in) diag - A structure that is used to regulate diagnostic output.
1284 ! (inout) CS - The control structure set up by initialize_dyn_legacy_split.
1285 ! (in) restart_CS - A pointer to the restart control structure.
1286 ! (inout) Accel_diag - A set of pointers to the various accelerations in
1287 ! the momentum equations, which can be used for later derived
1288 ! diagnostics, like energy budgets.
1289 ! (inout) Cont_diag - A structure with pointers to various terms in the
1290 ! continuity equations.
1291 ! (inout) MIS - The "MOM6 Internal State" structure, used to pass around
1292 ! pointers to various arrays for diagnostic purposes.
1293 ! (in) VarMix - A pointer to a structure with fields that specify the
1294 ! spatially variable viscosities.
1295 ! (inout) MEKE - A pointer to a structure containing fields related to
1296 ! the Mesoscale Eddy Kinetic Energy.
1297 ! (in) OBC - If open boundary conditions are used, this points to the
1298 ! ocean_OBC_type that was set up in MOM_initialization.
1299 ! (in) update_OBC_CSp - If open boundary condition updates are used,
1300 ! this points to the appropriate control structure.
1301 ! (in) ALE_CS - This points to the ALE control structure.
1302 ! (in) setVisc_CSp - This points to the set_visc control structure.
1303 ! (inout) visc - A structure containing vertical viscosities, bottom drag
1304 ! viscosities, and related fields.
1305 ! (in) dirs - A structure containing several relevant directory paths.
1306 ! (in) ntrunc - A target for the variable that records the number of times
1307 ! the velocity is truncated (this should be 0).
1308 
1309  ! This subroutine initializes all of the variables that are used by this
1310  ! dynamic core, including diagnostics and the cpu clocks.
1311 
1312  ! This subroutine initializes any variables that are specific to this time
1313  ! stepping scheme, including the cpu clocks.
1314  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: h_tmp
1315  character(len=40) :: mdl = "MOM_dynamics_legacy_split" ! This module's name.
1316  character(len=48) :: thickness_units, flux_units
1317  logical :: adiabatic, use_tides, debug_truncations
1318  integer :: i, j, k, is, ie, js, je, isd, ied, jsd, jed, nz
1319  integer :: isdb, iedb, jsdb, jedb
1320  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
1321  isd = g%isd ; ied = g%ied ; jsd = g%jsd ; jed = g%jed
1322  isdb = g%IsdB ; iedb = g%IedB ; jsdb = g%JsdB ; jedb = g%JedB
1323 
1324  if (.not.associated(cs)) call mom_error(fatal, &
1325  "initialize_dyn_legacy_split called with an unassociated control structure.")
1326  if (cs%module_is_initialized) then
1327  call mom_error(warning, "initialize_dyn_legacy_split called with a control "// &
1328  "structure that has already been initialized.")
1329  return
1330  endif
1331  cs%module_is_initialized = .true.
1332 
1333  cs%diag => diag
1334 
1335  call get_param(param_file, mdl, "TIDES", use_tides, &
1336  "If true, apply tidal momentum forcing.", default=.false.)
1337  call get_param(param_file, mdl, "BE", cs%be, &
1338  "If SPLIT is true, BE determines the relative weighting \n"//&
1339  "of a 2nd-order Runga-Kutta baroclinic time stepping \n"//&
1340  "scheme (0.5) and a backward Euler scheme (1) that is \n"//&
1341  "used for the Coriolis and inertial terms. BE may be \n"//&
1342  "from 0.5 to 1, but instability may occur near 0.5. \n"//&
1343  "BE is also applicable if SPLIT is false and USE_RK2 \n"//&
1344  "is true.", units="nondim", default=0.6)
1345  call get_param(param_file, mdl, "BEGW", cs%begw, &
1346  "If SPLIT is true, BEGW is a number from 0 to 1 that \n"//&
1347  "controls the extent to which the treatment of gravity \n"//&
1348  "waves is forward-backward (0) or simulated backward \n"//&
1349  "Euler (1). 0 is almost always used.\n"//&
1350  "If SPLIT is false and USE_RK2 is true, BEGW can be \n"//&
1351  "between 0 and 0.5 to damp gravity waves.", &
1352  units="nondim", default=0.0)
1353 
1354  call get_param(param_file, mdl, "FLUX_BT_COUPLING", cs%flux_BT_coupling, &
1355  "If true, use mass fluxes to ensure consistency between \n"//&
1356  "the baroclinic and barotropic modes. This is only used \n"//&
1357  "if SPLIT is true.", default=.false.)
1358  call get_param(param_file, mdl, "READJUST_BT_TRANS", cs%readjust_BT_trans, &
1359  "If true, make a barotropic adjustment to the layer \n"//&
1360  "velocities after the thermodynamic part of the step \n"//&
1361  "to ensure that the interaction between the thermodynamics \n"//&
1362  "and the continuity solver do not change the barotropic \n"//&
1363  "transport. This is only used if FLUX_BT_COUPLING and \n"//&
1364  "SPLIT are true.", default=.false.)
1365  call get_param(param_file, mdl, "SPLIT_BOTTOM_STRESS", cs%split_bottom_stress, &
1366  "If true, provide the bottom stress calculated by the \n"//&
1367  "vertical viscosity to the barotropic solver.", default=.false.)
1368  call get_param(param_file, mdl, "BT_USE_LAYER_FLUXES", cs%BT_use_layer_fluxes, &
1369  "If true, use the summed layered fluxes plus an \n"//&
1370  "adjustment due to the change in the barotropic velocity \n"//&
1371  "in the barotropic continuity equation.", default=.true.)
1372  call get_param(param_file, mdl, "DEBUG", cs%debug, &
1373  "If true, write out verbose debugging data.", default=.false.)
1374  call get_param(param_file, mdl, "ADIABATIC", adiabatic, default=.false., do_not_log=.true.)
1375  if (.not.cs%flux_BT_coupling .or. adiabatic) cs%readjust_BT_trans = .false.
1376  call get_param(param_file, mdl, "DEBUG_TRUNCATIONS", debug_truncations, &
1377  default=.false.)
1378 
1379  allocate(cs%taux_bot(isdb:iedb,jsd:jed)) ; cs%taux_bot(:,:) = 0.0
1380  allocate(cs%tauy_bot(isd:ied,jsdb:jedb)) ; cs%tauy_bot(:,:) = 0.0
1381 
1382  alloc_(cs%uhbt(isdb:iedb,jsd:jed)) ; cs%uhbt(:,:) = 0.0
1383  alloc_(cs%vhbt(isd:ied,jsdb:jedb)) ; cs%vhbt(:,:) = 0.0
1384  alloc_(cs%visc_rem_u(isdb:iedb,jsd:jed,nz)) ; cs%visc_rem_u(:,:,:) = 0.0
1385  alloc_(cs%visc_rem_v(isd:ied,jsdb:jedb,nz)) ; cs%visc_rem_v(:,:,:) = 0.0
1386  alloc_(cs%eta_PF(isd:ied,jsd:jed)) ; cs%eta_PF(:,:) = 0.0
1387  alloc_(cs%pbce(isd:ied,jsd:jed,nz)) ; cs%pbce(:,:,:) = 0.0
1388 
1389  alloc_(cs%u_accel_bt(isdb:iedb,jsd:jed,nz)) ; cs%u_accel_bt(:,:,:) = 0.0
1390  alloc_(cs%v_accel_bt(isd:ied,jsdb:jedb,nz)) ; cs%v_accel_bt(:,:,:) = 0.0
1391 
1392  mis%diffu => cs%diffu ; mis%diffv => cs%diffv
1393  mis%PFu => cs%PFu ; mis%PFv => cs%PFv
1394  mis%CAu => cs%CAu ; mis%CAv => cs%CAv
1395  mis%pbce => cs%pbce
1396  mis%u_accel_bt => cs%u_accel_bt ; mis%v_accel_bt => cs%v_accel_bt
1397  mis%u_av => cs%u_av ; mis%v_av => cs%v_av
1398 
1399  cs%ADp => accel_diag ; cs%CDp => cont_diag
1400  accel_diag%diffu => cs%diffu ; accel_diag%diffv => cs%diffv
1401  accel_diag%PFu => cs%PFu ; accel_diag%PFv => cs%PFv
1402  accel_diag%CAu => cs%CAu ; accel_diag%CAv => cs%CAv
1403 ! Accel_diag%pbce => CS%pbce
1404 ! Accel_diag%u_accel_bt => CS%u_accel_bt ; Accel_diag%v_accel_bt => CS%v_accel_bt
1405 ! Accel_diag%u_av => CS%u_av ; Accel_diag%v_av => CS%v_av
1406 
1407  call continuity_init(time, g, gv, param_file, diag, cs%continuity_CSp)
1408  call coriolisadv_init(time, g, param_file, diag, cs%ADp, cs%CoriolisAdv_CSp)
1409  if (use_tides) call tidal_forcing_init(time, g, param_file, cs%tides_CSp)
1410  call pressureforce_init(time, g, gv, param_file, diag, cs%PressureForce_CSp, &
1411  cs%tides_CSp)
1412  call hor_visc_init(time, g, param_file, diag, cs%hor_visc_CSp)
1413  call vertvisc_init(mis, time, g, gv, param_file, diag, cs%ADp, dirs, &
1414  ntrunc, cs%vertvisc_CSp)
1415  if (.not.associated(setvisc_csp)) call mom_error(fatal, &
1416  "initialize_dyn_legacy_split called with setVisc_CSp unassociated.")
1417  cs%set_visc_CSp => setvisc_csp
1418 
1419  if (associated(ale_csp)) cs%ALE_CSp => ale_csp
1420  if (associated(obc)) cs%OBC => obc
1421  if (associated(update_obc_csp)) cs%update_OBC_CSp => update_obc_csp
1422 
1423  if (.not. query_initialized(cs%eta,"sfc",restart_cs)) then
1424  ! Estimate eta based on the layer thicknesses - h. With the Boussinesq
1425  ! approximation, eta is the free surface height anomaly, while without it
1426  ! eta is the mass of ocean per unit area. eta always has the same
1427  ! dimensions as h, either m or kg m-3.
1428  ! CS%eta(:,:) = 0.0 already from initialization.
1429  if (gv%Boussinesq) then
1430  do j=js,je ; do i=is,ie ; cs%eta(i,j) = -g%bathyT(i,j) ; enddo ; enddo
1431  endif
1432  do k=1,nz ; do j=js,je ; do i=is,ie
1433  cs%eta(i,j) = cs%eta(i,j) + h(i,j,k)
1434  enddo ; enddo ; enddo
1435  endif
1436  ! Copy eta into an output array.
1437  do j=js,je ; do i=is,ie ; eta(i,j) = cs%eta(i,j) ; enddo ; enddo
1438 
1439  call legacy_barotropic_init(u, v, h, cs%eta, time, g, gv, param_file, diag, &
1440  cs%barotropic_CSp, restart_cs, cs%BT_cont, cs%tides_CSp)
1441 
1442  if (.not. query_initialized(cs%diffu,"diffu",restart_cs) .or. &
1443  .not. query_initialized(cs%diffv,"diffv",restart_cs)) &
1444  call horizontal_viscosity(u, v, h, cs%diffu, cs%diffv, meke, varmix, &
1445  g, gv, cs%hor_visc_CSp)
1446  if (.not. query_initialized(cs%u_av,"u2", restart_cs) .or. &
1447  .not. query_initialized(cs%u_av,"v2", restart_cs)) then
1448  cs%u_av(:,:,:) = u(:,:,:)
1449  cs%v_av(:,:,:) = v(:,:,:)
1450  endif
1451 ! This call is just here to initialize uh and vh.
1452  if (.not. query_initialized(uh,"uh",restart_cs) .or. &
1453  .not. query_initialized(vh,"vh",restart_cs)) then
1454  h_tmp(:,:,:) = h(:,:,:)
1455  call continuity(u, v, h, h_tmp, uh, vh, dt, g, gv, cs%continuity_CSp, obc=cs%OBC)
1456  call cpu_clock_begin(id_clock_pass_init)
1457  call pass_var(h_tmp, g%Domain)
1458  call cpu_clock_end(id_clock_pass_init)
1459  cs%h_av(:,:,:) = 0.5*(h(:,:,:) + h_tmp(:,:,:))
1460  else
1461  if (.not. query_initialized(cs%h_av,"h2",restart_cs)) &
1462  cs%h_av(:,:,:) = h(:,:,:)
1463  endif
1464 
1465  ! Determine whether there is a barotropic transport that is to be used
1466  ! to adjust the layers' velocities.
1467  cs%readjust_velocity = .false.
1468  if (cs%readjust_BT_trans) then
1469  if (query_initialized(cs%uhbt_in,"uhbt_in",restart_cs) .and. &
1470  query_initialized(cs%vhbt_in,"vhbt_in",restart_cs)) then
1471  cs%readjust_velocity = .true.
1472  call cpu_clock_begin(id_clock_pass_init)
1473  call pass_vector(cs%uhbt_in, cs%vhbt_in, g%Domain)
1474  call cpu_clock_end(id_clock_pass_init)
1475  endif
1476  endif
1477 
1478  call cpu_clock_begin(id_clock_pass_init)
1479  call pass_vector(cs%u_av,cs%v_av, g%Domain)
1480  call pass_var(cs%h_av, g%Domain)
1481  call pass_vector(uh, vh, g%Domain)
1482  call cpu_clock_end(id_clock_pass_init)
1483 
1484  flux_units = get_flux_units(gv)
1485  cs%id_uh = register_diag_field('ocean_model', 'uh', diag%axesCuL, time, &
1486  'Zonal Thickness Flux', flux_units)
1487  cs%id_vh = register_diag_field('ocean_model', 'vh', diag%axesCvL, time, &
1488  'Meridional Thickness Flux', flux_units)
1489  cs%id_CAu = register_diag_field('ocean_model', 'CAu', diag%axesCuL, time, &
1490  'Zonal Coriolis and Advective Acceleration', 'meter second-2')
1491  cs%id_CAv = register_diag_field('ocean_model', 'CAv', diag%axesCvL, time, &
1492  'Meridional Coriolis and Advective Acceleration', 'meter second-2')
1493  cs%id_PFu = register_diag_field('ocean_model', 'PFu', diag%axesCuL, time, &
1494  'Zonal Pressure Force Acceleration', 'meter second-2')
1495  cs%id_PFv = register_diag_field('ocean_model', 'PFv', diag%axesCvL, time, &
1496  'Meridional Pressure Force Acceleration', 'meter second-2')
1497 
1498  cs%id_uav = register_diag_field('ocean_model', 'uav', diag%axesCuL, time, &
1499  'Barotropic-step Averaged Zonal Velocity', 'meter second-1')
1500  cs%id_vav = register_diag_field('ocean_model', 'vav', diag%axesCvL, time, &
1501  'Barotropic-step Averaged Meridional Velocity', 'meter second-1')
1502 
1503 
1504  if (cs%flux_BT_coupling) then
1505  cs%id_du_adj = register_diag_field('ocean_model', 'du_adj', diag%axesCuL, time, &
1506  'Zonal velocity adjustments due to nonstandard terms', 'meter second-1')
1507  cs%id_dv_adj = register_diag_field('ocean_model', 'dv_adj', diag%axesCvL, time, &
1508  'Meridional velocity adjustments due to nonstandard terms', 'meter second-1')
1509  if (cs%id_du_adj > 0) call safe_alloc_ptr(cs%ADp%du_other,isdb,iedb,jsd,jed,nz)
1510  if (cs%id_dv_adj > 0) call safe_alloc_ptr(cs%ADp%dv_other,isd,ied,jsdb,jedb,nz)
1511  endif
1512  cs%id_u_BT_accel = register_diag_field('ocean_model', 'u_BT_accel', diag%axesCuL, time, &
1513  'Barotropic Anomaly Zonal Acceleration', 'meter second-1')
1514  cs%id_v_BT_accel = register_diag_field('ocean_model', 'v_BT_accel', diag%axesCvL, time, &
1515  'Barotropic Anomaly Meridional Acceleration', 'meter second-1')
1516 
1517  if (debug_truncations) then
1518  if (cs%flux_BT_coupling) then
1519  call safe_alloc_ptr(cs%ADp%du_other,isdb,iedb,jsd,jed,nz)
1520  call safe_alloc_ptr(cs%ADp%dv_other,isd,ied,jsdb,jedb,nz)
1521  endif
1522  endif
1523 
1524  id_clock_cor = cpu_clock_id('(Ocean Coriolis & mom advection)', grain=clock_module)
1525  id_clock_continuity = cpu_clock_id('(Ocean continuity equation)', grain=clock_module)
1526  id_clock_pres = cpu_clock_id('(Ocean pressure force)', grain=clock_module)
1527  id_clock_vertvisc = cpu_clock_id('(Ocean vertical viscosity)', grain=clock_module)
1528  id_clock_horvisc = cpu_clock_id('(Ocean horizontal viscosity)', grain=clock_module)
1529  id_clock_mom_update = cpu_clock_id('(Ocean momentum increments)', grain=clock_module)
1530  id_clock_pass = cpu_clock_id('(Ocean message passing)', grain=clock_module)
1531  id_clock_pass_init = cpu_clock_id('(Ocean init message passing)', grain=clock_routine)
1532  id_clock_btcalc = cpu_clock_id('(Ocean barotropic mode calc)', grain=clock_module)
1533  id_clock_btstep = cpu_clock_id('(Ocean barotropic mode stepping)', grain=clock_module)
1534  id_clock_btforce = cpu_clock_id('(Ocean barotropic forcing calc)', grain=clock_module)
1535 
1536 

◆ register_restarts_dyn_legacy_split()

subroutine, public mom_dynamics_legacy_split::register_restarts_dyn_legacy_split ( type(hor_index_type), intent(in)  HI,
type(verticalgrid_type), intent(in)  GV,
type(param_file_type), intent(in)  param_file,
type(mom_dyn_legacy_split_cs), pointer  CS,
type(mom_restart_cs), pointer  restart_CS,
real, dimension(szib_(hi),szj_(hi),szk_(gv)), intent(inout), target  uh,
real, dimension(szi_(hi),szjb_(hi),szk_(gv)), intent(inout), target  vh 
)
Parameters
[in]hiA horizontal index type structure.
[in]gvThe ocean's vertical grid structure.
[in]param_fileA structure to parse for run-time parameters.
csThe control structure set up by initialize_dyn_legacy_split.
restart_csA pointer to the restart control structure.
[in,out]uhThe zonal volume or mass transport,
[in,out]vhThe meridional volume or mass

Definition at line 1103 of file MOM_dynamics_legacy_split.F90.

1103  type(hor_index_type), intent(in) :: hi !< A horizontal index type structure.
1104  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
1105  type(param_file_type), intent(in) :: param_file !< A structure to parse for run-time
1106  !! parameters.
1107  type(mom_dyn_legacy_split_cs), pointer :: cs !< The control structure set up by
1108  !! initialize_dyn_legacy_split.
1109  type(mom_restart_cs), pointer :: restart_cs !< A pointer to the restart
1110  !! control structure.
1111  real, dimension(SZIB_(HI),SZJ_(HI),SZK_(GV)), &
1112  target, intent(inout) :: uh !< The zonal volume or mass transport,
1113  !! in m3 s-1 or kg s-1.
1114  real, dimension(SZI_(HI),SZJB_(HI),SZK_(GV)), &
1115  target, intent(inout) :: vh !< The meridional volume or mass
1116  !! transport, in m3 s-1 or kg s-1.
1117 ! This subroutine sets up any auxiliary restart variables that are specific
1118 ! to the unsplit time stepping scheme. All variables registered here should
1119 ! have the ability to be recreated if they are not present in a restart file.
1120 
1121 ! Arguments: HI - A horizontal index type structure.
1122 ! (in) GV - The ocean's vertical grid structure.
1123 ! (in) param_file - A structure indicating the open file to parse for
1124 ! model parameter values.
1125 ! (inout) CS - The control structure set up by initialize_dyn_legacy_split.
1126 ! (in) restart_CS - A pointer to the restart control structure.
1127 ! (inout) uh - The zonal volume or mass transport, in m3 s-1 or kg s-1.
1128 ! (inout) vh - The meridional volume or mass transport, in m3 s-1 or kg s-1.
1129 
1130  type(vardesc) :: vd
1131  character(len=40) :: mdl = "MOM_dynamics_legacy_split" ! This module's name.
1132  character(len=48) :: thickness_units, flux_units
1133  logical :: adiabatic, flux_bt_coupling, readjust_bt_trans
1134  integer :: isd, ied, jsd, jed, nz, isdb, iedb, jsdb, jedb
1135  isd = hi%isd ; ied = hi%ied ; jsd = hi%jsd ; jed = hi%jed ; nz = gv%ke
1136  isdb = hi%IsdB ; iedb = hi%IedB ; jsdb = hi%JsdB ; jedb = hi%JedB
1137 
1138 ! This is where a control structure that is specific to this module would be allocated.
1139  if (associated(cs)) then
1140  call mom_error(warning, "register_restarts_dyn_legacy_split called with an associated "// &
1141  "control structure.")
1142  return
1143  endif
1144  allocate(cs)
1145 
1146  call get_param(param_file, "MOM_legacy_split", "FLUX_BT_COUPLING", flux_bt_coupling, &
1147  default=.false., do_not_log=.true.)
1148  call get_param(param_file, "MOM_legacy_split", "READJUST_BT_TRANS", readjust_bt_trans, &
1149  default=.false., do_not_log=.true.)
1150  call get_param(param_file, "MOM_legacy_split", "ADIABATIC", adiabatic, &
1151  default=.false., do_not_log=.true.)
1152  if (.not.flux_bt_coupling .or. adiabatic) readjust_bt_trans = .false.
1153 
1154  alloc_(cs%diffu(isdb:iedb,jsd:jed,nz)) ; cs%diffu(:,:,:) = 0.0
1155  alloc_(cs%diffv(isd:ied,jsdb:jedb,nz)) ; cs%diffv(:,:,:) = 0.0
1156  alloc_(cs%CAu(isdb:iedb,jsd:jed,nz)) ; cs%CAu(:,:,:) = 0.0
1157  alloc_(cs%CAv(isd:ied,jsdb:jedb,nz)) ; cs%CAv(:,:,:) = 0.0
1158  alloc_(cs%PFu(isdb:iedb,jsd:jed,nz)) ; cs%PFu(:,:,:) = 0.0
1159  alloc_(cs%PFv(isd:ied,jsdb:jedb,nz)) ; cs%PFv(:,:,:) = 0.0
1160 
1161  alloc_(cs%eta(isd:ied,jsd:jed)) ; cs%eta(:,:) = 0.0
1162  alloc_(cs%u_av(isdb:iedb,jsd:jed,nz)) ; cs%u_av(:,:,:) = 0.0
1163  alloc_(cs%v_av(isd:ied,jsdb:jedb,nz)) ; cs%v_av(:,:,:) = 0.0
1164  alloc_(cs%h_av(isd:ied,jsd:jed,nz)) ; cs%h_av(:,:,:) = gv%Angstrom
1165  alloc_(cs%uhbt_in(isdb:iedb,jsd:jed)) ; cs%uhbt_in(:,:) = 0.0
1166  alloc_(cs%vhbt_in(isd:ied,jsdb:jedb)) ; cs%vhbt_in(:,:) = 0.0
1167 
1168  thickness_units = get_thickness_units(gv)
1169  flux_units = get_flux_units(gv)
1170 
1171  vd = var_desc("sfc",thickness_units,"Free surface Height",'h','1')
1172  call register_restart_field(cs%eta, vd, .false., restart_cs)
1173 
1174  vd = var_desc("u2","meter second-1","Auxiliary Zonal velocity",'u','L')
1175  call register_restart_field(cs%u_av, vd, .false., restart_cs)
1176 
1177  vd = var_desc("v2","meter second-1","Auxiliary Meridional velocity",'v','L')
1178  call register_restart_field(cs%v_av, vd, .false., restart_cs)
1179 
1180  vd = var_desc("h2",thickness_units,"Auxiliary Layer Thickness",'h','L')
1181  call register_restart_field(cs%h_av, vd, .false., restart_cs)
1182 
1183  vd = var_desc("uh",flux_units,"Zonal thickness flux",'u','L')
1184  call register_restart_field(uh, vd, .false., restart_cs)
1185 
1186  vd = var_desc("vh",flux_units,"Meridional thickness flux",'v','L')
1187  call register_restart_field(vh, vd, .false., restart_cs)
1188 
1189  vd = var_desc("diffu","meter second-2","Zonal horizontal viscous acceleration",'u','L')
1190  call register_restart_field(cs%diffu, vd, .false., restart_cs)
1191 
1192  vd = var_desc("diffv","meter second-2","Meridional horizontal viscous acceleration",'v','L')
1193  call register_restart_field(cs%diffv, vd, .false., restart_cs)
1194 
1195  call register_legacy_barotropic_restarts(hi, gv, param_file, &
1196  cs%barotropic_CSp, restart_cs)
1197 
1198  if (readjust_bt_trans) then
1199  vd = var_desc("uhbt_in",flux_units,"Final instantaneous barotropic zonal thickness flux",&
1200  'u','1')
1201  call register_restart_field(cs%uhbt_in, vd, .false., restart_cs)
1202 
1203  vd = var_desc("vhbt_in",flux_units,"Final instantaneous barotropic meridional thickness flux",&
1204  'v','1')
1205  call register_restart_field(cs%vhbt_in, vd, .false., restart_cs)
1206  endif
1207 

◆ step_mom_dyn_legacy_split()

subroutine, public mom_dynamics_legacy_split::step_mom_dyn_legacy_split ( real, dimension(szib_(g),szj_(g),szk_(g)), intent(inout), target  u,
real, dimension(szi_(g),szjb_(g),szk_(g)), intent(inout), target  v,
real, dimension(szi_(g),szj_(g),szk_(g)), intent(inout)  h,
type(thermo_var_ptrs), intent(in)  tv,
type(vertvisc_type), intent(inout)  visc,
type(time_type), intent(in)  Time_local,
real, intent(in)  dt,
type(forcing), intent(in)  fluxes,
real, dimension(:,:), pointer  p_surf_begin,
real, dimension(:,:), pointer  p_surf_end,
real, intent(in)  dt_since_flux,
real, intent(in)  dt_therm,
real, dimension(szib_(g),szj_(g),szk_(g)), intent(inout), target  uh,
real, dimension(szi_(g),szjb_(g),szk_(g)), intent(inout), target  vh,
real, dimension(szib_(g),szj_(g),szk_(g)), intent(inout)  uhtr,
real, dimension(szi_(g),szjb_(g),szk_(g)), intent(inout)  vhtr,
real, dimension(szi_(g),szj_(g)), intent(out)  eta_av,
type(ocean_grid_type), intent(inout)  G,
type(verticalgrid_type), intent(in)  GV,
type(mom_dyn_legacy_split_cs), pointer  CS,
logical, intent(in)  calc_dtbt,
type(varmix_cs), pointer  VarMix,
type(meke_type), pointer  MEKE 
)
Parameters
[in,out]gThe ocean's grid structure.
[in]gvThe ocean's vertical grid structure.
[in,out]uThe zonal velocity, in m s-1.
[in,out]vThe meridional velocity, in m s-1.
[in,out]hLayer thicknesses, in H (usually m or kg m-2).
[in]tvA structure pointing to various. thermodynamic variables.
[in,out]viscA structure containing vertical viscosities, bottom drag viscosities, and related fields.
[in]time_localThe model time at the end of the time step.
[in]dtThe baroclinic dynamics time step, in s
[in]fluxesA structure containing pointers to any possible forcing fields. Unused fields have NULL ptrs.
p_surf_beginA pointer (perhaps NULL) to the surface pressure at the beginning of this dynamic step, in Pa.
p_surf_endA pointer (perhaps NULL) to the surface pressure at the end of this dynamic step, in Pa.
[in]dt_since_fluxThe elapsed time since fluxes were applied, in s.
[in]dt_thermThe thermodynamic time step, in s.
[in,out]uhThe zonal volume or mass transport,
[in,out]vhThe meridional volume or mass transport,
[in,out]uhtrThe accumulated zonal volume or mass
[in,out]vhtrThe accumulated meridional volume or mass
[out]eta_avThe free surface height or column mass
csThe control structure set up by
[in]calc_dtbtIf true, recalculate the barotropic time step.
varmixA pointer to a structure with fields that specify the spatially variable viscosities.
mekeA pointer to a structure containing fields related to the Mesoscale Eddy Kinetic Energy.

Definition at line 275 of file MOM_dynamics_legacy_split.F90.

References mom_continuity::continuity(), mom_coriolisadv::coradcalc(), id_clock_btcalc, id_clock_btforce, id_clock_btstep, id_clock_continuity, id_clock_cor, id_clock_horvisc, id_clock_mom_update, id_clock_pass, id_clock_pres, id_clock_vertvisc, mom_legacy_barotropic::legacy_set_dtbt(), mom_checksum_packages::mom_accel_chksum(), mom_open_boundary::open_boundary_zero_normal_flow(), mom_pressureforce::pressureforce(), mom_set_visc::set_viscous_ml(), mom_domains::to_all, and mom_boundary_update::update_obc_data().

275  type(ocean_grid_type), intent(inout) :: g !< The ocean's grid structure.
276  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure.
277  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
278  target, intent(inout) :: u !< The zonal velocity, in m s-1.
279  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
280  target, intent(inout) :: v !< The meridional velocity, in m s-1.
281  real, dimension(SZI_(G),SZJ_(G),SZK_(G)), &
282  intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2).
283  type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various.
284  !! thermodynamic variables.
285  type(vertvisc_type), intent(inout) :: visc !< A structure containing vertical viscosities,
286  !! bottom drag viscosities, and related fields.
287  type(time_type), intent(in) :: time_local !< The model time at the end
288  !! of the time step.
289  real, intent(in) :: dt !< The baroclinic dynamics time step, in s
290  type(forcing), intent(in) :: fluxes !< A structure containing pointers to any
291  !! possible forcing fields. Unused fields
292  !! have NULL ptrs.
293  real, dimension(:,:), pointer :: p_surf_begin !< A pointer (perhaps NULL) to the
294  !! surface pressure at the beginning
295  !! of this dynamic step, in Pa.
296  real, dimension(:,:), pointer :: p_surf_end !< A pointer (perhaps NULL) to the
297  !! surface pressure at the end of
298  !! this dynamic step, in Pa.
299  real, intent(in) :: dt_since_flux !< The elapsed time since fluxes
300  !! were applied, in s.
301  real, intent(in) :: dt_therm !< The thermodynamic time step, in s.
302  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
303  target, intent(inout) :: uh !< The zonal volume or mass transport,
304  !! in m3 s-1 or kg s-1.
305  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
306  target, intent(inout) :: vh !< The meridional volume or mass transport,
307  !! in m3 s-1 or kg s-1.
308  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), &
309  intent(inout) :: uhtr !< The accumulated zonal volume or mass
310  !! transport since the last tracer advection,
311  !! in m3 or kg.
312  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), &
313  intent(inout) :: vhtr !< The accumulated meridional volume or mass
314  !! transport since the last tracer advection,
315  !! in m3 or kg.
316  real, dimension(SZI_(G),SZJ_(G)), &
317  intent(out) :: eta_av !< The free surface height or column mass
318  !! time-averaged over a time step,
319  !! in m or kg m-2.
320  type(mom_dyn_legacy_split_cs), &
321  pointer :: cs !< The control structure set up by
322  !! initialize_dyn_legacy_split.
323  logical, intent(in) :: calc_dtbt !< If true, recalculate the
324  !! barotropic time step.
325  type(varmix_cs), pointer :: varmix !<A pointer to a structure with fields that
326  !! specify the spatially variable viscosities.
327  type(meke_type), pointer :: meke !< A pointer to a structure containing fields
328  !! related to the Mesoscale Eddy Kinetic Energy.
329 ! Arguments: u - The zonal velocity, in m s-1.
330 ! (inout) v - The meridional velocity, in m s-1.
331 ! (inout) h - The layer thicknesses, in m or kg m-2, depending on
332 ! whether the Boussinesq approximation is made.
333 ! (in) tv - a structure pointing to various thermodynamic variables.
334 ! (inout) visc - A structure containing vertical viscosities, bottom drag
335 ! viscosities, and related fields.
336 ! (in) Time_local - The model time at the end of the time step.
337 ! (in) dt - The time step in s.
338 ! (in) fluxes - A structure containing pointers to any possible
339 ! forcing fields. Unused fields have NULL ptrs.
340 ! (in) p_surf_begin - A pointer (perhaps NULL) to the surface pressure
341 ! at the beginning of this dynamic step, in Pa.
342 ! (in) p_surf_end - A pointer (perhaps NULL) to the surface pressure
343 ! at the end of this dynamic step, in Pa.
344 ! (in) dt_since_flux - The elapsed time since fluxes were applied, in s.
345 ! (in) dt_therm - The thermodynamic time step, in s.
346 ! (inout) uh - The zonal volume or mass transport, in m3 s-1 or kg s-1.
347 ! (inout) vh - The meridional volume or mass transport, in m3 s-1 or kg s-1.
348 ! (inout) uhtr - The accumulated zonal volume or mass transport since the last
349 ! tracer advection, in m3 or kg.
350 ! (inout) vhtr - The accumulated meridional volume or mass transport since the last
351 ! tracer advection, in m3 or kg.
352 ! (out) eta_av - The free surface height or column mass time-averaged
353 ! over a time step, in m or kg m-2.
354 ! (in) G - The ocean's grid structure.
355 ! (in) GV - The ocean's vertical grid structure.
356 ! (in) CS - The control structure set up by initialize_dyn_legacy_split.
357 ! (in) calc_dtbt - If true, recalculate the barotropic time step.
358 ! (in) VarMix - A pointer to a structure with fields that specify the
359 ! spatially variable viscosities.
360 ! (inout) MEKE - A pointer to a structure containing fields related to
361 ! the Mesoscale Eddy Kinetic Energy.
362 
363  real :: dt_pred ! The time step for the predictor part of the baroclinic
364  ! time stepping.
365 
366  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: &
367  up ! Predicted zonal velocitiy in m s-1.
368  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: &
369  vp ! Predicted meridional velocitiy in m s-1.
370  real, dimension(SZI_(G),SZJ_(G),SZK_(G)) :: &
371  hp ! Predicted thickness in m or kg m-2 (H).
372 
373  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_bc_accel
374  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_bc_accel
375  ! u_bc_accel and v_bc_accel are the summed baroclinic accelerations of each
376  ! layer calculated by the non-barotropic part of the model, both in m s-2.
377  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), target :: uh_in
378  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), target :: vh_in
379  ! uh_in and vh_in are the zonal or meridional mass transports that would be
380  ! obtained using the initial velocities, both in m3 s-1 or kg s-1.
381  real, dimension(SZIB_(G),SZJ_(G)) :: uhbt_out
382  real, dimension(SZI_(G),SZJB_(G)) :: vhbt_out
383  ! uhbt_out and vhbt_out are the vertically summed transports from the
384  ! barotropic solver based on its final velocities, both in m3 s-1 or kg s-1.
385  real, dimension(SZI_(G),SZJ_(G)) :: eta_pred
386  ! eta_pred is the predictor value of the free surface height or column mass,
387  ! in m or kg m-2.
388  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)), target :: u_adj
389  real, dimension(SZI_(G),SZJB_(G),SZK_(G)), target :: v_adj
390  ! u_adj and v_adj are the zonal or meridional velocities after u and v
391  ! have been barotropically adjusted so the resulting transports match
392  ! uhbt_out and vhbt_out, both in m s-1.
393  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_tmp
394  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_tmp
395  ! u_tmp and v_tmp are temporary velocities used in diagnostic calculations.
396 
397  real, dimension(SZIB_(G),SZJ_(G),SZK_(G)) :: u_old_rad_obc
398  real, dimension(SZI_(G),SZJB_(G),SZK_(G)) :: v_old_rad_obc
399  ! u_old_rad_OBC and v_old_rad_OBC are the starting velocities, which are
400  ! saved for use in the Flather open boundary condition code, both in m s-1.
401 
402  real :: pa_to_eta ! A factor that converts pressures to the units of eta.
403  real, pointer, dimension(:,:) :: &
404  p_surf => null(), eta_pf_start => null(), &
405  taux_bot => null(), tauy_bot => null(), &
406  uhbt_in, vhbt_in, eta
407  real, pointer, dimension(:,:,:) :: &
408  uh_ptr => null(), u_ptr => null(), vh_ptr => null(), v_ptr => null(), &
409  u_init => null(), v_init => null(), & ! Pointers to u and v or u_adj and v_adj.
410  u_av, & ! The zonal velocity time-averaged over a time step, in m s-1.
411  v_av, & ! The meridional velocity time-averaged over a time step, in m s-1.
412  h_av ! The layer thickness time-averaged over a time step, in m or
413  ! kg m-2.
414  real :: idt
415  logical :: dyn_p_surf
416  logical :: bt_cont_bt_thick ! If true, use the BT_cont_type to estimate the
417  ! relative weightings of the layers in calculating
418  ! the barotropic accelerations.
419  integer :: pid_bbl_h, pid_eta_pf, pid_eta, pid_visc
420  integer :: pid_h, pid_u, pid_u_av, pid_uh, pid_uhbt_in
421  integer :: i, j, k, is, ie, js, je, isq, ieq, jsq, jeq, nz
422  is = g%isc ; ie = g%iec ; js = g%jsc ; je = g%jec ; nz = g%ke
423  isq = g%IscB ; ieq = g%IecB ; jsq = g%JscB ; jeq = g%JecB
424  u_av => cs%u_av ; v_av => cs%v_av ; h_av => cs%h_av
425  eta => cs%eta ; uhbt_in => cs%uhbt_in ; vhbt_in => cs%vhbt_in
426  idt = 1.0 / dt
427 
428  up(:,:,:) = 0.0 ; vp(:,:,:) = 0.0 ; hp(:,:,:) = h(:,:,:)
429 
430  if (cs%debug) then
431  call mom_state_chksum("Start predictor ", u, v, h, uh, vh, g, gv)
432  call check_redundant("Start predictor u ", u, v, g)
433  call check_redundant("Start predictor uh ", uh, vh, g)
434  endif
435 
436  dyn_p_surf = associated(p_surf_begin) .and. associated(p_surf_end)
437  if (dyn_p_surf) then
438  p_surf => p_surf_end
439  call safe_alloc_ptr(eta_pf_start,g%isd,g%ied,g%jsd,g%jed)
440  eta_pf_start(:,:) = 0.0
441  else
442  p_surf => fluxes%p_surf
443  endif
444 
445  if (associated(cs%OBC)) then
446  do k=1,nz ; do j=js,je ; do i=is-2,ie+1
447  u_old_rad_obc(i,j,k) = u(i,j,k)
448  enddo ; enddo ; enddo
449  do k=1,nz ; do j=js-2,je+1 ; do i=is,ie
450  v_old_rad_obc(i,j,k) = v(i,j,k)
451  enddo ; enddo ; enddo
452  endif
453 
454  if (ASSOCIATED(cs%ADp%du_other)) cs%ADp%du_other(:,:,:) = 0.0
455  if (ASSOCIATED(cs%ADp%dv_other)) cs%ADp%dv_other(:,:,:) = 0.0
456 
457  bt_cont_bt_thick = .false.
458  if (associated(cs%BT_cont)) bt_cont_bt_thick = &
459  (associated(cs%BT_cont%h_u) .and. associated(cs%BT_cont%h_v))
460 
461  if (cs%split_bottom_stress) then
462  taux_bot => cs%taux_bot ; tauy_bot => cs%tauy_bot
463  endif
464 
465 ! PFu = d/dx M(h,T,S)
466 ! pbce = dM/deta
467  if (cs%begw == 0.0) call enable_averaging(dt, time_local, cs%diag)
468  call cpu_clock_begin(id_clock_pres)
469  call pressureforce(h, tv, cs%PFu, cs%PFv, g, gv, cs%PressureForce_CSp, &
470  cs%ALE_CSp, p_surf, cs%pbce, cs%eta_PF)
471  if (dyn_p_surf) then
472  if (gv%Boussinesq) then
473  pa_to_eta = 1.0 / (gv%Rho0*gv%g_Earth)
474  else
475  pa_to_eta = 1.0 / gv%H_to_Pa
476  endif
477  do j=jsq,jeq+1 ; do i=isq,ieq+1
478  eta_pf_start(i,j) = cs%eta_PF(i,j) - pa_to_eta * &
479  (p_surf_begin(i,j) - p_surf_end(i,j))
480  enddo ; enddo
481  endif
482  call cpu_clock_end(id_clock_pres)
483  call disable_averaging(cs%diag)
484 
485  if (g%nonblocking_updates) then
486  call cpu_clock_begin(id_clock_pass)
487  pid_eta_pf = pass_var_start(cs%eta_PF, g%Domain)
488  pid_eta = pass_var_start(eta, g%Domain)
489  if (cs%readjust_velocity) &
490  pid_uhbt_in = pass_vector_start(uhbt_in, vhbt_in, g%Domain)
491  call cpu_clock_end(id_clock_pass)
492  endif
493 
494  if (associated(cs%OBC)) then; if (cs%OBC%update_OBC) then
495  call update_obc_data(cs%OBC, g, gv, tv, h, cs%update_OBC_CSp, time_local)
496  endif; endif
497 
498 ! CAu = -(f+zeta_av)/h_av vh + d/dx KE_av
499  call cpu_clock_begin(id_clock_cor)
500  call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, g, gv, &
501  cs%CoriolisAdv_CSp)
502  call cpu_clock_end(id_clock_cor)
503 
504 ! u_bc_accel = CAu + PFu + diffu(u[n-1])
505  call cpu_clock_begin(id_clock_btforce)
506  do k=1,nz ; do j=js,je ; do i=isq,ieq
507  u_bc_accel(i,j,k) = (cs%Cau(i,j,k) + cs%PFu(i,j,k)) + cs%diffu(i,j,k)
508  enddo ; enddo ; enddo
509  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
510  v_bc_accel(i,j,k) = (cs%Cav(i,j,k) + cs%PFv(i,j,k)) + cs%diffv(i,j,k)
511  enddo ; enddo ; enddo
512  if (associated(cs%OBC)) then
513  call open_boundary_zero_normal_flow(cs%OBC, g, u_bc_accel, v_bc_accel)
514  endif
515  call cpu_clock_end(id_clock_btforce)
516 
517  if (cs%debug) then
518  call check_redundant("pre-btstep CS%Ca ", cs%Cau, cs%Cav, g)
519  call check_redundant("pre-btstep CS%PF ", cs%PFu, cs%PFv, g)
520  call check_redundant("pre-btstep CS%diff ", cs%diffu, cs%diffv, g)
521  call check_redundant("pre-btstep u_bc_accel ", u_bc_accel, v_bc_accel, g)
522  endif
523 
524  if (g%nonblocking_updates) then
525  call cpu_clock_begin(id_clock_pass)
526  call pass_var_complete(pid_eta_pf, cs%eta_PF, g%Domain)
527  call pass_var_complete(pid_eta, eta, g%Domain)
528  if (cs%readjust_velocity) &
529  call pass_vector_complete(pid_uhbt_in, uhbt_in, vhbt_in, g%Domain)
530  call cpu_clock_end(id_clock_pass)
531  endif
532 
533  call cpu_clock_begin(id_clock_vertvisc)
534  do k=1,nz ; do j=js,je ; do i=isq,ieq
535  up(i,j,k) = g%mask2dCu(i,j) * (u(i,j,k) + dt * u_bc_accel(i,j,k))
536  enddo ; enddo ; enddo
537  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
538  vp(i,j,k) = g%mask2dCv(i,j) * (v(i,j,k) + dt * v_bc_accel(i,j,k))
539  enddo ; enddo ; enddo
540  call enable_averaging(dt, time_local, cs%diag)
541  call set_viscous_ml(u, v, h, tv, fluxes, visc, dt, g, gv, &
542  cs%set_visc_CSp)
543  call disable_averaging(cs%diag)
544 
545  call vertvisc_coef(up, vp, h, fluxes, visc, dt, g, gv, cs%vertvisc_CSp, cs%OBC)
546  call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt, g, gv, cs%vertvisc_CSp)
547  call cpu_clock_end(id_clock_vertvisc)
548 
549  call cpu_clock_begin(id_clock_pass)
550  if (g%nonblocking_updates) then
551  pid_visc = pass_vector_start(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
552  to_all+scalar_pair, cgrid_ne)
553  else
554  call pass_var(cs%eta_PF, g%Domain, complete=.false.)
555  call pass_var(eta, g%Domain)
556  if (cs%readjust_velocity) call pass_vector(uhbt_in, vhbt_in, g%Domain)
557  call pass_vector(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
558  to_all+scalar_pair, cgrid_ne)
559  endif
560  call cpu_clock_end(id_clock_pass)
561 
562  call cpu_clock_begin(id_clock_btcalc)
563  ! Calculate the relative layer weights for determining barotropic quantities.
564  if (.not.bt_cont_bt_thick) &
565  call legacy_btcalc(h, g, gv, cs%barotropic_CSp)
566  call legacy_bt_mass_source(h, eta, fluxes, .true., dt_therm, dt_since_flux, &
567  g, gv, cs%barotropic_CSp)
568  call cpu_clock_end(id_clock_btcalc)
569 
570  if (g%nonblocking_updates) then
571  call cpu_clock_begin(id_clock_pass)
572  call pass_vector_complete(pid_visc, cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
573  to_all+scalar_pair, cgrid_ne)
574  call cpu_clock_end(id_clock_pass)
575  endif
576 
577 ! u_accel_bt = layer accelerations due to barotropic solver
578  if (cs%flux_BT_coupling) then
579  call cpu_clock_begin(id_clock_continuity)
580  if (cs%readjust_velocity) then
581  ! Adjust the input velocites so that their transports match uhbt_out & vhbt_out.
582  call continuity(u, v, h, hp, uh_in, vh_in, dt, g, gv, &
583  cs%continuity_CSp, uhbt_in, vhbt_in, cs%OBC, &
584  cs%visc_rem_u, cs%visc_rem_v, u_adj, v_adj, &
585  bt_cont=cs%BT_cont)
586  u_init => u_adj ; v_init => v_adj
587  if (ASSOCIATED(cs%ADp%du_other)) then ; do k=1,nz ; do j=js,je ; do i=isq,ieq
588  cs%ADp%du_other(i,j,k) = u_adj(i,j,k) - u(i,j,k)
589  enddo ; enddo ; enddo ; endif
590  if (ASSOCIATED(cs%ADp%dv_other)) then ; do k=1,nz ; do j=jsq,jeq ; do i=is,ie
591  cs%ADp%dv_other(i,j,k) = v_adj(i,j,k) - v(i,j,k)
592  enddo ; enddo ; enddo ; endif
593  cs%readjust_velocity = .false.
594  else
595  call continuity(u, v, h, hp, uh_in, vh_in, dt, g, gv, &
596  cs%continuity_CSp, obc=cs%OBC, bt_cont=cs%BT_cont)
597 !### call continuity(u, v, h, hp, uh_in, vh_in, dt, G, GV, &
598 !### CS%continuity_CSp, OBC=CS%OBC, visc_rem_u=CS%visc_rem_u, &
599 !### visc_rem_v=CS%visc_rem_v, BT_cont=CS%BT_cont)
600  u_init => u ; v_init => v
601  endif
602  call cpu_clock_end(id_clock_continuity)
603 
604  if (bt_cont_bt_thick) then
605  call cpu_clock_begin(id_clock_pass)
606  call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
607  to_all+scalar_pair, cgrid_ne)
608  call cpu_clock_end(id_clock_pass)
609  call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
610  endif
611  call cpu_clock_begin(id_clock_btstep)
612  if (calc_dtbt) call legacy_set_dtbt(g, gv, cs%barotropic_CSp, eta, cs%pbce, cs%BT_cont)
613  call legacy_btstep(.true., uh_in, vh_in, eta, dt, u_bc_accel, v_bc_accel, &
614  fluxes, cs%pbce, cs%eta_PF, uh, vh, cs%u_accel_bt, &
615  cs%v_accel_bt, eta_pred, cs%uhbt, cs%vhbt, g, gv, &
616  cs%barotropic_CSp, cs%visc_rem_u, cs%visc_rem_v, &
617  uhbt_out = uhbt_out, vhbt_out = vhbt_out, obc = cs%OBC, &
618  bt_cont = cs%BT_cont, eta_pf_start = eta_pf_start, &
619  taux_bot=taux_bot, tauy_bot=tauy_bot)
620  call cpu_clock_end(id_clock_btstep)
621  else
622 
623  if (associated(cs%BT_cont) .or. cs%BT_use_layer_fluxes) then
624  call cpu_clock_begin(id_clock_continuity)
625  call continuity(u, v, h, hp, uh_in, vh_in, dt, g, gv, &
626  cs%continuity_CSp, obc=cs%OBC, &
627  visc_rem_u=cs%visc_rem_u, visc_rem_v=cs%visc_rem_v, &
628  bt_cont=cs%BT_cont)
629  call cpu_clock_end(id_clock_continuity)
630  if (bt_cont_bt_thick) then
631  call cpu_clock_begin(id_clock_pass)
632  call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
633  to_all+scalar_pair, cgrid_ne)
634  call cpu_clock_end(id_clock_pass)
635  call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
636  endif
637  endif
638 
639  if (cs%BT_use_layer_fluxes) then
640  uh_ptr => uh_in; vh_ptr => vh_in; u_ptr => u; v_ptr => v
641  endif
642 
643  u_init => u ; v_init => v
644  call cpu_clock_begin(id_clock_btstep)
645  if (calc_dtbt) call legacy_set_dtbt(g, gv, cs%barotropic_CSp, eta, cs%pbce)
646  call legacy_btstep(.false., u, v, eta, dt, u_bc_accel, v_bc_accel, &
647  fluxes, cs%pbce, cs%eta_PF, u_av, v_av, cs%u_accel_bt, &
648  cs%v_accel_bt, eta_pred, cs%uhbt, cs%vhbt, g, gv, cs%barotropic_CSp,&
649  cs%visc_rem_u, cs%visc_rem_v, obc=cs%OBC, &
650  bt_cont = cs%BT_cont, eta_pf_start=eta_pf_start, &
651  taux_bot=taux_bot, tauy_bot=tauy_bot, &
652  uh0=uh_ptr, vh0=vh_ptr, u_uh0=u_ptr, v_vh0=v_ptr)
653  call cpu_clock_end(id_clock_btstep)
654  endif
655 
656 ! up = u + dt_pred*( u_bc_accel + u_accel_bt )
657  dt_pred = dt * cs%be
658  call cpu_clock_begin(id_clock_mom_update)
659  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
660  vp(i,j,k) = g%mask2dCv(i,j) * (v_init(i,j,k) + dt_pred * &
661  (v_bc_accel(i,j,k) + cs%v_accel_bt(i,j,k)))
662  enddo ; enddo ; enddo
663 
664  do k=1,nz ; do j=js,je ; do i=isq,ieq
665  up(i,j,k) = g%mask2dCu(i,j) * (u_init(i,j,k) + dt_pred * &
666  (u_bc_accel(i,j,k) + cs%u_accel_bt(i,j,k)))
667  enddo ; enddo ; enddo
668  call cpu_clock_end(id_clock_mom_update)
669 
670  if (cs%debug) then
671  call uvchksum("Predictor 1 [uv]", up, vp, g%HI,haloshift=0)
672  call hchksum(h, "Predictor 1 h", g%HI, haloshift=1, scale=gv%H_to_m)
673  call uvchksum("Predictor 1 [uv]h", uh, vh, &
674  g%HI, haloshift=2, scale=gv%H_to_m)
675 ! call MOM_state_chksum("Predictor 1", up, vp, h, uh, vh, G, GV, haloshift=1)
676  call mom_accel_chksum("Predictor accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
677  cs%diffu, cs%diffv, g, gv, cs%pbce, cs%u_accel_bt, cs%v_accel_bt)
678  call mom_state_chksum("Predictor 1 init", u_init, v_init, h, uh, vh, g, gv, haloshift=2)
679  call check_redundant("Predictor 1 up", up, vp, g)
680  call check_redundant("Predictor 1 uh", uh, vh, g)
681  endif
682 
683 ! up <- up + dt_pred d/dz visc d/dz up
684 ! u_av <- u_av + dt_pred d/dz visc d/dz u_av
685  call cpu_clock_begin(id_clock_vertvisc)
686  call vertvisc_coef(up, vp, h, fluxes, visc, dt_pred, g, gv, cs%vertvisc_CSp, &
687  cs%OBC)
688  call vertvisc(up, vp, h, fluxes, visc, dt_pred, cs%OBC, cs%ADp, cs%CDp, g, &
689  gv, cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot)
690  if (g%nonblocking_updates) then
691  call cpu_clock_end(id_clock_vertvisc) ; call cpu_clock_begin(id_clock_pass)
692  pid_u = pass_vector_start(up, vp, g%Domain)
693  call cpu_clock_end(id_clock_pass) ; call cpu_clock_begin(id_clock_vertvisc)
694  endif
695  call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt_pred, g, gv, cs%vertvisc_CSp)
696  call cpu_clock_end(id_clock_vertvisc)
697 
698  call cpu_clock_begin(id_clock_pass)
699  call pass_vector(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
700  to_all+scalar_pair, cgrid_ne)
701  if (g%nonblocking_updates) then
702  call pass_vector_complete(pid_u, up, vp, g%Domain)
703  else
704  call pass_vector(up, vp, g%Domain)
705  endif
706  call cpu_clock_end(id_clock_pass)
707 
708 ! uh = u_av * h
709 ! hp = h + dt * div . uh
710  call cpu_clock_begin(id_clock_continuity)
711  call continuity(up, vp, h, hp, uh, vh, dt, g, gv, cs%continuity_CSp, &
712  cs%uhbt, cs%vhbt, cs%OBC, cs%visc_rem_u, &
713  cs%visc_rem_v, u_av, v_av, bt_cont=cs%BT_cont)
714  call cpu_clock_end(id_clock_continuity)
715 
716  call cpu_clock_begin(id_clock_pass)
717  call pass_var(hp, g%Domain)
718  if (g%nonblocking_updates) then
719  pid_u_av = pass_vector_start(u_av, v_av, g%Domain)
720  pid_uh = pass_vector_start(uh(:,:,:), vh(:,:,:), g%Domain)
721  else
722  call pass_vector(u_av, v_av, g%Domain, complete=.false.)
723  call pass_vector(uh(:,:,:), vh(:,:,:), g%Domain)
724  endif
725  call cpu_clock_end(id_clock_pass)
726 
727  if (associated(cs%OBC)) then
728  call radiation_open_bdry_conds(cs%OBC, u_av, u_old_rad_obc, v_av, v_old_rad_obc, g, dt)
729  endif
730 
731 ! h_av = (h + hp)/2
732  do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2
733  h_av(i,j,k) = 0.5*(h(i,j,k) + hp(i,j,k))
734  enddo ; enddo ; enddo
735 
736 ! The correction phase of the time step starts here.
737  call enable_averaging(dt, time_local, cs%diag)
738 
739 ! Calculate a revised estimate of the free-surface height correction to be
740 ! used in the next call to btstep. This call is at this point so that
741 ! hp can be changed if CS%begw /= 0.
742 ! eta_cor = ... (hidden inside CS%barotropic_CSp)
743  call cpu_clock_begin(id_clock_btcalc)
744  call legacy_bt_mass_source(hp, eta_pred, fluxes, .false., dt_therm, &
745  dt_since_flux+dt, g, gv, cs%barotropic_CSp)
746  call cpu_clock_end(id_clock_btcalc)
747 
748  if (cs%begw /= 0.0) then
749  ! hp <- (1-begw)*h_in + begw*hp
750  ! Back up hp to the value it would have had after a time-step of
751  ! begw*dt. hp is not used again until recalculated by continuity.
752  do k=1,nz ; do j=js-1,je+1 ; do i=is-1,ie+1
753  hp(i,j,k) = (1.0-cs%begw)*h(i,j,k) + cs%begw*hp(i,j,k)
754  enddo ; enddo ; enddo
755 
756 ! PFu = d/dx M(hp,T,S)
757 ! pbce = dM/deta
758  call cpu_clock_begin(id_clock_pres)
759  call pressureforce(hp, tv, cs%PFu, cs%PFv, g, gv, &
760  cs%PressureForce_CSp, cs%ALE_CSp, &
761  p_surf, cs%pbce, cs%eta_PF)
762  call cpu_clock_end(id_clock_pres)
763  call cpu_clock_begin(id_clock_pass)
764  call pass_var(cs%eta_PF, g%Domain)
765  call cpu_clock_end(id_clock_pass)
766  endif
767 
768  if (g%nonblocking_updates) then
769  call cpu_clock_begin(id_clock_pass)
770  call pass_vector_complete(pid_u_av, u_av, v_av, g%Domain)
771  call pass_vector_complete(pid_uh, uh(:,:,:), vh(:,:,:), g%Domain)
772  call cpu_clock_end(id_clock_pass)
773  endif
774 
775  if (associated(cs%OBC)) then; if (cs%OBC%update_OBC) then
776  call update_obc_data(cs%OBC, g, gv, tv, h, cs%update_OBC_CSp, time_local)
777  endif; endif
778 
779  if (bt_cont_bt_thick) then
780  call cpu_clock_begin(id_clock_pass)
781  call pass_vector(cs%BT_cont%h_u, cs%BT_cont%h_v, g%Domain, &
782  to_all+scalar_pair, cgrid_ne)
783  call cpu_clock_end(id_clock_pass)
784  call legacy_btcalc(h, g, gv, cs%barotropic_CSp, cs%BT_cont%h_u, cs%BT_cont%h_v)
785  endif
786 
787  if (cs%debug) then
788  call mom_state_chksum("Predictor ", up, vp, hp, uh, vh, g, gv)
789  call uvchksum("Predictor avg [uv]", u_av, v_av, g%HI, haloshift=1)
790  call hchksum(h_av,"Predictor avg h",g%HI,haloshift=0, scale=gv%H_to_m)
791  ! call MOM_state_chksum("Predictor avg ", u_av, v_av, h_av,uh, vh, G, GV)
792  call check_redundant("Predictor up ", up, vp, g)
793  call check_redundant("Predictor uh ", uh, vh, g)
794  endif
795 
796 ! diffu = horizontal viscosity terms (u_av)
797  call cpu_clock_begin(id_clock_horvisc)
798  call horizontal_viscosity(u_av, v_av, h_av, cs%diffu, cs%diffv, &
799  meke, varmix, g, gv, cs%hor_visc_CSp, obc=cs%OBC)
800  call cpu_clock_end(id_clock_horvisc)
801 
802 ! CAu = -(f+zeta_av)/h_av vh + d/dx KE_av
803  call cpu_clock_begin(id_clock_cor)
804  call coradcalc(u_av, v_av, h_av, uh, vh, cs%CAu, cs%CAv, cs%OBC, cs%ADp, g, gv, &
805  cs%CoriolisAdv_CSp)
806  call cpu_clock_end(id_clock_cor)
807 
808 ! Calculate the momentum forcing terms for the barotropic equations.
809 
810 ! u_bc_accel = CAu + PFu + diffu(u[n-1])
811  call cpu_clock_begin(id_clock_btforce)
812  do k=1,nz ; do j=js,je ; do i=isq,ieq
813  u_bc_accel(i,j,k) = (cs%Cau(i,j,k) + cs%PFu(i,j,k)) + cs%diffu(i,j,k)
814  enddo ; enddo ; enddo
815  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
816  v_bc_accel(i,j,k) = (cs%Cav(i,j,k) + cs%PFv(i,j,k)) + cs%diffv(i,j,k)
817  enddo ; enddo ; enddo
818  if (associated(cs%OBC)) then
819  call open_boundary_zero_normal_flow(cs%OBC, g, u_bc_accel, v_bc_accel)
820  endif
821  call cpu_clock_end(id_clock_btforce)
822 
823  if (cs%debug) then
824  call check_redundant("corr pre-btstep CS%Ca ", cs%Cau, cs%Cav, g)
825  call check_redundant("corr pre-btstep CS%PF ", cs%PFu, cs%PFv, g)
826  call check_redundant("corr pre-btstep CS%diff ", cs%diffu, cs%diffv, g)
827  call check_redundant("corr pre-btstep u_bc_accel ", u_bc_accel, v_bc_accel, g)
828  endif
829 
830 ! u_accel_bt = layer accelerations due to barotropic solver
831 ! pbce = dM/deta
832  call cpu_clock_begin(id_clock_btstep)
833  if (cs%flux_BT_coupling) then
834  call legacy_btstep(.true., uh_in, vh_in, eta, dt, u_bc_accel, v_bc_accel, &
835  fluxes, cs%pbce, cs%eta_PF, uh, vh, cs%u_accel_bt, &
836  cs%v_accel_bt, eta, cs%uhbt, cs%vhbt, g, gv, &
837  cs%barotropic_CSp, cs%visc_rem_u, cs%visc_rem_v, etaav=eta_av, &
838  uhbt_out = uhbt_out, vhbt_out = vhbt_out, obc=cs%OBC, &
839  bt_cont = cs%BT_cont, eta_pf_start = eta_pf_start, &
840  taux_bot=taux_bot, tauy_bot=tauy_bot)
841  else
842  if (cs%BT_use_layer_fluxes) then
843  uh_ptr => uh ; vh_ptr => vh ; u_ptr => u_av ; v_ptr => v_av
844  endif
845 
846  call legacy_btstep(.false., u, v, eta, dt, u_bc_accel, v_bc_accel, &
847  fluxes, cs%pbce, cs%eta_PF, u_av, v_av, cs%u_accel_bt, &
848  cs%v_accel_bt, eta, cs%uhbt, cs%vhbt, g, gv, &
849  cs%barotropic_CSp, cs%visc_rem_u, cs%visc_rem_v, &
850  etaav=eta_av, obc=cs%OBC, &
851  bt_cont = cs%BT_cont, eta_pf_start=eta_pf_start, &
852  taux_bot=taux_bot, tauy_bot=tauy_bot, &
853  uh0=uh_ptr, vh0=vh_ptr, u_uh0=u_ptr, v_vh0=v_ptr)
854  endif
855  call cpu_clock_end(id_clock_btstep)
856 
857  if (cs%debug) then
858  call check_redundant("u_accel_bt ", cs%u_accel_bt, cs%v_accel_bt, g)
859  endif
860 
861 ! u = u + dt*( u_bc_accel + u_accel_bt )
862  call cpu_clock_begin(id_clock_mom_update)
863  do k=1,nz ; do j=js,je ; do i=isq,ieq
864  u(i,j,k) = g%mask2dCu(i,j) * (u_init(i,j,k) + dt * &
865  (u_bc_accel(i,j,k) + cs%u_accel_bt(i,j,k)))
866  enddo ; enddo ; enddo
867 
868  do k=1,nz ; do j=jsq,jeq ; do i=is,ie
869  v(i,j,k) = g%mask2dCv(i,j) * (v_init(i,j,k) + dt * &
870  (v_bc_accel(i,j,k) + cs%v_accel_bt(i,j,k)))
871  enddo ; enddo ; enddo
872  call cpu_clock_end(id_clock_mom_update)
873 
874  if (cs%debug) then
875  call uvchksum("Corrector 1 [uv]", u, v, g%HI, haloshift=0)
876  call hchksum(h,"Corrector 1 h",g%HI,haloshift=2, scale=gv%H_to_m)
877  call uvchksum("Corrector 1 [uv]h", &
878  uh, vh, g%HI, haloshift=2, scale=gv%H_to_m)
879  ! call MOM_state_chksum("Corrector 1", u, v, h, uh, vh, G, GV, haloshift=1)
880  call mom_accel_chksum("Corrector accel", cs%CAu, cs%CAv, cs%PFu, cs%PFv, &
881  cs%diffu, cs%diffv, g, gv, cs%pbce, cs%u_accel_bt, cs%v_accel_bt)
882  endif
883 
884 ! u <- u + dt d/dz visc d/dz u
885 ! u_av <- u_av + dt d/dz visc d/dz u_av
886  call cpu_clock_begin(id_clock_vertvisc)
887  call vertvisc_coef(u, v, h, fluxes, visc, dt, g, gv, cs%vertvisc_CSp, cs%OBC)
888  call vertvisc(u, v, h, fluxes, visc, dt, cs%OBC, cs%ADp, cs%CDp, g, gv, &
889  cs%vertvisc_CSp, cs%taux_bot, cs%tauy_bot)
890  if (g%nonblocking_updates) then
891  call cpu_clock_end(id_clock_vertvisc) ; call cpu_clock_begin(id_clock_pass)
892  pid_u = pass_vector_start(u, v, g%Domain)
893  call cpu_clock_end(id_clock_pass) ; call cpu_clock_begin(id_clock_vertvisc)
894  endif
895  call vertvisc_remnant(visc, cs%visc_rem_u, cs%visc_rem_v, dt, g, gv, cs%vertvisc_CSp)
896  call cpu_clock_end(id_clock_vertvisc)
897 
898 ! Later, h_av = (h_in + h_out)/2, but for now use h_av to store h_in.
899  do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2
900  h_av(i,j,k) = h(i,j,k)
901  enddo ; enddo ; enddo
902 
903  call cpu_clock_begin(id_clock_pass)
904  call pass_vector(cs%visc_rem_u, cs%visc_rem_v, g%Domain, &
905  to_all+scalar_pair, cgrid_ne)
906  if (g%nonblocking_updates) then
907  call pass_vector_complete(pid_u, u, v, g%Domain)
908  else
909  call pass_vector(u, v, g%Domain)
910  endif
911  call cpu_clock_end(id_clock_pass)
912 
913 ! uh = u_av * h
914 ! h = h + dt * div . uh
915  if (cs%flux_BT_coupling) then
916  ! u_av and v_av adjusted so their mass transports match uhbt and vhbt.
917  ! Also, determine the values of u and v so that their transports
918  ! that agree with uhbt_out and vhbt_out.
919  if (ASSOCIATED(cs%ADp%du_other)) then ; do k=1,nz ; do j=js,je ; do i=isq,ieq
920  u_tmp(i,j,k) = u(i,j,k)
921  enddo ; enddo ; enddo ; endif
922  if (ASSOCIATED(cs%ADp%dv_other)) then ; do k=1,nz ; do j=jsq,jeq ; do i=is,ie
923  v_tmp(i,j,k) = v(i,j,k)
924  enddo ; enddo ; enddo ; endif
925  call cpu_clock_begin(id_clock_continuity)
926  call continuity(u, v, h, h, uh, vh, dt, g, gv, &
927  cs%continuity_CSp, cs%uhbt, cs%vhbt, cs%OBC, &
928  cs%visc_rem_u, cs%visc_rem_v, u_av, v_av, &
929  uhbt_out, vhbt_out, u, v)
930  call cpu_clock_end(id_clock_continuity)
931  ! Whenever thickness changes let the diag manager know, target grids
932  ! for vertical remapping may need to be regenerated.
933  call diag_update_remap_grids(cs%diag)
934  if (g%nonblocking_updates) then
935  call cpu_clock_begin(id_clock_pass)
936  pid_h = pass_var_start(h, g%Domain)
937  call cpu_clock_end(id_clock_pass)
938  endif
939  if (ASSOCIATED(cs%ADp%du_other)) then ; do k=1,nz ; do j=js,je ; do i=isq,ieq
940  cs%ADp%du_other(i,j,k) = cs%ADp%du_other(i,j,k) + (u(i,j,k) - u_tmp(i,j,k))
941  enddo ; enddo ; enddo ; endif
942  if (ASSOCIATED(cs%ADp%dv_other)) then ; do k=1,nz ; do j=jsq,jeq ; do i=is,ie
943  cs%ADp%dv_other(i,j,k) = cs%ADp%dv_other(i,j,k) + (v(i,j,k) - v_tmp(i,j,k))
944  enddo ; enddo ; enddo ; endif
945 
946  call cpu_clock_begin(id_clock_vertvisc)
947  call vertvisc_limit_vel(u, v, h_av, cs%ADp, cs%CDp, fluxes, visc, dt, g, gv, cs%vertvisc_CSp)
948  if (g%nonblocking_updates) then
949  call cpu_clock_end(id_clock_vertvisc) ; call cpu_clock_begin(id_clock_pass)
950  pid_u = pass_vector_start(u, v, g%Domain)
951  call cpu_clock_end(id_clock_pass) ; call cpu_clock_begin(id_clock_vertvisc)
952  endif
953  call vertvisc_limit_vel(u_av, v_av, h_av, cs%ADp, cs%CDp, fluxes, visc, dt, g, gv, cs%vertvisc_CSp)
954  call cpu_clock_end(id_clock_vertvisc)
955 
956  call cpu_clock_begin(id_clock_pass)
957  if (g%nonblocking_updates) then
958  call pass_var_complete(pid_h, h, g%Domain)
959  call pass_vector_complete(pid_u, u, v, g%Domain)
960  else
961  call pass_var(h, g%Domain)
962  call pass_vector(u, v, g%Domain, complete=.false.)
963  endif
964  call cpu_clock_end(id_clock_pass)
965  else
966  ! u_av and v_av adjusted so their mass transports match uhbt and vhbt.
967  call cpu_clock_begin(id_clock_continuity)
968  call continuity(u, v, h, h, uh, vh, dt, g, gv, &
969  cs%continuity_CSp, cs%uhbt, cs%vhbt, cs%OBC, &
970  cs%visc_rem_u, cs%visc_rem_v, u_av, v_av)
971  call cpu_clock_end(id_clock_continuity)
972  ! Whenever thickness changes let the diag manager know, target grids
973  ! for vertical remapping may need to be regenerated.
974  call diag_update_remap_grids(cs%diag)
975  call cpu_clock_begin(id_clock_pass)
976  call pass_var(h, g%Domain)
977  call cpu_clock_end(id_clock_pass)
978  endif
979 
980  call cpu_clock_begin(id_clock_pass)
981  if (g%nonblocking_updates) then
982  pid_uh = pass_vector_start(uh(:,:,:), vh(:,:,:), g%Domain)
983  pid_u_av = pass_vector_start(u_av, v_av, g%Domain)
984  else
985  call pass_vector(u_av, v_av, g%Domain, complete=.false.)
986  call pass_vector(uh(:,:,:), vh(:,:,:), g%Domain)
987  endif
988  call cpu_clock_end(id_clock_pass)
989 
990  if (associated(cs%OBC)) then
991  call radiation_open_bdry_conds(cs%OBC, u, u_old_rad_obc, v, v_old_rad_obc, g, dt)
992  endif
993 
994 ! h_av = (h_in + h_out)/2 . Going in to this line, h_av = h_in.
995  do k=1,nz ; do j=js-2,je+2 ; do i=is-2,ie+2
996  h_av(i,j,k) = 0.5*(h_av(i,j,k) + h(i,j,k))
997  enddo ; enddo ; enddo
998 
999  if (g%nonblocking_updates) then
1000  call cpu_clock_begin(id_clock_pass)
1001  call pass_vector_complete(pid_uh, uh(:,:,:), vh(:,:,:), g%Domain)
1002  call pass_vector_complete(pid_u_av, u_av, v_av, g%Domain)
1003  call cpu_clock_end(id_clock_pass)
1004  endif
1005 
1006  do k=1,nz ; do j=js-2,je+2 ; do i=isq-2,ieq+2
1007  uhtr(i,j,k) = uhtr(i,j,k) + uh(i,j,k)*dt
1008  enddo ; enddo ; enddo
1009  do k=1,nz ; do j=jsq-2,jeq+2 ; do i=is-2,ie+2
1010  vhtr(i,j,k) = vhtr(i,j,k) + vh(i,j,k)*dt
1011  enddo ; enddo ; enddo
1012 
1013 ! The time-averaged free surface height has already been set by the last
1014 ! call to btstep.
1015 
1016 ! Here various terms used in to update the momentum equations are
1017 ! offered for averaging.
1018  if (cs%id_PFu > 0) call post_data(cs%id_PFu, cs%PFu, cs%diag)
1019  if (cs%id_PFv > 0) call post_data(cs%id_PFv, cs%PFv, cs%diag)
1020  if (cs%id_CAu > 0) call post_data(cs%id_CAu, cs%CAu, cs%diag)
1021  if (cs%id_CAv > 0) call post_data(cs%id_CAv, cs%CAv, cs%diag)
1022 
1023 ! Here the thickness fluxes are offered for averaging.
1024  if (cs%id_uh > 0) call post_data(cs%id_uh, uh, cs%diag)
1025  if (cs%id_vh > 0) call post_data(cs%id_vh, vh, cs%diag)
1026  if (cs%id_uav > 0) call post_data(cs%id_uav, u_av, cs%diag)
1027  if (cs%id_vav > 0) call post_data(cs%id_vav, v_av, cs%diag)
1028  if (cs%id_u_BT_accel > 0) call post_data(cs%id_u_BT_accel, cs%u_accel_bt, cs%diag)
1029  if (cs%id_v_BT_accel > 0) call post_data(cs%id_v_BT_accel, cs%v_accel_bt, cs%diag)
1030  if (cs%id_du_adj > 0) call post_data(cs%id_du_adj, cs%ADp%du_other, cs%diag)
1031  if (cs%id_dv_adj > 0) call post_data(cs%id_dv_adj, cs%ADp%dv_other, cs%diag)
1032  if (cs%debug) then
1033  call mom_state_chksum("Corrector ", u, v, h, uh, vh, g, gv)
1034  call uvchksum("Corrector avg [uv]", u_av, v_av, g%HI, haloshift=1)
1035  call hchksum(h_av,"Corrector avg h",g%HI,haloshift=1, scale=gv%H_to_m)
1036  ! call MOM_state_chksum("Corrector avg ", u_av, v_av, h_av, uh, vh, G, GV)
1037  endif
1038 
Here is the call graph for this function:

Variable Documentation

◆ id_clock_btcalc

integer mom_dynamics_legacy_split::id_clock_btcalc
private

◆ id_clock_btforce

integer mom_dynamics_legacy_split::id_clock_btforce
private

◆ id_clock_btstep

integer mom_dynamics_legacy_split::id_clock_btstep
private

Definition at line 264 of file MOM_dynamics_legacy_split.F90.

Referenced by initialize_dyn_legacy_split(), and step_mom_dyn_legacy_split().

264 integer :: id_clock_btstep, id_clock_btcalc, id_clock_btforce

◆ id_clock_continuity

integer mom_dynamics_legacy_split::id_clock_continuity
private

Definition at line 263 of file MOM_dynamics_legacy_split.F90.

Referenced by adjustments_dyn_legacy_split(), initialize_dyn_legacy_split(), and step_mom_dyn_legacy_split().

263 integer :: id_clock_continuity, id_clock_thick_diff

◆ id_clock_cor

integer mom_dynamics_legacy_split::id_clock_cor

Definition at line 261 of file MOM_dynamics_legacy_split.F90.

Referenced by initialize_dyn_legacy_split(), and step_mom_dyn_legacy_split().

261 integer :: id_clock_cor, id_clock_pres, id_clock_vertvisc

◆ id_clock_horvisc

integer mom_dynamics_legacy_split::id_clock_horvisc
private

Definition at line 262 of file MOM_dynamics_legacy_split.F90.

Referenced by initialize_dyn_legacy_split(), and step_mom_dyn_legacy_split().

262 integer :: id_clock_horvisc, id_clock_mom_update

◆ id_clock_mom_update

integer mom_dynamics_legacy_split::id_clock_mom_update
private

◆ id_clock_pass

integer mom_dynamics_legacy_split::id_clock_pass
private

Definition at line 265 of file MOM_dynamics_legacy_split.F90.

Referenced by initialize_dyn_legacy_split(), and step_mom_dyn_legacy_split().

265 integer :: id_clock_pass, id_clock_pass_init

◆ id_clock_pass_init

integer mom_dynamics_legacy_split::id_clock_pass_init
private

Definition at line 265 of file MOM_dynamics_legacy_split.F90.

Referenced by initialize_dyn_legacy_split().

◆ id_clock_pres

integer mom_dynamics_legacy_split::id_clock_pres
private

◆ id_clock_thick_diff

integer mom_dynamics_legacy_split::id_clock_thick_diff
private

Definition at line 263 of file MOM_dynamics_legacy_split.F90.

◆ id_clock_vertvisc

integer mom_dynamics_legacy_split::id_clock_vertvisc
private