# Motivation

```Ghost cells``` are layers of cells at boundaries of pieces of a
dataset. These cells are used by data parallel algorithms, to insure
the correctness of their results. For instance, consider an algorithm
that computes the external faces of a dataset. Consider also that the
algorithm runs in parallel on several nodes, each node processing a
piece of the original dataset. This operation would produce incorrect
faces at boundaries of pieces. Ghosts cells can prevent this. See the
following [wiki entry](http://www.vtk.org/Wiki/VTK/Parallel_Pipeline)
for a more detailed description of ghost cells.

```Blanking cells``` are used to specify that certain pieces of a grid
are not part of the data. For instance, a regular dataset with a hole
in it could be specified by blanking the cells that cover the
hole. Blanking cells are supported for ```vtkStructuredGrid``` and
```vtkUniformGrid```.

We change how ghost and blanked cells are stored to:

  1. better support blanking: in the past blanked cells were stored as
     members of ```vtkStructuredGrid``` and ```vtkUniformGrid```. This
     created the need for special processing when these arrays needed
     to be passed between algorithms or processes. Now, blanked cells
     are marked with a bit in a field array. Field arrays are passed
     automatically between algorithms and processes

  2. provide binary compatibility with VisIt: VTK now uses the
     [same bits as VisIt](http://www.visitusers.org/index.php?title=Representing_ghost_data)
     to mark ghost cells and blanked cells

  3. save space: the arrays for storing blanking are not needed anymore

Note that ghosts and blanking exists for both cells and points. Simply
replace cell with point to get the corresponding description for point
ghosts and blanking.

# Changes overview

To achieve our goals we made the following changes:

  1. Previously, ghost cells were marked in a ```unsigned char```
     attribute array called "```vtkGhostLevels```". For each cell, the
     ghost level was stored at the corresponding cell id. Now, there
     is no distinction between ghost levels. Cells at any ghost level,
     are marked by setting ```vtkDataSetAttributes::DUPLICATECELL```
     bit at the corresponding cell id, in the ```unsigned char```
     attribute array called
     ```vtkDataSetAttributes::GhostArrayName()```
     ("```vtkGhostType```").

  2. Previously, filters striped all ghost cells they requested from
     upstream before finalizing the output. This is no longer
     done. The user can remove all ghost cells at the end of pipeline
     processing, if needed. Note that ghost cells are not shown in the
     render window, and only consume a small amount of memory compared
     with the whole dataset which means that removing them is often
     not necessary.

  3. ```vtkUniformGrid``` and ```vtkStructuredGrid``` previously
     supported blanking through member arrays ```CellVisibility``` and
     ```PointVisibility```. These arrays are removed and the blanking
     functionality is supported by setting
     ```vtkDataSetAttributes::HIDDENCELL``` bit at the corresponding
     cell id in the "```vtkGhostType```" attribute array.

  4. We increase file version for VTK Legacy files (see VTK/IO/Legacy)
     to 4.0 (from 3.0). We increase file version for VTK XML files
     (see VTK/IO/XML) to 2.0 (from 0.1 for files using UInt32 header
     type and from 1.0 for files using UInt64 header type). We
     increase these versions because ghost cells are now stored in a
     file using the new ```vtkGhostType``` format described in the
     previous section.  New readers reading old files convert a
     ```vtkGhostLevels``` attribute array to a ```vtkGhostType```
     array. This preserves ghost cells written using old readers.

# Bits used in the ghost type array

We use the following bits to store information about each cell in the
dataset. These bits are
[compatible](http://www.visitusers.org/index.php?title=Representing_ghost_data)
with Visit.

```vtkDataSetAttribute::DUPLICATECELL``` specifies that this cell is
present on multiple processors. This is a ghost cell. This cell is not
rendered. It is present only to help obtain correct results when
processing only a subset of the original data. Attributes associated
with these cells are valid, so they can be used in certain statistical
operations such as min/max. Ghost cells should not be used in
operations such as average because this would result counting the same
cell several times. A similar description applies to
```vtkDataSetAttribute::DUPLICATEPOINT```

```vtkDataSetAttribute::REFINEDCELL``` specifies that other cells are
present that refine this cell. Because the coarser grid is often a
structured grid, it is difficult to remove cells that are further
refined. Instead, this bit is used to mark this kind of cells. Values
associated with this cell may be used in interpolation. Note that
there is no vtkDataSetAttribute::REFINEDPOINT.

```vtkDataSetAttribute::HIDDENCELL``` specifies that this cell is not
part of the model, it is only used to maintain the connectivity of the
grid. This is a blank cell. It is not rendered and any values
associated with it are ignored. A similar description applies to
```vtkDataSetAttribute::HIDDENPOINT```

Other bits specified by VisIt are not used in VTK.

# API Changes

To test if a cell is a ghost cell, previously, we used
```grid->GetCellData()->GetArray("vtkGhostLevels")->GetValue(cellId) >
0```. This is because we stored ghost levels in the ghost array. Now
we use ```grid->GetCellGhostArray()->GetValue(cellId) &
vtkDataSetAttributes::DUPLICATECELL```.

To specify that a cell is a ghost cell, instead of
```grid->GetCellData()->GetArray("vtkGhostLevels")->SetValue(cellId,
ghostLevel)```, use: ``` vtkUnsignedCharArray* ghosts =
grid->GetCellGhostArray(); ghosts->SetValue(cellId,
ghosts->GetValue(cellId) | vtkDataSetAttributes::DUPLICATECELL); ```
Note that we use a 'or' operation to preserve other bits that might be
set for the cell.

To create a new ghost array, instead of
```vtkDataSetAttributes::GenerateGhostLevelArray```, use
```vtkDataSetAttributes::GenerateGhostArray```. We changed the name
because there are no ghost levels in the new ghost array.

To test if there are any ghost cells, instead of
```grid->GetCellData()->GetArray("vtkGhostLevels") != NULL```, use
```grid->HasAnyGhostCells()```. Make similar changes to test if there
are any blank cells. We made this change because previously a non-NULL
ghost array meant that there are ghost cells, now this means that
there are blank cells or ghost cells.

To get a pointer to the ghost array, instead of
```grid->GetCellData()->GetArray("vtkGhostLevels")```, use
```grid->GetCellGhostArray()```. This new function avoids O(N) string
comparisons by caching the ghost array pointer.

We remove a ghostLevel parameter from
```vtkPolyData::RemoveGhostCells```,
```vtkUnstructuredGrid::RemoveGhostCells```,
```vtkGlyph3D::Execute```,
```vtkDataSetSurfaceFilter::UnstructuredGridExecute```. This is
because we no longer remove ghost levels requested by a filter after
the filter finishes executing.

We remove ```GetCellVisibilityArray``` from ```vtkStructuredGrid```
and ```vtkUniformGrid```. Use ```GetCellGhostArray``` instead and use
```vtkDataSetAttributes::HIDDENCELL``` bit to set or test if a cell is
blanked.

We add an extra parameter to ```vtkDataReader::ReadFieldData```,
```vtkXMLDataReader::ReadArrayValues```,
```vtkXMLStructuredDataReader::ReadSubExtent``` which specifies if we
read cell or point data. This is needed so that we can use the proper
bits when converting ghost levels.

We remove ```vtkStructuredGridWriter:::WriteBlanking``` as blanking is
now written when saving the ```vtkGhostType``` array.
