MOM6
mom_regridding Module Reference

Detailed Description

Generates vertical grids as part of the ALE algorithm.

A vertical grid is defined solely by the cell thicknesses, \(h\). Most calculations in this module start with the coordinate at the bottom of the column set to -depth, and use a increasing value of coordinate with decreasing k. This is consistent with the rest of MOM6 that uses position, \(z\) which is a negative quantity for most of the ocean.

A change in grid is define through a change in position of the interfaces:

\[ z^n_{k+1/2} = z^{n-1}_{k+1/2} + \Delta z_{k+1/2} \]

with the positive upward coordinate convention

\[ z_{k-1/2} = z_{k+1/2} + h_k \]

so that

\[ h^n_k = h^{n-1}_k + ( \Delta z_{k-1/2} - \Delta z_{k+1/2} ) \]

Original date of creation: 2008.06.09 by L. White

Data Types

type  regridding_cs
 Regridding control structure. More...
 

Functions/Subroutines

subroutine, public initialize_regridding (CS, GV, max_depth, param_file, mod, coord_mode, param_prefix, param_suffix)
 Initialization and configures a regridding control structure based on customizable run-time parameters. More...
 
subroutine check_grid_def (filename, varname, expected_units, msg, ierr)
 Do some basic checks on the vertical grid definition file, variable. More...
 
subroutine, public end_regridding (CS)
 Deallocation of regridding memory. More...
 
subroutine, public regridding_main (remapCS, CS, G, GV, h, tv, h_new, dzInterface, frac_shelf_h, conv_adjust)
 
subroutine calc_h_new_by_dz (G, GV, h, dzInterface, h_new)
 Calculates h_new from h + delta_k dzInterface. More...
 
subroutine, public check_remapping_grid (G, GV, h, dzInterface, msg)
 Check that the total thickness of two grids match. More...
 
subroutine, public check_grid_column (nk, depth, h, dzInterface, msg)
 Check that the total thickness of new and old grids are consistent. More...
 
subroutine filtered_grid_motion (CS, nk, z_old, z_new, dz_g)
 Returns the change in interface position motion after filtering and assuming the top and bottom interfaces do not move. The filtering is a function of depth, and is applied as the integrated average filtering over the trajectory of the interface. By design, this code can not give tangled interfaces provided that z_old and z_new are not already tangled. More...
 
subroutine build_zstar_grid (CS, G, GV, h, dzInterface, frac_shelf_h)
 Builds a z*-ccordinate grid with partial steps (Adcroft and Campin, 2004). z* is defined as z* = (z-eta)/(H+eta)*H s.t. z*=0 when z=eta and z*=-H when z=-H . More...
 
subroutine build_sigma_grid (CS, G, GV, h, dzInterface)
 
subroutine build_rho_grid (G, GV, h, tv, dzInterface, remapCS, CS)
 
subroutine build_grid_hycom1 (G, GV, h, tv, dzInterface, CS)
 Builds a simple HyCOM-like grid with the deepest location of potential density interpolated from the column profile and a clipping of depth for each interface to a fixed z* or p* grid. This should probably be (optionally?) changed to find the nearest location of the target density. More...
 
subroutine build_grid_adaptive (G, GV, h, tv, dzInterface, remapCS, CS)
 
subroutine build_grid_slight (G, GV, h, tv, dzInterface, CS)
 Builds a grid that tracks density interfaces for water that is denser than the surface density plus an increment of some number of layers, and uses all lighter layers uniformly above this location. Note that this amounts to interpolating to find the depth of an arbitrary (non-integer) interface index which should make the results vary smoothly in space to the extent that the surface density and interior stratification vary smoothly in space. Over shallow topography, this will tend to give a uniform sigma-like coordinate. For sufficiently shallow water, a minimum grid spacing is used to avoid certain instabilities. More...
 
subroutine, public adjust_interface_motion (nk, min_thickness, h_old, dz_int)
 Adjust dz_Interface to ensure non-negative future thicknesses. More...
 
subroutine build_grid_arbitrary (G, GV, h, dzInterface, h_new, CS)
 
subroutine, public inflate_vanished_layers_old (CS, G, GV, h)
 
subroutine convective_adjustment (G, GV, h, tv)
 
real function, dimension(nk), public uniformresolution (nk, coordMode, maxDepth, rhoLight, rhoHeavy)
 
subroutine initcoord (CS, coord_mode)
 
subroutine, public setcoordinateresolution (dz, CS)
 
subroutine, public set_target_densities_from_gv (GV, CS)
 Set target densities based on the old Rlay variable. More...
 
subroutine, public set_target_densities (CS, rho_int)
 Set target densities based on vector of interface values. More...
 
subroutine, public set_regrid_max_depths (CS, max_depths, units_to_H)
 Set maximum interface depths based on a vector of input values. More...
 
subroutine, public set_regrid_max_thickness (CS, max_h, units_to_H)
 Set maximum layer thicknesses based on a vector of input values. More...
 
real function, dimension(cs%nk), public getcoordinateresolution (CS)
 
real function, dimension(cs%nk+1), public getcoordinateinterfaces (CS)
 Query the target coordinate interface positions. More...
 
character(len=20) function, public getcoordinateunits (CS)
 
character(len=20) function, public getcoordinateshortname (CS)
 
subroutine, public set_regrid_params (CS, boundary_extrapolation, min_thickness, old_grid_weight, interp_scheme, depth_of_time_filter_shallow, depth_of_time_filter_deep, compress_fraction, dz_min_surface, nz_fixed_surface, Rho_ML_avg_depth, nlay_ML_to_interior, fix_haloclines, halocline_filt_len, halocline_strat_tol, integrate_downward_for_e, adaptTimeRatio, adaptZoom, adaptZoomCoeff, adaptBuoyCoeff, adaptAlpha, adaptDoMin)
 Can be used to set any of the parameters for MOM_regridding. More...
 
integer function, public get_regrid_size (CS)
 Returns the number of levels/layers in the regridding control structure. More...
 
type(zlike_cs) function, public get_zlike_cs (CS)
 
type(sigma_cs) function, public get_sigma_cs (CS)
 
type(rho_cs) function, public get_rho_cs (CS)
 
real function, dimension(cs%nk), public getstaticthickness (CS, SSH, depth)
 
subroutine dz_function1 (string, dz)
 Parses a string and generates a dz(:) profile that goes like k**power. More...
 

Variables

character(len= *), parameter, public regriddingcoordinatemodedoc = " LAYER - Isopycnal or stacked shallow water layers\n"// " ZSTAR, Z* - stetched geopotential z*\n"// " SIGMA_SHELF_ZSTAR - stetched geopotential z* ignoring shelf\n"// " SIGMA - terrain following coordinates\n"// " RHO - continuous isopycnal\n"// " HYCOM1 - HyCOM-like hybrid coordinate\n"// " SLIGHT - stretched coordinates above continuous isopycnal\n"// " ADAPTIVE - optimize for smooth neutral density surfaces"
 Documentation for coordinate options. More...
 
character(len= *), parameter, public regriddinginterpschemedoc = " P1M_H2 (2nd-order accurate)\n"// " P1M_H4 (2nd-order accurate)\n"// " P1M_IH4 (2nd-order accurate)\n"// " PLM (2nd-order accurate)\n"// " PPM_H4 (3rd-order accurate)\n"// " PPM_IH4 (3rd-order accurate)\n"// " P3M_IH4IH3 (4th-order accurate)\n"// " P3M_IH6IH5 (4th-order accurate)\n"// " PQM_IH4IH3 (4th-order accurate)\n"// " PQM_IH6IH5 (5th-order accurate)"
 
character(len= *), parameter, public regriddingdefaultinterpscheme = "P1M_H2"
 
logical, parameter, public regriddingdefaultboundaryextrapolation = .false.
 
real, parameter, public regriddingdefaultminthickness = 1.e-3
 

Function/Subroutine Documentation

◆ adjust_interface_motion()

subroutine, public mom_regridding::adjust_interface_motion ( integer, intent(in)  nk,
real, intent(in)  min_thickness,
real, dimension(nk), intent(in)  h_old,
real, dimension(nk+1), intent(inout)  dz_int 
)

Adjust dz_Interface to ensure non-negative future thicknesses.

Parameters
[in]nkNumber of layers
[in]min_thicknessMinium allowed thickness of h (H units)
[in]h_oldMinium allowed thickness of h (H units)
[in,out]dz_intMinium allowed thickness of h (H units)

Definition at line 1550 of file MOM_regridding.F90.

Referenced by build_grid_adaptive(), build_grid_hycom1(), build_grid_slight(), and build_zstar_grid().

1550  integer, intent(in) :: nk !< Number of layers
1551  real, intent(in) :: min_thickness !< Minium allowed thickness of h (H units)
1552  real, dimension(nk), intent(in) :: h_old !< Minium allowed thickness of h (H units)
1553  real, dimension(nk+1), intent(inout) :: dz_int !< Minium allowed thickness of h (H units)
1554  ! Local variables
1555  integer :: k
1556  real :: h_new, eps, h_total, h_err
1557 
1558  eps = 1. ; eps = epsilon(eps)
1559 
1560  h_total = 0. ; h_err = 0.
1561  do k = 1, nk
1562  h_total = h_total + h_old(k)
1563  h_err = h_err + max( h_old(k), abs(dz_int(k)), abs(dz_int(k+1)) )*eps
1564  h_new = h_old(k) + ( dz_int(k) - dz_int(k+1) )
1565  if (h_new < -3.0*h_err) then
1566  write(0,*) 'h<0 at k=',k,'h_old=',h_old(k), &
1567  'wup=',dz_int(k),'wdn=',dz_int(k+1),'dw_dz=',dz_int(k) - dz_int(k+1), &
1568  'h_new=',h_new,'h_err=',h_err
1569  call mom_error( fatal, 'MOM_regridding: adjust_interface_motion() - '//&
1570  'implied h<0 is larger than roundoff!')
1571  endif
1572  enddo
1573  do k = nk,2,-1
1574  h_new = h_old(k) + ( dz_int(k) - dz_int(k+1) )
1575  if (h_new<min_thickness) dz_int(k) = ( dz_int(k+1) - h_old(k) ) + min_thickness ! Implies next h_new = min_thickness
1576  h_new = h_old(k) + ( dz_int(k) - dz_int(k+1) )
1577  if (h_new<0.) dz_int(k) = ( 1. - eps ) * ( dz_int(k+1) - h_old(k) ) ! Backup in case min_thickness==0
1578  h_new = h_old(k) + ( dz_int(k) - dz_int(k+1) )
1579  if (h_new<0.) then
1580  write(0,*) 'h<0 at k=',k,'h_old=',h_old(k), &
1581  'wup=',dz_int(k),'wdn=',dz_int(k+1),'dw_dz=',dz_int(k) - dz_int(k+1), &
1582  'h_new=',h_new
1583  stop 'Still did not work!'
1584  call mom_error( fatal, 'MOM_regridding: adjust_interface_motion() - '//&
1585  'Repeated adjustment for roundoff h<0 failed!')
1586  endif
1587  enddo
1588  !if (dz_int(1)/=0.) stop 'MOM_regridding: adjust_interface_motion() surface moved'
1589 
Here is the caller graph for this function:

◆ build_grid_adaptive()

subroutine mom_regridding::build_grid_adaptive ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
type(thermo_var_ptrs), intent(in)  tv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(inout)  dzInterface,
type(remapping_cs), intent(in)  remapCS,
type(regridding_cs), intent(in)  CS 
)
private
Parameters
[in]gThe ocean's grid structure
[in]gvThe ocean's vertical grid structure
[in]hLayer thicknesses, in H (usually m or kg m-2)
[in]tvA structure pointing to various thermodynamic variables

Definition at line 1432 of file MOM_regridding.F90.

References adjust_interface_motion(), and filtered_grid_motion().

Referenced by regridding_main().

1432  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
1433  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure
1434  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H (usually m or kg m-2)
1435  type(thermo_var_ptrs), intent(in) :: tv !< A structure pointing to various thermodynamic variables
1436  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: dzinterface
1437  type(remapping_cs), intent(in) :: remapcs
1438  type(regridding_cs), intent(in) :: cs
1439 
1440  ! local variables
1441  integer :: i, j, k, nz ! indices and dimension lengths
1442  ! temperature, salinity and pressure on interfaces
1443  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: tint, sint
1444  ! current interface positions and after tendency term is applied
1445  ! positive downward
1446  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1) :: zint
1447  real, dimension(SZK_(GV)+1) :: znext
1448 
1449  nz = gv%ke
1450 
1451  ! position surface at z = 0.
1452  zint(:,:,1) = 0.
1453 
1454  ! work on interior interfaces
1455  do k = 2, nz ; do j = g%jsc-2,g%jec+2 ; do i = g%isc-2,g%iec+2
1456  tint(i,j,k) = 0.5 * (tv%T(i,j,k-1) + tv%T(i,j,k))
1457  sint(i,j,k) = 0.5 * (tv%S(i,j,k-1) + tv%S(i,j,k))
1458  zint(i,j,k) = zint(i,j,k-1) + h(i,j,k-1) ! zInt in [H]
1459  enddo ; enddo ; enddo
1460 
1461  ! top and bottom temp/salt interfaces are just the layer
1462  ! average values
1463  tint(:,:,1) = tv%T(:,:,1) ; tint(:,:,nz+1) = tv%T(:,:,nz)
1464  sint(:,:,1) = tv%S(:,:,1) ; sint(:,:,nz+1) = tv%S(:,:,nz)
1465 
1466  ! set the bottom interface depth
1467  zint(:,:,nz+1) = zint(:,:,nz) + h(:,:,nz)
1468 
1469  ! calculate horizontal density derivatives (alpha/beta)
1470  ! between cells in a 5-point stencil, columnwise
1471  do j = g%jsc-1,g%jec+1 ; do i = g%isc-1,g%iec+1
1472  if (g%mask2dT(i,j) < 0.5) then
1473  dzinterface(i,j,:) = 0. ! land point, don't move interfaces, and skip
1474  cycle
1475  endif
1476 
1477  call build_adapt_column(cs%adapt_CS, g, gv, tv, i, j, zint, tint, sint, h, znext)
1478 
1479  call filtered_grid_motion(cs, nz, zint(i,j,:), znext, dzinterface(i,j,:))
1480  ! convert from depth to z
1481  do k = 1, nz+1 ; dzinterface(i,j,k) = -dzinterface(i,j,k) ; enddo
1482  call adjust_interface_motion(nz, cs%min_thickness, h(i,j,:), dzinterface(i,j,:))
1483  enddo ; enddo
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_grid_arbitrary()

subroutine mom_regridding::build_grid_arbitrary ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g), szk_(gv)), intent(in)  h,
real, dimension(szi_(g),szj_(g), szk_(gv)+1), intent(inout)  dzInterface,
real, intent(inout)  h_new,
type(regridding_cs), intent(in)  CS 
)
private
Parameters
[in]gOcean grid structure
[in]gvOcean vertical grid structure
[in]hOriginal ayer thicknesses, in H
[in,out]dzinterfaceThe change in interface depth in H
[in,out]h_newNew layer thicknesses, in H
[in]csRegridding control structure

Definition at line 1596 of file MOM_regridding.F90.

Referenced by regridding_main().

