mirror of
https://gitlab.kitware.com/vtk/vtk-m
synced 2024-10-05 09:59:12 +00:00
c62e38bab6
With recent changes to `ArrayHandle`, the type for the associated array portal is now the same across all devices. This means that almost all exec objects no longer need to be specialized on the device types. Thus, clean up the locator exec objects to no longer need to be templated on device.
124 lines
4.6 KiB
C++
124 lines
4.6 KiB
C++
//============================================================================
|
|
// 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.
|
|
//
|
|
// Copyright 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
|
|
// Copyright 2014 UT-Battelle, LLC.
|
|
// Copyright 2017 Los Alamos National Security.
|
|
//
|
|
// Under the terms of Contract DE-NA0003525 with NTESS,
|
|
// the U.S. Government retains certain rights in this software.
|
|
//
|
|
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
|
|
// Laboratory (LANL), the U.S. Government retains certain rights in
|
|
// this software.
|
|
//============================================================================
|
|
#include <vtkm/cont/PointLocatorSparseGrid.h>
|
|
|
|
namespace vtkm
|
|
{
|
|
namespace cont
|
|
{
|
|
|
|
namespace internal
|
|
{
|
|
|
|
class BinPointsWorklet : public vtkm::worklet::WorkletMapField
|
|
{
|
|
public:
|
|
using ControlSignature = void(FieldIn coord, FieldOut label);
|
|
|
|
using ExecutionSignature = void(_1, _2);
|
|
|
|
VTKM_CONT
|
|
BinPointsWorklet(vtkm::Vec3f min, vtkm::Vec3f max, vtkm::Id3 dims)
|
|
: Min(min)
|
|
, Dims(dims)
|
|
, Dxdydz((max - Min) / Dims)
|
|
{
|
|
}
|
|
|
|
template <typename CoordVecType, typename IdType>
|
|
VTKM_EXEC void operator()(const CoordVecType& coord, IdType& label) const
|
|
{
|
|
vtkm::Id3 ijk = (coord - Min) / Dxdydz;
|
|
ijk = vtkm::Max(ijk, vtkm::Id3(0));
|
|
ijk = vtkm::Min(ijk, this->Dims - vtkm::Id3(1));
|
|
label = ijk[0] + ijk[1] * Dims[0] + ijk[2] * Dims[0] * Dims[1];
|
|
}
|
|
|
|
private:
|
|
vtkm::Vec3f Min;
|
|
vtkm::Id3 Dims;
|
|
vtkm::Vec3f Dxdydz;
|
|
};
|
|
|
|
} // internal
|
|
|
|
void PointLocatorSparseGrid::Build()
|
|
{
|
|
VTKM_LOG_SCOPE(vtkm::cont::LogLevel::Perf, "PointLocatorSparseGrid::Build");
|
|
|
|
if (this->IsRangeInvalid())
|
|
{
|
|
this->Range = this->GetCoordinates().GetRange();
|
|
}
|
|
|
|
auto rmin = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(this->Range[0].Min),
|
|
static_cast<vtkm::FloatDefault>(this->Range[1].Min),
|
|
static_cast<vtkm::FloatDefault>(this->Range[2].Min));
|
|
auto rmax = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(this->Range[0].Max),
|
|
static_cast<vtkm::FloatDefault>(this->Range[1].Max),
|
|
static_cast<vtkm::FloatDefault>(this->Range[2].Max));
|
|
|
|
// generate unique id for each input point
|
|
vtkm::cont::ArrayHandleCounting<vtkm::Id> pointCounting(
|
|
0, 1, this->GetCoordinates().GetNumberOfValues());
|
|
vtkm::cont::ArrayCopy(pointCounting, this->PointIds);
|
|
|
|
using internal::BinPointsWorklet;
|
|
|
|
// bin points into cells and give each of them the cell id.
|
|
vtkm::cont::ArrayHandle<vtkm::Id> cellIds;
|
|
BinPointsWorklet cellIdWorklet(rmin, rmax, this->Dims);
|
|
vtkm::worklet::DispatcherMapField<BinPointsWorklet> dispatchCellId(cellIdWorklet);
|
|
dispatchCellId.Invoke(this->GetCoordinates(), cellIds);
|
|
|
|
// Group points of the same cell together by sorting them according to the cell ids
|
|
vtkm::cont::Algorithm::SortByKey(cellIds, this->PointIds);
|
|
|
|
// for each cell, find the lower and upper bound of indices to the sorted point ids.
|
|
vtkm::cont::ArrayHandleCounting<vtkm::Id> cell_ids_counting(
|
|
0, 1, this->Dims[0] * this->Dims[1] * this->Dims[2]);
|
|
vtkm::cont::Algorithm::UpperBounds(cellIds, cell_ids_counting, this->CellUpper);
|
|
vtkm::cont::Algorithm::LowerBounds(cellIds, cell_ids_counting, this->CellLower);
|
|
}
|
|
|
|
VTKM_CONT void PointLocatorSparseGrid::PrepareExecutionObject(
|
|
ExecutionObjectHandleType& execObjHandle,
|
|
vtkm::cont::DeviceAdapterId device,
|
|
vtkm::cont::Token& token) const
|
|
{
|
|
auto rmin = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(this->Range[0].Min),
|
|
static_cast<vtkm::FloatDefault>(this->Range[1].Min),
|
|
static_cast<vtkm::FloatDefault>(this->Range[2].Min));
|
|
auto rmax = vtkm::make_Vec(static_cast<vtkm::FloatDefault>(this->Range[0].Max),
|
|
static_cast<vtkm::FloatDefault>(this->Range[1].Max),
|
|
static_cast<vtkm::FloatDefault>(this->Range[2].Max));
|
|
vtkm::exec::PointLocatorSparseGrid* h = new vtkm::exec::PointLocatorSparseGrid(
|
|
rmin,
|
|
rmax,
|
|
this->Dims,
|
|
this->GetCoordinates().GetDataAsMultiplexer().PrepareForInput(device, token),
|
|
this->PointIds.PrepareForInput(device, token),
|
|
this->CellLower.PrepareForInput(device, token),
|
|
this->CellUpper.PrepareForInput(device, token));
|
|
execObjHandle.Reset(h);
|
|
}
|
|
}
|
|
} // vtkm::cont
|