//============================================================================ // 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. //============================================================================ #ifndef vtk_m_filter_particle_density_base_h #define vtk_m_filter_particle_density_base_h #include #include namespace vtkm { namespace filter { // We only need the CoordinateSystem and scalar fields of the input dataset thus a FilterField template class ParticleDensityBase : public vtkm::filter::FilterDataSetWithField { public: // deposit scalar field associated with particles, e.g. mass/charge to mesh cells using SupportedTypes = vtkm::TypeListFieldScalar; protected: ParticleDensityBase(const vtkm::Id3& dimension, const vtkm::Vec3f& origin, const vtkm::Vec3f& spacing) : Dimension(dimension) , Origin(origin) , Spacing(spacing) , ComputeNumberDensity(false) , DivideByVolume(true) { } ParticleDensityBase(const vtkm::Id3& dimension, const vtkm::Bounds& bounds) : Dimension(dimension) , Origin({ static_cast(bounds.X.Min), static_cast(bounds.Y.Min), static_cast(bounds.Z.Min) }) , Spacing(vtkm::Vec3f{ static_cast(bounds.X.Length()), static_cast(bounds.Y.Length()), static_cast(bounds.Z.Length()) } / Dimension) , ComputeNumberDensity(false) , DivideByVolume(true) { } public: template VTKM_CONT vtkm::cont::DataSet PrepareForExecution(const vtkm::cont::DataSet& input, vtkm::filter::PolicyBase policy) { if (this->ComputeNumberDensity) { return static_cast(this)->DoExecute( input, vtkm::cont::make_ArrayHandleConstant(vtkm::FloatDefault{ 1 }, input.GetNumberOfPoints()), vtkm::filter::FieldMetadata{}, // Ignored policy); } else { return this->FilterDataSetWithField::PrepareForExecution(input, policy); } } template VTKM_CONT bool DoMapField(vtkm::cont::DataSet&, const vtkm::cont::ArrayHandle&, const vtkm::filter::FieldMetadata&, vtkm::filter::PolicyBase) { return false; } VTKM_CONT void SetComputeNumberDensity(bool yes) { this->ComputeNumberDensity = yes; } VTKM_CONT bool GetComputeNumberDensity() const { return this->ComputeNumberDensity; } VTKM_CONT void SetDivideByVolume(bool yes) { this->DivideByVolume = yes; } VTKM_CONT bool GetDivideByVolume() const { return this->DivideByVolume; } protected: vtkm::Id3 Dimension; // Cell dimension vtkm::Vec3f Origin; vtkm::Vec3f Spacing; bool ComputeNumberDensity; bool DivideByVolume; public: // conceptually protected but CUDA needs this to be public class DivideByVolumeWorklet : public vtkm::worklet::WorkletMapField { public: using ControlSignature = void(FieldInOut field); using ExecutionSignature = void(_1); VTKM_EXEC_CONT explicit DivideByVolumeWorklet(vtkm::Float64 volume) : Volume(volume) { } template VTKM_EXEC void operator()(T& value) const { value = static_cast(value / Volume); } private: vtkm::Float64 Volume; }; // class DivideByVolumeWorklet }; } } #endif //vtk_m_filter_particle_density_base_h