==============================
Data Sets
==============================

.. index:: data set

A *data set*, implemented with the :class:`vtkm::cont::DataSet` class,
contains and manages the geometric data structures that |VTKm| operates on.

.. index::
   single: cell set
   single: field
   single: coordinate system

.. doxygenclass:: vtkm::cont::DataSet

In addition to the base :class:`vtkm::cont::DataSet`, |VTKm| provides :class:`vtkm::cont::PartitionedDataSet` to represent data partitioned into multiple domains.
A :class:`vtkm::cont::PartitionedDataSet` is implemented as a collection of :class:`vtkm::cont::DataSet` objects.
Partitioned data sets are described later in :secref:`dataset:Partitioned Data Sets`.


------------------------------
Building Data Sets
------------------------------

.. index:: data set ; building

Before we go into detail on the cell sets, fields, and coordinate systems that make up a data set in |VTKm|, let us first discuss how to build a data set.
One simple way to build a data set is to load data from a file using the `vtkm::io` module.
Reading files is discussed in detail in :chapref:`io:File I/O`.

This section describes building data sets of different types using a set of
classes named `DataSetBuilder*`, which provide a convenience layer
on top of :class:`vtkm::cont::DataSet` to make it easier to create data sets.

.. didyouknow::
  To simplify the introduction of :class:`vtkm::cont::DataSet` objects, this section uses the simplest mechanisms.
  In many cases this involves loading data in a `std::vector` and passing that to |VTKm|, which usually causes the data to be copied.
  This is not the most efficient method to load data into |VTKm|.
  Although it is sufficient for small data or data that come from a "slow" source, such as a file, it might be a bottleneck for large data generated by another library.
  It is possible to adapt |VTKm|'s :class:`vtkm::cont::DataSet` to externally defined data.
  This is done by wrapping existing data into what is called `ArrayHandle`, but this is a more advanced topic that will not be addressed in this chapter.
  `ArrayHandle` objects are introduced in :chapref:`basic-array-handles:Basic Array Handles` and more adaptive techniques are described in later chapters.

Creating Uniform Grids
==============================

.. index::
   single: uniform grid
   single: regular grid
   single: image

Uniform grids are meshes that have a regular array structure with points uniformly spaced parallel to the axes.
Uniform grids are also sometimes called regular grids or images.

The :class:`vtkm::cont::DataSetBuilderUniform` class can be used to easily create 2- or 3-dimensional uniform grids.
:class:`vtkm::cont::DataSetBuilderUniform` has several versions of a method named :func:`vtkm::cont::DataSetBuilderUniform::Create` that takes the number of points in each dimension, the origin, and the spacing.
The origin is the location of the first point of the data (in the lower left corner), and the spacing is the distance between points in the x, y, and z directions.

.. doxygenclass:: vtkm::cont::DataSetBuilderUniform
   :members:

The following example creates a :class:`vtkm::cont::DataSet` containing a uniform grid of :math:`101 \times 101 \times 26` points.

.. load-example:: CreateUniformGrid
   :file: GuideExampleDataSetCreation.cxx
   :caption: Creating a uniform grid.}{.cxx}

If not specified, the origin will be at the coordinates :math:`(0,0,0)` and the spacing will be :math:`1` in each direction.
Thus, in the previous example the width, height, and depth of the mesh in physical space will be :math:`100`, :math:`100`, and :math`25`, respectively, and the mesh will be centered at :math:`(50, 50, 12.5)`.
Let us say we actually want a mesh of the same dimensions, but we want the :math:`z` direction to be stretched out so that the mesh will be the same size in each direction, and we want the mesh centered at the origin.

.. load-example:: CreateUniformGridCustomOriginSpacing
   :file: GuideExampleDataSetCreation.cxx
   :caption: Creating a uniform grid with custom origin and spacing.

Creating Rectilinear Grids
==============================

.. index:: rectilinear grid

A rectilinear grid is similar to a uniform grid except that a rectilinear grid can adjust the spacing between adjacent grid points.
This allows the rectilinear grid to have tighter sampling in some areas of space, but the points are still constrained to be aligned with the axes and each other.
The irregular spacing of a rectilinear grid is specified by providing a separate array each for the x, y, and z coordinates.

