CellSetPermutation.h 14.6 KB
Newer Older
1 2 3 4 5 6 7 8
//============================================================================
//  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.
//
9
//  Copyright 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
10 11 12
//  Copyright 2015 UT-Battelle, LLC.
//  Copyright 2015 Los Alamos National Security.
//
13
//  Under the terms of Contract DE-NA0003525 with NTESS,
14 15 16 17 18 19 20 21 22 23 24
//  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.
//============================================================================
#ifndef vtk_m_cont_CellSetPermutation_h
#define vtk_m_cont_CellSetPermutation_h

#include <vtkm/CellShape.h>
#include <vtkm/CellTraits.h>
25
#include <vtkm/cont/ArrayHandleCast.h>
26 27
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/CellSet.h>
28 29 30 31
#include <vtkm/cont/internal/ConnectivityExplicitInternals.h>
#include <vtkm/internal/ConnectivityStructuredInternals.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapTopology.h>
32 33

#include <vtkm/exec/ConnectivityPermuted.h>
34

35 36 37 38
#ifndef VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG
#define VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG VTKM_DEFAULT_STORAGE_TAG
#endif

39 40 41 42
namespace vtkm
{
namespace cont
{
43

44 45
namespace internal
{
46

47 48
struct WriteConnectivity : public vtkm::worklet::WorkletMapPointToCell
{
49
  using ControlSignature = void(CellSetIn cellset,
50 51
                                FieldInCell<IdType> offset,
                                WholeArrayOut<> connectivity);
52
  using ExecutionSignature = void(PointCount, PointIndices, _2, _3);
53
  using InputDomain = _1;
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70

  template <typename PointIndicesType, typename OutPortalType>
  VTKM_EXEC void operator()(vtkm::IdComponent pointcount,
                            const PointIndicesType& pointIndices,
                            vtkm::Id offset,
                            OutPortalType& connectivity) const
  {
    for (vtkm::IdComponent i = 0; i < pointcount; ++i)
    {
      connectivity.Set(offset++, pointIndices[i]);
    }
  }
};

// default for CellSetExplicit and CellSetSingleType
template <typename CellSetPermutationType>
class PointToCell
71
{
72 73 74 75 76 77 78
private:
  using NumIndicesArrayType = decltype(make_ArrayHandlePermutation(
    std::declval<CellSetPermutationType>().GetValidCellIds(),
    std::declval<CellSetPermutationType>().GetFullCellSet().GetNumIndicesArray(
      vtkm::TopologyElementTagPoint(),
      vtkm::TopologyElementTagCell())));

79
public:
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
  using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
    VTKM_DEFAULT_STORAGE_TAG, // dummy, shapes array is not used
    typename NumIndicesArrayType::StorageTag>;

  template <typename Device>
  static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
  {
    ConnectivityArrays conn;
    conn.NumIndices =
      NumIndicesArrayType(cellset.GetValidCellIds(),
                          cellset.GetFullCellSet().GetNumIndicesArray(
                            vtkm::TopologyElementTagPoint(), vtkm::TopologyElementTagCell()));
    vtkm::Id connectivityLength = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(
      vtkm::cont::make_ArrayHandleCast(conn.NumIndices, vtkm::Id()), conn.IndexOffsets);
    conn.Connectivity.Allocate(connectivityLength);
    vtkm::worklet::DispatcherMapTopology<WriteConnectivity, Device>().Invoke(
      cellset, conn.IndexOffsets, conn.Connectivity);

    return conn;
  }
};

// specialization for CellSetStructured
template <vtkm::IdComponent DIMENSION, typename PermutationArrayHandleType>
class PointToCell<CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>>
{
private:
  using CellSetPermutationType =
    CellSetPermutation<CellSetStructured<DIMENSION>, PermutationArrayHandleType>;

public:
  using ConnectivityArrays = vtkm::cont::internal::ConnectivityExplicitInternals<
    VTKM_DEFAULT_STORAGE_TAG, // dummy, shapes array is not used
    typename vtkm::cont::ArrayHandleConstant<vtkm::IdComponent>::StorageTag,
    VTKM_DEFAULT_STORAGE_TAG,
    typename vtkm::cont::ArrayHandleCounting<vtkm::Id>::StorageTag>;

