import xarray
import numpy
[docs]def alter_bottom_depth(config, bottomDepth, refBottomDepth, maxLevelCell):
"""
Alter ``bottomDepth`` and ``maxLevelCell`` for full or partial top cells,
if requested
Parameters
----------
config : compass.config.CompassConfigParser
Configuration options with parameters used to construct the vertical
grid
bottomDepth : xarray.DataArray
The positive-down depth of the seafloor
refBottomDepth : xarray.DataArray
A 1D array of positive-down depths of the bottom of each z level
maxLevelCell : xarray.DataArray
The zero-based index of the bottom valid level
Returns
-------
bottomDepth : xarray.DataArray
The positive-down depth of the seafloor, after alteration
maxLevelCell : xarray.DataArray
The zero-based index of the bottom valid level, after alteration
"""
section = config['vertical_grid']
partial_cell_type = 'none'
min_pc_fraction = 0.
if config.has_option('vertical_grid', 'partial_cell_type'):
partial_cell_type = section.get('partial_cell_type').lower()
min_pc_fraction = section.getfloat('min_pc_fraction')
if partial_cell_type == 'full':
bottomDepth = _compute_full_cells_depth(
refBottomDepth, maxLevelCell)
elif partial_cell_type == 'partial':
bottomDepth, maxLevelCell = _alter_bottom_depth_for_partial_cells(
bottomDepth, refBottomDepth, maxLevelCell, min_pc_fraction)
elif partial_cell_type != 'none':
raise ValueError('Unexpected partial cell type {}'.format(
partial_cell_type))
return bottomDepth, maxLevelCell
[docs]def alter_ssh(config, ssh, refBottomDepth, minLevelCell):
"""
Alter ``ssh`` and ``maxLevelCell`` for full or partial top cells,
if requested
Parameters
----------
config : compass.config.CompassConfigParser
Configuration options with parameters used to construct the vertical
grid
ssh : xarray.DataArray
The sea surface height
refBottomDepth : xarray.DataArray
A 1D array of positive-down depths of the bottom of each z level
minLevelCell : xarray.DataArray
The zero-based index of the top valid level
Returns
-------
ssh : xarray.DataArray
The sea surface height, after alteration
minLevelCell : xarray.DataArray
The zero-based index of the top valid level, after alteration
"""
section = config['vertical_grid']
partial_cell_type = 'none'
min_pc_fraction = 0.
if config.has_option('vertical_grid', 'partial_cell_type'):
partial_cell_type = section.get('partial_cell_type').lower()
min_pc_fraction = section.getfloat('min_pc_fraction')
if partial_cell_type == 'full':
ssh = _compute_full_cells_depth(
refBottomDepth, minLevelCell-1)
elif partial_cell_type == 'partial':
ssh, minLevelCell = _alter_ssh_for_partial_cells(
ssh, refBottomDepth, minLevelCell, min_pc_fraction)
elif partial_cell_type != 'none':
raise ValueError('Unexpected partial cell type {}'.format(
partial_cell_type))
return ssh, minLevelCell
def _compute_full_cells_depth(refBottomDepth, levelIndex):
"""
Compute the full cell bottom depth given a level index
"""
depth = refBottomDepth.isel(nVertLevels=levelIndex).where(
levelIndex >= 0, other=0.)
return depth
def _alter_bottom_depth_for_partial_cells(bottomDepth, refBottomDepth,
maxLevelCell, min_pc_fraction):
"""
Alter bottomDepth and maxLevelCell for partial cells
"""
fullBot = _compute_full_cells_depth(refBottomDepth, maxLevelCell)
fullTop = _compute_full_cells_depth(refBottomDepth, maxLevelCell-1)
fullThickness = fullBot - fullTop
minBottomDepth = fullBot - (1. - min_pc_fraction)*fullThickness
minBottomDepthMid = 0.5*(minBottomDepth + fullTop)
# where the bottom depth is far too shallow, we're going to fill in the
# last level
mask = bottomDepth < minBottomDepthMid
maxLevelCell = xarray.where(mask, maxLevelCell-1, maxLevelCell)
bottomDepth = xarray.where(mask, fullTop, bottomDepth)
# where the bottom depth only a bit too shallows, we move it deeper
mask = numpy.logical_and(numpy.logical_not(mask),
bottomDepth < minBottomDepth)
bottomDepth = xarray.where(mask, minBottomDepth, bottomDepth)
return bottomDepth, maxLevelCell
def _alter_ssh_for_partial_cells(ssh, refBottomDepth, minLevelCell,
min_pc_fraction):
"""
Alter ssh and minLevelCell for partial cells
"""
zBot = -_compute_full_cells_depth(refBottomDepth, minLevelCell)
zTop = -_compute_full_cells_depth(refBottomDepth, minLevelCell-1)
fullThickness = zTop - zBot
minSSH = zBot + min_pc_fraction * fullThickness
minSSHMid = 0.5 * (minSSH + zBot)
# where the SSH is far too deep, we're going to fill the current top level
mask = ssh < minSSHMid
minLevelCell = xarray.where(mask, minLevelCell + 1, minLevelCell)
ssh = xarray.where(mask, zBot, ssh)
# where the SSH only a bit too deep, we move it shallower
mask = numpy.logical_and(numpy.logical_not(mask), ssh < minSSH)
ssh = xarray.where(mask, minSSH, ssh)
return ssh, minLevelCell