The :class:`vtkm::cont::DataSetBuilderRectilinear` class can be used to easily create
2- or 3-dimensional rectilinear grids.
:class:`vtkm::cont::DataSetBuilderRectilinear` has several versions of a method
named :func:`vtkm::cont::DataSetBuilderRectilinear::Create` that takes these coordinate arrays and builds a
:class:`vtkm::cont::DataSet` out of them. The arrays can be supplied as either
standard C arrays or as `std::vector` objects, in which case the
data in the arrays are copied into the :class:`vtkm::cont::DataSet`. These
arrays can also be passed as :class:`vtkm::cont::ArrayHandle` objects (introduced later in this book), in which
case the data are shallow copied.

.. doxygenclass:: vtkm::cont::DataSetBuilderRectilinear
   :members:

The following example creates a :class:`vtkm::cont::DataSet` containing a rectilinear
grid with :math:`201 \times 201 \times 101` points with different irregular
spacing along each axis.


.. load-example:: CreateRectilinearGrid
   :file: GuideExampleDataSetCreation.cxx
   :caption: Creating a rectilinear grid.

Creating Explicit Meshes
==============================

.. index::
   single: explicit mesh
   single: unstructured grid

An explicit mesh is an arbitrary collection of cells with arbitrary connections.
It can have multiple different types of cells.
Explicit meshes are also known as unstructured grids.
Explicit meshes can contain cells of different shapes.
The shapes that |VTKm| currently supports are listed in :numref:`fig:CreateExplicitMeshesCellShapes`.
Each shape is identified using either a numeric identifier, provided by |VTKm| with identifiers of the form ``vtkm::CELL_SHAPE_*`` or special tag structures of the form ``vtkm::CellSetTag*``.
Cell shapes are discussed in detail in :chapref:`working-with-cells:Working with Cells`.

.. figure:: images/CellConnections.png
   :width: 100%
   :name: fig:CreateExplicitMeshesCellShapes

   Basic Cell Shapes.

.. todo:: Add ``vtkm::CellShapeTagPolyLine`` to this figure.

..
   .. |CellConnectionsVertex| image:: images/CellConnectionsVertex.png
   .. |CellConnectionsLine| image:: images/CellConnectionsLine.png
   .. |CellConnectionsPolyLine| image:: images/CellConnectionsPolyLine.png
   .. |CellConnectionsTriangle| image:: images/CellConnectionsTriangle.png
   .. |CellConnectionsPolygon| image:: images/CellConnectionsPolygon.png
   .. |CellConnectionsQuadrilateral| image:: images/CellConnectionsQuadrilateral.png
   .. |CellConnectionsTetrahedron| image:: images/CellConnectionsTetrahedron.png
   .. |CellConnectionsHexahedron| image:: images/CellConnectionsHexahedron.png
   .. |CellConnectionsWedge| image:: images/CellConnectionsWedge.png
   .. |CellConnectionsPyramid| image:: images/CellConnectionsPyramid.png

   .. table:: Basic Cell Shapes
      :name: ExplicitCellShapes
      :width: 100%

      +----------------------------------------------+----------------------------------------------+----------------------------------------------+
      | :enumerator:`vtkm::CELL_SHAPE_VERTEX`        | :enumerator:`vtkm::CELL_SHAPE_Line`          | :enumerator:`vtkm::CELL_SHAPE_POLY_LINE`     |
      | :struct:`vtkm::CellShapeTagVertex`           | :struct:`vtkm::CellShapeTagLine`             | :struct:`vtkm::CellShapeTagPolyLine`         |
      | |CellConnectionsVertex|                      | |CellConnectionsLine|                        | |CellConnectionsPolyLine|                    |
      +----------------------------------------------+----------------------------------------------+----------------------------------------------+
      | :enumerator:`vtkm::CELL_SHAPE_TRIANGLE`      | :enumerator:`vtkm::CELL_SHAPE_POLYGON`       | :enumerator:`vtkm::CELL_SHAPE_QUADRILATERAL` |
      | :struct:`vtkm::CellShapeTagTriangle`         | :struct:`vtkm::CellShapeTagPolygon`          | :struct:`vtkm::CellShapeTagQuadrilateral`    |
      | |CellConnectionsTriangle|                    | |CellConnectionsPolygon|                     | |CellConnectionsQuadrilateral|               |
      +----------------------------------------------+----------------------------------------------+----------------------------------------------+
      | :enumerator:`vtkm::CELL_SHAPE_TETRAHEDRON`   | :enumerator:`vtkm::CELL_SHAPE_HEXAHEDRON`    | :enumerator:`vtkm::CELL_SHAPE_WEDGE`         |
      | :struct:`vtkm::CellShapeTagTetrahedron`      | :struct:`vtkm::CellShapeTagHexahedron`       | :struct:`vtkm::CellShapeTagWedge`            |
      | |CellConnectionsTetrahedron|                 | |CellConnectionsHexahedron|                  | |CellConnectionsWedge|                       |
      +----------------------------------------------+----------------------------------------------+----------------------------------------------+
      |                                              | :enumerator:`vtkm::CELL_SHAPE_PYRAMID`       |                                              |
      |                                              | :struct:`vtkm::CellShapeTagPyramid`          |                                              |
      |                                              | |CellConnectionsPyramid|                     |                                              |
      +----------------------------------------------+----------------------------------------------+----------------------------------------------+