  template <typename Device>
  static ConnectivityArrays Get(const CellSetPermutationType& cellset, Device)
  {
    vtkm::Id numberOfCells = cellset.GetNumberOfCells();
    vtkm::IdComponent numPointsInCell =
      vtkm::internal::ConnectivityStructuredInternals<DIMENSION>::NUM_POINTS_IN_CELL;
    vtkm::Id connectivityLength = numberOfCells * numPointsInCell;

    ConnectivityArrays conn;
    conn.NumIndices = make_ArrayHandleConstant(numPointsInCell, numberOfCells);
    conn.IndexOffsets = ArrayHandleCounting<vtkm::Id>(0, numPointsInCell, numberOfCells);
    conn.Connectivity.Allocate(connectivityLength);
    vtkm::worklet::DispatcherMapTopology<WriteConnectivity, Device>().Invoke(
      cellset, conn.IndexOffsets, conn.Connectivity);

    return conn;
  }
};

template <typename CellSetPermutationType>
struct CellSetPermutationTraits;

template <typename OriginalCellSet_, typename PermutationArrayHandleType_>
struct CellSetPermutationTraits<CellSetPermutation<OriginalCellSet_, PermutationArrayHandleType_>>
{
  using OriginalCellSet = OriginalCellSet_;
  using PermutationArrayHandleType = PermutationArrayHandleType_;
};

template <typename OriginalCellSet_,
          typename OriginalPermutationArrayHandleType,
          typename PermutationArrayHandleType_>
struct CellSetPermutationTraits<
  CellSetPermutation<CellSetPermutation<OriginalCellSet_, OriginalPermutationArrayHandleType>,
                     PermutationArrayHandleType_>>
{
  using PreviousCellSet = CellSetPermutation<OriginalCellSet_, OriginalPermutationArrayHandleType>;
  using PermutationArrayHandleType = vtkm::cont::ArrayHandlePermutation<
    PermutationArrayHandleType_,
    typename CellSetPermutationTraits<PreviousCellSet>::PermutationArrayHandleType>;
  using OriginalCellSet = typename CellSetPermutationTraits<PreviousCellSet>::OriginalCellSet;
  using Superclass = CellSetPermutation<OriginalCellSet, PermutationArrayHandleType>;
};

} // internal

template <typename OriginalCellSetType_,
          typename PermutationArrayHandleType_ =
            vtkm::cont::ArrayHandle<vtkm::Id, VTKM_DEFAULT_CELLSET_PERMUTATION_STORAGE_TAG>>
class CellSetPermutation : public CellSet
{
public:
  using OriginalCellSetType = OriginalCellSetType_;
  using PermutationArrayHandleType = PermutationArrayHandleType_;

172
  VTKM_CONT
173 174 175
  CellSetPermutation(const PermutationArrayHandleType& validCellIds,
                     const OriginalCellSetType& cellset,
                     const std::string& name = std::string())
176 177 178
    : CellSet(name)
    , ValidCellIds(validCellIds)
    , FullCellSet(cellset)
179 180 181
  {
  }

182
  VTKM_CONT
183
  CellSetPermutation(const std::string& name = std::string())
184 185 186
    : CellSet(name)
    , ValidCellIds()
    , FullCellSet()
187 188 189
  {
  }

190
  VTKM_CONT
191
  const OriginalCellSetType& GetFullCellSet() const { return this->FullCellSet; }
192

193
  VTKM_CONT
194
  const PermutationArrayHandleType& GetValidCellIds() const { return this->ValidCellIds; }
195

196 197
  VTKM_CONT
  vtkm::Id GetNumberOfCells() const override { return this->ValidCellIds.GetNumberOfValues(); }
198

199 200 201 202 203 204 205 206 207 208 209 210 211 212 213
  VTKM_CONT
  vtkm::Id GetNumberOfPoints() const override { return this->FullCellSet.GetNumberOfPoints(); }

  VTKM_CONT
  vtkm::Id GetNumberOfFaces() const override { return -1; }

  VTKM_CONT
  vtkm::Id GetNumberOfEdges() const override { return -1; }