1596 !------------------------------------------------------------------------------
1597 ! This routine builds a grid based on arbitrary rules
1598 !------------------------------------------------------------------------------
1599 
1600  ! Arguments
1601  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
1602  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
1603  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(in) :: h !< Original ayer thicknesses, in H
1604  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzinterface !< The change in interface depth in H
1605  real, intent(inout) :: h_new !< New layer thicknesses, in H
1606  type(regridding_cs), intent(in) :: cs !< Regridding control structure
1607 
1608  ! Local variables
1609  integer :: i, j, k
1610  integer :: nz
1611  real :: z_inter(szk_(gv)+1)
1612  real :: total_height
1613  real :: delta_h
1614  real :: max_depth
1615  real :: min_thickness
1616  real :: eta ! local elevation
1617  real :: local_depth
1618  real :: x1, y1, x2, y2
1619  real :: x, t
1620 
1621  nz = gv%ke
1622 
1623  max_depth = g%max_depth
1624  min_thickness = cs%min_thickness
1625 
1626  do j = g%jsc-1,g%jec+1
1627  do i = g%isc-1,g%iec+1
1628 
1629  ! Local depth
1630  local_depth = g%bathyT(i,j)*gv%m_to_H
1631 
1632  ! Determine water column height
1633  total_height = 0.0
1634  do k = 1,nz
1635  total_height = total_height + h(i,j,k)
1636  end do
1637 
1638  eta = total_height - local_depth
1639 
1640  ! Compute new thicknesses based on stretched water column
1641  delta_h = (max_depth + eta) / nz
1642 
1643  ! Define interfaces
1644  z_inter(1) = eta
1645  do k = 1,nz
1646  z_inter(k+1) = z_inter(k) - delta_h
1647  end do
1648 
1649  ! Refine grid in the middle
1650  do k = 1,nz+1
1651  x1 = 0.35; y1 = 0.45; x2 = 0.65; y2 = 0.55
1652 
1653  x = - ( z_inter(k) - eta ) / max_depth
1654 
1655  if ( x <= x1 ) then
1656  t = y1*x/x1
1657  else if ( (x > x1 ) .and. ( x < x2 )) then
1658  t = y1 + (y2-y1) * (x-x1) / (x2-x1)
1659  else
1660  t = y2 + (1.0-y2) * (x-x2) / (1.0-x2)
1661  end if
1662 
1663  z_inter(k) = -t * max_depth + eta
1664 
1665  end do
1666 
1667  ! Modify interface heights to account for topography
1668  z_inter(nz+1) = - local_depth
1669 
1670  ! Modify interface heights to avoid layers of zero thicknesses
1671  do k = nz,1,-1
1672  if ( z_inter(k) < (z_inter(k+1) + min_thickness) ) then
1673  z_inter(k) = z_inter(k+1) + min_thickness
1674  end if
1675  end do
1676 
1677  ! Chnage in interface position
1678  x = 0. ! Left boundary at x=0
1679  dzinterface(i,j,1) = 0.
1680  do k = 2,nz
1681  x = x + h(i,j,k)
1682  dzinterface(i,j,k) = z_inter(k) - x
1683  end do
1684  dzinterface(i,j,nz+1) = 0.
1685 
1686  end do
1687  end do
1688 
1689 stop 'OOOOOOPS' ! For some reason the gnu compiler will not let me delete this
1690  ! routine????
1691 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the caller graph for this function:

◆ build_grid_hycom1()

subroutine mom_regridding::build_grid_hycom1 ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
type(thermo_var_ptrs), intent(in)  tv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(inout)  dzInterface,
type(regridding_cs), intent(in)  CS 
)
private

Builds a simple HyCOM-like grid with the deepest location of potential density interpolated from the column profile and a clipping of depth for each interface to a fixed z* or p* grid. This should probably be (optionally?) changed to find the nearest location of the target density.

Remarks
{ Based on Bleck, 2002: An oceanice general circulation model framed in hybrid isopycnic-Cartesian coordinates, Ocean Modelling 37, 55-88. http://dx.doi.org/10.1016/S1463-5003(01)00012-9 }
Parameters
[in]gGrid structure
[in]gvOcean vertical grid structure
[in]hExisting model thickness, in H units
[in]tvThermodynamics structure
[in,out]dzinterfaceChanges in interface position
[in]csRegridding control structure

Definition at line 1382 of file MOM_regridding.F90.

References adjust_interface_motion(), coord_hycom::build_hycom1_column(), filtered_grid_motion(), and mom_error_handler::mom_error().

Referenced by regridding_main().

1382  type(ocean_grid_type), intent(in) :: g !< Grid structure
1383  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
1384  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Existing model thickness, in H units
1385  type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure
1386  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: dzinterface !< Changes in interface position
1387  type(regridding_cs), intent(in) :: cs !< Regridding control structure
1388 
1389  ! Local variables
1390  real, dimension(SZK_(GV)+1) :: z_col, z_col_new ! Interface positions relative to the surface in H units (m or kg m-2)
1391  real, dimension(SZK_(GV)+1) :: dz_col ! The realized change in z_col in H units (m or kg m-2)
1392  real, dimension(SZK_(GV)) :: p_col ! Layer pressure in Pa
1393  integer :: i, j, k, nz
1394  real :: depth
1395 
1396  nz = gv%ke
1397 
1398  if (.not.cs%target_density_set) call mom_error(fatal, "build_grid_HyCOM1 : "//&
1399  "Target densities must be set before build_grid_HyCOM1 is called.")
1400 
1401  ! Build grid based on target interface densities
1402  do j = g%jsc-1,g%jec+1 ; do i = g%isc-1,g%iec+1
1403  if (g%mask2dT(i,j)>0.) then
1404 
1405  depth = g%bathyT(i,j) * gv%m_to_H
1406 
1407  z_col(1) = 0. ! Work downward rather than bottom up
1408  do k = 1, nz
1409  z_col(k+1) = z_col(k) + h(i,j,k) ! Work in units of h (m or Pa)
1410  p_col(k) = cs%ref_pressure + cs%compressibility_fraction * &
1411  ( 0.5 * ( z_col(k) + z_col(k+1) ) * gv%H_to_Pa - cs%ref_pressure )
1412  enddo
1413 
1414  call build_hycom1_column(cs%hycom_CS, tv%eqn_of_state, nz, depth, &
1415  h(i, j, :), tv%T(i, j, :), tv%S(i, j, :), p_col, z_col, z_col_new)
1416 
1417  ! Calculate the final change in grid position after blending new and old grids
1418  call filtered_grid_motion( cs, nz, z_col, z_col_new, dz_col )
1419  do k=1,nz+1 ; dzinterface(i,j,k) = -dz_col(k) ; enddo
1420 
1421  ! This adjusts things robust to round-off errors
1422  call adjust_interface_motion( nz, cs%min_thickness, h(i,j,:), dzinterface(i,j,:) )
1423 
1424  else ! on land
1425  dzinterface(i,j,:) = 0.
1426  endif ! mask2dT
1427  enddo; enddo ! i,j
1428 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_grid_slight()

subroutine mom_regridding::build_grid_slight ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(in)  h,
type(thermo_var_ptrs), intent(in)  tv,
real, dimension(szi_(g),szj_(g),szk_(gv)+1), intent(inout)  dzInterface,
type(regridding_cs), intent(in)  CS 
)
private

Builds a grid that tracks density interfaces for water that is denser than the surface density plus an increment of some number of layers, and uses all lighter layers uniformly above this location. Note that this amounts to interpolating to find the depth of an arbitrary (non-integer) interface index which should make the results vary smoothly in space to the extent that the surface density and interior stratification vary smoothly in space. Over shallow topography, this will tend to give a uniform sigma-like coordinate. For sufficiently shallow water, a minimum grid spacing is used to avoid certain instabilities.

Parameters
[in]gGrid structure
[in]gvOcean vertical grid structure
[in]hExisting model thickness, in H units
[in]tvThermodynamics structure
[in,out]dzinterfaceChanges in interface position
[in]csRegridding control structure

Definition at line 1496 of file MOM_regridding.F90.

References adjust_interface_motion(), and filtered_grid_motion().

Referenced by regridding_main().

1496  type(ocean_grid_type), intent(in) :: g !< Grid structure
1497  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
1498  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Existing model thickness, in H units
1499  type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure
1500  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(inout) :: dzinterface !< Changes in interface position
1501  type(regridding_cs), intent(in) :: cs !< Regridding control structure
1502 
1503  real, dimension(SZK_(GV)+1) :: z_col, z_col_new ! Interface positions relative to the surface in H units (m or kg m-2)
1504  real, dimension(SZK_(GV)+1) :: dz_col ! The realized change in z_col in H units (m or kg m-2)
1505  real, dimension(SZK_(GV)) :: p_col ! Layer pressure in Pa
1506  real :: depth
1507  integer :: i, j, k, nz
1508 
1509  nz = gv%ke
1510 
1511  if (.not.cs%target_density_set) call mom_error(fatal, "build_grid_SLight : "//&
1512  "Target densities must be set before build_grid_SLight is called.")
1513 
1514  ! Build grid based on target interface densities
1515  do j = g%jsc-1,g%jec+1 ; do i = g%isc-1,g%iec+1
1516  if (g%mask2dT(i,j)>0.) then
1517 
1518  depth = g%bathyT(i,j) * gv%m_to_H
1519  z_col(1) = 0. ! Work downward rather than bottom up
1520  do k=1,nz
1521  z_col(k+1) = z_col(k) + h(i, j, k) ! Work in units of h (m or Pa)
1522  p_col(k) = cs%ref_pressure + cs%compressibility_fraction * &
1523  ( 0.5 * ( z_col(k) + z_col(k+1) ) * gv%H_to_Pa - cs%ref_pressure )
1524  enddo
1525 
1526  call build_slight_column(cs%slight_CS, tv%eqn_of_state, gv%H_to_Pa, gv%m_to_H, &
1527  gv%H_subroundoff, nz, depth, &
1528  h(i, j, :), tv%T(i, j, :), tv%S(i, j, :), p_col, z_col, z_col_new)
1529 
1530  ! Calculate the final change in grid position after blending new and old grids
1531  call filtered_grid_motion( cs, nz, z_col, z_col_new, dz_col )
1532  do k=1,nz+1 ; dzinterface(i,j,k) = -dz_col(k) ; enddo
1533 #ifdef __DO_SAFETY_CHECKS__
1534  if (dzinterface(i,j,1) /= 0.) stop 'build_grid_SLight: Surface moved?!'
1535  if (dzinterface(i,j,nz+1) /= 0.) stop 'build_grid_SLight: Bottom moved?!'
1536 #endif
1537 
1538  ! This adjusts things robust to round-off errors
1539  call adjust_interface_motion( nz, cs%min_thickness, h(i,j,:), dzinterface(i,j,:) )
1540 
1541  else ! on land
1542  dzinterface(i,j,:) = 0.
1543  endif ! mask2dT
1544  enddo; enddo ! i,j
1545 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_rho_grid()

subroutine mom_regridding::build_rho_grid ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
type(thermo_var_ptrs), intent(in)  tv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(inout)  dzInterface,
type(remapping_cs), intent(in)  remapCS,
type(regridding_cs), intent(in)  CS 
)
private
Parameters
[in]gOcean grid structure
[in]gvOcean vertical grid structure
[in]hLayer thicknesses, in H
[in]tvThermodynamics structure
[in,out]dzinterfaceThe change in interface depth in H
[in]remapcsThe remapping control structure
[in]csRegridding control structure

Definition at line 1259 of file MOM_regridding.F90.

References filtered_grid_motion(), and mom_error_handler::mom_error().

Referenced by regridding_main().

1259 !------------------------------------------------------------------------------
1260 ! This routine builds a new grid based on a given set of target interface
1261 ! densities (these target densities are computed by taking the mean value
1262 ! of given layer densities). The algorithn operates as follows within each
1263 ! column:
1264 ! 1. Given T & S within each layer, the layer densities are computed.
1265 ! 2. Based on these layer densities, a global density profile is reconstructed
1266 ! (this profile is monotonically increasing and may be discontinuous)
1267 ! 3. The new grid interfaces are determined based on the target interface
1268 ! densities.
1269 ! 4. T & S are remapped onto the new grid.
1270 ! 5. Return to step 1 until convergence or until the maximum number of
1271 ! iterations is reached, whichever comes first.
1272 !------------------------------------------------------------------------------
1273 
1274  ! Arguments
1275  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
1276  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
1277  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H
1278  type(thermo_var_ptrs), intent(in) :: tv !< Thermodynamics structure
1279  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzinterface !< The change in interface depth in H
1280  type(remapping_cs), intent(in) :: remapcs !< The remapping control structure
1281  type(regridding_cs), intent(in) :: cs !< Regridding control structure
1282 
1283  ! Local variables
1284  integer :: nz
1285  integer :: i, j, k
1286  real :: nominaldepth, totalthickness
1287  real, dimension(SZK_(GV)+1) :: zold, znew
1288 #ifdef __DO_SAFETY_CHECKS__
1289  real :: dh
1290 #endif
1291 
1292  nz = gv%ke
1293 
1294  if (.not.cs%target_density_set) call mom_error(fatal, "build_rho_grid: "//&
1295  "Target densities must be set before build_rho_grid is called.")
1296 
1297  ! Build grid based on target interface densities
1298  do j = g%jsc-1,g%jec+1
1299  do i = g%isc-1,g%iec+1
1300 
1301  if (g%mask2dT(i,j)==0.) then
1302  dzinterface(i,j,:) = 0.
1303  cycle
1304  endif
1305 
1306 
1307  ! Local depth (G%bathyT is positive)
1308  nominaldepth = g%bathyT(i,j)*gv%m_to_H
1309 
1310  call build_rho_column(cs%rho_CS, remapcs, nz, nominaldepth, h(i, j, :)*gv%H_to_m, &
1311  tv%T(i, j, :), tv%S(i, j, :), tv%eqn_of_state, znew)
1312 
1313  if (cs%integrate_downward_for_e) then
1314  zold(1) = 0.
1315  do k = 1,nz
1316  zold(k+1) = zold(k) - h(i,j,k)
1317  enddo
1318  else
1319  ! The rest of the model defines grids integrating up from the bottom
1320  zold(nz+1) = - nominaldepth
1321  do k = nz,1,-1
1322  zold(k) = zold(k+1) + h(i,j,k)
1323  enddo
1324  endif
1325 
1326  ! Calculate the final change in grid position after blending new and old grids
1327  call filtered_grid_motion( cs, nz, zold, znew, dzinterface(i,j,:) )
1328 
1329 #ifdef __DO_SAFETY_CHECKS__
1330  do k = 2,nz
1331  if (znew(k) > zold(1)) then
1332  write(0,*) 'zOld=',zold
1333  write(0,*) 'zNew=',znew
1334  call mom_error( fatal, 'MOM_regridding, build_rho_grid: '//&
1335  'interior interface above surface!' )
1336  endif
1337  if (znew(k) > znew(k-1)) then
1338  write(0,*) 'zOld=',zold
1339  write(0,*) 'zNew=',znew
1340  call mom_error( fatal, 'MOM_regridding, build_rho_grid: '//&
1341  'interior interfaces cross!' )
1342  endif
1343  enddo
1344 
1345  totalthickness = 0.0
1346  do k = 1,nz
1347  totalthickness = totalthickness + h(i,j,k)
1348  enddo
1349 
1350  dh=max(nominaldepth,totalthickness)
1351  if (abs(znew(1)-zold(1))>(nz-1)*0.5*epsilon(dh)*dh) then
1352  write(0,*) 'min_thickness=',cs%min_thickness
1353  write(0,*) 'nominalDepth=',nominaldepth,'totalThickness=',totalthickness
1354  write(0,*) 'zNew(1)-zOld(1) = ',znew(1)-zold(1),epsilon(dh),nz
1355  do k=1,nz+1
1356  write(0,*) k,zold(k),znew(k)
1357  enddo
1358  do k=1,nz
1359  write(0,*) k,h(i,j,k),znew(k)-znew(k+1)
1360  enddo
1361  call mom_error( fatal, &
1362  'MOM_regridding, build_rho_grid: top surface has moved!!!' )
1363  endif
1364 #endif
1365 
1366  end do ! end loop on i
1367  end do ! end loop on j
1368 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_sigma_grid()

subroutine mom_regridding::build_sigma_grid ( type(regridding_cs), intent(in)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(inout)  dzInterface 
)
private
Parameters
[in]csRegridding control structure
[in]gOcean grid structure
[in]gvocean vertical grid structure
[in]hLayer thicknesses, in H
[in,out]dzinterfaceThe change in interface depth in H.

Definition at line 1182 of file MOM_regridding.F90.

References coord_sigma::build_sigma_column(), filtered_grid_motion(), and mom_error_handler::mom_error().

Referenced by regridding_main().