.. figure:: images/ExplicitCellConnections.png
   :width: 100%
   :name: fig:ExplicitMesh

   An example explicit mesh.

The cells of an explicit mesh are defined with the following 3 arrays, which are depicted graphically in :numref:`fig:ExplicitMesh`.

.. index:: explicit mesh ; shapes

Shapes
  An array of ids identifying the shape of the cell.
  Each value is a :type:`vtkm::UInt8` and should be set to one of the ``vtkm::CELL_SHAPE_*`` constants.
  The shapes and their identifiers are shown in :numref:`fig:CreateExplicitMeshesCellShapes`.
  The size of this array is equal to the number of cells in the set.

.. index:: explicit mesh ; connectivity

Connectivity
  An array that lists all the points that comprise each cell.
  Each entry in the array is a :type:`vtkm::Id` giving the point id associated with a vertex of a cell.
  The points for each cell are given in a prescribed order for each shape, which is also shown in :numref:`fig:CreateExplicitMeshesCellShapes`.
  The point indices are stored consecutively from the first cell to the last.

.. index:: explicit mesh ; offsets

Offsets
  An array of :type:`vtkm::Id`'s pointing to the index in the connectivity array where the points for a particular cell starts.
  The size of this array is equal to the number of cells in the set plus 1.
  The first entry is expected to be 0 (since the connectivity of the first cell is at the start of the connectivity array).
  The last entry, which does not correspond to any cell, should be the size of the connectivity array.

One important item that is missing from this list of arrays is a count of the number of indices associated with each cell.
This is not explicitly represented in |VTKm|'s mesh structure because it can be implicitly derived from the offsets array by subtracting consecutive entries.
However, it is usually the case when building an explicit mesh that you will have an array of these counts rather than the offsets.
It is for this reason that |VTKm| contains mechanisms to build an explicit data set with a "num indices" arrays rather than an offsets array.

The :class:`vtkm::cont::DataSetBuilderExplicit` class can be used to create data sets with explicit meshes.
:class:`vtkm::cont::DataSetBuilderExplicit` has several versions of a method named :func:`vtkm::cont::DataSetBuilderExplicit::Create`.
Generally, these methods take the shapes, number of indices, and connectivity arrays as well as an array of point coordinates.

.. doxygenclass:: vtkm::cont::DataSetBuilderExplicit
   :members:

The following example creates a mesh like the one shown in
:numref:`fig:ExplicitMesh`.

.. load-example:: CreateExplicitGrid
   :file: GuideExampleDataSetCreation.cxx
   :caption: Creating an explicit mesh with :class:`vtkm::cont::DataSetBuilderExplicit`.

Often it is awkward to build your own arrays and then pass them to :class:`vtkm::cont::DataSetBuilderExplicit`.
There also exists an alternate builder class named :class:`vtkm::cont::DataSetBuilderExplicitIterative` that allows you to specify each cell and point one at a time rather than all at once.
This is done by calling one of the versions of :func:`vtkm::cont::DataSetBuilderExplicitIterative::AddPoint` and one of the versions of :func:`vtkm::cont::DataSetBuilderExplicitIterative::AddCell` for each point and cell, respectively.

.. doxygenclass:: vtkm::cont::DataSetBuilderExplicitIterative
   :members:

The next example also builds the mesh shown in :numref:`fig:ExplicitMesh` except this time using :class:`vtkm::cont::DataSetBuilderExplicitIterative`.

.. load-example:: CreateExplicitGridIterative
   :file: GuideExampleDataSetCreation.cxx
   :caption: Creating an explicit mesh with :class:`vtkm::cont::DataSetBuilderExplicitIterative`.

Add Fields
==============================

In addition to creating the geometric structure of a data set, it is usually important to add fields to the data.
Fields describe numerical data associated with the topological elements in a cell.
They often represent a physical quantity (such as temperature, mass, or volume fraction) but can also represent other information (such as indices or classifications).

The easiest way to define fields in a data set is to use the :func:`vtkm::cont::DataSet::AddPointField` and :func:`vtkm::cont::DataSet::AddCellField` methods.
Each of these methods take a requisite field name and the array with with field data.

Both :func:`vtkm::cont::DataSet::AddPointField` and :func:`vtkm::cont::DataSet::AddCellField` are overloaded to accept arrays of data in different structures.
Field arrays can be passed as standard C arrays or as ``std::vector``'s, in which case the data are copied.
Field arrays can also be passed in a ``ArrayHandle`` (introduced later in this book), in which case the data are not copied.

.. doxygenfunction:: vtkm::cont::DataSet::AddPointField(const std::string&, const vtkm::cont::UnknownArrayHandle&)

.. doxygenfunction:: vtkm::cont::DataSet::AddPointField(const std::string&, const std::vector<T>&)

.. doxygenfunction:: vtkm::cont::DataSet::AddPointField(const std::string&, const T*, const vtkm::Id&)

.. doxygenfunction:: vtkm::cont::DataSet::AddCellField(const std::string&, const vtkm::cont::UnknownArrayHandle&)

.. doxygenfunction:: vtkm::cont::DataSet::AddCellField(const std::string&, const std::vector<T>&)

.. doxygenfunction:: vtkm::cont::DataSet::AddCellField(const std::string&, const T*, const vtkm::Id&)

The following (somewhat contrived) example defines fields for a uniform grid that identify which points and cells are on the boundary of the mesh.

.. load-example:: AddFieldData
   :file: GuideExampleDataSetCreation.cxx
   :caption: Adding fields to a :class:`vtkm::cont::DataSet`.


------------------------------
Cell Sets
------------------------------

.. index:: cell set
.. index:: data set ; cell set

.. index::
   triple: cell; shape; point
   triple: cell; shape; edge
   triple: cell; shape; face

A cell set determines the topological structure of the data in a data set.

.. doxygenclass:: vtkm::cont::CellSet
   :members:

3D cells are made up of *points*, *edges*, and *faces*.
(2D cells have only points and edges, and 1D cells have only points.)
:numref:`fig:CellTopology` shows the relationship between a cell's shape and these topological elements.
The arrangement of these points, edges, and faces is defined by the *shape* of the cell, which prescribes a specific ordering of each.
The basic cell shapes provided by |VTKm| are discussed in detail in :chapref:`working-with-cells:Working with Cells`.

.. todo:: Add cell shape reference above.

.. figure:: images/CellConstituents.png
   :width: 50%
   :name: fig:CellTopology

   The relationship between a cell shape and its topological elements (points, edges, and faces).

There are multiple ways to express the connections of a cell set, each with
different benefits and restrictions. These different cell set types are
managed by different cell set classes in |VTKm|. All |VTKm| cell set classes
inherit from :class:`vtkm::cont::CellSet`. The two basic types of cell sets are
structured and explicit, and there are several variations of these types.

Structured Cell Sets
==============================

.. index::
   single: cell set; structured
   single: structured cell set

.. doxygenclass:: vtkm::cont::CellSetStructured
   :members:

The number of points in a :class:`vtkm::cont::CellSetStructured` is implicitly :math:`i \times j \times k` and the number of cells is implicitly :math:`(i-1) \times (j-1) \times (k-1)` (for 3D grids).
:numref:`fig:CellSetStructured` demonstrates this arrangement.

.. figure:: images/StructuredCellSet.png
   :width: 100%
   :name: fig:CellSetStructured

   The arrangement of points and cells in a 3D structured grid.