  VTKM_CONT
  vtkm::IdComponent GetNumberOfPointsInCell(vtkm::Id cellIndex) const
  {
    return this->FullCellSet.GetNumberOfPointsInCell(
      this->ValidCellIds.GetPortalConstControl().Get(cellIndex));
  }
214

215
  //This is the way you can fill the memory from another system without copying
216
  VTKM_CONT
217
  void Fill(const PermutationArrayHandleType& validCellIds, const OriginalCellSetType& cellset)
218
  {
219 220
    this->ValidCellIds = validCellIds;
    this->FullCellSet = cellset;
221 222
  }

223
  VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagCell) const
224
  {
225 226 227
    return this->ValidCellIds.GetNumberOfValues();
  }

228 229 230 231 232
  VTKM_CONT vtkm::Id GetSchedulingRange(vtkm::TopologyElementTagPoint) const
  {
    return this->FullCellSet.GetNumberOfPoints();
  }

233
  template <typename Device, typename FromTopology, typename ToTopology>
234 235 236 237
  struct ExecutionTypes;

  template <typename Device>
  struct ExecutionTypes<Device, vtkm::TopologyElementTagPoint, vtkm::TopologyElementTagCell>
238
  {
239 240
    VTKM_IS_DEVICE_ADAPTER_TAG(Device);

241 242 243 244 245 246
    using ExecPortalType =
      typename PermutationArrayHandleType::template ExecutionTypes<Device>::PortalConst;
    using OrigExecObjectType = typename OriginalCellSetType::template ExecutionTypes<
      Device,
      vtkm::TopologyElementTagPoint,
      vtkm::TopologyElementTagCell>::ExecObjectType;
247

248 249 250
    using ExecObjectType =
      vtkm::exec::ConnectivityPermutedPointToCell<ExecPortalType, OrigExecObjectType>;
  };
251

252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
  template <typename Device>
  struct ExecutionTypes<Device, vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint>
  {
    VTKM_IS_DEVICE_ADAPTER_TAG(Device);

    using ConnectiviyPortalType =
      typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;
    using NumIndicesPortalType = typename vtkm::cont::ArrayHandle<
      vtkm::IdComponent>::template ExecutionTypes<Device>::PortalConst;
    using IndexOffsetPortalType =
      typename vtkm::cont::ArrayHandle<vtkm::Id>::template ExecutionTypes<Device>::PortalConst;

    using ExecObjectType = vtkm::exec::ConnectivityPermutedCellToPoint<ConnectiviyPortalType,
                                                                       NumIndicesPortalType,
                                                                       IndexOffsetPortalType>;
267 268
  };

269 270 271 272 273 274 275 276 277 278 279 280 281
  template <typename Device>
  VTKM_CONT typename ExecutionTypes<Device,
                                    vtkm::TopologyElementTagPoint,
                                    vtkm::TopologyElementTagCell>::ExecObjectType
  PrepareForInput(Device device,
                  vtkm::TopologyElementTagPoint from,
                  vtkm::TopologyElementTagCell to) const
  {
    using ConnectivityType = typename ExecutionTypes<Device,
                                                     vtkm::TopologyElementTagPoint,
                                                     vtkm::TopologyElementTagCell>::ExecObjectType;
    return ConnectivityType(this->ValidCellIds.PrepareForInput(device),
                            this->FullCellSet.PrepareForInput(device, from, to));
282 283 284
  }

