Trouble with f:R^2->C
As a minimal VTK-m example, I tried to build a complex function plot, such as this:
You sample it uniformly on the 2D plane, and then you have (r, theta) to graph in Paraview.
The original code was:
#include <complex>
#include <vtkm/cont/Initialize.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/io/writer/VTKDataSetWriter.h>
vtkm::cont::DataSet chirp_transform_dataset(double s_min, double s_max, double t_min, double t_max, int s_samples)
{
vtkm::cont::DataSetBuilderUniform dsb;
vtkm::Id2 dims(s_samples, s_samples);
vtkm::Vec2f_64 origin(t_min, s_min);
vtkm::Float64 ds = (s_max - s_min)/vtkm::Float64(dims[0] - 1);
vtkm::Float64 dt = (t_max - t_min)/vtkm::Float64(dims[1] - 1);
vtkm::Vec2f_64 spacing(dt, ds);
vtkm::cont::DataSet dataSet = dsb.Create(dims, origin, spacing);
vtkm::cont::DataSetFieldAdd dsf;
vtkm::Id nVerts = s_samples*s_samples;
std::vector<std::complex<double>> pointvar(nVerts);
vtkm::Id idx = 0;
for (vtkm::Id y = 0; y < dims[0]; ++y)
{
for (vtkm::Id x = 0; x < dims[1]; ++x)
{
double s = s_min + y*ds;
double t = t_min + x*dt;
pointvar[idx] = std::exp(std::complex<double>(s, t*t));
idx++;
}
}
dsf.AddPointField(dataSet, "complex_graph", pointvar.data(), pointvar.size());
return dataSet;
}
int main(int argc, char* argv[])
{
vtkm::cont::Initialize(argc, argv, vtkm::cont::InitializeOptions::Strict);
{
vtkm::cont::DataSet input = chirp_transform_dataset(0.00001, 1.0, -2.0, 2.0, 512);
vtkm::io::writer::VTKDataSetWriter writer("chirp.vtk");
writer.WriteDataSet(input);
}
return 0;
}
However, this fails with:
In file included from /usr/local/include/vtkm-1.4/vtkm/cont/testing/MakeTestDataSet.h:15:
In file included from /usr/local/include/vtkm-1.4/vtkm/cont/DataSet.h:16:
In file included from /usr/local/include/vtkm-1.4/vtkm/cont/CoordinateSystem.h:18:
In file included from /usr/local/include/vtkm-1.4/vtkm/cont/Field.h:22:
In file included from /usr/local/include/vtkm-1.4/vtkm/cont/VariantArrayHandle.h:25:
/usr/local/include/vtkm-1.4/vtkm/cont/internal/VariantArrayHandleContainer.h:97:66: error: no type named 'IsSizeStatic' in
'vtkm::VecTraits<std::__1::complex<double> >'
this->GetNumberOfComponents(typename vtkm::VecTraits<T>::IsSizeStatic{});
Is this a bug? I'm not sure, because it seems like VTK-m likes its own types a little better, so I replace std::vector<std::complex<double>> pointvar(nVerts);
by std::vector<vtkm::Vec2f_64> pointvar(nVerts);
and change the assignment to pointvar[idx] = {z.real(), z.imag()};
. That fixes the compilation problem, but when I write the .vtk
file, it fails with:
libc++abi.dylib: terminating with uncaught exception of type vtkm::cont::ErrorBadValue: Could not find appropriate cast for array in CastAndCall1.
Array: valueType=N4vtkm3VecIdLi2EEE storageType=N4vtkm4cont17StorageTagVirtualE numValues=262144 bytes=4194304 [(-0.65365,-0.75681) (-0.676977,-0.736017) (-0.699556,-0.714592) ... (-1.90157,-1.94244) (-1.8402,-2.00068) (-1.77679,-2.0572)]
TypeList: N4vtkm17TypeListTagCommonE
The code which reproduces this problem is:
#include <complex>
#include <vtkm/cont/Initialize.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/io/writer/VTKDataSetWriter.h>
vtkm::cont::DataSet chirp_transform_dataset(double s_min, double s_max, double t_min, double t_max, int s_samples)
{
vtkm::cont::DataSetBuilderUniform dsb;
vtkm::Id2 dims(s_samples, s_samples);
vtkm::Vec2f_64 origin(t_min, s_min);
vtkm::Float64 ds = (s_max - s_min)/vtkm::Float64(dims[0] - 1);
vtkm::Float64 dt = (t_max - t_min)/vtkm::Float64(dims[1] - 1);
vtkm::Vec2f_64 spacing(dt, ds);
vtkm::cont::DataSet dataSet = dsb.Create(dims, origin, spacing);
vtkm::cont::DataSetFieldAdd dsf;
vtkm::Id nVerts = s_samples*s_samples;
std::vector<vtkm::Vec2f_64> pointvar(nVerts);
vtkm::Id idx = 0;
for (vtkm::Id y = 0; y < dims[0]; ++y)
{
for (vtkm::Id x = 0; x < dims[1]; ++x)
{
double s = s_min + y*ds;
double t = t_min + x*dt;
auto z = std::exp(std::complex<double>(s, t*t));
pointvar[idx] = {z.real(), z.imag()};
idx++;
}
}
dsf.AddPointField(dataSet, "complex_graph", pointvar.data(), pointvar.size());
return dataSet;
}
int main(int argc, char* argv[])
{
vtkm::cont::Initialize(argc, argv, vtkm::cont::InitializeOptions::Strict);
{
vtkm::cont::DataSet input = chirp_transform_dataset(0.00001, 1.0, -2.0, 2.0, 512);
vtkm::io::writer::VTKDataSetWriter writer("chirp.vtk");
writer.WriteDataSet(input);
}
return 0;
}
On Mac, build on top of VTK-m commit 2796dc33.
Update: I got it to work by using two datasets:
std::vector<double> r(nVerts);
std::vector<double> theta(nVerts);
...
dsf.AddPointField(dataSet, "r", r.data(), r.size());
dsf.AddPointField(dataSet, "theta", theta.data(), theta.size());
I'll leave this open for now just in case my other two attempts against the problem were expected to work, or if the error messages should be cleaner. But I'm good.