The big advantage of using :class:`vtkm::cont::CellSetStructured` to define a cell set is that it is very space efficient because the entire topology can be defined by the three integers specifying the dimensions.
Also, algorithms can be optimized for :class:`vtkm::cont::CellSetStructured`'s regular nature.
However, :class:`vtkm::cont::CellSetStructured`'s strictly regular grid also limits its applicability.
A structured cell set can only be a dense grid of lines, quadrilaterals, or hexahedra.
It cannot represent irregular data well.

Many data models in other software packages, such as the one for VTK, make a distinction between uniform, rectilinear, and curvilinear grids.
|VTKm|'s cell sets do not.
All three of these grid types are represented by :class:`vtkm::cont::CellSetStructured`.
This is because in a |VTKm| data set the cell set and the coordinate system are defined independently and used interchangeably.
A structured cell set with uniform point coordinates makes a uniform grid.
A structured cell set with point coordinates defined irregularly along coordinate axes makes a rectilinear grid.
And a structured cell set with arbitrary point coordinates makes a curvilinear grid.
The point coordinates are defined by the data set's coordinate system, which is discussed in :secref:`dataset:Coordinate Systems`.

Explicit Cell Sets
==============================

.. index::
   single: cell set; explicit
   single: explicit cell set

.. doxygenclass:: vtkm::cont::CellSetExplicit
   :members:

The types of cell sets are listed in :numref:`fig:ExplicitCellSetShapes`.


.. figure:: images/CellConnections.png
   :width: 100%
   :name: fig:ExplicitCellSetShapes

   Basic Cell Shapes in a :class:`vtkm::cont::CellSetExplicit`.

An explicit cell set is defined with a minimum of three arrays.
The first array identifies the shape of each cell.
(Identifiers for cell shapes are shown in :numref:`fig:ExplicitCellSetShapes`.)
The second array has a sequence of point indices that make up each cell.
The third array identifies an offset into the second array where the point indices for each cell is found plus an extra entry at the end set to the size of the second array.
:numref:`fig:CellSetExplicit` shows a simple example of an explicit cell set.

.. figure:: images/ExplicitCellConnections.png
   :width: 100%
   :name: fig:CellSetExplicit

   Example of cells in a :class:`vtkm::cont::CellSetExplicit` and the arrays that define them.

An explicit cell set can also identify the number of indices defined for each cell by subtracting consecutive entries in the offsets array.
It is often the case when creating a :class:`vtkm::cont::CellSetExplicit` that you have an array containing the number of indices rather than the offsets.
Such an array can be converted to an offsets array that can be used with :class:`vtkm::cont::CellSetExplicit` by using the :func:`vtkm::cont::ConvertNumComponentsToOffsets` convenience function.
See the documentation for :class:`vtkm::cont::ArrayHandleGroupVecVariable` in :secref:`fancy-array-handles:Grouped Vector Arrays` for examples of using :func:`vtkm::cont::ConvertNumComponentsToOffsets`.

:class:`vtkm::cont::CellSetExplicit` is a powerful representation for a cell set
because it can represent an arbitrary collection of cells. However, because
all connections must be explicitly defined,
:class:`vtkm::cont::CellSetExplicit` requires a significant amount of memory to
represent the topology.

.. index::
   single: cell set; single type
   single: explicit cell set; single type
   single: single type cell set

An important specialization of an explicit cell set is
:class:`vtkm::cont::CellSetSingleType`.

.. doxygenclass:: vtkm::cont::CellSetSingleType
   :members:

Cell Set Permutations
==============================

.. index::
   single: cell set; permutation
   single: permutation cell set

To rearrange, and possibly subsample, cells in a ``CellSet``, use :type:`vtkm::cont::CellSetPermutation` to define a new set without copying.

.. doxygenclass:: vtkm::cont::CellSetPermutation
   :members:

.. didyouknow::
   Although :class:`vtkm::cont::CellSetPermutation` can mask cells, it cannot mask points.
   All points from the original cell set are available in the permuted cell set regardless of whether they are used.

The following example uses :class:`vtkm::cont::CellSetPermutation` with a counting array to expose every tenth cell.
This provides a simple way to subsample a data set.

.. load-example:: CreateCellSetPermutation
   :file: GuideExampleDataSetCreation.cxx
   :caption: Subsampling a data set with :class:`vtkm::cont::CellSetPermutation`.

Cell Set Extrude
==============================

.. doxygenclass:: vtkm::cont::CellSetExtrude
   :members:

.. figure:: images/ExtrudedCellSet.png
   :width: 100%
   :name: fig:CellSetExtruded

   An example of an extruded wedge from XZ-plane coordinates.
   Six wedges are extracted from three XZ-plane points.

The extruded mesh is advantageous because it is represented on-the-fly as required, so no additional memory is required.
In contrast other forms of cell sets, such as :class:`vtkm::cont::CellSetExplicit`, need to be explicitly constructed by replicating the vertices and cells.
:numref:`fig:CellSetExtruded` shows an example of six wedges extruded from three 2-dimensional coordinates.

Unknown Cell Sets
==============================

Each of the aforementioned cell set types are represented by a different class.
A :class:`vtkm::cont::DataSet` object must hold one of these cell set objects that represent the cell structure.
The actual object used is not determined until run time.

The :class:`vtkm::cont::DataSet` object manages the cell set object with :class:`vtkm::cont::UnknownCellSet`.
When you call :func:`vtkm::cont::DataSet::GetCellSet`, it returns a :class:`vtkm::cont::UnknownCellSet`.

The :class:`vtkm::cont::UnknownCellSet` object provides mechanisms to query the cell set, identify its type, and cast it to one of the concrete ``CellSet`` types.
See Chapter \ref{chap:UnknownCellSet} for details on working with :class:`vtkm::cont::UnknownCellSet`.

.. todo:: Add previous reference to UnknownCellSet chapter.


------------------------------
Fields
------------------------------

.. index::
   single: field
   single: data set; field

A field on a data set provides a value on every point in space on the mesh.
Fields are often used to describe physical properties such as pressure, temperature, mass, velocity, and much more.
Fields are represented in a |VTKm| data set as an array where each value is associated with a particular element type of a mesh (such as points or cells).
This association of field values to mesh elements and the structure of the cell set determines how the field is interpolated throughout the space of the mesh.

Fields are manged by the :class:`vtkm::cont::Field` class.

.. doxygenclass:: vtkm::cont::Field

Fields are identified by a simple name string.

.. doxygenfunction:: vtkm::cont::Field::GetName

The :class:`vtkm::cont::Field` object internally holds a reference to an array in a type-agnostic way.
Filters and other |VTKm| units will determine the type of the array and pull it out of the :class:`vtkm::cont::Field`.

.. doxygenfunction:: vtkm::cont::Field::GetData() const

The field data is associated with a particular type of element of a mesh such as points, cells, or the whole mesh.

.. doxygenfunction:: vtkm::cont::Field::GetAssociation

Associations are identified by the :enum:`vtkm::cont::Field::Association` enumeration.

.. doxygenenum:: vtkm::cont::Field::Association

The :class:`vtkm::cont::Field` class also has several convenience methods for querying the association.

.. doxygenfunction:: vtkm::cont::Field::IsPointField

.. doxygenfunction:: vtkm::cont::Field::IsCellField

.. doxygenfunction:: vtkm::cont::Field::IsWholeDataSetField

.. doxygenfunction:: vtkm::cont::Field::IsPartitionsField

.. doxygenfunction:: vtkm::cont::Field::IsGlobalField

.. index:: double: range; field

:class:`vtkm::cont::Field` has a convenience method named :func:`vtkm::cont::Field::GetRange` that finds the range of values stored in the field array.

.. doxygenfunction:: vtkm::cont::Field::GetRange() const

.. didyouknow::
   The :class:`vtkm::cont::Field` class does not give direct access to the data in the field.
   This is in part because the field can hold any number of data types and in part because data access is more efficient in filters and other features that run in parallel.
   The :func:`vtkm::cont::Field::PrintSummary` function can be used to get some summary information for debugging.
   To get direct access to the data, you will first have to get a :class:`vtkm::cont::UnknownArrayHandle` from :func:`vtkm::cont::Field::Data`.
   The :class:`vtkm::cont::UnknownArrayHandle` then has to be converted to a :class:`vtkm::cont::ArrayHandle` of the proper type as described in :chapref:`unknown-array-handle:Unknown Array Handles`.
   Once the proper :class:`vtkm::cont::ArrayHandle` is retrieved, the data can finally be accessed through an array portal as described in :secref:`basic-array-handles:Array Portals`.


------------------------------
Coordinate Systems
------------------------------

.. index::
   single: coordinate system
   single: data set; coordinate system

A coordinate system determines the location of a mesh's elements in space.
The spatial location is described by providing a 3D vector at each point that gives the coordinates there.
The point coordinates can then be interpolated throughout the mesh.

.. doxygenclass:: vtkm::cont::CoordinateSystem

In addition to all the methods provided by the :class:`vtkm::cont::Field` superclass, the :class:`vtkm::cont::CoordinateSystem` also provides a :func:`vtkm::cont::CoordinateSystem::GetBounds` convenience method that returns a :class:`vtkm::Bounds` object giving the spatial bounds of the coordinate system.

.. doxygenfunction:: vtkm::cont::CoordinateSystem::GetBounds

It is typical for a :class:`vtkm::cont::DataSet` to have one coordinate system defined, but it is possible to define multiple coordinate systems.
This is helpful when there are multiple ways to express coordinates.
For example, positions in geographic may be expressed as Cartesian coordinates or as latitude-longitude coordinates.
Both are valid and useful in different ways.

It is also valid to have a :class:`vtkm::cont::DataSet` with no coordinate system.
This is useful when the structure is not rooted in physical space.
For example, if the cell set is representing a graph structure, there might not be any physical space that has meaning for the graph.


------------------------------
Partitioned Data Sets
------------------------------

.. index::
   single: partitioned data set
   single: data set; partitioned

.. doxygenclass:: vtkm::cont::PartitionedDataSet
   :members:

The following example creates a :class:`vtkm::cont::PartitionedDataSet` containing two uniform grid data sets.

.. load-example:: CreatePartitionedDataSet
   :file: GuideExampleDataSetCreation.cxx
   :caption: Creating a :class:`vtkm::cont::PartitionedDataSet`.

It is always possible to retrieve the independent blocks in a :class:`vtkm::cont::PartitionedDataSet`, from which you can iterate and get information about the data.
However, |VTKm| provides several helper functions to collect metadata information about the collection as a whole.

.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::DataSet&, vtkm::Id)

.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::PartitionedDataSet&, vtkm::Id)

.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::DataSet&, const std::string&)

.. doxygenfunction:: vtkm::cont::BoundsCompute(const vtkm::cont::PartitionedDataSet&, const std::string&)

.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::DataSet&, vtkm::Id)

.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet&, vtkm::Id)

.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::DataSet&, const std::string&)

.. doxygenfunction:: vtkm::cont::BoundsGlobalCompute(const vtkm::cont::PartitionedDataSet&, const std::string&)

.. doxygenfunction:: vtkm::cont::FieldRangeCompute(const vtkm::cont::DataSet&, const std::string&, vtkm::cont::Field::Association)

.. doxygenfunction:: vtkm::cont::FieldRangeCompute(const vtkm::cont::PartitionedDataSet&, const std::string&, vtkm::cont::Field::Association)

.. doxygenfunction:: vtkm::cont::FieldRangeGlobalCompute(const vtkm::cont::DataSet&, const std::string&, vtkm::cont::Field::Association)

.. doxygenfunction:: vtkm::cont::FieldRangeGlobalCompute(const vtkm::cont::PartitionedDataSet&, const std::string&, vtkm::cont::Field::Association)

The following example illustrates a spatial bounds query and a field range query on a :class:`vtkm::cont::PartitionedDataSet`.

.. load-example:: QueryPartitionedDataSet
   :file: GuideExampleDataSetCreation.cxx
   :caption: Queries on a :class:`vtkm::cont::PartitionedDataSet`.

.. didyouknow::
  The aforementioned functions for querying a :class:`vtkm::cont::PartitionedDataSet` object also work on :class:`vtkm::cont::DataSet` objects.
  This is particularly useful with the :func:`vtkm::cont::BoundsGlobalCompute` and :func:`vtkm::cont::FieldRangeGlobalCompute` functions to manage distributed parallel objects.

Filters can be executed on :class:`vtkm::cont::PartitionedDataSet` objects in a similar way they are executed on :class:`vtkm::cont::DataSet` objects.
In both cases, the :func:`vtkm::cont::Filter::Execute` method is called on the filter giving data object as an argument.

.. load-example:: FilterPartitionedDataSet
   :file: GuideExampleDataSetCreation.cxx
   :caption: Applying a filter to multi block data.
