Source code for compass.ocean.vertical.partial_cells

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