1182 !------------------------------------------------------------------------------
1183 ! This routine builds a grid based on terrain-following coordinates.
1184 ! The module parameter coordinateResolution(:) determines the resolution in
1185 ! sigma coordinate, dSigma(:). sigma-coordinates are defined by
1186 ! sigma = (eta-z)/(H+eta) s.t. sigma=0 at z=eta and sigma=1 at z=-H .
1187 !------------------------------------------------------------------------------
1188 
1189  ! Arguments
1190  type(regridding_cs), intent(in) :: cs !< Regridding control structure
1191  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
1192  type(verticalgrid_type), intent(in) :: gv !< ocean vertical grid structure
1193  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H
1194  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzinterface !< The change in interface depth in H.
1195 
1196  ! Local variables
1197  integer :: i, j, k
1198  integer :: nz
1199  real :: nominaldepth, totalthickness, dh
1200  real, dimension(SZK_(GV)+1) :: zold, znew
1201 
1202  nz = gv%ke
1203 
1204  do i = g%isc-1,g%iec+1
1205  do j = g%jsc-1,g%jec+1
1206 
1207  if (g%mask2dT(i,j)==0.) then
1208  dzinterface(i,j,:) = 0.
1209  cycle
1210  endif
1211 
1212  ! The rest of the model defines grids integrating up from the bottom
1213  nominaldepth = g%bathyT(i,j)*gv%m_to_H
1214 
1215  ! Determine water column height
1216  totalthickness = 0.0
1217  do k = 1,nz
1218  totalthickness = totalthickness + h(i,j,k)
1219  end do
1220 
1221  call build_sigma_column(cs%sigma_CS, nz, nominaldepth, totalthickness, znew)
1222 
1223  ! Calculate the final change in grid position after blending new and old grids
1224  zold(nz+1) = -nominaldepth
1225  do k = nz,1,-1
1226  zold(k) = zold(k+1) + h(i, j, k)
1227  end do
1228 
1229  call filtered_grid_motion( cs, nz, zold, znew, dzinterface(i,j,:) )
1230 
1231 #ifdef __DO_SAFETY_CHECKS__
1232  dh=max(nominaldepth,totalthickness)
1233  if (abs(znew(1)-zold(1))>(nz-1)*0.5*epsilon(dh)*dh) then
1234  write(0,*) 'min_thickness=',cs%min_thickness
1235  write(0,*) 'nominalDepth=',nominaldepth,'totalThickness=',totalthickness
1236  write(0,*) 'dzInterface(1) = ',dzinterface(i,j,1),epsilon(dh),nz
1237  do k=1,nz+1
1238  write(0,*) k,zold(k),znew(k)
1239  enddo
1240  do k=1,nz
1241  write(0,*) k,h(i,j,k),znew(k)-znew(k+1),totalthickness*cs%coordinateResolution(k),cs%coordinateResolution(k)
1242  enddo
1243  call mom_error( fatal, &
1244  'MOM_regridding, build_sigma_grid: top surface has moved!!!' )
1245  endif
1246  dzinterface(i,j,1) = 0.
1247  dzinterface(i,j,nz+1) = 0.
1248 #endif
1249 
1250  end do
1251  end do
1252 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ build_zstar_grid()

subroutine mom_regridding::build_zstar_grid ( type(regridding_cs), intent(in)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(inout)  dzInterface,
real, dimension(:,:), optional, pointer  frac_shelf_h 
)
private

Builds a z*-ccordinate grid with partial steps (Adcroft and Campin, 2004). z* is defined as z* = (z-eta)/(H+eta)*H s.t. z*=0 when z=eta and z*=-H when z=-H .

Parameters
[in]csRegridding control structure
[in]gOcean grid structure
[in]gvocean vertical grid structure
[in]hLayer thicknesses, in H
[in,out]dzinterfaceThe change in interface depth in H.
frac_shelf_hFractional ice shelf coverage.

Definition at line 1090 of file MOM_regridding.F90.

References adjust_interface_motion(), coord_zlike::build_zstar_column(), filtered_grid_motion(), and mom_error_handler::mom_error().

Referenced by regridding_main().

1090 
1091  ! Arguments
1092  type(regridding_cs), intent(in) :: cs !< Regridding control structure
1093  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
1094  type(verticalgrid_type), intent(in) :: gv !< ocean vertical grid structure
1095  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses, in H
1096  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzinterface !< The change in interface depth in H.
1097  real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage.
1098  ! Local variables
1099  integer :: i, j, k
1100  integer :: nz
1101  real :: nominaldepth, totalthickness, dh
1102  real, dimension(SZK_(GV)+1) :: zold, znew
1103  real :: minthickness
1104  logical :: ice_shelf
1105 
1106  nz = gv%ke
1107  minthickness = cs%min_thickness
1108  ice_shelf = .false.
1109  if (present(frac_shelf_h)) then
1110  if (associated(frac_shelf_h)) ice_shelf = .true.
1111  endif
1112 
1113 !$OMP parallel do default(none) shared(G,GV,dzInterface,CS,nz,h,frac_shelf_h, &
1114 !$OMP ice_shelf,minThickness) &
1115 !$OMP private(nominalDepth,totalThickness, &
1116 !$OMP zNew,dh,zOld)
1117  do j = g%jsc-1,g%jec+1
1118  do i = g%isc-1,g%iec+1
1119 
1120  if (g%mask2dT(i,j)==0.) then
1121  dzinterface(i,j,:) = 0.
1122  cycle
1123  endif
1124 
1125  ! Local depth (G%bathyT is positive)
1126  nominaldepth = g%bathyT(i,j)*gv%m_to_H
1127 
1128  ! Determine water column thickness
1129  totalthickness = 0.0
1130  do k = 1,nz
1131  totalthickness = totalthickness + h(i,j,k)
1132  end do
1133 
1134  zold(nz+1) = - nominaldepth
1135  do k = nz,1,-1
1136  zold(k) = zold(k+1) + h(i,j,k)
1137  enddo
1138 
1139  if (ice_shelf) then
1140  if (frac_shelf_h(i,j) > 0.) then ! under ice shelf
1141  call build_zstar_column(cs%zlike_CS, nz, nominaldepth, totalthickness, znew, &
1142  z_rigid_top = totalthickness-nominaldepth, &
1143  eta_orig = zold(1))
1144  else
1145  call build_zstar_column(cs%zlike_CS, nz, nominaldepth, totalthickness, znew)
1146  endif
1147  else
1148  call build_zstar_column(cs%zlike_CS, nz, nominaldepth, totalthickness, znew)
1149  endif
1150 
1151  ! Calculate the final change in grid position after blending new and old grids
1152  call filtered_grid_motion( cs, nz, zold, znew, dzinterface(i,j,:) )
1153 
1154 #ifdef __DO_SAFETY_CHECKS__
1155  dh=max(nominaldepth,totalthickness)
1156  if (abs(znew(1)-zold(1))>(nz-1)*0.5*epsilon(dh)*dh) then
1157  write(0,*) 'min_thickness=',minthickness
1158  write(0,*) 'nominalDepth=',nominaldepth,'totalThickness=',totalthickness
1159  write(0,*) 'dzInterface(1) = ',dzinterface(i,j,1),epsilon(dh),nz
1160  do k=1,nz+1
1161  write(0,*) k,zold(k),znew(k)
1162  enddo
1163  do k=1,nz
1164  write(0,*) k,h(i,j,k),znew(k)-znew(k+1),cs%coordinateResolution(k)
1165  enddo
1166  call mom_error( fatal, &
1167  'MOM_regridding, build_zstar_grid(): top surface has moved!!!' )
1168  endif
1169 #endif
1170 
1171  call adjust_interface_motion( nz, cs%min_thickness, h(i,j,:), dzinterface(i,j,:) )
1172 
1173  end do
1174  end do
1175 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ calc_h_new_by_dz()

subroutine mom_regridding::calc_h_new_by_dz ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(in)  dzInterface,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(inout)  h_new 
)
private

Calculates h_new from h + delta_k dzInterface.

Parameters
[in]gGrid structure
[in]gvOcean vertical grid structure
[in]hOld layer thicknesses (m)
[in]dzinterfaceChange in interface positions (m)
[in,out]h_newNew layer thicknesses (m)

Definition at line 855 of file MOM_regridding.F90.

Referenced by regridding_main().

855  type(ocean_grid_type), intent(in) :: g !< Grid structure
856  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
857  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Old layer thicknesses (m)
858  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: dzinterface !< Change in interface positions (m)
859  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h_new !< New layer thicknesses (m)
860  ! Local variables
861  integer :: i, j, k
862 
863 !$OMP parallel do default(none) shared(G,GV,h,dzInterface,h_new)
864  do j = g%jsc-1,g%jec+1
865  do i = g%isc-1,g%iec+1
866  if (g%mask2dT(i,j)>0.) then
867  do k=1,gv%ke
868  h_new(i,j,k) = max( 0., h(i,j,k) + ( dzinterface(i,j,k) - dzinterface(i,j,k+1) ) )
869  enddo
870  else
871  h_new(i,j,:) = h(i,j,:)
872  endif
873  enddo
874  enddo
875 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the caller graph for this function:

◆ check_grid_column()

subroutine, public mom_regridding::check_grid_column ( integer, intent(in)  nk,
real, intent(in)  depth,
real, dimension(nk), intent(in)  h,
real, dimension(nk+1), intent(in)  dzInterface,
character(len=*), intent(in)  msg 
)

Check that the total thickness of new and old grids are consistent.

Parameters
[in]nkNumber of cells
[in]depthDepth of bottom (m)
[in]hCell thicknesses (m)
[in]dzinterfaceChange in interface positions (m)
[in]msgMessage to append to errors

Definition at line 899 of file MOM_regridding.F90.

References mom_error_handler::mom_error().

Referenced by check_remapping_grid().

899  integer, intent(in) :: nk !< Number of cells
900  real, intent(in) :: depth !< Depth of bottom (m)
901  real, dimension(nk), intent(in) :: h !< Cell thicknesses (m)
902  real, dimension(nk+1), intent(in) :: dzinterface !< Change in interface positions (m)
903  character(len=*), intent(in) :: msg !< Message to append to errors
904  ! Local variables
905  integer :: k
906  real :: eps, total_h_old, total_h_new, h_new, z_old, z_new
907 
908  eps =1. ; eps = epsilon(eps)
909 
910  ! Total thickness of grid h
911  total_h_old = 0.
912  do k = 1,nk
913  total_h_old = total_h_old + h(k)
914  enddo
915 
916  ! Integrate upwards for the interfaces consistent with the rest of MOM6
917  z_old = - depth
918  if (depth == 0.) z_old = - total_h_old
919  total_h_new = 0.
920  do k = nk,1,-1
921  z_old = z_old + h(k) ! Old interface position above layer k
922  z_new = z_old + dzinterface(k) ! New interface position based on dzInterface
923  h_new = h(k) + ( dzinterface(k) - dzinterface(k+1) ) ! New thickness
924  if (h_new<0.) then
925  write(0,*) 'k,h,hnew=',k,h(k),h_new
926  write(0,*) 'dzI(k+1),dzI(k)=',dzinterface(k+1),dzinterface(k)
927  call mom_error( fatal, 'MOM_regridding, check_grid_column: '//&
928  'Negative layer thickness implied by re-gridding, '//trim(msg))
929  endif
930  total_h_new = total_h_new + h_new
931 
932  enddo
933 
934  ! Conservation by implied h_new
935  if (abs(total_h_new-total_h_old)>real(nk-1)*0.5*(total_h_old+total_h_new)*eps) then
936  write(0,*) 'nk=',nk
937  do k = 1,nk
938  write(0,*) 'k,h,hnew=',k,h(k),h(k)+(dzinterface(k)-dzinterface(k+1))
939  enddo
940  write(0,*) 'Hold,Hnew,Hnew-Hold=',total_h_old,total_h_new,total_h_new-total_h_old
941  write(0,*) 'eps,(n)/2*eps*H=',eps,real(nk-1)*0.5*(total_h_old+total_h_new)*eps
942  call mom_error( fatal, 'MOM_regridding, check_grid_column: '//&
943  'Re-gridding did NOT conserve total thickness to within roundoff '//trim(msg))
944  endif
945 
946  ! Check that the top and bottom are intentionally moving
947  if (dzinterface(1) /= 0.) call mom_error( fatal, &
948  'MOM_regridding, check_grid_column: Non-zero dzInterface at surface! '//trim(msg))
949  if (dzinterface(nk+1) /= 0.) call mom_error( fatal, &
950  'MOM_regridding, check_grid_column: Non-zero dzInterface at bottom! '//trim(msg))
951 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ check_grid_def()

subroutine mom_regridding::check_grid_def ( character(len=*), intent(in)  filename,
character(len=*), intent(in)  varname,
character(len=*), intent(in)  expected_units,
character(len=*), intent(inout)  msg,
logical, intent(out)  ierr 
)
private

Do some basic checks on the vertical grid definition file, variable.

Parameters
[in]filenameFile name
[in]varnameVariable name
[in]expected_unitsExpected units of variable
[in,out]msgMessage to use for errors
[out]ierrTrue if an error occurs

Definition at line 685 of file MOM_regridding.F90.

Referenced by initialize_regridding().

685  character(len=*), intent(in) :: filename !< File name
686  character(len=*), intent(in) :: varname !< Variable name
687  character(len=*), intent(in) :: expected_units !< Expected units of variable
688  character(len=*), intent(inout) :: msg !< Message to use for errors
689  logical, intent(out) :: ierr !< True if an error occurs
690  ! Local variables
691  character (len=200) :: units, long_name
692  integer :: ncid, status, intid, vid
693  integer :: i
694 
695  ierr = .false.
696  status = nf90_open(trim(filename), nf90_nowrite, ncid);
697  if (status /= nf90_noerr) then
698  ierr = .true.
699  msg = 'File not found: '//trim(filename)
700  return
701  endif
702 
703  status = nf90_inq_varid(ncid, trim(varname), vid)
704  if (status /= nf90_noerr) then
705  ierr = .true.
706  msg = 'Var not found: '//trim(varname)
707  return
708  endif
709 
710  status = nf90_get_att(ncid, vid, "units", units)
711  if (status /= nf90_noerr) then
712  ierr = .true.
713  msg = 'Attribute not found: units'
714  return
715  endif
716  ! NF90_GET_ATT can return attributes with null characters, which TRIM will not truncate.
717  ! This loop replaces any null characters with a space so that the following check between
718  ! the read units and the expected units will pass
719  do i=1,len_trim(units)
720  if (units(i:i) == char(0)) units(i:i) = " "
721  enddo
722 
723  if (trim(units) /= trim(expected_units)) then
724  if (trim(expected_units) == "meters") then
725  if (trim(units) /= "m") then
726  ierr = .true.
727  endif
728  else
729  ierr = .true.
730  endif
731  endif
732 
733  if (ierr) then
734  msg = 'Units incorrect: '//trim(units)//' /= '//trim(expected_units)
735  endif
736 
Here is the caller graph for this function:

◆ check_remapping_grid()

subroutine, public mom_regridding::check_remapping_grid ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(in)  h,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(in)  dzInterface,
character(len=*), intent(in)  msg 
)

Check that the total thickness of two grids match.

Parameters
[in]gGrid structure
[in]gvOcean vertical grid structure
[in]hLayer thicknesses (m)
[in]dzinterfaceChange in interface positions (m)
[in]msgMessage to append to errors

Definition at line 880 of file MOM_regridding.F90.

References check_grid_column().

Referenced by regridding_main().

880  type(ocean_grid_type), intent(in) :: g !< Grid structure
881  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
882  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(in) :: h !< Layer thicknesses (m)
883  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)+1), intent(in) :: dzinterface !< Change in interface positions (m)
884  character(len=*), intent(in) :: msg !< Message to append to errors
885  ! Local variables
886  integer :: i, j
887 
888 !$OMP parallel do default(none) shared(G,GV,h,dzInterface,msg)
889  do j = g%jsc-1,g%jec+1
890  do i = g%isc-1,g%iec+1
891  if (g%mask2dT(i,j)>0.) call check_grid_column( gv%ke, g%bathyT(i,j), h(i,j,:), dzinterface(i,j,:), msg )
892  enddo
893  enddo
894 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:
Here is the caller graph for this function:

◆ convective_adjustment()

subroutine mom_regridding::convective_adjustment ( type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g),szk_(gv)), intent(inout)  h,
type(thermo_var_ptrs), intent(inout)  tv 
)
private
Parameters
[in]gThe ocean's grid structure
[in]gvThe ocean's vertical grid structure
[in,out]hLayer thicknesses, in H (usually m or kg m-2)
[in,out]tvA structure pointing to various thermodynamic variables

Definition at line 1742 of file MOM_regridding.F90.

Referenced by regridding_main().

