2015-08-20 16:57:19 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2015-08-20 16:57:19 +00:00
|
|
|
// 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.
|
|
|
|
//============================================================================
|
|
|
|
#ifndef vtk_m_exec_Derivative_h
|
|
|
|
#define vtk_m_exec_Derivative_h
|
|
|
|
|
2016-04-20 21:41:14 +00:00
|
|
|
#include <vtkm/Assert.h>
|
2015-08-20 16:57:19 +00:00
|
|
|
#include <vtkm/CellShape.h>
|
2017-07-05 19:58:35 +00:00
|
|
|
#include <vtkm/VecAxisAlignedPointCoordinates.h>
|
2019-09-09 19:01:03 +00:00
|
|
|
#include <vtkm/VecTraits.h>
|
2015-08-20 16:57:19 +00:00
|
|
|
|
2015-08-21 04:29:54 +00:00
|
|
|
#include <vtkm/exec/CellInterpolate.h>
|
2015-08-20 16:57:19 +00:00
|
|
|
#include <vtkm/exec/FunctorBase.h>
|
2019-09-25 01:22:10 +00:00
|
|
|
|
|
|
|
#include <vtkc/vtkc.h>
|
2015-08-20 16:57:19 +00:00
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace exec
|
|
|
|
{
|
2015-08-20 16:57:19 +00:00
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
/// \brief Take the derivative (get the gradient) of a point field in a cell.
|
|
|
|
///
|
|
|
|
/// Given the point field values for each node and the parametric coordinates
|
|
|
|
/// of a point within the cell, finds the derivative with respect to each
|
|
|
|
/// coordinate (i.e. the gradient) at that point. The derivative is not always
|
|
|
|
/// constant in some "linear" cells.
|
|
|
|
///
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FieldVecType, typename WorldCoordType, typename ParametricCoordType>
|
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivative(
|
2017-05-26 17:53:28 +00:00
|
|
|
const FieldVecType& pointFieldValues,
|
|
|
|
const WorldCoordType& worldCoordinateValues,
|
|
|
|
const vtkm::Vec<ParametricCoordType, 3>& parametricCoords,
|
|
|
|
vtkm::CellShapeTagGeneric shape,
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
2015-08-20 16:57:19 +00:00
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
vtkm::Vec<typename FieldVecType::ComponentType, 3> result;
|
2015-08-20 16:57:19 +00:00
|
|
|
switch (shape.Id)
|
|
|
|
{
|
2017-05-26 17:53:28 +00:00
|
|
|
vtkmGenericCellShapeMacro(
|
|
|
|
result = CellDerivative(
|
|
|
|
pointFieldValues, worldCoordinateValues, parametricCoords, CellShapeTag(), worklet));
|
2015-08-20 16:57:19 +00:00
|
|
|
default:
|
|
|
|
worklet.RaiseError("Unknown cell shape sent to derivative.");
|
2017-05-18 14:29:41 +00:00
|
|
|
return vtkm::Vec<typename FieldVecType::ComponentType, 3>();
|
2015-08-20 16:57:19 +00:00
|
|
|
}
|
2016-03-31 13:22:23 +00:00
|
|
|
return result;
|
2015-08-20 16:57:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2019-09-25 01:22:10 +00:00
|
|
|
namespace internal
|
2015-08-20 16:57:19 +00:00
|
|
|
{
|
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
template <typename VtkcCellShapeTag,
|
|
|
|
typename FieldVecType,
|
|
|
|
typename WorldCoordType,
|
|
|
|
typename ParametricCoordType>
|
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivativeImpl(
|
|
|
|
VtkcCellShapeTag tag,
|
2017-05-26 17:53:28 +00:00
|
|
|
const FieldVecType& field,
|
|
|
|
const WorldCoordType& wCoords,
|
2019-09-25 01:22:10 +00:00
|
|
|
const ParametricCoordType& pcoords,
|
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
2016-12-06 00:18:46 +00:00
|
|
|
{
|
2019-09-25 01:22:10 +00:00
|
|
|
VTKM_ASSERT(field.GetNumberOfComponents() == tag.numberOfPoints());
|
|
|
|
VTKM_ASSERT(wCoords.GetNumberOfComponents() == tag.numberOfPoints());
|
2016-12-06 00:18:46 +00:00
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
using FieldType = typename FieldVecType::ComponentType;
|
2016-12-06 00:18:46 +00:00
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
auto fieldNumComponents = vtkm::VecTraits<FieldType>::GetNumberOfComponents(field[0]);
|
|
|
|
vtkm::Vec<FieldType, 3> derivs;
|
|
|
|
auto status = vtkc::derivative(tag,
|
|
|
|
vtkc::makeFieldAccessorNestedSOA(wCoords, 3),
|
|
|
|
vtkc::makeFieldAccessorNestedSOA(field, fieldNumComponents),
|
|
|
|
pcoords,
|
|
|
|
derivs[0],
|
|
|
|
derivs[1],
|
|
|
|
derivs[2]);
|
|
|
|
if (status != vtkc::ErrorCode::SUCCESS)
|
2016-12-06 00:18:46 +00:00
|
|
|
{
|
2019-09-25 01:22:10 +00:00
|
|
|
worklet.RaiseError(vtkc::errorString(status));
|
|
|
|
derivs = vtkm::TypeTraits<vtkm::Vec<FieldType, 3>>::ZeroInitialization();
|
2016-12-06 00:18:46 +00:00
|
|
|
}
|
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
return derivs;
|
2016-12-06 00:18:46 +00:00
|
|
|
}
|
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
} // namespace internal
|
2016-12-06 00:18:46 +00:00
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
template <typename FieldVecType,
|
|
|
|
typename WorldCoordType,
|
|
|
|
typename ParametricCoordType,
|
|
|
|
typename CellShapeTag>
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivative(
|
2017-05-26 17:53:28 +00:00
|
|
|
const FieldVecType& field,
|
|
|
|
const WorldCoordType& wCoords,
|
2019-09-25 01:22:10 +00:00
|
|
|
const vtkm::Vec<ParametricCoordType, 3>& pcoords,
|
|
|
|
CellShapeTag shape,
|
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
2015-08-20 16:57:19 +00:00
|
|
|
{
|
2019-09-25 01:22:10 +00:00
|
|
|
return internal::CellDerivativeImpl(
|
|
|
|
vtkm::internal::make_VtkcCellShapeTag(shape), field, wCoords, pcoords, worklet);
|
2015-08-20 16:57:19 +00:00
|
|
|
}
|
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
template <typename FieldVecType, typename WorldCoordType, typename ParametricCoordType>
|
2017-05-18 14:29:41 +00:00
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivative(
|
2019-09-25 01:22:10 +00:00
|
|
|
const FieldVecType&,
|
|
|
|
const WorldCoordType&,
|
|
|
|
const vtkm::Vec<ParametricCoordType, 3>&,
|
|
|
|
vtkm::CellShapeTagEmpty,
|
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
2015-09-01 22:30:03 +00:00
|
|
|
{
|
2019-09-25 01:22:10 +00:00
|
|
|
worklet.RaiseError("Attempted to take derivative in empty cell.");
|
|
|
|
return vtkm::Vec<typename FieldVecType::ComponentType, 3>();
|
2015-09-01 22:30:03 +00:00
|
|
|
}
|
|
|
|
|
2019-05-17 17:35:35 +00:00
|
|
|
template <typename FieldVecType, typename WorldCoordType, typename ParametricCoordType>
|
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivative(
|
|
|
|
const FieldVecType& field,
|
|
|
|
const WorldCoordType& wCoords,
|
|
|
|
const vtkm::Vec<ParametricCoordType, 3>& pcoords,
|
|
|
|
vtkm::CellShapeTagPolyLine,
|
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
|
|
|
{
|
|
|
|
vtkm::IdComponent numPoints = field.GetNumberOfComponents();
|
|
|
|
VTKM_ASSERT(numPoints >= 1);
|
|
|
|
VTKM_ASSERT(numPoints == wCoords.GetNumberOfComponents());
|
2019-05-28 17:25:23 +00:00
|
|
|
|
2019-05-17 17:35:35 +00:00
|
|
|
switch (numPoints)
|
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
return CellDerivative(field, wCoords, pcoords, vtkm::CellShapeTagVertex(), worklet);
|
|
|
|
case 2:
|
|
|
|
return CellDerivative(field, wCoords, pcoords, vtkm::CellShapeTagLine(), worklet);
|
|
|
|
}
|
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
auto dt = static_cast<ParametricCoordType>(1) / static_cast<ParametricCoordType>(numPoints - 1);
|
|
|
|
auto idx = static_cast<vtkm::IdComponent>(vtkm::Ceil(pcoords[0] / dt));
|
2019-05-28 17:25:23 +00:00
|
|
|
if (idx == 0)
|
2019-05-17 17:35:35 +00:00
|
|
|
{
|
|
|
|
idx = 1;
|
2016-11-09 22:22:06 +00:00
|
|
|
}
|
2019-09-25 01:22:10 +00:00
|
|
|
if (idx > numPoints - 1)
|
2016-11-09 22:22:06 +00:00
|
|
|
{
|
2019-09-25 01:22:10 +00:00
|
|
|
idx = numPoints - 1;
|
2015-08-20 16:57:19 +00:00
|
|
|
}
|
|
|
|
|
2019-09-25 01:22:10 +00:00
|
|
|
auto lineField = vtkm::make_Vec(field[idx - 1], field[idx]);
|
|
|
|
auto lineWCoords = vtkm::make_Vec(wCoords[idx - 1], wCoords[idx]);
|
|
|
|
auto pc = (pcoords[0] - static_cast<ParametricCoordType>(idx) * dt) / dt;
|
|
|
|
return internal::CellDerivativeImpl(vtkc::Line{}, lineField, lineWCoords, &pc, worklet);
|
2016-11-09 22:22:06 +00:00
|
|
|
}
|
|
|
|
|
2015-08-20 16:57:19 +00:00
|
|
|
//-----------------------------------------------------------------------------
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FieldVecType, typename WorldCoordType, typename ParametricCoordType>
|
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivative(
|
2017-05-26 17:53:28 +00:00
|
|
|
const FieldVecType& field,
|
|
|
|
const WorldCoordType& wCoords,
|
|
|
|
const vtkm::Vec<ParametricCoordType, 3>& pcoords,
|
|
|
|
vtkm::CellShapeTagPolygon,
|
2017-05-18 14:29:41 +00:00
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
2016-11-09 22:22:06 +00:00
|
|
|
{
|
|
|
|
VTKM_ASSERT(field.GetNumberOfComponents() == wCoords.GetNumberOfComponents());
|
|
|
|
|
|
|
|
const vtkm::IdComponent numPoints = field.GetNumberOfComponents();
|
|
|
|
VTKM_ASSERT(numPoints > 0);
|
|
|
|
|
|
|
|
switch (field.GetNumberOfComponents())
|
|
|
|
{
|
2017-05-18 14:29:41 +00:00
|
|
|
case 1:
|
|
|
|
return CellDerivative(field, wCoords, pcoords, vtkm::CellShapeTagVertex(), worklet);
|
|
|
|
case 2:
|
|
|
|
return CellDerivative(field, wCoords, pcoords, vtkm::CellShapeTagLine(), worklet);
|
2019-09-25 01:22:10 +00:00
|
|
|
default:
|
|
|
|
return internal::CellDerivativeImpl(
|
|
|
|
vtkc::Polygon(numPoints), field, wCoords, pcoords, worklet);
|
2016-11-09 22:22:06 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FieldVecType, typename ParametricCoordType>
|
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivative(
|
2017-05-26 17:53:28 +00:00
|
|
|
const FieldVecType& field,
|
2017-07-05 19:58:35 +00:00
|
|
|
const vtkm::VecAxisAlignedPointCoordinates<2>& wCoords,
|
2017-05-26 17:53:28 +00:00
|
|
|
const vtkm::Vec<ParametricCoordType, 3>& pcoords,
|
|
|
|
vtkm::CellShapeTagQuad,
|
2019-09-25 01:22:10 +00:00
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
2015-08-20 16:57:19 +00:00
|
|
|
{
|
2019-09-25 01:22:10 +00:00
|
|
|
return internal::CellDerivativeImpl(vtkc::Pixel{}, field, wCoords, pcoords, worklet);
|
2015-08-20 16:57:19 +00:00
|
|
|
}
|
|
|
|
|
2017-05-18 14:29:41 +00:00
|
|
|
template <typename FieldVecType, typename ParametricCoordType>
|
|
|
|
VTKM_EXEC vtkm::Vec<typename FieldVecType::ComponentType, 3> CellDerivative(
|
2017-05-26 17:53:28 +00:00
|
|
|
const FieldVecType& field,
|
2017-07-05 19:58:35 +00:00
|
|
|
const vtkm::VecAxisAlignedPointCoordinates<3>& wCoords,
|
2017-05-26 17:53:28 +00:00
|
|
|
const vtkm::Vec<ParametricCoordType, 3>& pcoords,
|
|
|
|
vtkm::CellShapeTagHexahedron,
|
2019-09-25 01:22:10 +00:00
|
|
|
const vtkm::exec::FunctorBase& worklet)
|
2015-08-20 16:57:19 +00:00
|
|
|
{
|
2019-09-25 01:22:10 +00:00
|
|
|
return internal::CellDerivativeImpl(vtkc::Voxel{}, field, wCoords, pcoords, worklet);
|
2015-08-20 16:57:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace vtkm::exec
|
|
|
|
|
|
|
|
#endif //vtk_m_exec_Derivative_h
|