2017-04-18 20:49:03 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt for details.
|
2019-04-15 23:24:21 +00:00
|
|
|
//
|
2017-04-18 20:49:03 +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_worklet_particleadvection_GridEvaluators_h
|
|
|
|
#define vtk_m_worklet_particleadvection_GridEvaluators_h
|
|
|
|
|
|
|
|
#include <vtkm/Types.h>
|
2017-07-07 17:36:31 +00:00
|
|
|
#include <vtkm/VectorAnalysis.h>
|
2017-04-18 20:49:03 +00:00
|
|
|
#include <vtkm/cont/ArrayHandle.h>
|
2019-01-30 18:47:27 +00:00
|
|
|
#include <vtkm/cont/CellLocator.h>
|
2019-03-15 17:40:48 +00:00
|
|
|
#include <vtkm/cont/CellLocatorBoundingIntervalHierarchy.h>
|
2019-01-30 18:47:27 +00:00
|
|
|
#include <vtkm/cont/CellLocatorRectilinearGrid.h>
|
|
|
|
#include <vtkm/cont/CellLocatorUniformGrid.h>
|
2017-04-18 20:49:03 +00:00
|
|
|
#include <vtkm/cont/CellSetStructured.h>
|
2017-07-07 17:36:31 +00:00
|
|
|
#include <vtkm/cont/DataSet.h>
|
|
|
|
#include <vtkm/cont/DeviceAdapter.h>
|
2017-04-18 20:49:03 +00:00
|
|
|
|
2019-01-30 18:47:27 +00:00
|
|
|
#include <vtkm/worklet/particleadvection/CellInterpolationHelper.h>
|
2018-07-08 01:19:39 +00:00
|
|
|
#include <vtkm/worklet/particleadvection/Integrators.h>
|
|
|
|
|
2017-07-07 17:36:31 +00:00
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace worklet
|
|
|
|
{
|
|
|
|
namespace particleadvection
|
|
|
|
{
|
2017-04-18 20:49:03 +00:00
|
|
|
|
2019-01-30 18:47:27 +00:00
|
|
|
template <typename DeviceAdapter, typename FieldArrayType>
|
|
|
|
class ExecutionGridEvaluator
|
|
|
|
{
|
|
|
|
using FieldPortalType =
|
|
|
|
typename FieldArrayType::template ExecutionTypes<DeviceAdapter>::PortalConst;
|
|
|
|
|
|
|
|
public:
|
|
|
|
VTKM_CONT
|
|
|
|
ExecutionGridEvaluator() = default;
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
ExecutionGridEvaluator(std::shared_ptr<vtkm::cont::CellLocator> locator,
|
|
|
|
std::shared_ptr<vtkm::cont::CellInterpolationHelper> interpolationHelper,
|
|
|
|
const vtkm::Bounds& bounds,
|
|
|
|
const FieldArrayType& field)
|
|
|
|
: Bounds(bounds)
|
|
|
|
, Field(field.PrepareForInput(DeviceAdapter()))
|
|
|
|
{
|
|
|
|
Locator = locator->PrepareForExecution(DeviceAdapter());
|
|
|
|
InterpolationHelper = interpolationHelper->PrepareForExecution(DeviceAdapter());
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Point>
|
|
|
|
VTKM_EXEC bool IsWithinSpatialBoundary(const Point point) const
|
|
|
|
{
|
|
|
|
vtkm::Id cellId;
|
|
|
|
Point parametric;
|
|
|
|
vtkm::exec::FunctorBase tmp;
|
|
|
|
|
|
|
|
Locator->FindCell(point, cellId, parametric, tmp);
|
|
|
|
return cellId != -1;
|
|
|
|
}
|
|
|
|
VTKM_EXEC
|
|
|
|
bool IsWithinTemporalBoundary(const vtkm::FloatDefault vtkmNotUsed(time)) const { return true; }
|
|
|
|
VTKM_EXEC
|
|
|
|
void GetSpatialBoundary(vtkm::Vec<vtkm::FloatDefault, 3>& dir,
|
|
|
|
vtkm::Vec<ScalarType, 3>& boundary) const
|
|
|
|
{
|
|
|
|
// Based on the direction of the velocity we need to be able to tell where
|
|
|
|
// the particle will exit the domain from to actually push it out of domain.
|
|
|
|
boundary[0] = static_cast<ScalarType>(dir[0] > 0 ? this->Bounds.X.Max : this->Bounds.X.Min);
|
|
|
|
boundary[1] = static_cast<ScalarType>(dir[1] > 0 ? this->Bounds.Y.Max : this->Bounds.Y.Min);
|
|
|
|
boundary[2] = static_cast<ScalarType>(dir[2] > 0 ? this->Bounds.Z.Max : this->Bounds.Z.Min);
|
|
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
|
|
void GetTemporalBoundary(vtkm::FloatDefault& boundary) const
|
|
|
|
{
|
|
|
|
// Return the time of the newest time slice
|
|
|
|
boundary = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Point>
|
|
|
|
VTKM_EXEC bool Evaluate(const Point& pos, vtkm::FloatDefault vtkmNotUsed(time), Point& out) const
|
|
|
|
{
|
|
|
|
return this->Evaluate(pos, out);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Point>
|
|
|
|
VTKM_EXEC bool Evaluate(const Point point, Point& out) const
|
|
|
|
{
|
|
|
|
vtkm::Id cellId;
|
|
|
|
Point parametric;
|
|
|
|
vtkm::exec::FunctorBase tmp;
|
|
|
|
Locator->FindCell(point, cellId, parametric, tmp);
|
|
|
|
if (cellId == -1)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
vtkm::UInt8 cellShape;
|
|
|
|
vtkm::IdComponent nVerts;
|
|
|
|
vtkm::VecVariable<vtkm::Id, 8> ptIndices;
|
|
|
|
vtkm::VecVariable<vtkm::Vec<vtkm::FloatDefault, 3>, 8> fieldValues;
|
|
|
|
InterpolationHelper->GetCellInfo(cellId, cellShape, nVerts, ptIndices);
|
|
|
|
|
|
|
|
for (vtkm::IdComponent i = 0; i < nVerts; i++)
|
|
|
|
fieldValues.Append(Field.Get(ptIndices[i]));
|
|
|
|
out = vtkm::exec::CellInterpolate(fieldValues, parametric, cellShape, tmp);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
const vtkm::exec::CellLocator* Locator;
|
|
|
|
const vtkm::exec::CellInterpolationHelper* InterpolationHelper;
|
|
|
|
vtkm::Bounds Bounds;
|
|
|
|
FieldPortalType Field;
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename FieldArrayType>
|
|
|
|
class GridEvaluator : public vtkm::cont::ExecutionObjectBase
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
using UniformType = vtkm::cont::ArrayHandleUniformPointCoordinates;
|
|
|
|
using AxisHandle = vtkm::cont::ArrayHandle<vtkm::FloatDefault>;
|
|
|
|
using RectilinearType =
|
|
|
|
vtkm::cont::ArrayHandleCartesianProduct<AxisHandle, AxisHandle, AxisHandle>;
|
|
|
|
using StructuredType = vtkm::cont::CellSetStructured<3>;
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
GridEvaluator() = default;
|
|
|
|
|
|
|
|
VTKM_CONT
|
|
|
|
GridEvaluator(const vtkm::cont::CoordinateSystem& coordinates,
|
|
|
|
const vtkm::cont::DynamicCellSet& cellset,
|
|
|
|
const FieldArrayType& field)
|
|
|
|
: Vectors(field)
|
|
|
|
, Bounds(coordinates.GetBounds())
|
|
|
|
{
|
|
|
|
if (cellset.IsSameType(StructuredType()))
|
|
|
|
{
|
|
|
|
if (coordinates.GetData().IsType<UniformType>())
|
|
|
|
{
|
|
|
|
vtkm::cont::CellLocatorUniformGrid locator;
|
|
|
|
locator.SetCoordinates(coordinates);
|
|
|
|
locator.SetCellSet(cellset);
|
|
|
|
locator.Update();
|
|
|
|
this->Locator = std::make_shared<vtkm::cont::CellLocatorUniformGrid>(locator);
|
|
|
|
}
|
|
|
|
else if (coordinates.GetData().IsType<RectilinearType>() &&
|
|
|
|
cellset.IsSameType(StructuredType()))
|
|
|
|
{
|
|
|
|
vtkm::cont::CellLocatorRectilinearGrid locator;
|
|
|
|
locator.SetCoordinates(coordinates);
|
|
|
|
locator.SetCellSet(cellset);
|
|
|
|
locator.Update();
|
|
|
|
this->Locator = std::make_shared<vtkm::cont::CellLocatorRectilinearGrid>(locator);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
throw vtkm::cont::ErrorInternal("Cells are not structured.");
|
|
|
|
|
|
|
|
vtkm::cont::StructuredCellInterpolationHelper interpolationHelper(cellset);
|
|
|
|
this->InterpolationHelper =
|
|
|
|
std::make_shared<vtkm::cont::StructuredCellInterpolationHelper>(interpolationHelper);
|
|
|
|
}
|
2019-02-20 20:37:42 +00:00
|
|
|
else if (cellset.IsSameType(vtkm::cont::CellSetSingleType<>()))
|
|
|
|
{
|
2019-03-15 17:40:48 +00:00
|
|
|
vtkm::cont::CellLocatorBoundingIntervalHierarchy locator;
|
2019-02-20 20:37:42 +00:00
|
|
|
locator.SetCoordinates(coordinates);
|
|
|
|
locator.SetCellSet(cellset);
|
|
|
|
locator.Update();
|
2019-03-15 17:40:48 +00:00
|
|
|
this->Locator = std::make_shared<vtkm::cont::CellLocatorBoundingIntervalHierarchy>(locator);
|
2019-02-20 20:37:42 +00:00
|
|
|
vtkm::cont::SingleCellExplicitInterpolationHelper interpolationHelper(cellset);
|
|
|
|
this->InterpolationHelper =
|
|
|
|
std::make_shared<vtkm::cont::SingleCellExplicitInterpolationHelper>(interpolationHelper);
|
|
|
|
}
|
|
|
|
else if (cellset.IsSameType(vtkm::cont::CellSetExplicit<>()))
|
|
|
|
{
|
2019-03-15 17:40:48 +00:00
|
|
|
vtkm::cont::CellLocatorBoundingIntervalHierarchy locator;
|
2019-02-20 20:37:42 +00:00
|
|
|
locator.SetCoordinates(coordinates);
|
|
|
|
locator.SetCellSet(cellset);
|
|
|
|
locator.Update();
|
2019-03-15 17:40:48 +00:00
|
|
|
this->Locator = std::make_shared<vtkm::cont::CellLocatorBoundingIntervalHierarchy>(locator);
|
2019-02-20 20:37:42 +00:00
|
|
|
vtkm::cont::CellExplicitInterpolationHelper interpolationHelper(cellset);
|
|
|
|
this->InterpolationHelper =
|
|
|
|
std::make_shared<vtkm::cont::CellExplicitInterpolationHelper>(interpolationHelper);
|
|
|
|
}
|
2019-01-30 18:47:27 +00:00
|
|
|
else
|
|
|
|
throw vtkm::cont::ErrorInternal("Unsupported cellset type.");
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename DeviceAdapter>
|
|
|
|
VTKM_CONT ExecutionGridEvaluator<DeviceAdapter, FieldArrayType> PrepareForExecution(
|
|
|
|
DeviceAdapter) const
|
|
|
|
{
|
|
|
|
return ExecutionGridEvaluator<DeviceAdapter, FieldArrayType>(
|
|
|
|
this->Locator, this->InterpolationHelper, this->Bounds, this->Vectors);
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
std::shared_ptr<vtkm::cont::CellLocator> Locator;
|
|
|
|
std::shared_ptr<vtkm::cont::CellInterpolationHelper> InterpolationHelper;
|
|
|
|
FieldArrayType Vectors;
|
|
|
|
vtkm::Bounds Bounds;
|
|
|
|
};
|
|
|
|
|
2017-06-30 19:26:15 +00:00
|
|
|
} //namespace particleadvection
|
|
|
|
} //namespace worklet
|
|
|
|
} //namespace vtkm
|
2017-04-18 20:49:03 +00:00
|
|
|
|
|
|
|
#endif // vtk_m_worklet_particleadvection_GridEvaluators_h
|