1742 !------------------------------------------------------------------------------
1743 ! Check each water column to see whether it is stratified. If not, sort the
1744 ! layers by successive swappings of water masses (bubble sort algorithm)
1745 !------------------------------------------------------------------------------
1746 
1747  ! Arguments
1748  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
1749  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure
1750  real, dimension(SZI_(G),SZJ_(G),SZK_(GV)), intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2)
1751  type(thermo_var_ptrs), intent(inout) :: tv !< A structure pointing to various thermodynamic variables
1752 
1753  ! Local variables
1754  integer :: i, j, k
1755  real :: t0, t1 ! temperatures
1756  real :: s0, s1 ! salinities
1757  real :: r0, r1 ! densities
1758  real :: h0, h1
1759  logical :: stratified
1760  real, dimension(GV%ke) :: p_col, densities
1761 
1762  p_col(:) = 0.
1763 
1764  ! Loop on columns
1765  do j = g%jsc-1,g%jec+1 ; do i = g%isc-1,g%iec+1
1766 
1767  ! Compute densities within current water column
1768  call calculate_density( tv%T(i,j,:), tv%S(i,j,:), p_col, &
1769  densities, 1, gv%ke, tv%eqn_of_state )
1770 
1771  ! Repeat restratification until complete
1772  do
1773  stratified = .true.
1774  do k = 1,gv%ke-1
1775  ! Gather information of current and next cells
1776  t0 = tv%T(i,j,k) ; t1 = tv%T(i,j,k+1)
1777  s0 = tv%S(i,j,k) ; s1 = tv%S(i,j,k+1)
1778  r0 = densities(k) ; r1 = densities(k+1)
1779  h0 = h(i,j,k) ; h1 = h(i,j,k+1)
1780  ! If the density of the current cell is larger than the density
1781  ! below it, we swap the cells and recalculate the densitiies
1782  ! within the swapped cells
1783  if ( r0 > r1 ) then
1784  tv%T(i,j,k) = t1 ; tv%T(i,j,k+1) = t0
1785  tv%S(i,j,k) = s1 ; tv%S(i,j,k+1) = s0
1786  h(i,j,k) = h1 ; h(i,j,k+1) = h0
1787  ! Recompute densities at levels k and k+1
1788  call calculate_density( tv%T(i,j,k), tv%S(i,j,k), p_col(k), &
1789  densities(k), tv%eqn_of_state )
1790  call calculate_density( tv%T(i,j,k+1), tv%S(i,j,k+1), p_col(k+1), &
1791  densities(k+1), tv%eqn_of_state )
1792  stratified = .false.
1793  end if
1794  enddo ! k
1795 
1796  if ( stratified ) exit
1797  enddo
1798 
1799  enddo ; enddo ! i & j
1800 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the caller graph for this function:

◆ dz_function1()

subroutine mom_regridding::dz_function1 ( character(len=*), intent(in)  string,
real, dimension(:), intent(inout)  dz 
)
private

Parses a string and generates a dz(:) profile that goes like k**power.

Parameters
[in]stringString with list of parameters in form dz_min, H_total, power, precision
[in,out]dzProfile of nominal thicknesses

Definition at line 2219 of file MOM_regridding.F90.

Referenced by initialize_regridding().

2219  character(len=*), intent(in) :: string !< String with list of parameters in form
2220  !! dz_min, H_total, power, precision
2221  real, dimension(:), intent(inout) :: dz !< Profile of nominal thicknesses
2222  ! Local variables
2223  integer :: nk, k
2224  real :: dz_min, power, prec, h_total
2225 
2226  nk = size(dz) ! Number of cells
2227  prec = -1024.
2228  read( string, *) dz_min, h_total, power, prec
2229  if (prec == -1024.) call mom_error(fatal,"dz_function1: "// &
2230  "Problem reading FNC1: string ="//trim(string))
2231  ! Create profile of ( dz - dz_min )
2232  do k = 1, nk
2233  dz(k) = (real(k-1)/real(nk-1))**power
2234  enddo
2235  dz(:) = ( h_total - real(nk) * dz_min ) * ( dz(:) / sum(dz) ) ! Rescale to so total is H_total
2236  dz(:) = anint( dz(:) / prec ) * prec ! Rounds to precision prec
2237  dz(:) = ( h_total - real(nk) * dz_min ) * ( dz(:) / sum(dz) ) ! Rescale to so total is H_total
2238  dz(:) = anint( dz(:) / prec ) * prec ! Rounds to precision prec
2239  dz(nk) = dz(nk) + ( h_total - sum( dz(:) + dz_min ) ) ! Adjust bottommost layer
2240  dz(:) = anint( dz(:) / prec ) * prec ! Rounds to precision prec
2241  dz(:) = dz(:) + dz_min ! Finally add in the constant dz_min
2242 
Here is the caller graph for this function:

◆ end_regridding()

subroutine, public mom_regridding::end_regridding ( type(regridding_cs), intent(inout)  CS)

Deallocation of regridding memory.

Parameters
[in,out]csRegridding control structure

Definition at line 741 of file MOM_regridding.F90.

References coord_adapt::end_coord_adapt(), coord_hycom::end_coord_hycom(), coord_sigma::end_coord_sigma(), coord_slight::end_coord_slight(), and coord_zlike::end_coord_zlike().

741  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
742 
743  if (associated(cs%zlike_CS)) call end_coord_zlike(cs%zlike_CS)
744  if (associated(cs%sigma_CS)) call end_coord_sigma(cs%sigma_CS)
745  if (associated(cs%rho_CS)) call end_coord_rho(cs%rho_CS)
746  if (associated(cs%hycom_CS)) call end_coord_hycom(cs%hycom_CS)
747  if (associated(cs%slight_CS)) call end_coord_slight(cs%slight_CS)
748  if (associated(cs%adapt_CS)) call end_coord_adapt(cs%adapt_CS)
749 
750  deallocate( cs%coordinateResolution )
751  if (allocated(cs%target_density)) deallocate( cs%target_density )
752  if (allocated(cs%max_interface_depths) ) deallocate( cs%max_interface_depths )
753  if (allocated(cs%max_layer_thickness) ) deallocate( cs%max_layer_thickness )
754 
Here is the call graph for this function:

◆ filtered_grid_motion()

subroutine mom_regridding::filtered_grid_motion ( type(regridding_cs), intent(in)  CS,
integer, intent(in)  nk,
real, dimension(nk+1), intent(in)  z_old,
real, dimension(nk+1), intent(in)  z_new,
real, dimension(nk+1), intent(inout)  dz_g 
)
private

Returns the change in interface position motion after filtering and assuming the top and bottom interfaces do not move. The filtering is a function of depth, and is applied as the integrated average filtering over the trajectory of the interface. By design, this code can not give tangled interfaces provided that z_old and z_new are not already tangled.

Parameters
[in]csRegridding control structure
[in]nkNumber of cells
[in]z_oldOld grid position (m)
[in]z_newNew grid position (m)
[in,out]dz_gChange in interface positions (m)

Definition at line 960 of file MOM_regridding.F90.

References mom_error_handler::mom_error().

Referenced by build_grid_adaptive(), build_grid_hycom1(), build_grid_slight(), build_rho_grid(), build_sigma_grid(), and build_zstar_grid().

960  type(regridding_cs), intent(in) :: cs !< Regridding control structure
961  integer, intent(in) :: nk !< Number of cells
962  real, dimension(nk+1), intent(in) :: z_old !< Old grid position (m)
963  real, dimension(nk+1), intent(in) :: z_new !< New grid position (m)
964  real, dimension(nk+1), intent(inout) :: dz_g !< Change in interface positions (m)
965  ! Local variables
966  real :: sgn ! The sign convention for downward.
967  real :: dz_tgt, zr1
968  real :: aq, bq, dz0, z0, f0
969  real :: zs, zd, dzwt, idzwt
970  real :: wtd, iwtd
971  real :: int_zs, int_zd, dint_zs_zd
972 ! For debugging:
973  real, dimension(nk+1) :: z_act
974 ! real, dimension(nk+1) :: ddz_g_s, ddz_g_d
975  logical :: debug = .false.
976  integer :: k
977 
978  if ((z_old(nk+1) - z_old(1)) * (z_new(nk+1) - z_new(1)) < 0.0) then
979  call mom_error(fatal, "filtered_grid_motion: z_old and z_new use different sign conventions.")
980  elseif ((z_old(nk+1) - z_old(1)) * (z_new(nk+1) - z_new(1)) == 0.0) then
981  ! This is a massless column, so do nothing and return.
982  do k=1,nk+1 ; dz_g(k) = 0.0 ; enddo ; return
983  elseif ((z_old(nk+1) - z_old(1)) + (z_new(nk+1) - z_new(1)) > 0.0) then
984  sgn = 1.0
985  else
986  sgn = -1.0
987  endif
988 
989  if (debug) then
990  do k=2,nk+1
991  if (sgn*(z_new(k)-z_new(k-1)) < -5e-16*(abs(z_new(k))+abs(z_new(k-1))) ) &
992  call mom_error(fatal, "filtered_grid_motion: z_new is tangled.")
993  if (sgn*(z_old(k)-z_old(k-1)) < -5e-16*(abs(z_old(k))+abs(z_old(k-1))) ) &
994  call mom_error(fatal, "filtered_grid_motion: z_old is tangled.")
995  enddo
996  ! ddz_g_s(:) = 0.0 ; ddz_g_d(:) = 0.0
997  endif
998 
999  zs = cs%depth_of_time_filter_shallow
1000  zd = cs%depth_of_time_filter_deep
1001  wtd = 1.0 - cs%old_grid_weight
1002  iwtd = 1.0 / wtd
1003 
1004  dzwt = (zd - zs)
1005  idzwt = 0.0 ; if (abs(zd - zs) > 0.0) idzwt = 1.0 / (zd - zs)
1006  dint_zs_zd = 0.5*(1.0 + iwtd) * (zd - zs)
1007  aq = 0.5*(iwtd - 1.0)
1008 
1009  dz_g(1) = 0.0
1010  do k = 2,nk
1011  ! zr1 is positive and increases with depth, and dz_tgt is positive downward.
1012  dz_tgt = sgn*(z_new(k) - z_old(k))
1013  zr1 = sgn*(z_old(k) - z_old(1))
1014 
1015  ! First, handle the two simple and common cases that do not pass through
1016  ! the adjustment rate transition zone.
1017  if ((zr1 > zd) .and. (zr1 + wtd * dz_tgt > zd)) then
1018  dz_g(k) = sgn * wtd * dz_tgt
1019  elseif ((zr1 < zs) .and. (zr1 + dz_tgt < zs)) then
1020  dz_g(k) = sgn * dz_tgt
1021  else
1022  ! Find the new value by inverting the equation
1023  ! integral(0 to dz_new) Iwt(z) dz = dz_tgt
1024  ! This is trivial where Iwt is a constant, and agrees with the two limits above.
1025 
1026  ! Take test values at the transition points to figure out which segment
1027  ! the new value will be found in.
1028  if (zr1 >= zd) then
1029  int_zd = iwtd*(zd - zr1)
1030  int_zs = int_zd - dint_zs_zd
1031  elseif (zr1 <= zs) then
1032  int_zs = (zs - zr1)
1033  int_zd = dint_zs_zd + (zs - zr1)
1034  else
1035 ! Int_zd = (zd - zr1) * (Iwtd + 0.5*(1.0 - Iwtd) * (zd - zr1) / (zd - zs))
1036  int_zd = (zd - zr1) * (iwtd*(0.5*(zd+zr1) - zs) + 0.5*(zd - zr1)) * idzwt
1037  int_zs = (zs - zr1) * (0.5*iwtd * ((zr1 - zs)) + (zd - 0.5*(zr1+zs))) * idzwt
1038  ! It has been verified that Int_zs = Int_zd - dInt_zs_zd to within roundoff.
1039  endif
1040 
1041  if (dz_tgt >= int_zd) then ! The new location is in the deep, slow region.
1042  dz_g(k) = sgn * ((zd-zr1) + wtd*(dz_tgt - int_zd))
1043  elseif (dz_tgt <= int_zs) then ! The new location is in the shallow region.
1044  dz_g(k) = sgn * ((zs-zr1) + (dz_tgt - int_zs))
1045  else ! We need to solve a quadratic equation for z_new.
1046  ! For accuracy, do the integral from the starting depth or the nearest
1047  ! edge of the transition region. The results with each choice are
1048  ! mathematically equivalent, but differ in roundoff, and this choice
1049  ! should minimize the likelihood of inadvertently overlapping interfaces.
1050  if (zr1 <= zs) then ; dz0 = zs-zr1 ; z0 = zs ; f0 = dz_tgt - int_zs
1051  elseif (zr1 >= zd) then ; dz0 = zd-zr1 ; z0 = zd ; f0 = dz_tgt - int_zd
1052  else ; dz0 = 0.0 ; z0 = zr1 ; f0 = dz_tgt ; endif
1053 
1054  bq = (dzwt + 2.0*aq*(z0-zs))
1055  ! Solve the quadratic: Aq*(zn-z0)**2 + Bq*(zn-z0) - F0*dzwt = 0
1056  ! Note that b>=0, and the two terms in the standard form cancel for the right root.
1057  dz_g(k) = sgn * (dz0 + 2.0*f0*dzwt / (bq + sqrt(bq**2 + 4.0*aq*f0*dzwt) ))
1058 
1059 ! if (debug) then
1060 ! dz0 = zs-zr1 ; z0 = zs ; F0 = dz_tgt - Int_zs ; Bq = (dzwt + 2.0*Aq*(z0-zs))
1061 ! ddz_g_s(k) = sgn * (dz0 + 2.0*F0*dzwt / (Bq + sqrt(Bq**2 + 4.0*Aq*F0*dzwt) )) - dz_g(k)
1062 ! dz0 = zd-zr1 ; z0 = zd ; F0 = dz_tgt - Int_zd ; Bq = (dzwt + 2.0*Aq*(z0-zs))
1063 ! ddz_g_d(k) = sgn * (dz0 + 2.0*F0*dzwt / (Bq + sqrt(Bq**2 + 4.0*Aq*F0*dzwt) )) - dz_g(k)
1064 !
1065 ! if (abs(ddz_g_s(k)) > 1e-12*(abs(dz_g(k)) + abs(dz_g(k)+ddz_g_s(k)))) &
1066 ! call MOM_error(WARNING, "filtered_grid_motion: Expect z_output to be tangled (sc).")
1067 ! if (abs(ddz_g_d(k) - ddz_g_s(k)) > 1e-12*(abs(dz_g(k)+ddz_g_d(k)) + abs(dz_g(k)+ddz_g_s(k)))) &
1068 ! call MOM_error(WARNING, "filtered_grid_motion: Expect z_output to be tangled.")
1069 ! endif
1070  endif
1071 
1072  endif
1073  enddo
1074  dz_g(nk+1) = 0.0
1075 
1076  if (debug) then
1077  do k=1,nk+1 ; z_act(k) = z_old(k) + dz_g(k) ; enddo
1078  do k=2,nk+1
1079  if (sgn*((z_act(k))-z_act(k-1)) < -1e-15*(abs(z_act(k))+abs(z_act(k-1))) ) &
1080  call mom_error(fatal, "filtered_grid_motion: z_output is tangled.")
1081  enddo
1082  endif
1083 
Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_regrid_size()

integer function, public mom_regridding::get_regrid_size ( type(regridding_cs), intent(inout)  CS)

Returns the number of levels/layers in the regridding control structure.

Parameters
[in,out]csRegridding control structure

Definition at line 2151 of file MOM_regridding.F90.

2151  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
2152 
2153  get_regrid_size = cs%nk
2154 

◆ get_rho_cs()

type(rho_cs) function, public mom_regridding::get_rho_cs ( type(regridding_cs), intent(in)  CS)

Definition at line 2172 of file MOM_regridding.F90.

Referenced by mom_diag_remap::diag_remap_update().

2172  type(regridding_cs), intent(in) :: cs
2173  type(rho_cs) :: get_rho_cs
2174 
2175  get_rho_cs = cs%rho_CS
Here is the caller graph for this function:

◆ get_sigma_cs()

type(sigma_cs) function, public mom_regridding::get_sigma_cs ( type(regridding_cs), intent(in)  CS)

Definition at line 2165 of file MOM_regridding.F90.

Referenced by mom_diag_remap::diag_remap_update().

2165  type(regridding_cs), intent(in) :: cs
2166  type(sigma_cs) :: get_sigma_cs
2167 
2168  get_sigma_cs = cs%sigma_CS
Here is the caller graph for this function:

◆ get_zlike_cs()

type(zlike_cs) function, public mom_regridding::get_zlike_cs ( type(regridding_cs), intent(in)  CS)

Definition at line 2158 of file MOM_regridding.F90.

Referenced by mom_diag_remap::diag_remap_update().

2158  type(regridding_cs), intent(in) :: cs
2159  type(zlike_cs) :: get_zlike_cs
2160 
2161  get_zlike_cs = cs%zlike_CS
Here is the caller graph for this function:

◆ getcoordinateinterfaces()

real function, dimension(cs%nk+1), public mom_regridding::getcoordinateinterfaces ( type(regridding_cs), intent(in)  CS)

Query the target coordinate interface positions.

Parameters
[in]csRegridding control structure
Returns
Interface positions in target coordinate

Definition at line 1982 of file MOM_regridding.F90.

1982  type(regridding_cs), intent(in) :: cs !< Regridding control structure
1983  real, dimension(CS%nk+1) :: getcoordinateinterfaces !< Interface positions in target coordinate
1984 
1985  integer :: k
1986 
1987  ! When using a coordinate with target densities, we need to get the actual
1988  ! densities, rather than computing the interfaces based on resolution
1989  if (cs%regridding_scheme == regridding_rho) then
1990  if (.not. cs%target_density_set) &
1991  call mom_error(fatal, 'MOM_regridding, getCoordinateInterfaces: '//&
1992  'target densities not set!')
1993 
1994  getcoordinateinterfaces(:) = cs%target_density(:)
1995  else
1996  getcoordinateinterfaces(1) = 0.
1997  do k = 1, cs%nk
1998  getcoordinateinterfaces(k+1) = getcoordinateinterfaces(k) &
1999  -cs%coordinateResolution(k)
2000  enddo
2001  ! The following line has an "abs()" to allow ferret users to reference
2002  ! data by index. It is a temporary work around... :( -AJA
2003  getcoordinateinterfaces(:) = abs( getcoordinateinterfaces(:) )
2004  end if
2005 

◆ getcoordinateresolution()

real function, dimension(cs%nk), public mom_regridding::getcoordinateresolution ( type(regridding_cs), intent(in)  CS)

Definition at line 1973 of file MOM_regridding.F90.

Referenced by mom_state_initialization::mom_temp_salt_initialize_from_z().

1973  type(regridding_cs), intent(in) :: cs
1974  real, dimension(CS%nk) :: getcoordinateresolution
1975 
1976  getcoordinateresolution(:) = cs%coordinateResolution(:)
1977 
Here is the caller graph for this function:

◆ getcoordinateshortname()

character(len=20) function, public mom_regridding::getcoordinateshortname ( type(regridding_cs), intent(in)  CS)

Definition at line 2037 of file MOM_regridding.F90.

2037  type(regridding_cs), intent(in) :: cs
2038  character(len=20) :: getcoordinateshortname
2039 
2040  select case ( cs%regridding_scheme )
2041  case ( regridding_zstar )
2042  !getCoordinateShortName = 'z*'
2043  ! The following line is a temporary work around... :( -AJA
2044  getcoordinateshortname = 'pseudo-depth, -z*'
2045  case ( regridding_sigma_shelf_zstar )
2046  getcoordinateshortname = 'pseudo-depth, -z*/sigma'
2047  case ( regridding_sigma )
2048  getcoordinateshortname = 'sigma'
2049  case ( regridding_rho )
2050  getcoordinateshortname = 'rho'
2051  case ( regridding_arbitrary )
2052  getcoordinateshortname = 'coordinate'
2053  case ( regridding_hycom1 )
2054  getcoordinateshortname = 'z-rho'
2055  case ( regridding_slight )
2056  getcoordinateshortname = 's-rho'
2057  case ( regridding_adaptive )
2058  getcoordinateshortname = 'adaptive'
2059  case default
2060  call mom_error(fatal,'MOM_regridding, getCoordinateShortName: '//&
2061  'Unknown regridding scheme selected!')
2062  end select ! type of grid
2063 

◆ getcoordinateunits()

character(len=20) function, public mom_regridding::getcoordinateunits ( type(regridding_cs), intent(in)  CS)

Definition at line 2012 of file MOM_regridding.F90.

2012  type(regridding_cs), intent(in) :: cs
2013  character(len=20) :: getcoordinateunits
2014 
2015  select case ( cs%regridding_scheme )
2016  case ( regridding_zstar, regridding_hycom1, regridding_slight, regridding_adaptive )
2017  getcoordinateunits = 'meter'
2018  case ( regridding_sigma_shelf_zstar )
2019  getcoordinateunits = 'meter/fraction'
2020  case ( regridding_sigma )
2021  getcoordinateunits = 'fraction'
2022  case ( regridding_rho )
2023  getcoordinateunits = 'kg/m3'
2024  case ( regridding_arbitrary )
2025  getcoordinateunits = 'unknown'
2026  case default
2027  call mom_error(fatal,'MOM_regridding, getCoordinateUnits: '//&
2028  'Unknown regridding scheme selected!')
2029  end select ! type of grid
2030 

◆ getstaticthickness()

real function, dimension(cs%nk), public mom_regridding::getstaticthickness ( type(regridding_cs), intent(in)  CS,
real, intent(in)  SSH,
real, intent(in)  depth 
)

Definition at line 2182 of file MOM_regridding.F90.

Referenced by mom_ale::ale_initthicknesstocoord().

2182  type(regridding_cs), intent(in) :: cs
2183  real, intent(in) :: ssh
2184  real, intent(in) :: depth
2185  real, dimension(CS%nk) :: getstaticthickness
2186  ! Local
2187  integer :: k
2188  real :: z, dz
2189 
2190  select case ( cs%regridding_scheme )
2191  case ( regridding_zstar, regridding_sigma_shelf_zstar, regridding_hycom1, regridding_slight, regridding_adaptive )
2192  if (depth>0.) then
2193  z = ssh
2194  do k = 1, cs%nk
2195  dz = cs%coordinateResolution(k) * ( 1. + ssh/depth ) ! Nominal dz*
2196  dz = max(dz, 0.) ! Avoid negative incase ssh=-depth
2197  dz = min(dz, depth - z) ! Clip if below topography
2198  z = z + dz ! Bottom of layer
2199  getstaticthickness(k) = dz
2200  enddo
2201  else
2202  getstaticthickness(:) = 0. ! On land ...
2203  endif
2204  case ( regridding_sigma )
2205  getstaticthickness(:) = cs%coordinateResolution(:) * ( depth + ssh )
2206  case ( regridding_rho )
2207  getstaticthickness(:) = 0. ! Not applicable
2208  case ( regridding_arbitrary )
2209  getstaticthickness(:) = 0. ! Not applicable
2210  case default
2211  call mom_error(fatal,'MOM_regridding, getStaticThickness: '//&
2212  'Unknown regridding scheme selected!')
2213  end select ! type of grid
2214 
Here is the caller graph for this function:

◆ inflate_vanished_layers_old()

subroutine, public mom_regridding::inflate_vanished_layers_old ( type(regridding_cs), intent(in)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension(szi_(g),szj_(g), szk_(gv)), intent(inout)  h 
)
Parameters
[in]gThe ocean's grid structure
[in]gvThe ocean's vertical grid structure
[in,out]hLayer thicknesses, in H (usually m or kg m-2)

Definition at line 1700 of file MOM_regridding.F90.

1700 !------------------------------------------------------------------------------
1701 ! This routine is called when initializing the regridding options. The
1702 ! objective is to make sure all layers are at least as thick as the minimum
1703 ! thickness allowed for regridding purposes (this parameter is set in the
1704 ! MOM_input file or defaulted to 1.0e-3). When layers are too thin, they
1705 ! are inflated up to the minmum thickness.
1706 !------------------------------------------------------------------------------
1707 
1708  ! Arguments
1709  type(regridding_cs), intent(in) :: cs
1710  type(ocean_grid_type), intent(in) :: g !< The ocean's grid structure
1711  type(verticalgrid_type), intent(in) :: gv !< The ocean's vertical grid structure
1712  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h !< Layer thicknesses, in H (usually m or kg m-2)
1713 
1714  ! Local variables
1715  integer :: i, j, k
1716  real :: htmp(gv%ke)
1717 
1718  do i = g%isc-1,g%iec+1
1719  do j = g%jsc-1,g%jec+1
1720 
1721  ! Build grid for current column
1722  do k = 1,gv%ke
1723  htmp(k) = h(i,j,k)
1724  end do
1725 
1726  call old_inflate_layers_1d( cs%min_thickness, gv%ke, htmp )
1727 
1728  ! Save modified grid
1729  do k = 1,gv%ke
1730  h(i,j,k) = htmp(k)
1731  end do
1732 
1733  end do
1734  end do
1735 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19

◆ initcoord()

subroutine mom_regridding::initcoord ( type(regridding_cs), intent(inout)  CS,
character(len=*), intent(in)  coord_mode 
)
private

Definition at line 1842 of file MOM_regridding.F90.

Referenced by initialize_regridding().

1842  type(regridding_cs), intent(inout) :: cs
1843  character(len=*), intent(in) :: coord_mode
1844 
1845  select case (coordinatemode(coord_mode))
1846  case (regridding_zstar)
1847  call init_coord_zlike(cs%zlike_CS, cs%nk, cs%coordinateResolution)
1848  case (regridding_sigma_shelf_zstar)
1849  call init_coord_zlike(cs%zlike_CS, cs%nk, cs%coordinateResolution)
1850  case (regridding_sigma)
1851  call init_coord_sigma(cs%sigma_CS, cs%nk, cs%coordinateResolution)
1852  case (regridding_rho)
1853  call init_coord_rho(cs%rho_CS, cs%nk, cs%ref_pressure, cs%target_density, cs%interp_CS)
1854  case (regridding_hycom1)
1855  call init_coord_hycom(cs%hycom_CS, cs%nk, cs%coordinateResolution, cs%target_density, cs%interp_CS)
1856  case (regridding_slight)
1857  call init_coord_slight(cs%slight_CS, cs%nk, cs%ref_pressure, cs%target_density, cs%interp_CS)
1858  case (regridding_adaptive)
1859  call init_coord_adapt(cs%adapt_CS, cs%nk, cs%coordinateResolution)
1860  end select
Here is the caller graph for this function:

◆ initialize_regridding()

subroutine, public mom_regridding::initialize_regridding ( type(regridding_cs), intent(inout)  CS,
type(verticalgrid_type), intent(in)  GV,
real, intent(in)  max_depth,
type(param_file_type), intent(in)  param_file,
character(len=*), intent(in)  mod,
character(len=*), intent(in)  coord_mode,
character(len=*), intent(in)  param_prefix,
character(len=*), intent(in)  param_suffix 
)

Initialization and configures a regridding control structure based on customizable run-time parameters.

Parameters
[in,out]csRegridding control structure
[in]gvOcean vertical grid structure
[in]max_depthThe maximum depth of the ocean, in m.
[in]param_fileParameter file
[in]modName of calling module.
[in]coord_modeCoordinate mode
[in]param_prefixString to prefix to parameter names. If empty, causes main model parameters to be used.
[in]param_suffixString to append to parameter names.

Definition at line 164 of file MOM_regridding.F90.

References check_grid_def(), dz_function1(), mom_string_functions::extract_integer(), mom_string_functions::extract_real(), mom_string_functions::extractword(), initcoord(), mom_error_handler::mom_error(), regrid_consts::regridding_adaptive, regrid_consts::regridding_hycom1, regrid_consts::regridding_slight, regriddingdefaultboundaryextrapolation, regriddingdefaultinterpscheme, regriddingdefaultminthickness, regriddinginterpschemedoc, set_regrid_max_depths(), set_regrid_max_thickness(), set_regrid_params(), set_target_densities(), set_target_densities_from_gv(), setcoordinateresolution(), and uniformresolution().

164  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
165  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
166  real, intent(in) :: max_depth !< The maximum depth of the ocean, in m.
167  type(param_file_type), intent(in) :: param_file !< Parameter file
168  character(len=*), intent(in) :: mod !< Name of calling module.
169  character(len=*), intent(in) :: coord_mode !< Coordinate mode
170  character(len=*), intent(in) :: param_prefix !< String to prefix to parameter names.
171  !! If empty, causes main model parameters to be used.
172  character(len=*), intent(in) :: param_suffix !< String to append to parameter names.
173  ! Local variables
174  integer :: ke ! Number of levels
175  character(len=80) :: string, string2, varname ! Temporary strings
176  character(len=40) :: coord_units, param_name, coord_res_param ! Temporary strings
177  character(len=200) :: inputdir, filename
178  character(len=320) :: message ! Temporary strings
179  character(len=12) :: expected_units ! Temporary strings
180  logical :: tmplogical, fix_haloclines, set_max, do_sum, main_parameters
181  logical :: coord_is_state_dependent, ierr
182  real :: filt_len, strat_tol, index_scale, tmpreal
183  real :: dz_fixed_sfc, rho_avg_depth, nlay_sfc_int
184  real :: adapttimeratio, adaptzoom, adaptzoomcoeff, adaptbuoycoeff, adaptalpha
185  integer :: nz_fixed_sfc, k, nzf(4)
186  real, dimension(:), allocatable :: dz ! Resolution (thickness) in units of coordinate
187  real, dimension(:), allocatable :: h_max ! Maximum layer thicknesses, in m.
188  real, dimension(:), allocatable :: dz_max ! Thicknesses used to find maximum interface depths, in m.
189  real, dimension(:), allocatable :: z_max ! Maximum interface depths, in m.
190  real, dimension(:), allocatable :: rho_target ! Target density used in HYBRID mode
191  ! Thicknesses that give level centers corresponding to table 2 of WOA09
192  real, dimension(40) :: woa09_dz = (/ 5., 10., 10., 15., 22.5, 25., 25., 25., &
193  37.5, 50., 50., 75., 100., 100., 100., 100., &
194  100., 100., 100., 100., 100., 100., 100., 175., &
195  250., 375., 500., 500., 500., 500., 500., 500., &
196  500., 500., 500., 500., 500., 500., 500., 500. /)
197 
198  call get_param(param_file, mod, "INPUTDIR", inputdir, default=".")
199  inputdir = slasher(inputdir)
200 
201  main_parameters=.false.
202  if (len_trim(param_prefix)==0) main_parameters=.true.
203  if (main_parameters .and. len_trim(param_suffix)>0) call mom_error(fatal,trim(mod)//', initialize_regridding: '// &
204  'Suffix provided without prefix for parameter names!')
205 
206  cs%nk = 0
207  cs%regridding_scheme = coordinatemode(coord_mode)
208  coord_is_state_dependent = state_dependent(coord_mode)
209 
210  if (main_parameters) then
211  ! Read coordinate units parameter (main model = REGRIDDING_COORDINATE_UNITS)
212  call get_param(param_file, mod, "REGRIDDING_COORDINATE_UNITS", coord_units, &
213  "Units of the regridding coordinuate.",&
214  default=coordinateunits(coord_mode))
215  else
216  coord_units=coordinateunits(coord_mode)
217  endif
218 
219  if (coord_is_state_dependent) then
220  if (main_parameters) then
221  param_name = "INTERPOLATION_SCHEME"
222  string2 = regriddingdefaultinterpscheme
223  else
224  param_name = trim(param_prefix)//"_INTERP_SCHEME_"//trim(param_suffix)
225  string2 = 'PPM_H4' ! Default for diagnostics
226  endif
227  call get_param(param_file, mod, "INTERPOLATION_SCHEME", string, &
228  "This sets the interpolation scheme to use to\n"//&
229  "determine the new grid. These parameters are\n"//&
230  "only relevant when REGRIDDING_COORDINATE_MODE is\n"//&
231  "set to a function of state. Otherwise, it is not\n"//&
232  "used. It can be one of the following schemes:\n"//&
233  trim(regriddinginterpschemedoc), default=trim(string2))
234  call set_regrid_params(cs, interp_scheme=string)
235  endif
236 
237  if (main_parameters .and. coord_is_state_dependent) then
238  call get_param(param_file, mod, "BOUNDARY_EXTRAPOLATION", tmplogical, &
239  "When defined, a proper high-order reconstruction\n"//&
240  "scheme is used within boundary cells rather\n"//&
241  "than PCM. E.g., if PPM is used for remapping, a\n"//&
242  "PPM reconstruction will also be used within\n"//&
243  "boundary cells.", default=regriddingdefaultboundaryextrapolation)
244  call set_regrid_params(cs, boundary_extrapolation=tmplogical)
245  else
246  call set_regrid_params(cs, boundary_extrapolation=.false.)
247  endif
248 
249  ! Read coordinate configuration parameter (main model = ALE_COORDINATE_CONFIG)
250  if (main_parameters) then
251  param_name = "ALE_COORDINATE_CONFIG"
252  coord_res_param = "ALE_RESOLUTION"
253  string2 = 'UNIFORM'
254  else
255  param_name = trim(param_prefix)//"_DEF_"//trim(param_suffix)
256  coord_res_param = trim(param_prefix)//"_RES_"//trim(param_suffix)
257  string2 = 'UNIFORM'
258  if (max_depth>3000.) string2='WOA09' ! For convenience
259  endif
260  call get_param(param_file, mod, param_name, string, &
261  "Determines how to specify the coordinate\n"//&
262  "resolution. Valid options are:\n"//&
263  " PARAM - use the vector-parameter "//trim(coord_res_param)//"\n"//&
264  " UNIFORM[:N] - uniformly distributed\n"//&
265  " FILE:string - read from a file. The string specifies\n"//&
266  " the filename and variable name, separated\n"//&
267  " by a comma or space, e.g. FILE:lev.nc,dz\n"//&
268  " or FILE:lev.nc,interfaces=zw\n"//&
269  " WOA09[:N] - the WOA09 vertical grid (approximately)\n"//&
270  " FNC1:string - FNC1:dz_min,H_total,power,precision\n"//&
271  " HYBRID:string - read from a file. The string specifies\n"//&
272  " the filename and two variable names, separated\n"//&
273  " by a comma or space, for sigma-2 and dz. e.g.\n"//&
274  " HYBRID:vgrid.nc,sigma2,dz",&
275  default=trim(string2))
276  message = "The distribution of vertical resolution for the target\n"//&
277  "grid used for Eulerian-like coordinates. For example,\n"//&
278  "in z-coordinate mode, the parameter is a list of level\n"//&
279  "thicknesses (in m). In sigma-coordinate mode, the list\n"//&
280  "is of non-dimensional fractions of the water column."
281  if (index(trim(string),'UNIFORM')==1) then
282  if (len_trim(string)==7) then
283  ke = gv%ke ! Use model nk by default
284  tmpreal = max_depth
285  elseif (index(trim(string),'UNIFORM:')==1 .and. len_trim(string)>8) then
286  ! Format is "UNIFORM:N" or "UNIFORM:N,dz"
287  ke = extract_integer(string(9:len_trim(string)),'',1)
288  tmpreal = extract_real(string(9:len_trim(string)),',',2,missing_value=max_depth)
289  else
290  call mom_error(fatal,trim(mod)//', initialize_regridding: '// &
291  'Unable to interpret "'//trim(string)//'".')
292  endif
293  allocate(dz(ke))
294  if (ke==1) then
295  dz(:) = uniformresolution(ke, coord_mode, tmpreal, gv%Rlay(1), gv%Rlay(1))
296  else
297  dz(:) = uniformresolution(ke, coord_mode, tmpreal, &
298  gv%Rlay(1)+0.5*(gv%Rlay(1)-gv%Rlay(2)), &
299  gv%Rlay(ke)+0.5*(gv%Rlay(ke)-gv%Rlay(ke-1)) )
300  endif
301  if (main_parameters) call log_param(param_file, mod, "!"//coord_res_param, dz, &
302  trim(message), units=trim(coord_units))
303  elseif (trim(string)=='PARAM') then
304  ! Read coordinate resolution (main model = ALE_RESOLUTION)
305  ke = gv%ke ! Use model nk by default
306  allocate(dz(ke))
307  call get_param(param_file, mod, coord_res_param, dz, &
308  trim(message), units=trim(coord_units), fail_if_missing=.true.)
309  elseif (index(trim(string),'FILE:')==1) then
310  ! FILE:filename,var_name is assumed to be reading level thickness variables
311  ! FILE:filename,interfaces=var_name reads positions
312  if (string(6:6)=='.' .or. string(6:6)=='/') then
313  ! If we specified "FILE:./xyz" or "FILE:/xyz" then we have a relative or absolute path
314  filename = trim( extractword(trim(string(6:80)), 1) )
315  else
316  ! Otherwise assume we should look for the file in INPUTDIR
317  filename = trim(inputdir) // trim( extractword(trim(string(6:80)), 1) )
318  endif
319  if (.not. file_exists(filename)) call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
320  "Specified file not found: Looking for '"//trim(filename)//"' ("//trim(string)//")")
321 
322  varname = trim( extractword(trim(string(6:)), 2) )
323  if (len_trim(varname)==0) then
324  if (field_exists(filename,'dz')) then; varname = 'dz'
325  elseif (field_exists(filename,'dsigma')) then; varname = 'dsigma'
326  elseif (field_exists(filename,'ztest')) then; varname = 'ztest'
327  else ; call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
328  "Coordinate variable not specified and none could be guessed.")
329  endif
330  endif
331  ! This check fails when the variable is a dimension variable! -AJA
332  !if (.not. field_exists(fileName,trim(varName))) call MOM_error(FATAL,trim(mod)//", initialize_regridding: "// &
333  ! "Specified field not found: Looking for '"//trim(varName)//"' ("//trim(string)//")")
334  if (cs%regridding_scheme == regridding_sigma) then
335  expected_units = 'nondim'
336  elseif (cs%regridding_scheme == regridding_rho) then
337  expected_units = 'kg m-3'
338  else
339  expected_units = 'meters'
340  endif
341  if (index(trim(varname),'interfaces=')==1) then
342  varname=trim(varname(12:))
343  call check_grid_def(filename, varname, expected_units, message, ierr)
344  if (ierr) call mom_error(fatal,trim(mod)//", initialize_regridding: "//&
345  "Unsupported format in grid definition '"//trim(filename)//"'. Error message "//trim(message))
346  call field_size(trim(filename), trim(varname), nzf)
347  ke = nzf(1)-1
348  if (cs%regridding_scheme == regridding_rho) then
349  allocate(rho_target(ke+1))
350  call mom_read_data(trim(filename), trim(varname), rho_target)
351  else
352  allocate(dz(ke))
353  allocate(z_max(ke+1))
354  call mom_read_data(trim(filename), trim(varname), z_max)
355  dz(:) = abs(z_max(1:ke) - z_max(2:ke+1))
356  deallocate(z_max)
357  endif
358  else
359  ! Assume reading resolution
360  call field_size(trim(filename), trim(varname), nzf)
361  ke = nzf(1)
362  allocate(dz(ke))
363  call mom_read_data(trim(filename), trim(varname), dz)
364  endif
365  if (main_parameters .and. ke/=gv%ke) then
366  call mom_error(fatal,trim(mod)//', initialize_regridding: '// &
367  'Mismatch in number of model levels and "'//trim(string)//'".')
368  endif
369  if (main_parameters) call log_param(param_file, mod, "!"//coord_res_param, dz, &
370  trim(message), units=coordinateunits(coord_mode))
371  elseif (index(trim(string),'FNC1:')==1) then
372  ke = gv%ke; allocate(dz(ke))
373  call dz_function1( trim(string(6:)), dz )
374  if (main_parameters) call log_param(param_file, mod, "!"//coord_res_param, dz, &
375  trim(message), units=coordinateunits(coord_mode))
376  elseif (index(trim(string),'HYBRID:')==1) then
377  ke = gv%ke; allocate(dz(ke))
378  ! The following assumes the FILE: syntax of above but without "FILE:" in the string
379  allocate(rho_target(ke+1))
380  filename = trim( extractword(trim(string(8:)), 1) )
381  if (filename(1:1)/='.' .and. filename(1:1)/='/') filename = trim(inputdir) // trim( filename )
382  if (.not. file_exists(filename)) call mom_error(fatal,trim(mod)//", initialize_regridding: HYBRID "// &
383  "Specified file not found: Looking for '"//trim(filename)//"' ("//trim(string)//")")
384  varname = trim( extractword(trim(string(8:)), 2) )
385  if (.not. field_exists(filename,varname)) call mom_error(fatal,trim(mod)//", initialize_regridding: HYBRID "// &
386  "Specified field not found: Looking for '"//trim(varname)//"' ("//trim(string)//")")
387  call mom_read_data(trim(filename), trim(varname), rho_target)
388  varname = trim( extractword(trim(string(8:)), 3) )
389  if (varname(1:5) == 'FNC1:') then ! Use FNC1 to calculate dz
390  call dz_function1( trim(string((index(trim(string),'FNC1:')+5):)), dz )
391  else ! Read dz from file
392  if (.not. field_exists(filename,varname)) call mom_error(fatal,trim(mod)//", initialize_regridding: HYBRID "// &
393  "Specified field not found: Looking for '"//trim(varname)//"' ("//trim(string)//")")
394  call mom_read_data(trim(filename), trim(varname), dz)
395  endif
396  if (main_parameters) then
397  call log_param(param_file, mod, "!"//coord_res_param, dz, &
398  trim(message), units=coordinateunits(coord_mode))
399  call log_param(param_file, mod, "!TARGET_DENSITIES", rho_target, &
400  'HYBRID target densities for itnerfaces', units=coordinateunits(coord_mode))
401  endif
402  elseif (index(trim(string),'WOA09')==1) then
403  if (len_trim(string)==5) then
404  tmpreal = 0. ; ke = 0
405  do while (tmpreal<max_depth)
406  ke = ke + 1
407  tmpreal = tmpreal + woa09_dz(ke)
408  enddo
409  elseif (index(trim(string),'WOA09:')==1) then
410  if (len_trim(string)==6) call mom_error(fatal,trim(mod)//', initialize_regridding: '// &
411  'Expected string of form "WOA09:N" but got "'//trim(string)//'".')
412  ke = extract_integer(string(7:len_trim(string)),'',1)
413  endif
414  if (ke>40 .or. ke<1) call mom_error(fatal,trim(mod)//', initialize_regridding: '// &
415  'For "WOA05:N" N must 0<N<41 but got "'//trim(string)//'".')
416  allocate(dz(ke))
417  dz(1:ke) = woa09_dz(1:ke)
418  else
419  call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
420  "Unrecognized coordinate configuraiton"//trim(string))
421  endif
422 
423  if (main_parameters) then
424  ! This is a work around to apparently needed to work with the from_Z initialization... ???
425  if (coordinatemode(coord_mode) == regridding_zstar .or. &
426  coordinatemode(coord_mode) == regridding_hycom1 .or. &
427  coordinatemode(coord_mode) == regridding_slight .or. &
428  coordinatemode(coord_mode) == regridding_adaptive) then
429  ! Adjust target grid to be consistent with max_depth
430  tmpreal = sum( dz(:) )
431  if (tmpreal < max_depth) then
432  dz(ke) = dz(ke) + ( max_depth - tmpreal )
433  elseif (tmpreal > max_depth) then
434  if ( dz(ke) + ( max_depth - tmpreal ) > 0. ) then
435  dz(ke) = dz(ke) + ( max_depth - tmpreal )
436  else
437  call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
438  "MAXIMUM_DEPTH was too shallow to adjust bottom layer of DZ!"//trim(string))
439  endif
440  endif
441  endif
442  endif
443 
444  cs%nk=ke
445 
446  ! Target resolution (for fixed coordinates)
447  allocate( cs%coordinateResolution(cs%nk) ); cs%coordinateResolution(:) = -1.e30
448  if (state_dependent(cs%regridding_scheme)) then
449  ! Target values
450  allocate( cs%target_density(cs%nk+1) ); cs%target_density(:) = -1.e30
451  endif
452 
453  if (allocated(dz)) call setcoordinateresolution(dz, cs)
454 
455  if (allocated(rho_target)) then
456  call set_target_densities(cs, rho_target)
457  deallocate(rho_target)
458 
459  ! \todo This line looks like it would overwrite the target densities set just above?
460  elseif (coordinatemode(coord_mode) == regridding_rho) then
461  call set_target_densities_from_gv(gv, cs)
462  call log_param(param_file, mod, "!TARGET_DENSITIES", cs%target_density, &
463  'RHO target densities for interfaces', units=coordinateunits(coord_mode))
464  endif
465 
466  ! initialise coordinate-specific control structure
467  call initcoord(cs, coord_mode)
468 
469  if (main_parameters .and. coord_is_state_dependent) then
470  call get_param(param_file, mod, "REGRID_COMPRESSIBILITY_FRACTION", tmpreal, &
471  "When interpolating potential density profiles we can add\n"//&
472  "some artificial compressibility solely to make homogenous\n"//&
473  "regions appear stratified.", default=0.)
474  call set_regrid_params(cs, compress_fraction=tmpreal)
475  endif
476 
477  if (main_parameters) then
478  call get_param(param_file, mod, "MIN_THICKNESS", tmpreal, &
479  "When regridding, this is the minimum layer\n"//&
480  "thickness allowed.", units="m",&
481  default=regriddingdefaultminthickness )
482  call set_regrid_params(cs, min_thickness=tmpreal)
483  else
484  call set_regrid_params(cs, min_thickness=0.)
485  endif
486 
487  if (coordinatemode(coord_mode) == regridding_slight) then
488  ! Set SLight-specific regridding parameters.
489  call get_param(param_file, mod, "SLIGHT_DZ_SURFACE", dz_fixed_sfc, &
490  "The nominal thickness of fixed thickness near-surface\n"//&
491  "layers with the SLight coordinate.", units="m", default=1.0)
492  call get_param(param_file, mod, "SLIGHT_NZ_SURFACE_FIXED", nz_fixed_sfc, &
493  "The number of fixed-depth surface layers with the SLight\n"//&
494  "coordinate.", units="nondimensional", default=2)
495  call get_param(param_file, mod, "SLIGHT_SURFACE_AVG_DEPTH", rho_avg_depth, &
496  "The thickness of the surface region over which to average\n"//&
497  "when calculating the density to use to define the interior\n"//&
498  "with the SLight coordinate.", units="m", default=1.0)
499  call get_param(param_file, mod, "SLIGHT_NLAY_TO_INTERIOR", nlay_sfc_int, &
500  "The number of layers to offset the surface density when\n"//&
501  "defining where the interior ocean starts with SLight.", &
502  units="nondimensional", default=2.0)
503  call get_param(param_file, mod, "SLIGHT_FIX_HALOCLINES", fix_haloclines, &
504  "If true, identify regions above the reference pressure\n"//&
505  "where the reference pressure systematically underestimates\n"//&
506  "the stratification and use this in the definition of the\n"//&
507  "interior with the SLight coordinate.", default=.false.)
508 
509  call set_regrid_params(cs, dz_min_surface=dz_fixed_sfc, &
510  nz_fixed_surface=nz_fixed_sfc, rho_ml_avg_depth=rho_avg_depth, &
511  nlay_ml_to_interior=nlay_sfc_int, fix_haloclines=fix_haloclines)
512  if (fix_haloclines) then
513  ! Set additional parameters related to SLIGHT_FIX_HALOCLINES.
514  call get_param(param_file, mod, "HALOCLINE_FILTER_LENGTH", filt_len, &
515  "A length scale over which to smooth the temperature and\n"//&
516  "salinity before identifying erroneously unstable haloclines.", &
517  units="m", default=2.0)
518  call get_param(param_file, mod, "HALOCLINE_STRAT_TOL", strat_tol, &
519  "A tolerance for the ratio of the stratification of the\n"//&
520  "apparent coordinate stratification to the actual value\n"//&
521  "that is used to identify erroneously unstable haloclines.\n"//&
522  "This ratio is 1 when they are equal, and sensible values \n"//&
523  "are between 0 and 0.5.", units="nondimensional", default=0.2)
524  call set_regrid_params(cs, halocline_filt_len=filt_len, &
525  halocline_strat_tol=strat_tol)
526  endif
527 
528  endif
529 
530  if (coordinatemode(coord_mode) == regridding_adaptive) then
531  call get_param(param_file, mod, "ADAPT_TIME_RATIO", adapttimeratio, &
532  "Ratio of ALE timestep to grid timescale.", units="s", default=1e-1)
533  call get_param(param_file, mod, "ADAPT_ZOOM_DEPTH", adaptzoom, &
534  "Depth of near-surface zooming region.", units="m", default=200.0)
535  call get_param(param_file, mod, "ADAPT_ZOOM_COEFF", adaptzoomcoeff, &
536  "Coefficient of near-surface zooming diffusivity.", &
537  units="nondim", default=0.2)
538  call get_param(param_file, mod, "ADAPT_BUOY_COEFF", adaptbuoycoeff, &
539  "Coefficient of buoyancy diffusivity.", &
540  units="nondim", default=0.8)
541  call get_param(param_file, mod, "ADAPT_ALPHA", adaptalpha, &
542  "Scaling on optimization tendency.", &
543  units="nondim", default=1.0)
544  call get_param(param_file, mod, "ADAPT_DO_MIN_DEPTH", tmplogical, &
545  "If true, make a HyCOM-like mixed layer by preventing interfaces\n"//&
546  "from being shallower than the depths specified by the regridding coordinate.", &
547  default=.false.)
548 
549  call set_regrid_params(cs, adapttimeratio=adapttimeratio, adaptzoom=adaptzoom, &
550  adaptzoomcoeff=adaptzoomcoeff, adaptbuoycoeff=adaptbuoycoeff, adaptalpha=adaptalpha, &
551  adaptdomin=tmplogical)
552  endif
553 
554  if (main_parameters .and. coord_is_state_dependent) then
555  call get_param(param_file, mod, "MAXIMUM_INT_DEPTH_CONFIG", string, &
556  "Determines how to specify the maximum interface depths.\n"//&
557  "Valid options are:\n"//&
558  " NONE - there are no maximum interface depths\n"//&
559  " PARAM - use the vector-parameter MAXIMUM_INTERFACE_DEPTHS\n"//&
560  " FILE:string - read from a file. The string specifies\n"//&
561  " the filename and variable name, separated\n"//&
562  " by a comma or space, e.g. FILE:lev.nc,Z\n"//&
563  " FNC1:string - FNC1:dz_min,H_total,power,precision",&
564  default='NONE')
565  message = "The list of maximum depths for each interface."
566  allocate(z_max(ke+1))
567  allocate(dz_max(ke))
568  if ( trim(string) == "NONE") then
569  ! Do nothing.
570  elseif ( trim(string) == "PARAM") then
571  call get_param(param_file, mod, "MAXIMUM_INTERFACE_DEPTHS", z_max, &
572  trim(message), units="m", fail_if_missing=.true.)
573  call set_regrid_max_depths(cs, z_max, gv%m_to_H)
574  elseif (index(trim(string),'FILE:')==1) then
575  if (string(6:6)=='.' .or. string(6:6)=='/') then
576  ! If we specified "FILE:./xyz" or "FILE:/xyz" then we have a relative or absolute path
577  filename = trim( extractword(trim(string(6:80)), 1) )
578  else
579  ! Otherwise assume we should look for the file in INPUTDIR
580  filename = trim(inputdir) // trim( extractword(trim(string(6:80)), 1) )
581  endif
582  if (.not. file_exists(filename)) call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
583  "Specified file not found: Looking for '"//trim(filename)//"' ("//trim(string)//")")
584 
585  do_sum = .false.
586  varname = trim( extractword(trim(string(6:)), 2) )
587  if (.not. field_exists(filename,varname)) call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
588  "Specified field not found: Looking for '"//trim(varname)//"' ("//trim(string)//")")
589  if (len_trim(varname)==0) then
590  if (field_exists(filename,'z_max')) then; varname = 'z_max'
591  elseif (field_exists(filename,'dz')) then; varname = 'dz' ; do_sum = .true.
592  elseif (field_exists(filename,'dz_max')) then; varname = 'dz_max' ; do_sum = .true.
593  else ; call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
594  "MAXIMUM_INT_DEPTHS variable not specified and none could be guessed.")
595  endif
596  endif
597  if (do_sum) then
598  call mom_read_data(trim(filename), trim(varname), dz_max)
599  z_max(1) = 0.0 ; do k=1,ke ; z_max(k+1) = z_max(k) + dz_max(k) ; enddo
600  else
601  call mom_read_data(trim(filename), trim(varname), z_max)
602  endif
603  call log_param(param_file, mod, "!MAXIMUM_INT_DEPTHS", z_max, &
604  trim(message), units=coordinateunits(coord_mode))
605  call set_regrid_max_depths(cs, z_max, gv%m_to_H)
606  elseif (index(trim(string),'FNC1:')==1) then
607  call dz_function1( trim(string(6:)), dz_max )
608  if ((coordinatemode(coord_mode) == regridding_slight) .and. &
609  (dz_fixed_sfc > 0.0)) then
610  do k=1,nz_fixed_sfc ; dz_max(k) = dz_fixed_sfc ; enddo
611  endif
612  z_max(1) = 0.0 ; do k=1,ke ; z_max(k+1) = z_max(k) + dz_max(k) ; enddo
613  call log_param(param_file, mod, "!MAXIMUM_INT_DEPTHS", z_max, &
614  trim(message), units=coordinateunits(coord_mode))
615  call set_regrid_max_depths(cs, z_max, gv%m_to_H)
616  else
617  call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
618  "Unrecognized MAXIMUM_INT_DEPTH_CONFIG "//trim(string))
619  endif
620  deallocate(z_max)
621  deallocate(dz_max)
622 
623  ! Optionally specify maximum thicknesses for each layer, enforced by moving
624  ! the interface below a layer downward.
625  call get_param(param_file, mod, "MAX_LAYER_THICKNESS_CONFIG", string, &
626  "Determines how to specify the maximum layer thicknesses.\n"//&
627  "Valid options are:\n"//&
628  " NONE - there are no maximum layer thicknesses\n"//&
629  " PARAM - use the vector-parameter MAX_LAYER_THICKNESS\n"//&
630  " FILE:string - read from a file. The string specifies\n"//&
631  " the filename and variable name, separated\n"//&
632  " by a comma or space, e.g. FILE:lev.nc,Z\n"//&
633  " FNC1:string - FNC1:dz_min,H_total,power,precision",&
634  default='NONE')
635  message = "The list of maximum thickness for each layer."
636  allocate(h_max(ke))
637  if ( trim(string) == "NONE") then
638  ! Do nothing.
639  elseif ( trim(string) == "PARAM") then
640  call get_param(param_file, mod, "MAX_LAYER_THICKNESS", h_max, &
641  trim(message), units="m", fail_if_missing=.true.)
642  call set_regrid_max_thickness(cs, h_max, gv%m_to_H)
643  elseif (index(trim(string),'FILE:')==1) then
644  if (string(6:6)=='.' .or. string(6:6)=='/') then
645  ! If we specified "FILE:./xyz" or "FILE:/xyz" then we have a relative or absolute path
646  filename = trim( extractword(trim(string(6:80)), 1) )
647  else
648  ! Otherwise assume we should look for the file in INPUTDIR
649  filename = trim(inputdir) // trim( extractword(trim(string(6:80)), 1) )
650  endif
651  if (.not. file_exists(filename)) call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
652  "Specified file not found: Looking for '"//trim(filename)//"' ("//trim(string)//")")
653 
654  varname = trim( extractword(trim(string(6:)), 2) )
655  if (.not. field_exists(filename,varname)) call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
656  "Specified field not found: Looking for '"//trim(varname)//"' ("//trim(string)//")")
657  if (len_trim(varname)==0) then
658  if (field_exists(filename,'h_max')) then; varname = 'h_max'
659  elseif (field_exists(filename,'dz_max')) then; varname = 'dz_max'
660  else ; call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
661  "MAXIMUM_INT_DEPTHS variable not specified and none could be guessed.")
662  endif
663  endif
664  call mom_read_data(trim(filename), trim(varname), h_max)
665  call log_param(param_file, mod, "!MAX_LAYER_THICKNESS", h_max, &
666  trim(message), units=coordinateunits(coord_mode))
667  call set_regrid_max_thickness(cs, h_max, gv%m_to_H)
668  elseif (index(trim(string),'FNC1:')==1) then
669  call dz_function1( trim(string(6:)), h_max )
670  call log_param(param_file, mod, "!MAX_LAYER_THICKNESS", h_max, &
671  trim(message), units=coordinateunits(coord_mode))
672  call set_regrid_max_thickness(cs, h_max, gv%m_to_H)
673  else
674  call mom_error(fatal,trim(mod)//", initialize_regridding: "// &
675  "Unrecognized MAX_LAYER_THICKNESS_CONFIG "//trim(string))
676  endif
677  deallocate(h_max)
678  endif
679 
680  if (allocated(dz)) deallocate(dz)
Here is the call graph for this function:

◆ regridding_main()

subroutine, public mom_regridding::regridding_main ( type(remapping_cs), intent(in)  remapCS,
type(regridding_cs), intent(in)  CS,
type(ocean_grid_type), intent(in)  G,
type(verticalgrid_type), intent(in)  GV,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(inout)  h,
type(thermo_var_ptrs), intent(inout)  tv,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke), intent(inout)  h_new,
real, dimension( g %isd: g %ied, g %jsd: g %jed, gv %ke+1), intent(inout)  dzInterface,
real, dimension(:,:), optional, pointer  frac_shelf_h,
logical, intent(in), optional  conv_adjust 
)
Parameters
[in]remapcsRemapping parameters and options
[in]csRegridding control structure
[in]gOcean grid structure
[in]gvOcean vertical grid structure
[in,out]hCurrent 3D grid obtained after the last time step
[in,out]tvThermodynamical variables (T, S, ...)
[in,out]h_newNew 3D grid consistent with target coordinate
[in,out]dzinterfaceThe change in position of each interface
frac_shelf_hFractional ice shelf coverage

Definition at line 761 of file MOM_regridding.F90.

References build_grid_adaptive(), build_grid_arbitrary(), build_grid_hycom1(), build_grid_slight(), build_rho_grid(), build_sigma_grid(), build_zstar_grid(), calc_h_new_by_dz(), check_remapping_grid(), convective_adjustment(), mom_error_handler::mom_error(), regrid_consts::regridding_adaptive, regrid_consts::regridding_hycom1, and regrid_consts::regridding_slight.

761 !------------------------------------------------------------------------------
762 ! This routine takes care of (1) building a new grid and (2) remapping between
763 ! the old grid and the new grid. The creation of the new grid can be based
764 ! on z coordinates, target interface densities, sigma coordinates or any
765 ! arbitrary coordinate system.
766 ! The MOM6 interface positions are always calculated from the bottom up by
767 ! accumulating the layer thicknesses starting at z=-G%bathyT. z increases
768 ! upwards (decreasing k-index).
769 ! The new grid is defined by the change in position of those interfaces in z
770 ! dzInterface = zNew - zOld.
771 ! Thus, if the regridding inflates the top layer, hNew(1) > hOld(1), then the
772 ! second interface moves downward, zNew(2) < zOld(2), and dzInterface(2) < 0.
773 ! hNew(k) = hOld(k) - dzInterface(k+1) + dzInterface(k)
774 ! IMPORTANT NOTE:
775 ! This is the converse of the sign convention used in the remapping code!
776 !------------------------------------------------------------------------------
777 
778  ! Arguments
779  type(remapping_cs), intent(in) :: remapcs !< Remapping parameters and options
780  type(regridding_cs), intent(in) :: cs !< Regridding control structure
781  type(ocean_grid_type), intent(in) :: g !< Ocean grid structure
782  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
783  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h !< Current 3D grid obtained after the last time step
784  type(thermo_var_ptrs), intent(inout) :: tv !< Thermodynamical variables (T, S, ...)
785  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)), intent(inout) :: h_new !< New 3D grid consistent with target coordinate
786  real, dimension(SZI_(G),SZJ_(G), SZK_(GV)+1), intent(inout) :: dzinterface !< The change in position of each interface
787  real, dimension(:,:), optional, pointer :: frac_shelf_h !< Fractional ice shelf coverage
788  logical, optional, intent(in ) :: conv_adjust ! If true, do convective adjustment
789  ! Local variables
790  real :: trickgnucompiler
791  logical :: use_ice_shelf
792  logical :: do_convective_adjustment
793 
794  do_convective_adjustment = .true.
795  if (present(conv_adjust)) do_convective_adjustment = conv_adjust
796 
797  use_ice_shelf = .false.
798  if (present(frac_shelf_h)) then
799  if (associated(frac_shelf_h)) use_ice_shelf = .true.
800  endif
801 
802  select case ( cs%regridding_scheme )
803 
804  case ( regridding_zstar )
805  if (use_ice_shelf) then
806  call build_zstar_grid( cs, g, gv, h, dzinterface, frac_shelf_h )
807  else
808  call build_zstar_grid( cs, g, gv, h, dzinterface )
809  endif
810  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
811 
812  case ( regridding_sigma_shelf_zstar)
813  call build_zstar_grid( cs, g, gv, h, dzinterface )
814  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
815 
816  case ( regridding_sigma )
817  call build_sigma_grid( cs, g, gv, h, dzinterface )
818  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
819 
820  case ( regridding_rho )
821  if (do_convective_adjustment) call convective_adjustment(g, gv, h, tv)
822  call build_rho_grid( g, gv, h, tv, dzinterface, remapcs, cs )
823  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
824 
825  case ( regridding_arbitrary )
826  call build_grid_arbitrary( g, gv, h, dzinterface, trickgnucompiler, cs )
827  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
828 
829  case ( regridding_hycom1 )
830  call build_grid_hycom1( g, gv, h, tv, dzinterface, cs )
831  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
832 
833  case ( regridding_slight )
834  call build_grid_slight( g, gv, h, tv, dzinterface, cs )
835  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
836 
837  case ( regridding_adaptive )
838  call build_grid_adaptive(g, gv, h, tv, dzinterface, remapcs, cs)
839  call calc_h_new_by_dz(g, gv, h, dzinterface, h_new)
840 
841  case default
842  call mom_error(fatal,'MOM_regridding, regridding_main: '//&
843  'Unknown regridding scheme selected!')
844 
845  end select ! type of grid
846 
847 #ifdef __DO_SAFETY_CHECKS__
848  call check_remapping_grid(g, gv, h, dzinterface,'in regridding_main')
849 #endif
850 
Ocean grid type. See mom_grid for details.
Definition: MOM_grid.F90:19
Here is the call graph for this function:

◆ set_regrid_max_depths()

subroutine, public mom_regridding::set_regrid_max_depths ( type(regridding_cs), intent(inout)  CS,
real, dimension(cs%nk+1), intent(in)  max_depths,
real, intent(in), optional  units_to_H 
)

Set maximum interface depths based on a vector of input values.

Parameters
[in,out]csRegridding control structure
[in]max_depthsMaximum interface depths, in arbitrary units
[in]units_to_hA conversion factor for max_depths into H units

Definition at line 1906 of file MOM_regridding.F90.

Referenced by initialize_regridding().

1906  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
1907  real, dimension(CS%nk+1), intent(in) :: max_depths !< Maximum interface depths, in arbitrary units
1908  real, optional, intent(in) :: units_to_h !< A conversion factor for max_depths into H units
1909  ! Local variables
1910  real :: val_to_h
1911  integer :: k
1912 
1913  if (.not.allocated(cs%max_interface_depths)) allocate(cs%max_interface_depths(1:cs%nk+1))
1914 
1915  val_to_h = 1.0 ; if (present( units_to_h)) val_to_h = units_to_h
1916  if (max_depths(cs%nk+1) < max_depths(1)) val_to_h = -1.0*val_to_h
1917 
1918  ! Check for sign reversals in the depths.
1919  if (max_depths(cs%nk+1) < max_depths(1)) then
1920  do k=1,cs%nk ; if (max_depths(k+1) > max_depths(k)) &
1921  call mom_error(fatal, "Unordered list of maximum depths sent to set_regrid_max_depths!")
1922  enddo
1923  else
1924  do k=1,cs%nk ; if (max_depths(k+1) < max_depths(k)) &
1925  call mom_error(fatal, "Unordered list of maximum depths sent to set_regrid_max_depths.")
1926  enddo
1927  endif
1928 
1929  do k=1,cs%nk+1
1930  cs%max_interface_depths(k) = val_to_h * max_depths(k)
1931  enddo
1932 
1933  ! set max depths for coordinate
1934  select case (cs%regridding_scheme)
1935  case (regridding_hycom1)
1936  call set_hycom_params(cs%hycom_CS, max_interface_depths=cs%max_interface_depths)
1937  case (regridding_slight)
1938  call set_slight_params(cs%slight_CS, max_interface_depths=cs%max_interface_depths)
1939  end select
Here is the caller graph for this function:

◆ set_regrid_max_thickness()

subroutine, public mom_regridding::set_regrid_max_thickness ( type(regridding_cs), intent(inout)  CS,
real, dimension(cs%nk+1), intent(in)  max_h,
real, intent(in), optional  units_to_H 
)

Set maximum layer thicknesses based on a vector of input values.

Parameters
[in,out]csRegridding control structure
[in]max_hMaximum interface depths, in arbitrary units
[in]units_to_hA conversion factor for max_h into H units

Definition at line 1944 of file MOM_regridding.F90.

Referenced by initialize_regridding().

1944  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
1945  real, dimension(CS%nk+1), intent(in) :: max_h !< Maximum interface depths, in arbitrary units
1946  real, optional, intent(in) :: units_to_h !< A conversion factor for max_h into H units
1947  ! Local variables
1948  real :: val_to_h
1949  integer :: k
1950 
1951  if (.not.allocated(cs%max_layer_thickness)) allocate(cs%max_layer_thickness(1:cs%nk))
1952 
1953  val_to_h = 1.0 ; if (present( units_to_h)) val_to_h = units_to_h
1954 
1955  do k=1,cs%nk
1956  cs%max_layer_thickness(k) = val_to_h * max_h(k)
1957  enddo
1958 
1959  ! set max thickness for coordinate
1960  select case (cs%regridding_scheme)
1961  case (regridding_hycom1)
1962  call set_hycom_params(cs%hycom_CS, max_layer_thickness=cs%max_layer_thickness)
1963  case (regridding_slight)
1964  call set_slight_params(cs%slight_CS, max_layer_thickness=cs%max_layer_thickness)
1965  end select
Here is the caller graph for this function:

◆ set_regrid_params()

subroutine, public mom_regridding::set_regrid_params ( type(regridding_cs), intent(inout)  CS,
logical, intent(in), optional  boundary_extrapolation,
real, intent(in), optional  min_thickness,
real, intent(in), optional  old_grid_weight,
character(len=*), intent(in), optional  interp_scheme,
real, intent(in), optional  depth_of_time_filter_shallow,
real, intent(in), optional  depth_of_time_filter_deep,
real, intent(in), optional  compress_fraction,
real, intent(in), optional  dz_min_surface,
integer, intent(in), optional  nz_fixed_surface,
real, intent(in), optional  Rho_ML_avg_depth,
real, intent(in), optional  nlay_ML_to_interior,
logical, intent(in), optional  fix_haloclines,
real, intent(in), optional  halocline_filt_len,
real, intent(in), optional  halocline_strat_tol,
logical, intent(in), optional  integrate_downward_for_e,
real, intent(in), optional  adaptTimeRatio,
real, intent(in), optional  adaptZoom,
real, intent(in), optional  adaptZoomCoeff,
real, intent(in), optional  adaptBuoyCoeff,
real, intent(in), optional  adaptAlpha,
logical, intent(in), optional  adaptDoMin 
)

Can be used to set any of the parameters for MOM_regridding.

Parameters
[in,out]csRegridding control structure
[in]boundary_extrapolationExtrapolate in boundary cells
[in]min_thicknessMinimum thickness allowed when building the new grid (m)
[in]old_grid_weightWeight given to old coordinate when time-filtering grid
[in]interp_schemeInterpolation method for state-dependent coordinates
[in]depth_of_time_filter_shallowDepth to start cubic (H units)
[in]depth_of_time_filter_deepDepth to end cubic (H units)
[in]compress_fractionFraction of compressibility to add to potential density
[in]dz_min_surfaceThe fixed resolution in the topmost SLight_nkml_min layers (m)
[in]nz_fixed_surfaceThe number of fixed-thickess layers at the top of the model
[in]rho_ml_avg_depthAveraging depth over which to determine mixed layer potential density (m)
[in]nlay_ml_to_interiorNumber of layers to offset the mixed layer density to find resolved stratification (nondim)
[in]fix_haloclinesDetect regions with much weaker stratification in the coordinate
[in]halocline_filt_lenLength scale over which to filter T & S when looking for spuriously unstable water mass profiles (m)
[in]halocline_strat_tolValue of the stratification ratio that defines a problematic halocline region.
[in]integrate_downward_for_eIf true, integrate for interface positions downward from the top.

Definition at line 2073 of file MOM_regridding.F90.

Referenced by initialize_regridding(), and mom_state_initialization::mom_temp_salt_initialize_from_z().

2073  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
2074  logical, optional, intent(in) :: boundary_extrapolation !< Extrapolate in boundary cells
2075  real, optional, intent(in) :: min_thickness !< Minimum thickness allowed when building the new grid (m)
2076  real, optional, intent(in) :: old_grid_weight !< Weight given to old coordinate when time-filtering grid
2077  character(len=*), optional, intent(in) :: interp_scheme !< Interpolation method for state-dependent coordinates
2078  real, optional, intent(in) :: depth_of_time_filter_shallow !< Depth to start cubic (H units)
2079  real, optional, intent(in) :: depth_of_time_filter_deep !< Depth to end cubic (H units)
2080  real, optional, intent(in) :: compress_fraction !< Fraction of compressibility to add to potential density
2081  real, optional, intent(in) :: dz_min_surface !< The fixed resolution in the topmost SLight_nkml_min layers (m)
2082  integer, optional, intent(in) :: nz_fixed_surface !< The number of fixed-thickess layers at the top of the model
2083  real, optional, intent(in) :: rho_ml_avg_depth !< Averaging depth over which to determine mixed layer potential density (m)
2084  real, optional, intent(in) :: nlay_ml_to_interior !< Number of layers to offset the mixed layer density to find resolved stratification (nondim)
2085  logical, optional, intent(in) :: fix_haloclines !< Detect regions with much weaker stratification in the coordinate
2086  real, optional, intent(in) :: halocline_filt_len !< Length scale over which to filter T & S when looking for spuriously unstable water mass profiles (m)
2087  real, optional, intent(in) :: halocline_strat_tol !< Value of the stratification ratio that defines a problematic halocline region.
2088  logical, optional, intent(in) :: integrate_downward_for_e !< If true, integrate for interface positions downward from the top.
2089  real, optional, intent(in) :: adapttimeratio, adaptzoom, adaptzoomcoeff, adaptbuoycoeff, adaptalpha
2090  logical, optional, intent(in) :: adaptdomin
2091 
2092  if (present(interp_scheme)) call set_interp_scheme(cs%interp_CS, interp_scheme)
2093  if (present(boundary_extrapolation)) call set_interp_extrap(cs%interp_CS, boundary_extrapolation)
2094 
2095  if (present(old_grid_weight)) then
2096  if (old_grid_weight<0. .or. old_grid_weight>1.) &
2097  call mom_error(fatal,'MOM_regridding, set_regrid_params: Weight is out side the range 0..1!')
2098  cs%old_grid_weight = old_grid_weight
2099  endif
2100  if (present(depth_of_time_filter_shallow)) cs%depth_of_time_filter_shallow = depth_of_time_filter_shallow
2101  if (present(depth_of_time_filter_deep)) cs%depth_of_time_filter_deep = depth_of_time_filter_deep
2102  if (present(depth_of_time_filter_shallow) .or. present(depth_of_time_filter_deep)) then
2103  if (cs%depth_of_time_filter_deep<cs%depth_of_time_filter_shallow) call mom_error(fatal,'MOM_regridding, '//&
2104  'set_regrid_params: depth_of_time_filter_deep<depth_of_time_filter_shallow!')
2105  endif
2106 
2107  if (present(min_thickness)) cs%min_thickness = min_thickness
2108  if (present(compress_fraction)) cs%compressibility_fraction = compress_fraction
2109  if (present(integrate_downward_for_e)) cs%integrate_downward_for_e = integrate_downward_for_e
2110 
2111  select case (cs%regridding_scheme)
2112  case (regridding_zstar)
2113  if (present(min_thickness)) call set_zlike_params(cs%zlike_CS, min_thickness=min_thickness)
2114  case (regridding_sigma_shelf_zstar)
2115  if (present(min_thickness)) call set_zlike_params(cs%zlike_CS, min_thickness=min_thickness)
2116  case (regridding_sigma)
2117  if (present(min_thickness)) call set_sigma_params(cs%sigma_CS, min_thickness=min_thickness)
2118  case (regridding_rho)
2119  if (present(min_thickness)) call set_rho_params(cs%rho_CS, min_thickness=min_thickness)
2120  if (present(integrate_downward_for_e)) call set_rho_params(cs%rho_CS, integrate_downward_for_e=integrate_downward_for_e)
2121  if (associated(cs%rho_CS) .and. (present(interp_scheme) .or. present(boundary_extrapolation))) &
2122  call set_rho_params(cs%rho_CS, interp_cs=cs%interp_CS)
2123  case (regridding_hycom1)
2124  if (associated(cs%hycom_CS) .and. (present(interp_scheme) .or. present(boundary_extrapolation))) &
2125  call set_hycom_params(cs%hycom_CS, interp_cs=cs%interp_CS)
2126  case (regridding_slight)
2127  if (present(min_thickness)) call set_slight_params(cs%slight_CS, min_thickness=min_thickness)
2128  if (present(dz_min_surface)) call set_slight_params(cs%slight_CS, dz_ml_min=dz_min_surface)
2129  if (present(nz_fixed_surface)) call set_slight_params(cs%slight_CS, nz_fixed_surface=nz_fixed_surface)
2130  if (present(rho_ml_avg_depth)) call set_slight_params(cs%slight_CS, rho_ml_avg_depth=rho_ml_avg_depth)
2131  if (present(nlay_ml_to_interior)) call set_slight_params(cs%slight_CS, nlay_ml_offset=nlay_ml_to_interior)
2132  if (present(fix_haloclines)) call set_slight_params(cs%slight_CS, fix_haloclines=fix_haloclines)
2133  if (present(halocline_filt_len)) call set_slight_params(cs%slight_CS, halocline_filter_length=halocline_filt_len)
2134  if (present(halocline_strat_tol)) call set_slight_params(cs%slight_CS, halocline_strat_tol=halocline_strat_tol)
2135  if (present(compress_fraction)) call set_slight_params(cs%slight_CS, compressibility_fraction=compress_fraction)
2136  if (associated(cs%slight_CS) .and. (present(interp_scheme) .or. present(boundary_extrapolation))) &
2137  call set_slight_params(cs%slight_CS, interp_cs=cs%interp_CS)
2138  case (regridding_adaptive)
2139  if (present(adapttimeratio)) call set_adapt_params(cs%adapt_CS, adapttimeratio=adapttimeratio)
2140  if (present(adaptzoom)) call set_adapt_params(cs%adapt_CS, adaptzoom=adaptzoom)
2141  if (present(adaptzoomcoeff)) call set_adapt_params(cs%adapt_CS, adaptzoomcoeff=adaptzoomcoeff)
2142  if (present(adaptbuoycoeff)) call set_adapt_params(cs%adapt_CS, adaptbuoycoeff=adaptbuoycoeff)
2143  if (present(adaptalpha)) call set_adapt_params(cs%adapt_CS, adaptalpha=adaptalpha)
2144  if (present(adaptdomin)) call set_adapt_params(cs%adapt_CS, adaptdomin=adaptdomin)
2145  end select
2146 
Here is the caller graph for this function:

◆ set_target_densities()

subroutine, public mom_regridding::set_target_densities ( type(regridding_cs), intent(inout)  CS,
real, dimension(cs%nk+1), intent(in)  rho_int 
)

Set target densities based on vector of interface values.

Parameters
[in,out]csRegridding control structure
[in]rho_intInterface densities

Definition at line 1896 of file MOM_regridding.F90.

Referenced by initialize_regridding().

1896  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
1897  real, dimension(CS%nk+1), intent(in) :: rho_int !< Interface densities
1898 
1899  cs%target_density(:) = rho_int(:)
1900  cs%target_density_set = .true.
1901 
Here is the caller graph for this function:

◆ set_target_densities_from_gv()

subroutine, public mom_regridding::set_target_densities_from_gv ( type(verticalgrid_type), intent(in)  GV,
type(regridding_cs), intent(inout)  CS 
)

Set target densities based on the old Rlay variable.

Parameters
[in]gvOcean vertical grid structure
[in,out]csRegridding control structure

Definition at line 1879 of file MOM_regridding.F90.

Referenced by initialize_regridding().

1879  type(verticalgrid_type), intent(in) :: gv !< Ocean vertical grid structure
1880  type(regridding_cs), intent(inout) :: cs !< Regridding control structure
1881  ! Local variables
1882  integer :: k, nz
1883 
1884  nz = cs%nk
1885  cs%target_density(1) = gv%Rlay(1)+0.5*(gv%Rlay(1)-gv%Rlay(2))
1886  cs%target_density(nz+1) = gv%Rlay(nz)+0.5*(gv%Rlay(nz)-gv%Rlay(nz-1))
1887  do k = 2,nz
1888  cs%target_density(k) = cs%target_density(k-1) + cs%coordinateResolution(k)
1889  end do
1890  cs%target_density_set = .true.
1891 
Here is the caller graph for this function:

◆ setcoordinateresolution()

subroutine, public mom_regridding::setcoordinateresolution ( real, dimension(:), intent(in)  dz,
type(regridding_cs), intent(inout)  CS 
)

Definition at line 1867 of file MOM_regridding.F90.

Referenced by initialize_regridding().

1867  real, dimension(:), intent(in) :: dz
1868  type(regridding_cs), intent(inout) :: cs
1869 
1870  if (size(dz)/=cs%nk) call mom_error( fatal, &
1871  'setCoordinateResolution: inconsistent number of levels' )
1872 
1873  cs%coordinateResolution(:) = dz(:)
1874 
Here is the caller graph for this function:

◆ uniformresolution()

real function, dimension(nk), public mom_regridding::uniformresolution ( integer, intent(in)  nk,
character(len=*), intent(in)  coordMode,
real, intent(in)  maxDepth,
real, intent(in)  rhoLight,
real, intent(in)  rhoHeavy 
)

Definition at line 1808 of file MOM_regridding.F90.

Referenced by initialize_regridding().

1808 !------------------------------------------------------------------------------
1809 ! Calculate a vector of uniform resolution in the units of the coordinate
1810 !------------------------------------------------------------------------------
1811  ! Arguments
1812  integer, intent(in) :: nk
1813  character(len=*), intent(in) :: coordmode
1814  real, intent(in) :: maxdepth, rholight, rhoheavy
1815  real :: uniformresolution(nk)
1816 
1817  ! Local variables
1818  integer :: scheme
1819 
1820  scheme = coordinatemode(coordmode)
1821  select case ( scheme )
1822 
1823  case ( regridding_zstar, regridding_hycom1, regridding_slight, regridding_sigma_shelf_zstar, &
1824  regridding_adaptive )
1825  uniformresolution(:) = maxdepth / real(nk)
1826 
1827  case ( regridding_rho )
1828  uniformresolution(:) = (rhoheavy - rholight) / real(nk)
1829 
1830  case ( regridding_sigma )
1831  uniformresolution(:) = 1. / real(nk)
1832 
1833  case default
1834  call mom_error(fatal, "MOM_regridding, uniformResolution: "//&
1835  "Unrecognized choice for coordinate mode ("//trim(coordmode)//").")
1836 
1837  end select ! type of grid
1838 
Here is the caller graph for this function:

Variable Documentation

◆ regriddingcoordinatemodedoc

character(len=*), parameter, public mom_regridding::regriddingcoordinatemodedoc = " LAYER - Isopycnal or stacked shallow water layers\n"// " ZSTAR, Z* - stetched geopotential z*\n"// " SIGMA_SHELF_ZSTAR - stetched geopotential z* ignoring shelf\n"// " SIGMA - terrain following coordinates\n"// " RHO - continuous isopycnal\n"// " HYCOM1 - HyCOM-like hybrid coordinate\n"// " SLIGHT - stretched coordinates above continuous isopycnal\n"// " ADAPTIVE - optimize for smooth neutral density surfaces"

Documentation for coordinate options.

Definition at line 132 of file MOM_regridding.F90.

132 character(len=*), parameter, public :: regriddingCoordinateModeDoc = &
133  " LAYER - Isopycnal or stacked shallow water layers\n"//&
134  " ZSTAR, Z* - stetched geopotential z*\n"//&
135  " SIGMA_SHELF_ZSTAR - stetched geopotential z* ignoring shelf\n"//&
136  " SIGMA - terrain following coordinates\n"//&
137  " RHO - continuous isopycnal\n"//&
138  " HYCOM1 - HyCOM-like hybrid coordinate\n"//&
139  " SLIGHT - stretched coordinates above continuous isopycnal\n"//&
140  " ADAPTIVE - optimize for smooth neutral density surfaces"

◆ regriddingdefaultboundaryextrapolation

logical, parameter, public mom_regridding::regriddingdefaultboundaryextrapolation = .false.

Definition at line 155 of file MOM_regridding.F90.

Referenced by initialize_regridding().

155 logical, parameter, public :: regriddingdefaultboundaryextrapolation = .false.

◆ regriddingdefaultinterpscheme

character(len=*), parameter, public mom_regridding::regriddingdefaultinterpscheme = "P1M_H2"

Definition at line 154 of file MOM_regridding.F90.

Referenced by initialize_regridding().

154 character(len=*), parameter, public :: regriddingDefaultInterpScheme = "P1M_H2"

◆ regriddingdefaultminthickness

real, parameter, public mom_regridding::regriddingdefaultminthickness = 1.e-3

Definition at line 156 of file MOM_regridding.F90.

Referenced by initialize_regridding().

156 real, parameter, public :: regriddingdefaultminthickness = 1.e-3

◆ regriddinginterpschemedoc

character(len=*), parameter, public mom_regridding::regriddinginterpschemedoc = " P1M_H2 (2nd-order accurate)\n"// " P1M_H4 (2nd-order accurate)\n"// " P1M_IH4 (2nd-order accurate)\n"// " PLM (2nd-order accurate)\n"// " PPM_H4 (3rd-order accurate)\n"// " PPM_IH4 (3rd-order accurate)\n"// " P3M_IH4IH3 (4th-order accurate)\n"// " P3M_IH6IH5 (4th-order accurate)\n"// " PQM_IH4IH3 (4th-order accurate)\n"// " PQM_IH6IH5 (5th-order accurate)"

Definition at line 143 of file MOM_regridding.F90.

Referenced by initialize_regridding().

143 character(len=*), parameter, public :: regriddingInterpSchemeDoc = &
144  " P1M_H2 (2nd-order accurate)\n"//&
145  " P1M_H4 (2nd-order accurate)\n"//&
146  " P1M_IH4 (2nd-order accurate)\n"//&
147  " PLM (2nd-order accurate)\n"//&
148  " PPM_H4 (3rd-order accurate)\n"//&
149  " PPM_IH4 (3rd-order accurate)\n"//&
150  " P3M_IH4IH3 (4th-order accurate)\n"//&
151  " P3M_IH6IH5 (4th-order accurate)\n"//&
152  " PQM_IH4IH3 (4th-order accurate)\n"//&
153  " PQM_IH6IH5 (5th-order accurate)"