Commit 4192b9a1 authored by Sebastien Jourdain's avatar Sebastien Jourdain Committed by David Thompson

Add a point-oscillator filter + example

The oscillator is a simple analytical source of time-varying data.
It provides a function value at each point that is computed as a
sum of Gaussian kernels -- each with a specified position, amplitude,
frequency, and phase.
parent 776d0854
.DS_Store
# Time-varying "oscillator" source-filter and example
The oscillator is a simple analytical source of time-varying data.
It provides a function value at each point of a uniform grid that
is computed as a sum of Gaussian kernels — each with a specified
position, amplitude, frequency, and phase.
The example (in `examples/oscillator`) generates volumetric Cinema
datasets that can be viewed in a web browser with [ArcticViewer][].
[ArcticViewer]: https://kitware.github.io/arctic-viewer/
......@@ -33,6 +33,7 @@ add_subdirectory(hello_world)
add_subdirectory(histogram)
add_subdirectory(isosurface)
add_subdirectory(multi_backend)
add_subdirectory(oscillator)
add_subdirectory(particle_advection)
add_subdirectory(temporal_advection)
add_subdirectory(redistribute_points)
......
##=============================================================================
##
## 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 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
## Copyright 2015 UT-Battelle, LLC.
## Copyright 2015 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.
##
##=============================================================================
cmake_minimum_required(VERSION 3.3...3.12 FATAL_ERROR)
project(Oscillator CXX)
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET)
add_executable(Oscillator_SERIAL Oscillator.cxx)
target_compile_definitions(Oscillator_SERIAL PRIVATE
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_SERIAL")
target_link_libraries(Oscillator_SERIAL PRIVATE vtkm_cont)
if (TARGET vtkm::tbb)
add_executable(Oscillator_TBB Oscillator.cxx)
target_compile_definitions(Oscillator_TBB PRIVATE
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_TBB")
target_link_libraries(Oscillator_TBB PRIVATE vtkm_cont)
endif()
if (TARGET vtkm::cuda)
vtkm_compile_as_cuda(oscillatorCudaSrc Oscillator.cxx)
add_executable(Oscillator_CUDA ${oscillatorCudaSrc})
target_compile_definitions(Oscillator_CUDA PRIVATE
"VTKM_DEVICE_ADAPTER=VTKM_DEVICE_ADAPTER_CUDA")
target_link_libraries(Oscillator_CUDA PRIVATE vtkm_cont)
endif()
This diff is collapsed.
# type center r omega0 zeta
periodic 44 44 64 35 0.785
periodic 128 44 64 35 1.57
periodic 212 44 64 35 2.355
periodic 44 128 64 35 3.14
periodic 128 128 64 35 3.925
periodic 212 128 64 35 4.71
periodic 44 212 64 35 5.495
periodic 128 212 64 35 6.28
periodic 212 212 64 35 7.065
periodic 86 86 64 20 7.065
periodic 86 170 64 20 5.495
periodic 168 86 64 20 3.14
periodic 170 170 64 20 1.57
# type center r omega0 zeta
periodic 16 16 16 8 3.14
periodic 16 16 48 8 3.14
periodic 16 48 16 8 3.14
periodic 16 48 48 8 3.14
periodic 48 16 16 8 3.14
periodic 48 16 48 8 3.14
periodic 48 48 16 8 3.14
periodic 48 48 48 8 3.14
# type center r omega0 zeta
damped 32 32 32 10. 3.14 .3
damped 16 32 16 10. 9.5 .1
damped 48 32 48 5. 3.14 .1
decaying 16 32 48 15 3.14
periodic 48 32 16 15 3.14
......@@ -49,6 +49,7 @@ set(headers
MaskPoints.h
NDEntropy.h
NDHistogram.h
OscillatorSource.h
PointAverage.h
PointElevation.h
PointTransform.h
......@@ -93,6 +94,7 @@ set(header_template_sources
MaskPoints.hxx
NDEntropy.hxx
NDHistogram.hxx
OscillatorSource.hxx
PointAverage.hxx
PointElevation.hxx
PointTransform.hxx
......
//============================================================================
// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 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.
//============================================================================
#ifndef vtk_m_filter_OscillatorSource_h
#define vtk_m_filter_OscillatorSource_h
#include "vtkm/filter/FilterField.h"
#include "vtkm/worklet/OscillatorSource.h"
namespace vtkm
{
namespace filter
{
/**\brief An analytical, time-varying array-source filter.
*
* This filter will create a new array (named "oscillation" by default)
* that evaluates to a sum of time-varying Gaussian exponentials
* specified in its configuration.
*/
class OscillatorSource : public vtkm::filter::FilterField<OscillatorSource>
{
public:
VTKM_CONT
OscillatorSource();
VTKM_CONT
void SetTime(vtkm::Float64 time);
VTKM_CONT
void AddPeriodic(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta);
VTKM_CONT
void AddDamped(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta);
VTKM_CONT
void AddDecaying(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta);
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
VTKM_CONT vtkm::cont::DataSet DoExecute(const vtkm::cont::DataSet& input,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMeta,
const vtkm::filter::PolicyBase<DerivedPolicy>& policy,
const DeviceAdapter& tag);
private:
vtkm::worklet::OscillatorSource Worklet;
};
template <>
class FilterTraits<OscillatorSource>
{
public:
//Point Oscillator can only convert Float and Double Vec3 arrays
using InputFieldTypeList = vtkm::TypeListTagFieldVec3;
};
}
}
#include "vtkm/filter/OscillatorSource.hxx"
#endif // vtk_m_filter_OscillatorSource_h
//============================================================================
// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 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/worklet/DispatcherMapField.h>
#include <vtkm/filter/internal/CreateResult.h>
namespace vtkm
{
namespace filter
{
//-----------------------------------------------------------------------------
inline VTKM_CONT OscillatorSource::OscillatorSource()
: Worklet()
{
this->SetUseCoordinateSystemAsField(true);
this->SetOutputFieldName("oscillation");
}
//-----------------------------------------------------------------------------
inline VTKM_CONT void OscillatorSource::SetTime(vtkm::Float64 time)
{
this->Worklet.SetTime(time);
}
//-----------------------------------------------------------------------------
inline VTKM_CONT void OscillatorSource::AddPeriodic(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta)
{
this->Worklet.AddPeriodic(x, y, z, radius, omega, zeta);
}
//-----------------------------------------------------------------------------
inline VTKM_CONT void OscillatorSource::AddDamped(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta)
{
this->Worklet.AddDamped(x, y, z, radius, omega, zeta);
}
//-----------------------------------------------------------------------------
inline VTKM_CONT void OscillatorSource::AddDecaying(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta)
{
this->Worklet.AddDecaying(x, y, z, radius, omega, zeta);
}
//-----------------------------------------------------------------------------
template <typename T, typename StorageType, typename DerivedPolicy, typename DeviceAdapter>
inline VTKM_CONT vtkm::cont::DataSet OscillatorSource::DoExecute(
const vtkm::cont::DataSet& inDataSet,
const vtkm::cont::ArrayHandle<T, StorageType>& field,
const vtkm::filter::FieldMetadata& fieldMetadata,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const DeviceAdapter&)
{
vtkm::cont::ArrayHandle<vtkm::Float64> outArray;
vtkm::worklet::DispatcherMapField<vtkm::worklet::OscillatorSource, DeviceAdapter> dispatcher(
this->Worklet);
//todo, we need to use the policy to determine the valid conversions
//that the dispatcher should do
dispatcher.Invoke(field, outArray);
return internal::CreateResult(inDataSet,
outArray,
this->GetOutputFieldName(),
fieldMetadata.GetAssociation(),
fieldMetadata.GetCellSetName());
}
}
} // namespace vtkm::filter
......@@ -53,6 +53,7 @@ set(headers
NDimsHistogram.h
NDimsHistMarginalization.h
Normalize.h
OscillatorSource.h
ParticleAdvection.h
PointAverage.h
PointElevation.h
......
//============================================================================
// 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 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 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.
//============================================================================
#ifndef vtk_m_worklet_OscillatorSource_h
#define vtk_m_worklet_OscillatorSource_h
#include <vtkm/Math.h>
#include <vtkm/worklet/WorkletMapField.h>
#define MAX_OSCILLATORS 10
namespace vtkm
{
namespace worklet
{
namespace internal
{
struct Oscillator
{
void Set(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta)
{
this->Center[0] = x;
this->Center[1] = y;
this->Center[2] = z;
this->Radius = radius;
this->Omega = omega;
this->Zeta = zeta;
}
vtkm::Vec<vtkm::Float64, 3> Center;
vtkm::Float64 Radius;
vtkm::Float64 Omega;
vtkm::Float64 Zeta;
};
}
class OscillatorSource : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<Vec3>, FieldOut<Scalar>);
typedef _2 ExecutionSignature(_1);
VTKM_CONT
OscillatorSource()
: NumberOfPeriodics(0)
, NumberOfDamped(0)
, NumberOfDecaying(0)
{
}
VTKM_CONT
void AddPeriodic(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta)
{
if (this->NumberOfPeriodics < MAX_OSCILLATORS)
{
this->PeriodicOscillators[this->NumberOfPeriodics].Set(x, y, z, radius, omega, zeta);
this->NumberOfPeriodics++;
}
}
VTKM_CONT
void AddDamped(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta)
{
if (this->NumberOfDamped < MAX_OSCILLATORS)
{
this->DampedOscillators[this->NumberOfDamped * 6].Set(x, y, z, radius, omega, zeta);
this->NumberOfDamped++;
}
}
VTKM_CONT
void AddDecaying(vtkm::Float64 x,
vtkm::Float64 y,
vtkm::Float64 z,
vtkm::Float64 radius,
vtkm::Float64 omega,
vtkm::Float64 zeta)
{
if (this->NumberOfDecaying < MAX_OSCILLATORS)
{
this->DecayingOscillators[this->NumberOfDecaying * 6].Set(x, y, z, radius, omega, zeta);
this->NumberOfDecaying++;
}
}
VTKM_CONT
void SetTime(vtkm::Float64 time) { this->Time = time; }
VTKM_EXEC
vtkm::Float64 operator()(const vtkm::Vec<vtkm::Float64, 3>& vec) const
{
vtkm::UInt8 oIdx;
vtkm::Float64 t0, t, result = 0;
const internal::Oscillator* oscillator;
t0 = 0.0;
t = this->Time * 2 * 3.14159265358979323846;
// Compute damped
for (oIdx = 0; oIdx < this->NumberOfDamped; oIdx++)
{
oscillator = &this->DampedOscillators[oIdx];
vtkm::Vec<vtkm::Float64, 3> delta = oscillator->Center - vec;
vtkm::Float64 dist2 = dot(delta, delta);
vtkm::Float64 dist_damp = vtkm::Exp(-dist2 / (2 * oscillator->Radius * oscillator->Radius));
vtkm::Float64 phi = vtkm::ACos(oscillator->Zeta);
vtkm::Float64 val = 1. -
vtkm::Exp(-oscillator->Zeta * oscillator->Omega * t0) *
(vtkm::Sin(vtkm::Sqrt(1 - oscillator->Zeta * oscillator->Zeta) * oscillator->Omega * t +
phi) /
vtkm::Sin(phi));
result += val * dist_damp;
}
// Compute decaying
for (oIdx = 0; oIdx < this->NumberOfDecaying; oIdx++)
{
oscillator = &this->DecayingOscillators[oIdx];
t = t0 + 1 / oscillator->Omega;
vtkm::Vec<vtkm::Float64, 3> delta = oscillator->Center - vec;
vtkm::Float64 dist2 = dot(delta, delta);
vtkm::Float64 dist_damp = vtkm::Exp(-dist2 / (2 * oscillator->Radius * oscillator->Radius));
vtkm::Float64 val = vtkm::Sin(t / oscillator->Omega) / (oscillator->Omega * t);
result += val * dist_damp;
}
// Compute periodic
for (oIdx = 0; oIdx < this->NumberOfPeriodics; oIdx++)
{
oscillator = &this->PeriodicOscillators[oIdx];
t = t0 + 1 / oscillator->Omega;
vtkm::Vec<vtkm::Float64, 3> delta = oscillator->Center - vec;
vtkm::Float64 dist2 = dot(delta, delta);
vtkm::Float64 dist_damp = vtkm::Exp(-dist2 / (2 * oscillator->Radius * oscillator->Radius));
vtkm::Float64 val = vtkm::Sin(t / oscillator->Omega);
result += val * dist_damp;
}
// We are done...
return result;
}
template <typename T>
VTKM_EXEC vtkm::Float64 operator()(const vtkm::Vec<T, 3>& vec) const
{
return (*this)(vtkm::make_Vec(static_cast<vtkm::Float64>(vec[0]),
static_cast<vtkm::Float64>(vec[1]),
static_cast<vtkm::Float64>(vec[2])));
}
private:
vtkm::Vec<internal::Oscillator, MAX_OSCILLATORS> PeriodicOscillators;
vtkm::Vec<internal::Oscillator, MAX_OSCILLATORS> DampedOscillators;
vtkm::Vec<internal::Oscillator, MAX_OSCILLATORS> DecayingOscillators;
vtkm::UInt8 NumberOfPeriodics;
vtkm::UInt8 NumberOfDamped;
vtkm::UInt8 NumberOfDecaying;
vtkm::Float64 Time;
};
}
} // namespace vtkm
#endif // vtk_m_worklet_PointElevation_h
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment