diff --git a/docs/users-guide/dataset.rst b/docs/users-guide/dataset.rst index aa8bc3bb3..b1394300e 100644 --- a/docs/users-guide/dataset.rst +++ b/docs/users-guide/dataset.rst @@ -118,9 +118,7 @@ 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 ???. - -.. todo:: Add cell shape reference above. +Cell shapes are discussed in detail in :chapref:`working-with-cells:Working with Cells`. .. figure:: images/CellConnections.png :width: 100% @@ -128,6 +126,8 @@ Cell shapes are discussed in detail in ???. Basic Cell Shapes. +.. todo:: Add ``vtkm::CellShapeTagPolyLine`` to this figure. + .. .. |CellConnectionsVertex| image:: images/CellConnectionsVertex.png .. |CellConnectionsLine| image:: images/CellConnectionsLine.png @@ -280,7 +280,7 @@ A cell set determines the topological structure of the data in a data set. (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 Section~\ref{sec:CellShapeTagsIds} starting on page~\pageref{sec:CellShapeTagsIds}. +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. diff --git a/docs/users-guide/examples/CMakeLists.txt b/docs/users-guide/examples/CMakeLists.txt index 810910676..8e793fb97 100644 --- a/docs/users-guide/examples/CMakeLists.txt +++ b/docs/users-guide/examples/CMakeLists.txt @@ -10,6 +10,7 @@ set(examples GuideExampleArrayHandle.cxx + GuideExampleCellShapes.cxx GuideExampleColorTables.cxx GuideExampleCoreDataTypes.cxx GuideExampleEnvironmentModifierMacros.cxx @@ -28,6 +29,7 @@ set(examples set(examples_device GuideExampleCellEdgesFaces.cxx GuideExampleCellLocator.cxx + GuideExampleCellOperations.cxx GuideExampleDataSetCreation.cxx GuideExampleErrorHandling.cxx GuideExampleFilterDataSetWithField.cxx diff --git a/docs/users-guide/examples/GuideExampleCellOperations.cxx b/docs/users-guide/examples/GuideExampleCellOperations.cxx new file mode 100644 index 000000000..17deb2887 --- /dev/null +++ b/docs/users-guide/examples/GuideExampleCellOperations.cxx @@ -0,0 +1,153 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#include +#include +#include + +#include +#include + +#include +#include + +namespace +{ + +//// +//// BEGIN-EXAMPLE CellCenters +//// +struct CellCenters : vtkm::worklet::WorkletVisitCellsWithPoints +{ + using ControlSignature = void(CellSetIn, + FieldInPoint inputField, + FieldOutCell outputField); + using ExecutionSignature = void(CellShape, PointCount, _2, _3); + using InputDomain = _1; + + template + VTKM_EXEC void operator()(CellShapeTag shape, + vtkm::IdComponent pointCount, + const FieldInVecType& inputField, + FieldOutType& outputField) const + { + vtkm::Vec3f center; + vtkm::ErrorCode status = + vtkm::exec::ParametricCoordinatesCenter(pointCount, shape, center); + if (status != vtkm::ErrorCode::Success) + { + this->RaiseError(vtkm::ErrorString(status)); + return; + } + vtkm::exec::CellInterpolate(inputField, center, shape, outputField); + } +}; +//// +//// END-EXAMPLE CellCenters +//// + +void TryCellCenters() +{ + std::cout << "Trying CellCenters worklet." << std::endl; + + vtkm::cont::DataSet dataSet = + vtkm::cont::testing::MakeTestDataSet().Make3DUniformDataSet0(); + + using ArrayType = vtkm::cont::ArrayHandle; + ArrayType centers; + + vtkm::worklet::DispatcherMapTopology dispatcher; + dispatcher.Invoke(dataSet.GetCellSet(), + dataSet.GetField("pointvar").GetData().AsArrayHandle(), + centers); + + vtkm::cont::printSummary_ArrayHandle(centers, std::cout); + std::cout << std::endl; + + VTKM_TEST_ASSERT(centers.GetNumberOfValues() == + dataSet.GetCellSet().GetNumberOfCells(), + "Bad number of cells."); + VTKM_TEST_ASSERT(test_equal(60.1875, centers.ReadPortal().Get(0)), "Bad first value."); +} +//// +//// BEGIN-EXAMPLE CellDerivatives +//// +struct CellDerivatives : vtkm::worklet::WorkletVisitCellsWithPoints +{ + using ControlSignature = void(CellSetIn, + FieldInPoint inputField, + FieldInPoint pointCoordinates, + FieldOutCell outputField); + using ExecutionSignature = void(CellShape, PointCount, _2, _3, _4); + using InputDomain = _1; + + template + VTKM_EXEC void operator()(CellShapeTag shape, + vtkm::IdComponent pointCount, + const FieldInVecType& inputField, + const PointCoordVecType& pointCoordinates, + FieldOutType& outputField) const + { + vtkm::Vec3f center; + vtkm::ErrorCode status = + vtkm::exec::ParametricCoordinatesCenter(pointCount, shape, center); + if (status != vtkm::ErrorCode::Success) + { + this->RaiseError(vtkm::ErrorString(status)); + return; + } + vtkm::exec::CellDerivative(inputField, pointCoordinates, center, shape, outputField); + } +}; +//// +//// END-EXAMPLE CellDerivatives +//// + +void TryCellDerivatives() +{ + std::cout << "Trying CellDerivatives worklet." << std::endl; + + vtkm::cont::DataSet dataSet = + vtkm::cont::testing::MakeTestDataSet().Make3DUniformDataSet0(); + + using ArrayType = vtkm::cont::ArrayHandle; + vtkm::cont::ArrayHandle derivatives; + + vtkm::worklet::DispatcherMapTopology dispatcher; + dispatcher.Invoke(dataSet.GetCellSet(), + dataSet.GetField("pointvar").GetData().AsArrayHandle(), + dataSet.GetCoordinateSystem().GetData(), + derivatives); + + vtkm::cont::printSummary_ArrayHandle(derivatives, std::cout); + std::cout << std::endl; + + VTKM_TEST_ASSERT(derivatives.GetNumberOfValues() == + dataSet.GetCellSet().GetNumberOfCells(), + "Bad number of cells."); + VTKM_TEST_ASSERT( + test_equal(vtkm::make_Vec(10.025, 30.075, 60.125), derivatives.ReadPortal().Get(0)), + "Bad first value."); +} + +void Run() +{ + TryCellCenters(); + TryCellDerivatives(); +} + +} // anonymous namespace + +int GuideExampleCellOperations(int argc, char* argv[]) +{ + return vtkm::cont::testing::Testing::Run(Run, argc, argv); +} diff --git a/docs/users-guide/examples/GuideExampleCellShapes.cxx b/docs/users-guide/examples/GuideExampleCellShapes.cxx new file mode 100644 index 000000000..becae4eee --- /dev/null +++ b/docs/users-guide/examples/GuideExampleCellShapes.cxx @@ -0,0 +1,150 @@ +//============================================================================ +// Copyright (c) Kitware, Inc. +// All rights reserved. +// See LICENSE.txt for details. +// +// This software is distributed WITHOUT ANY WARRANTY; without even +// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +// PURPOSE. See the above copyright notice for more information. +//============================================================================ +#include +#include +#include + +#include + +#include + +namespace CellShapesExamples +{ + +//// +//// BEGIN-EXAMPLE CellShapeIdToTag +//// +void CellFunction(vtkm::CellShapeTagTriangle) +{ + std::cout << "In CellFunction for triangles." << std::endl; +} + +void DoSomethingWithACell() +{ + // Calls CellFunction overloaded with a vtkm::CellShapeTagTriangle. + CellFunction(vtkm::CellShapeIdToTag::Tag()); +} +//// +//// END-EXAMPLE CellShapeIdToTag +//// + +//// +//// BEGIN-EXAMPLE GenericCellNormal +//// +namespace detail +{ + +template +VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormalImpl( + const PointCoordinatesVector& pointCoordinates, + vtkm::CellTopologicalDimensionsTag<2>, + const WorkletType& worklet) +{ + if (pointCoordinates.GetNumberOfComponents() >= 3) + { + return vtkm::TriangleNormal( + pointCoordinates[0], pointCoordinates[1], pointCoordinates[2]); + } + else + { + worklet.RaiseError("Degenerate polygon."); + return typename PointCoordinatesVector::ComponentType(); + } +} + +template +VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormalImpl( + const PointCoordinatesVector&, + vtkm::CellTopologicalDimensionsTag, + const WorkletType& worklet) +{ + worklet.RaiseError("Only polygons supported for cell normals."); + return typename PointCoordinatesVector::ComponentType(); +} + +} // namespace detail + +template +VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormal( + CellShape, + const PointCoordinatesVector& pointCoordinates, + const WorkletType& worklet) +{ + return detail::CellNormalImpl( + pointCoordinates, + typename vtkm::CellTraits::TopologicalDimensionsTag(), + worklet); +} + +template +VTKM_EXEC_CONT typename PointCoordinatesVector::ComponentType CellNormal( + vtkm::CellShapeTagGeneric shape, + const PointCoordinatesVector& pointCoordinates, + const WorkletType& worklet) +{ + switch (shape.Id) + { + vtkmGenericCellShapeMacro( + return CellNormal(CellShapeTag(), pointCoordinates, worklet)); + default: + worklet.RaiseError("Unknown cell type."); + return typename PointCoordinatesVector::ComponentType(); + } +} +//// +//// END-EXAMPLE GenericCellNormal +//// + +struct FakeWorklet : vtkm::exec::FunctorBase +{ +}; + +void Run() +{ + std::cout << "Basic identifier to tag." << std::endl; + DoSomethingWithACell(); + + std::cout << "Function with dynamic lookup of cell shape." << std::endl; + + vtkm::Vec pointCoordinates; + pointCoordinates[0] = vtkm::Vec3f(0.0f, 0.0f, 0.0f); + pointCoordinates[1] = vtkm::Vec3f(1.0f, 0.0f, 0.0f); + pointCoordinates[2] = vtkm::Vec3f(0.0f, 1.0f, 0.0f); + + vtkm::Vec3f expectedNormal(0.0f, 0.0f, 1.0f); + + char errorBuffer[256]; + errorBuffer[0] = '\0'; + vtkm::exec::internal::ErrorMessageBuffer errorMessage(errorBuffer, 256); + FakeWorklet worklet; + worklet.SetErrorMessageBuffer(errorMessage); + + vtkm::Vec3f normal = + CellNormal(vtkm::CellShapeTagTriangle(), pointCoordinates, worklet); + VTKM_TEST_ASSERT(!errorMessage.IsErrorRaised(), "Error finding normal."); + VTKM_TEST_ASSERT(test_equal(normal, expectedNormal), "Bad normal."); + + normal = CellNormal( + vtkm::CellShapeTagGeneric(vtkm::CELL_SHAPE_TRIANGLE), pointCoordinates, worklet); + VTKM_TEST_ASSERT(!errorMessage.IsErrorRaised(), "Error finding normal."); + VTKM_TEST_ASSERT(test_equal(normal, expectedNormal), "Bad normal."); + + CellNormal(vtkm::CellShapeTagLine(), pointCoordinates, worklet); + VTKM_TEST_ASSERT(errorMessage.IsErrorRaised(), "Expected error not raised."); +} + +} // namespace CellShapesExamples + +int GuideExampleCellShapes(int argc, char* argv[]) +{ + return vtkm::testing::Testing::Run(CellShapesExamples::Run, argc, argv); +} diff --git a/docs/users-guide/part-advanced.rst b/docs/users-guide/part-advanced.rst index 5982c2a78..4355565cd 100644 --- a/docs/users-guide/part-advanced.rst +++ b/docs/users-guide/part-advanced.rst @@ -11,3 +11,4 @@ Advanced Development extended-filter-impl.rst worklet-error-handling.rst math.rst + working-with-cells.rst diff --git a/docs/users-guide/working-with-cells.rst b/docs/users-guide/working-with-cells.rst new file mode 100644 index 000000000..a36d27afd --- /dev/null +++ b/docs/users-guide/working-with-cells.rst @@ -0,0 +1,258 @@ +============================== +Working with Cells +============================== + +.. index:: cell + +In the control environment, data is defined in mesh structures that comprise a set of finite cells. +(See :secref:`dataset:Cell Sets` for information on defining cell sets in the control environment.) +When worklets that operate on cells are scheduled, these grid structures are broken into their independent cells, and that data is handed to the worklet. +Thus, cell-based operations in the execution environment exclusively operate on independent cells. + +Unlike some other libraries such as VTK, |VTKm| does not have a cell class that holds all the information pertaining to a cell of a particular type. +Instead, |VTKm| provides tags or identifiers defining the cell shape, and companion data like coordinate and field information are held in separate structures. +This organization is designed so a worklet may specify exactly what information it needs, and only that information will be loaded. + + +------------------------------ +Cell Shape Tags and Ids +------------------------------ + +.. index:: + double: tag; cell shape + double: tag; shape + +Cell shapes can be specified with either a tag (defined with a struct with a name like ``CellShapeTag*``) or an enumerated identifier (defined with a constant number with a name like ``CELL_SHAPE_*``). +These shape tags and identifiers are defined in :file:`vtkm/CellShape.h` and declared in the ``vtkm`` namespace (because they can be used in either the control or the execution environment). +:numref:`fig:CellShapes` gives both the identifier and the tag names. + +.. figure:: images/CellConnections.png + :width: 100% + :name: fig:CellShapes + + Basic Cell Shapes. + +.. doxygenstruct:: vtkm::CellShapeTagVertex + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_VERTEX +.. doxygenstruct:: vtkm::CellShapeTagLine + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_LINE +.. doxygenstruct:: vtkm::CellShapeTagPolyLine + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_POLY_LINE +.. doxygenstruct:: vtkm::CellShapeTagTriangle + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_TRIANGLE +.. doxygenstruct:: vtkm::CellShapeTagPolygon + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_POLYGON +.. doxygenstruct:: vtkm::CellShapeTagQuad + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_QUAD +.. doxygenstruct:: vtkm::CellShapeTagTetra + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_TETRA +.. doxygenstruct:: vtkm::CellShapeTagHexahedron + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_HEXAHEDRON +.. doxygenstruct:: vtkm::CellShapeTagWedge + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_WEDGE +.. doxygenstruct:: vtkm::CellShapeTagPyramid + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_PYRAMID + +In addition to the basic cell shapes, there is a special "empty" cell with the identifier :enumerator:`vtkm::CELL_SHAPE_EMPTY` and tag :class:`vtkm::CellShapeTagEmpty`. +This type of cell has no points, edges, or faces and can be thought of as a placeholder for a null or void cell. + +.. doxygenstruct:: vtkm::CellShapeTagEmpty + :members: +.. doxygenenumvalue:: vtkm::CELL_SHAPE_EMPTY + +There is also a special cell shape "tag" named :class:`vtkm::CellShapeTagGeneric` that is used when the actual cell shape is not known at compile time. +:class:`vtkm::CellShapeTagGeneric` actually has a member variable named :var:`vtkm::CellShapeTagGeneric::Id` that stores the identifier for the cell shape. +There is no equivalent identifier for a generic cell; cell shape identifiers can be placed in a :type:`vtkm::IdComponent` at runtime. + +.. doxygenstruct:: vtkm::CellShapeTagGeneric + :members: + +When using cell shapes in templated classes and functions, you can use the :c:macro:`VTKM_IS_CELL_SHAPE_TAG` to ensure a type is a valid cell shape tag. +This macro takes one argument and will produce a compile error if the argument is not a cell shape tag type. + +.. doxygendefine:: VTKM_IS_CELL_SHAPE_TAG + +Converting Between Tags and Identifiers +======================================== + +Every cell shape tag has a member variable named ``Id`` that contains the identifier for the cell shape. +This provides a convenient mechanism for converting a cell shape tag to an identifier. +Most cell shape tags have their ``Id`` member as a compile-time constant, but :var:`vtkm::CellShapeTagGeneric::Id` is set at run time. + +The :file:`vtkm/CellShape.h` header also declares a templated class named :class:`vtkm::CellShapeIdToTag` that converts a cell shape identifier to a cell shape tag. +:class:`vtkm::CellShapeIdToTag` has a single template argument that is the identifier. +Inside the class is a type named :var:`vtkm::CellShapeIdToTag::Tag` that is the type of the correct tag. + +.. doxygenstruct:: vtkm::CellShapeIdToTag + :members: + +.. load-example:: CellShapeIdToTag + :file: GuideExampleCellShapes.cxx + :caption: Using :class:`vtkm::CellShapeIdToTag`. + +However, :class:`vtkm::CellShapeIdToTag` is only viable if the identifier can be resolved at compile time. +In the case where a cell identifier is stored in a variable or an array or the code is using a :class:`vtkm::CellShapeTagGeneric`, the correct cell shape is not known until run time. +In this case, the :c:macro:`vtkmGenericCellShapeMacro` macro can be used to check all possible conditions. +This macro is embedded in a switch statement where the condition is the cell shape identifier. + +.. doxygendefine:: vtkmGenericCellShapeMacro + +Often this method is used to implement the condition for a :class:`vtkm::CellShapeTagGeneric` in a function overloaded for cell types. +A demonstration of :c:macro:`vtkmGenericCellShapeMacro` is given in :numref:`ex:GenericCellNormal`. + +Cell Traits +============================== + +.. index:: cell traits + +The :file:`vtkm/CellTraits.h` header file contains a traits class named :class:`vtkm::CellTraits` that provides information about a cell. + +.. doxygenstruct:: vtkm::CellTraits + :members: + +.. doxygenstruct:: vtkm::CellTopologicalDimensionsTag +.. doxygenstruct:: vtkm::CellTraitsTagSizeFixed +.. doxygenstruct:: vtkm::CellTraitsTagSizeVariable + +.. load-example:: GenericCellNormal + :file: GuideExampleCellShapes.cxx + :caption: Using :class:`vtkm::CellTraits` to implement a polygon normal estimator. + + +----------------------------------- +Parametric and World Coordinates +----------------------------------- + +.. index:: + double: cell; parametric coordinates + double: cell; world coordinates + +Each cell type supports a one-to-one mapping between a set of parametric coordinates in the unit cube (or some subset of it) and the points in 3D space that are the locus contained in the cell. +Parametric coordinates are useful because certain features of the cell, such as vertex location and center, are at a consistent location in parametric space irrespective of the location and distortion of the cell in world space. +Also, many field operations are much easier with parametric coordinates. + +The :file:`vtkm/exec/ParametricCoordinates.h` header file contains the following functions for working with parametric coordinates. +These functions contain several overloads for using different cell shape tags. + +.. doxygenfunction:: vtkm::exec::ParametricCoordinatesCenter(vtkm::IdComponent, vtkm::CellShapeTagGeneric, vtkm::Vec&) +.. doxygenfunction:: vtkm::exec::ParametricCoordinatesPoint(vtkm::IdComponent, vtkm::IdComponent, vtkm::CellShapeTagGeneric, vtkm::Vec&) +.. doxygenfunction:: vtkm::exec::ParametricCoordinatesToWorldCoordinates(const WorldCoordVector&, const vtkm::Vec&, vtkm::CellShapeTagGeneric, typename WorldCoordVector::ComponentType&) +.. doxygenfunction:: vtkm::exec::WorldCoordinatesToParametricCoordinates(const WorldCoordVector&, const typename WorldCoordVector::ComponentType&, vtkm::CellShapeTagGeneric, typename WorldCoordVector::ComponentType&) + + +------------------------------ +Interpolation +------------------------------ + +.. index:: + double: cell; interpolation + +The shape of every cell is defined by the connections of some finite set of points. +Field values defined on those points can be interpolated to any point within the cell to estimate a continuous field. + +The :file:`vtkm/exec/CellInterpolate.h` header contains the function :func:`vtkm::exec::CellInterpolate` to do this interpolation. + +.. doxygenfunction:: vtkm::exec::CellInterpolate(const FieldVecType&, const vtkm::Vec&, vtkm::CellShapeTagGeneric, typename FieldVecType::ComponentType&) + +.. load-example:: CellCenters + :file: GuideExampleCellOperations.cxx + :caption: Interpolating field values to a cell's center. + + +------------------------------ +Derivatives +------------------------------ + +.. index:: + double: cell; derivative + double: cell; gradient + +Since interpolations provide a continuous field function over a cell, it is reasonable to consider the derivative of this function. +The :file:`vtkm/exec/CellDerivative.h` header contains the function :func:`vtkm::exec::CellDerivative` to compute derivatives. +The derivative is returned in a :class:`vtkm::Vec` of size 3 corresponding to the partial derivatives in the :math:`x`, :math:`y`, and :math:`z` directions. +This derivative is equivalent to the gradient of the field. + +.. load-example:: CellDerivatives + :file: GuideExampleCellOperations.cxx + :caption: Computing the derivative of the field at cell centers. + + +------------------------------ +Edges and Faces +------------------------------ + +.. index:: + single: point + single: cell; point + double: cell; shape + +As explained earlier in this chapter, a cell is defined by a collection of points and a shape identifier that describes how the points come together to form the structure of the cell. +The cell shapes supported by |VTKm| are documented in :secref:`working-with-cells:Cell Shape Tags and Ids`. +It contains :numref:`fig:CellShapes`, which shows how the points for each shape form the structure of the cell. + +.. index:: + single: edge + single: cell; edge + single: shape; edge + +Most cell shapes can be broken into subelements. +2D and 3D cells have pairs of points that form *edges* at the boundaries of the cell. +Likewise, 3D cells have loops of edges that form *faces* that encase the cell. +:numref:`fig:CellConstituents` demonstrates the relationship of these constituent elements for some example cell shapes. + +.. figure:: images/CellConstituents.png + :width: 50% + :name: fig:CellConstituents + + The constituent elements (points, edges, and faces) of cells.. + +The header file :file:`vtkm/exec/CellEdge.h` contains a collection of functions to help identify the edges of a cell. + +.. doxygenfunction:: vtkm::exec::CellEdgeNumberOfEdges(vtkm::IdComponent, vtkm::CellShapeTagGeneric, vtkm::IdComponent&) +.. doxygenfunction:: vtkm::exec::CellEdgeLocalIndex(vtkm::IdComponent, vtkm::IdComponent, vtkm::IdComponent, vtkm::CellShapeTagGeneric, vtkm::IdComponent&) +.. doxygenfunction:: vtkm::exec::CellEdgeCanonicalId + +The following example demonstrates a pair of worklets that use the cell edge functions. +As is typical for operations of this nature, one worklet counts the number of edges in each cell and another uses this count to generate the data. + +.. didyouknow:: + :numref:`ex:CellEdge` demonstrates one of many techniques for creating cell sets in a worklet. + Chapter~\ref{chap:GeneratingCellSets} describes this and many more such techniques. + +.. todo:: Fix chap:GeneratingCellSets reference above. + +.. load-example:: CellEdge + :file: GuideExampleCellEdgesFaces.cxx + :caption: Using cell edge functions. + +.. index:: + single: face + single: cell; face + single: shape; face + +The header file :file:`vtkm/exec/CellFace.h` contains a collection of functions to help identify the faces of a cell. + +.. doxygenfunction:: vtkm::exec::CellFaceNumberOfFaces +.. doxygenfunction:: vtkm::exec::CellFaceNumberOfPoints +.. doxygenfunction:: vtkm::exec::CellFaceShape +.. doxygenfunction:: vtkm::exec::CellFaceLocalIndex +.. doxygenfunction:: vtkm::exec::CellFaceCanonicalId + +The following example demonstrates a triple of worklets that use the cell face functions. +As is typical for operations of this nature, the worklets are used in steps to first count entities and then generate new entities. +In this case, the first worklet counts the number of faces and the second worklet counts the points in each face. +The third worklet generates cells for each face. + +.. load-example:: CellFace + :file: GuideExampleCellEdgesFaces.cxx + :caption: Using cell face functions. diff --git a/docs/users-guide/worklet-types.rst b/docs/users-guide/worklet-types.rst index 0a14171fd..4cc07b318 100644 --- a/docs/users-guide/worklet-types.rst +++ b/docs/users-guide/worklet-types.rst @@ -131,11 +131,9 @@ A visit cells with points worklet supports the following tags in the parameters :content-only: Point to cell field maps are a powerful construct that allow you to interpolate point fields throughout the space of the data set. -See Chapter \ref{chap:WorkingWithCells} for a description on how to work with the cell information provided to the worklet. +See :chapref:`working-with-cells:Working with Cells` for a description on how to work with the cell information provided to the worklet. The following example provides a simple demonstration that finds the geometric center of each cell by interpolating the point coordinates to the cell centers. -.. todo:: Fix reference to chapter on working with cells above. - .. load-example:: UseWorkletVisitCellsWithPoints :file: GuideExampleUseWorkletVisitCellsWithPoints.cxx :caption: Implementation and use of a visit cells with points worklet. @@ -210,7 +208,7 @@ The following example does a simple averaging, but you can also implement other This tag represents the cell set that defines the collection of elements the map will operate on. A \sigtag{CellSetIn} argument expects a \textidentifier{CellSet} subclass or an \textidentifier{UnknownCellSet} in the associated parameter of the \textidentifier{Invoker}. Each invocation of the worklet gets a cell shape tag. - (Cell shapes and the operations you can do with cells are discussed in Chapter \ref{chap:WorkingWithCells}.) + (Cell shapes and the operations you can do with cells are discussed in :chapref:`working-with-cells:Working with Cells`.) There must be exactly one \sigtag{CellSetIn} argument, and the worklet's \inputdomain must be set to this argument. @@ -248,7 +246,7 @@ The following example does a simple averaging, but you can also implement other \item[\sigtag{CellShape}] This tag produces a shape tag corresponding to the shape of the visited element. - (Cell shapes and the operations you can do with cells are discussed in Chapter \ref{chap:WorkingWithCells}.) + (Cell shapes and the operations you can do with cells are discussed in :chapref:`working-with-cells:Working with Cells`.) This is the same value that gets provided if you reference the \textsignature{CellSetIn} parameter. If the ``visit'' element is cells, the \sigtag{CellShape} clearly will match the shape of each cell. diff --git a/vtkm/CellShape.h b/vtkm/CellShape.h index 5985d1dc3..c6cbe85c5 100644 --- a/vtkm/CellShape.h +++ b/vtkm/CellShape.h @@ -33,20 +33,38 @@ namespace vtkm enum CellShapeIdEnum { // Linear cells + /// Placeholder for empty or invalid cells. CELL_SHAPE_EMPTY = lcl::ShapeId::EMPTY, + /// Vertex cells of a single point. CELL_SHAPE_VERTEX = lcl::ShapeId::VERTEX, //CELL_SHAPE_POLY_VERTEX = 2, + /// A line cell connecting two points. CELL_SHAPE_LINE = lcl::ShapeId::LINE, + /// A sequence of line segments. + /// A polyline has 2 or more points, and the points are connected in order + /// by line segments forming a piecewise linear curve. CELL_SHAPE_POLY_LINE = 4, + /// A triangle. CELL_SHAPE_TRIANGLE = lcl::ShapeId::TRIANGLE, //CELL_SHAPE_TRIANGLE_STRIP = 6, + /// A general polygon shape. + /// All polygons have points ordered in counterclockwise order around the front side. + /// Some operations may be invalid if the polygon is not a convex shape. CELL_SHAPE_POLYGON = lcl::ShapeId::POLYGON, //CELL_SHAPE_PIXEL = 8, + /// A four-sided polygon. CELL_SHAPE_QUAD = lcl::ShapeId::QUAD, + /// A tetrahedron. + /// A tetrahedron is a 3D polyhedron with 4 points and 4 triangular faces. CELL_SHAPE_TETRA = lcl::ShapeId::TETRA, //CELL_SHAPE_VOXEL = 11, + /// A hexahedron. CELL_SHAPE_HEXAHEDRON = lcl::ShapeId::HEXAHEDRON, + /// A wedge. + /// Wedges are simple prisms that can be formed by extruding a triangle. + /// They have 2 triangular faces and 3 quadrilateral faces. CELL_SHAPE_WEDGE = lcl::ShapeId::WEDGE, + /// A pyramid with a quadrilateral base and four triangular faces.0 CELL_SHAPE_PYRAMID = lcl::ShapeId::PYRAMID, NUMBER_OF_CELL_SHAPES @@ -157,6 +175,8 @@ struct CellShapeTagGeneric { } + /// An identifier that corresponds to one of the `CELL_SHAPE_*` identifiers. + /// This value is used to detect the proper shape at runtime. vtkm::UInt8 Id; }; diff --git a/vtkm/CellTraits.h b/vtkm/CellTraits.h index 3e79c2ffa..dad08c213 100644 --- a/vtkm/CellTraits.h +++ b/vtkm/CellTraits.h @@ -52,24 +52,24 @@ struct CellTraits static const vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = 3; /// This tag is typedef'ed to - /// vtkm::CellTopologicalDimensionsTag. This provides + /// `vtkm::CellTopologicalDimensionsTag`. This provides /// a convenient way to overload a function based on topological dimensions /// (which is usually more efficient than conditionals). /// using TopologicalDimensionsTag = vtkm::CellTopologicalDimensionsTag; - /// \brief A tag specifying whether the number of points is fixed. + /// @brief A tag specifying whether the number of points is fixed. /// - /// If set to \c CellTraitsTagSizeFixed, then \c NUM_POINTS is set. If set to - /// \c CellTraitsTagSizeVariable, then the number of points is not known at + /// If set to `vtkm::CellTraitsTagSizeFixed`, then `NUM_POINTS` is set. If set to + /// `vtkm::CellTraitsTagSizeVariable`, then the number of points is not known at /// compile time. /// using IsSizeFixed = vtkm::CellTraitsTagSizeFixed; - /// \brief Number of points in the cell. + /// @brief Number of points in the cell. /// - /// This is only defined for cell shapes of a fixed number of points (i.e. - /// \c IsSizedFixed is set to \c CellTraitsTagSizeFixed. + /// This is only defined for cell shapes of a fixed number of points (i.e., + /// `IsSizedFixed` is set to `vtkm::CellTraitsTagSizeFixed`). /// static constexpr vtkm::IdComponent NUM_POINTS = 3; }; diff --git a/vtkm/exec/CellDerivative.h b/vtkm/exec/CellDerivative.h index 9f1e87ccc..e9fc30c7e 100644 --- a/vtkm/exec/CellDerivative.h +++ b/vtkm/exec/CellDerivative.h @@ -181,6 +181,20 @@ VTKM_EXEC vtkm::ErrorCode CellDerivative(const FieldVecType& field, /// coordinate (i.e. the gradient) at that point. The derivative is not always /// constant in some "linear" cells. /// +/// @param[in] pointFieldValues A list of field values for each point in the cell. This +/// usually comes from a `FieldInPoint` argument in a +/// `vtkm::worklet::WorkletVisitCellsWithPoints`. +/// @param[in] worldCoordinateValues A list of world coordinates for each point in the cell. This +/// usually comes from a `FieldInPoint` argument in a +/// `vtkm::worklet::WorkletVisitCellsWithPoints` where the coordinate system is passed +/// into that argument. +/// @param[in] parametricCoords The parametric coordinates where you want to find the derivative. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result Value to store the derivative/gradient. Because the derivative is taken +/// partially in the x, y, and z directions, the result is a `vtkm::Vec` of size 3 with the +/// component type the same as the field. If the field is itself a vector, you get a `Vec` +/// of `Vec`s. template VTKM_EXEC vtkm::ErrorCode CellDerivative(const FieldVecType& pointFieldValues, const WorldCoordType& worldCoordinateValues, diff --git a/vtkm/exec/CellEdge.h b/vtkm/exec/CellEdge.h index e748a8dec..d1a84c55f 100644 --- a/vtkm/exec/CellEdge.h +++ b/vtkm/exec/CellEdge.h @@ -154,6 +154,12 @@ static inline VTKM_EXEC vtkm::ErrorCode CellEdgeNumberOfEdges(vtkm::IdComponent return vtkm::ErrorCode::Success; } +/// @brief Get the number of edges in a cell. +/// +/// @param[in] numPoints The number of points in the cell. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] numEdges A reference to return the number of edges. static inline VTKM_EXEC vtkm::ErrorCode CellEdgeNumberOfEdges(vtkm::IdComponent numPoints, vtkm::CellShapeTagGeneric shape, vtkm::IdComponent& numEdges) @@ -237,6 +243,18 @@ static inline VTKM_EXEC vtkm::ErrorCode CellEdgeLocalIndex(vtkm::IdComponent num return vtkm::ErrorCode::Success; } +/// Given the index for an edge of a cell and one of the points on that edge, this +/// function returns the point index for the cell. +/// To get the point indices relative to the data set, the returned index should be used +/// to reference a `PointIndices` list. +/// +/// @param[in] numPoints The number of points in the cell. +/// @param[in] pointIndex The index of the edge within the cell. +/// @param[in] edgeIndex The index of the point on the edge (either 0 or 1). +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result Reference to put the index of the point relative to the cell +/// (between 0 and the number of points in the cell). static inline VTKM_EXEC vtkm::ErrorCode CellEdgeLocalIndex(vtkm::IdComponent numPoints, vtkm::IdComponent pointIndex, vtkm::IdComponent edgeIndex, @@ -273,7 +291,7 @@ static inline VTKM_EXEC vtkm::ErrorCode CellEdgeLocalIndex(vtkm::IdComponent num } } -/// \brief Returns a canonical identifier for a cell edge +/// @brief Returns a canonical identifier for a cell edge /// /// Given information about a cell edge and the global point indices for that cell, returns a /// vtkm::Id2 that contains values that are unique to that edge. The values for two edges will be diff --git a/vtkm/exec/CellFace.h b/vtkm/exec/CellFace.h index 200dceebc..1f14d77b4 100644 --- a/vtkm/exec/CellFace.h +++ b/vtkm/exec/CellFace.h @@ -138,6 +138,11 @@ public: } // namespace detail +/// @brief Get the number of faces in a cell. +/// +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result A reference to return the number of faces. template static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfFaces(CellShapeTag shape, vtkm::IdComponent& result) @@ -148,6 +153,15 @@ static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfFaces(CellShapeTag shape return vtkm::ErrorCode::Success; } +/// @brief Get the number of points in a face. +/// +/// Given a local index to the face and a shape of the cell, this method returns the +/// number of points in that particular face. +/// +/// @param[in] faceIndex The index of the face within the cell. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result A reference to return the number of points in the selected face. template static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfPoints(vtkm::IdComponent faceIndex, CellShapeTag shape, @@ -171,6 +185,18 @@ static inline VTKM_EXEC vtkm::ErrorCode CellFaceNumberOfPoints(vtkm::IdComponent return vtkm::ErrorCode::Success; } +/// @brief Get the shape of a face. +/// +/// Given a local index to the face and a shape of the cell, this method returns the +/// identifier for the shape of that face. +/// Faces are always polygons, so it is valid to just to treat the face as a +/// `CELL_SHAPE_POLYGON`. However, the face will be checked to see if it can be +/// further specialized to `CELL_SHAPE_TRIANGLE` or `CELL_SHAPE_QUAD`. +/// +/// @param[in] faceIndex The index of the face within the cell. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result A reference to return the number of points in the selected face. template static inline VTKM_EXEC vtkm::ErrorCode CellFaceShape(vtkm::IdComponent faceIndex, CellShapeTag shape, @@ -200,6 +226,17 @@ static inline VTKM_EXEC vtkm::ErrorCode CellFaceShape(vtkm::IdComponent faceInde return vtkm::ErrorCode::Success; } +/// Given the index for a face of a cell and one of the points on that face, this +/// function returns the point index for the cell. +/// To get the point indices relative to the data set, the returned index should be used +/// to reference a `PointIndices` list. +/// +/// @param[in] pointIndex The index of the edge within the cell. +/// @param[in] faceIndex The index of the point on the face. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result Reference to put the index of the point relative to the cell +/// (between 0 and the number of points in the cell). template static inline VTKM_EXEC vtkm::ErrorCode CellFaceLocalIndex(vtkm::IdComponent pointIndex, vtkm::IdComponent faceIndex, @@ -221,10 +258,10 @@ static inline VTKM_EXEC vtkm::ErrorCode CellFaceLocalIndex(vtkm::IdComponent poi return vtkm::ErrorCode::Success; } -/// \brief Returns a canonical identifier for a cell face +/// @brief Returns a canonical identifier for a cell face /// /// Given information about a cell face and the global point indices for that cell, returns a -/// vtkm::Id3 that contains values that are unique to that face. The values for two faces will be +/// `vtkm::Id3` that contains values that are unique to that face. The values for two faces will be /// the same if and only if the faces contain the same points. /// /// Note that this property is only true if the mesh is conforming. That is, any two neighboring diff --git a/vtkm/exec/CellInterpolate.h b/vtkm/exec/CellInterpolate.h index 7224c6bd0..3be4b5035 100644 --- a/vtkm/exec/CellInterpolate.h +++ b/vtkm/exec/CellInterpolate.h @@ -158,6 +158,14 @@ VTKM_EXEC vtkm::ErrorCode CellInterpolate(const vtkm::VecAxisAlignedPointCoordin /// Given the point field values for each node and the parametric coordinates /// of a point within the cell, interpolates the field to that point. /// +/// @param[in] pointFieldValues A list of field values for each point in the cell. This +/// usually comes from a `FieldInPoint` argument in a +/// `vtkm::worklet::WorkletVisitCellsWithPoints`. +/// @param[in] parametricCoords The parametric coordinates where you want to get the interpolated +/// field value for. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result Value to store the interpolated field. template VTKM_EXEC vtkm::ErrorCode CellInterpolate(const FieldVecType& pointFieldValues, const vtkm::Vec& parametricCoords, diff --git a/vtkm/exec/ParametricCoordinates.h b/vtkm/exec/ParametricCoordinates.h index 68b826feb..23797004f 100644 --- a/vtkm/exec/ParametricCoordinates.h +++ b/vtkm/exec/ParametricCoordinates.h @@ -118,6 +118,10 @@ static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter( /// Returns the parametric center of the given cell shape with the given number /// of points. /// +/// @param[in] numPoints The number of points in the cell. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] pcoords `vtkm::Vec` to store the parametric center. template static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesCenter( vtkm::IdComponent numPoints, @@ -241,6 +245,12 @@ static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint( /// Returns the parametric coordinate of a cell point of the given shape with /// the given number of points. /// +/// @param[in] numPoints The number of points in the cell. +/// @param[in] pointIndex The local index for the point to get the parametric coordinates +/// of. This index is between 0 and _n_-1 where _n_ is the number of points in the cell. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] pcoords `vtkm::Vec` to store the parametric center. template static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesPoint( vtkm::IdComponent numPoints, @@ -354,8 +364,17 @@ static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates( } //----------------------------------------------------------------------------- -/// Returns the world coordinate corresponding to the given parametric coordinate of a cell. +/// Converts parametric coordinates (coordinates relative to the cell) to world coordinates +/// (coordinates in the global system). /// +/// @param[in] pointWCoords A list of world coordinates for each point in the cell. This +/// usually comes from a `FieldInPoint` argument in a +/// `vtkm::worklet::WorkletVisitCellsWithPoints` where the coordinate system is passed +/// into that argument. +/// @param[in] pcoords The parametric coordinates where you want to get world coordinates for. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result `vtkm::Vec` to store the interpolated world coordinates. template static inline VTKM_EXEC vtkm::ErrorCode ParametricCoordinatesToWorldCoordinates( const WorldCoordVector& pointWCoords, @@ -541,8 +560,18 @@ static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates( } //----------------------------------------------------------------------------- -/// Returns the world paramteric corresponding to the given world coordinate for a cell. +/// Converts world coordinates (coordinates in the global system) to parametric +/// coordinates (coordinates relative to the cell). This function can be slow for +/// cell types with nonlinear interpolation (which is anything that is not a simplex). /// +/// @param[in] pointWCoords A list of world coordinates for each point in the cell. This +/// usually comes from a `FieldInPoint` argument in a +/// `vtkm::worklet::WorkletVisitCellsWithPoints` where the coordinate system is passed +/// into that argument. +/// @param[in] wcoords The world coordinates where you want to get parametric coordinates for. +/// @param[in] shape A tag of type `CellShapeTag*` to identify the shape of the cell. +/// This method is overloaded for different shape types. +/// @param[out] result `vtkm::Vec` to store the associated parametric coordinates. template static inline VTKM_EXEC vtkm::ErrorCode WorldCoordinatesToParametricCoordinates( const WorldCoordVector& pointWCoords,