  template <typename Device>
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
  VTKM_CONT typename ExecutionTypes<Device,
                                    vtkm::TopologyElementTagCell,
                                    vtkm::TopologyElementTagPoint>::ExecObjectType
  PrepareForInput(Device device, vtkm::TopologyElementTagCell, vtkm::TopologyElementTagPoint) const
  {
    if (!this->CellToPoint.ElementsValid)
    {
      auto pointToCell = internal::PointToCell<CellSetPermutation>::Get(*this, device);
      internal::ComputeCellToPointConnectivity(
        this->CellToPoint, pointToCell, this->GetNumberOfPoints(), device);
      this->CellToPoint.BuildIndexOffsets(device);
    }

    using ConnectivityType = typename ExecutionTypes<Device,
                                                     vtkm::TopologyElementTagCell,
                                                     vtkm::TopologyElementTagPoint>::ExecObjectType;
    return ConnectivityType(this->CellToPoint.Connectivity.PrepareForInput(device),
                            this->CellToPoint.NumIndices.PrepareForInput(device),
                            this->CellToPoint.IndexOffsets.PrepareForInput(device));
304 305
  }

306 307
  VTKM_CONT
  void PrintSummary(std::ostream& out) const override
308
  {
309
    out << "CellSetPermutation of: " << std::endl;
310
    this->FullCellSet.PrintSummary(out);
311 312
    out << "Permutation Array: " << std::endl;
    vtkm::cont::printSummary_ArrayHandle(this->ValidCellIds, out);
313 314 315
  }

private:
316 317 318
  using CellToPointConnectivity = vtkm::cont::internal::ConnectivityExplicitInternals<
    typename ArrayHandleConstant<vtkm::UInt8>::StorageTag>;

319
  PermutationArrayHandleType ValidCellIds;
320 321
  OriginalCellSetType FullCellSet;
  mutable CellToPointConnectivity CellToPoint;
322 323
};

324 325 326 327 328 329 330 331
template <typename CellSetType,
          typename PermutationArrayHandleType1,
          typename PermutationArrayHandleType2>
class CellSetPermutation<CellSetPermutation<CellSetType, PermutationArrayHandleType1>,
                         PermutationArrayHandleType2>
  : public internal::CellSetPermutationTraits<
      CellSetPermutation<CellSetPermutation<CellSetType, PermutationArrayHandleType1>,
                         PermutationArrayHandleType2>>::Superclass
332
{
333 334
private:
  using Superclass = typename internal::CellSetPermutationTraits<CellSetPermutation>::Superclass;
335

336
public:
337
  VTKM_CONT
338 339
  CellSetPermutation(const PermutationArrayHandleType2& validCellIds,
                     const CellSetPermutation<CellSetType, PermutationArrayHandleType1>& cellset,
340
                     const std::string& name = std::string())
341 342 343
    : Superclass(vtkm::cont::make_ArrayHandlePermutation(validCellIds, cellset.GetValidCellIds()),
                 cellset.GetFullCellSet(),
                 name)
344 345 346
  {
  }

347
  VTKM_CONT
348
  CellSetPermutation(const std::string& name = std::string())
349
    : Superclass(name)
350 351
  {
  }
352

353
  VTKM_CONT
354 355
  void Fill(const PermutationArrayHandleType2& validCellIds,
            const CellSetPermutation<CellSetType, PermutationArrayHandleType1>& cellset)
356
  {
357 358
    this->ValidCellIds = make_ArrayHandlePermutation(validCellIds, cellset.GetValidCellIds());
    this->FullCellSet = cellset.GetFullCellSet();
359
  }
360 361
};

362 363
template <typename OriginalCellSet, typename PermutationArrayHandleType>
vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType> make_CellSetPermutation(
364 365
  const PermutationArrayHandleType& cellIndexMap,
  const OriginalCellSet& cellSet,
366
  const std::string& name)
367 368 369 370
{
  VTKM_IS_CELL_SET(OriginalCellSet);
  VTKM_IS_ARRAY_HANDLE(PermutationArrayHandleType);

371 372
  return vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType>(
    cellIndexMap, cellSet, name);
373 374
}

375 376
template <typename OriginalCellSet, typename PermutationArrayHandleType>
vtkm::cont::CellSetPermutation<OriginalCellSet, PermutationArrayHandleType> make_CellSetPermutation(
377 378
  const PermutationArrayHandleType& cellIndexMap,
  const OriginalCellSet& cellSet)
379 380 381 382
{
  VTKM_IS_CELL_SET(OriginalCellSet);
  VTKM_IS_ARRAY_HANDLE(PermutationArrayHandleType);

383
  return vtkm::cont::make_CellSetPermutation(cellIndexMap, cellSet, cellSet.GetName());
384
}
385 386 387 388
}
} // namespace vtkm::cont

#endif //vtk_m_cont_CellSetPermutation_h