1 //============================================================================
2 // Copyright (c) Kitware, Inc.
3 // All rights reserved.
4 // See LICENSE.txt for details.
5 //
6 // This software is distributed WITHOUT ANY WARRANTY; without even
7 // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
8 // PURPOSE. See the above copyright notice for more information.
9 //============================================================================
10
11 #include <vtkm/cont/CellSetStructured.h>
12 #include <vtkm/cont/DataSetBuilderUniform.h>
13 #include <vtkm/cont/DynamicCellSet.h>
14 #include <vtkm/cont/testing/MakeTestDataSet.h>
15 #include <vtkm/cont/testing/Testing.h>
16
17 #include <algorithm>
18 #include <random>
19 #include <time.h>
20 #include <vector>
21
22 namespace DataSetBuilderUniformNamespace
23 {
24
25 std::mt19937 g_RandomGenerator;
26
ValidateDataSet(const vtkm::cont::DataSet & ds,int dim,vtkm::Id numPoints,vtkm::Id numCells,vtkm::Bounds bounds)27 void ValidateDataSet(const vtkm::cont::DataSet& ds,
28 int dim,
29 vtkm::Id numPoints,
30 vtkm::Id numCells,
31 vtkm::Bounds bounds)
32 {
33 //Verify basics..
34
35 VTKM_TEST_ASSERT(ds.GetNumberOfFields() == 2, "Wrong number of fields.");
36 VTKM_TEST_ASSERT(ds.GetNumberOfCoordinateSystems() == 1, "Wrong number of coordinate systems.");
37 VTKM_TEST_ASSERT(ds.GetNumberOfPoints() == numPoints, "Wrong number of coordinates.");
38 VTKM_TEST_ASSERT(ds.GetNumberOfCells() == numCells, "Wrong number of cells.");
39
40 // test various field-getting methods and associations
41 try
42 {
43 ds.GetCellField("cellvar");
44 }
45 catch (...)
46 {
47 VTKM_TEST_FAIL("Failed to get field 'cellvar' with Association::CELL_SET.");
48 }
49
50 try
51 {
52 ds.GetPointField("pointvar");
53 }
54 catch (...)
55 {
56 VTKM_TEST_FAIL("Failed to get field 'pointvar' with ASSOC_POINT_SET.");
57 }
58
59 //Make sure bounds are correct.
60 vtkm::Bounds res = ds.GetCoordinateSystem().GetBounds();
61 VTKM_TEST_ASSERT(test_equal(bounds, res), "Bounds of coordinates do not match");
62 if (dim == 1)
63 {
64 vtkm::cont::CellSetStructured<1> cellSet;
65 ds.GetCellSet().CopyTo(cellSet);
66 vtkm::IdComponent shape = cellSet.GetCellShape();
67 VTKM_TEST_ASSERT(shape == vtkm::CELL_SHAPE_LINE, "Wrong element type");
68 }
69 else if (dim == 2)
70 {
71 vtkm::cont::CellSetStructured<2> cellSet;
72 ds.GetCellSet().CopyTo(cellSet);
73 vtkm::IdComponent shape = cellSet.GetCellShape();
74 VTKM_TEST_ASSERT(shape == vtkm::CELL_SHAPE_QUAD, "Wrong element type");
75 }
76 else if (dim == 3)
77 {
78 vtkm::cont::CellSetStructured<3> cellSet;
79 ds.GetCellSet().CopyTo(cellSet);
80 vtkm::IdComponent shape = cellSet.GetCellShape();
81 VTKM_TEST_ASSERT(shape == vtkm::CELL_SHAPE_HEXAHEDRON, "Wrong element type");
82 }
83 }
84
85 template <typename T>
FillMethod(vtkm::IdComponent method,vtkm::Id dimensionSize,T & origin,T & spacing)86 vtkm::Range FillMethod(vtkm::IdComponent method, vtkm::Id dimensionSize, T& origin, T& spacing)
87 {
88 switch (method)
89 {
90 case 0:
91 origin = 0;
92 spacing = 1;
93 break;
94 case 1:
95 origin = 0;
96 spacing = static_cast<T>(1.0 / static_cast<double>(dimensionSize));
97 break;
98 case 2:
99 origin = 0;
100 spacing = 2;
101 break;
102 case 3:
103 origin = static_cast<T>(-(dimensionSize - 1));
104 spacing = 1;
105 break;
106 case 4:
107 origin = static_cast<T>(2.780941);
108 spacing = static_cast<T>(182.381901);
109 break;
110 default:
111 origin = 0;
112 spacing = 0;
113 break;
114 }
115
116 return vtkm::Range(origin, origin + static_cast<T>(dimensionSize - 1) * spacing);
117 }
118
GetRangeByIndex(vtkm::Bounds & bounds,int comp)119 vtkm::Range& GetRangeByIndex(vtkm::Bounds& bounds, int comp)
120 {
121 VTKM_ASSERT(comp >= 0 && comp < 3);
122 switch (comp)
123 {
124 case 0:
125 return bounds.X;
126 case 1:
127 return bounds.Y;
128 default:
129 return bounds.Z;
130 }
131 }
132
133 template <typename T>
UniformTests()134 void UniformTests()
135 {
136 const vtkm::Id NUM_TRIALS = 10;
137 const vtkm::Id MAX_DIM_SIZE = 20;
138 const vtkm::Id NUM_FILL_METHODS = 5;
139
140 vtkm::cont::DataSetBuilderUniform dataSetBuilder;
141
142 std::uniform_int_distribution<vtkm::Id> randomDim(2, MAX_DIM_SIZE);
143 std::uniform_int_distribution<vtkm::IdComponent> randomFill(0, NUM_FILL_METHODS - 1);
144 std::uniform_int_distribution<vtkm::IdComponent> randomAxis(0, 2);
145
146 for (vtkm::Id trial = 0; trial < NUM_TRIALS; trial++)
147 {
148 std::cout << "Trial " << trial << std::endl;
149
150 vtkm::Id3 dimensions(
151 randomDim(g_RandomGenerator), randomDim(g_RandomGenerator), randomDim(g_RandomGenerator));
152
153 vtkm::IdComponent fillMethodX = randomFill(g_RandomGenerator);
154 vtkm::IdComponent fillMethodY = randomFill(g_RandomGenerator);
155 vtkm::IdComponent fillMethodZ = randomFill(g_RandomGenerator);
156 std::cout << "Fill methods: [" << fillMethodX << "," << fillMethodY << "," << fillMethodZ << "]"
157 << std::endl;
158
159 vtkm::Vec<T, 3> origin;
160 vtkm::Vec<T, 3> spacing;
161 vtkm::Range ranges[3];
162 ranges[0] = FillMethod(fillMethodX, dimensions[0], origin[0], spacing[0]);
163 ranges[1] = FillMethod(fillMethodY, dimensions[1], origin[1], spacing[1]);
164 ranges[2] = FillMethod(fillMethodZ, dimensions[2], origin[2], spacing[2]);
165
166 std::cout << "3D cellset" << std::endl;
167 {
168 vtkm::Id3 dims = dimensions;
169 vtkm::Bounds bounds(ranges[0], ranges[1], ranges[2]);
170
171 std::cout << "\tdimensions: " << dims << std::endl;
172 std::cout << "\toriging: " << origin << std::endl;
173 std::cout << "\tspacing: " << spacing << std::endl;
174 std::cout << "\tbounds: " << bounds << std::endl;
175
176 vtkm::Id numPoints = dims[0] * dims[1] * dims[2];
177 vtkm::Id numCells = (dims[0] - 1) * (dims[1] - 1) * (dims[2] - 1);
178
179 std::vector<T> pointvar(static_cast<unsigned long>(numPoints));
180 std::iota(pointvar.begin(), pointvar.end(), T(1.1));
181 std::vector<T> cellvar(static_cast<unsigned long>(numCells));
182 std::iota(cellvar.begin(), cellvar.end(), T(1.1));
183
184 vtkm::cont::DataSet dataSet;
185 dataSet = dataSetBuilder.Create(dims, origin, spacing);
186 dataSet.AddPointField("pointvar", pointvar);
187 dataSet.AddCellField("cellvar", cellvar);
188
189 ValidateDataSet(dataSet, 3, numPoints, numCells, bounds);
190 }
191
192 std::cout << "2D cellset, 2D parameters" << std::endl;
193 {
194 vtkm::Id2 dims(dimensions[0], dimensions[1]);
195 vtkm::Bounds bounds(ranges[0], ranges[1], vtkm::Range(0, 0));
196 vtkm::Vec<T, 2> org(origin[0], origin[1]);
197 vtkm::Vec<T, 2> spc(spacing[0], spacing[1]);
198
199 std::cout << "\tdimensions: " << dims << std::endl;
200 std::cout << "\toriging: " << org << std::endl;
201 std::cout << "\tspacing: " << spc << std::endl;
202 std::cout << "\tbounds: " << bounds << std::endl;
203
204 vtkm::Id numPoints = dims[0] * dims[1];
205 vtkm::Id numCells = (dims[0] - 1) * (dims[1] - 1);
206
207 std::vector<T> pointvar(static_cast<unsigned long>(numPoints));
208 std::iota(pointvar.begin(), pointvar.end(), T(1.1));
209 std::vector<T> cellvar(static_cast<unsigned long>(numCells));
210 std::iota(cellvar.begin(), cellvar.end(), T(1.1));
211
212 vtkm::cont::DataSet dataSet;
213 dataSet = dataSetBuilder.Create(dims, org, spc);
214 dataSet.AddPointField("pointvar", pointvar);
215 dataSet.AddCellField("cellvar", cellvar);
216
217 ValidateDataSet(dataSet, 2, numPoints, numCells, bounds);
218 }
219
220 std::cout << "2D cellset, 3D parameters" << std::endl;
221 {
222 vtkm::Id3 dims = dimensions;
223 vtkm::Bounds bounds(ranges[0], ranges[1], ranges[2]);
224
225 int x = randomAxis(g_RandomGenerator);
226 dims[x] = 1;
227 GetRangeByIndex(bounds, x).Max = ranges[x].Min;
228
229 std::cout << "\tdimensions: " << dims << std::endl;
230 std::cout << "\toriging: " << origin << std::endl;
231 std::cout << "\tspacing: " << spacing << std::endl;
232 std::cout << "\tbounds: " << bounds << std::endl;
233
234 vtkm::Id numPoints = dims[(x + 1) % 3] * dims[(x + 2) % 3];
235 vtkm::Id numCells = (dims[(x + 1) % 3] - 1) * (dims[(x + 2) % 3] - 1);
236
237 std::vector<T> pointvar(static_cast<unsigned long>(numPoints));
238 std::iota(pointvar.begin(), pointvar.end(), T(1.1));
239 std::vector<T> cellvar(static_cast<unsigned long>(numCells));
240 std::iota(cellvar.begin(), cellvar.end(), T(1.1));
241
242 vtkm::cont::DataSet dataSet;
243 dataSet = dataSetBuilder.Create(dims, origin, spacing);
244 dataSet.AddPointField("pointvar", pointvar);
245 dataSet.AddCellField("cellvar", cellvar);
246
247 ValidateDataSet(dataSet, 2, numPoints, numCells, bounds);
248 }
249
250 std::cout << "1D cellset, 1D parameters" << std::endl;
251 {
252 vtkm::Bounds bounds(ranges[0], vtkm::Range(0, 0), vtkm::Range(0, 0));
253
254 std::cout << "\tdimensions: " << dimensions[0] << std::endl;
255 std::cout << "\toriging: " << origin[0] << std::endl;
256 std::cout << "\tspacing: " << spacing[0] << std::endl;
257 std::cout << "\tbounds: " << bounds << std::endl;
258
259 vtkm::Id numPoints = dimensions[0];
260 vtkm::Id numCells = dimensions[0] - 1;
261
262 std::vector<T> pointvar(static_cast<unsigned long>(numPoints));
263 std::iota(pointvar.begin(), pointvar.end(), T(1.1));
264 std::vector<T> cellvar(static_cast<unsigned long>(numCells));
265 std::iota(cellvar.begin(), cellvar.end(), T(1.1));
266
267 vtkm::cont::DataSet dataSet;
268 dataSet = dataSetBuilder.Create(dimensions[0], origin[0], spacing[0]);
269 dataSet.AddPointField("pointvar", pointvar);
270 dataSet.AddCellField("cellvar", cellvar);
271
272 ValidateDataSet(dataSet, 1, numPoints, numCells, bounds);
273 }
274
275 std::cout << "1D cellset, 2D parameters" << std::endl;
276 {
277 vtkm::Id2 dims(dimensions[0], dimensions[1]);
278 vtkm::Bounds bounds(ranges[0], ranges[1], vtkm::Range(0, 0));
279 vtkm::Vec<T, 2> org(origin[0], origin[1]);
280 vtkm::Vec<T, 2> spc(spacing[0], spacing[1]);
281
282 int x = randomAxis(g_RandomGenerator) % 2;
283 dims[x] = 1;
284 GetRangeByIndex(bounds, x).Max = ranges[x].Min;
285
286 std::cout << "\tdimensions: " << dims << std::endl;
287 std::cout << "\toriging: " << org << std::endl;
288 std::cout << "\tspacing: " << spc << std::endl;
289 std::cout << "\tbounds: " << bounds << std::endl;
290
291 vtkm::Id numPoints = dims[(x + 1) % 2];
292 vtkm::Id numCells = dims[(x + 1) % 2] - 1;
293
294 std::vector<T> pointvar(static_cast<unsigned long>(numPoints));
295 std::iota(pointvar.begin(), pointvar.end(), T(1.1));
296 std::vector<T> cellvar(static_cast<unsigned long>(numCells));
297 std::iota(cellvar.begin(), cellvar.end(), T(1.1));
298
299 vtkm::cont::DataSet dataSet;
300 dataSet = dataSetBuilder.Create(dims, org, spc);
301 dataSet.AddPointField("pointvar", pointvar);
302 dataSet.AddCellField("cellvar", cellvar);
303
304 ValidateDataSet(dataSet, 1, numPoints, numCells, bounds);
305 }
306
307 std::cout << "1D cellset, 3D parameters" << std::endl;
308 {
309 vtkm::Id3 dims = dimensions;
310 vtkm::Bounds bounds(ranges[0], ranges[1], ranges[2]);
311
312 int x = randomAxis(g_RandomGenerator);
313 int x1 = (x + 1) % 3;
314 int x2 = (x + 2) % 3;
315 dims[x1] = dims[x2] = 1;
316 GetRangeByIndex(bounds, x1).Max = ranges[x1].Min;
317 GetRangeByIndex(bounds, x2).Max = ranges[x2].Min;
318
319 std::cout << "\tdimensions: " << dims << std::endl;
320 std::cout << "\toriging: " << origin << std::endl;
321 std::cout << "\tspacing: " << spacing << std::endl;
322 std::cout << "\tbounds: " << bounds << std::endl;
323
324 vtkm::Id numPoints = dims[x];
325 vtkm::Id numCells = dims[x] - 1;
326
327 std::vector<T> pointvar(static_cast<unsigned long>(numPoints));
328 std::iota(pointvar.begin(), pointvar.end(), T(1.1));
329 std::vector<T> cellvar(static_cast<unsigned long>(numCells));
330 std::iota(cellvar.begin(), cellvar.end(), T(1.1));
331
332 vtkm::cont::DataSet dataSet;
333 dataSet = dataSetBuilder.Create(dims, origin, spacing);
334 dataSet.AddPointField("pointvar", pointvar);
335 dataSet.AddCellField("cellvar", cellvar);
336
337 ValidateDataSet(dataSet, 1, numPoints, numCells, bounds);
338 }
339 }
340 }
341
TestDataSetBuilderUniform()342 void TestDataSetBuilderUniform()
343 {
344 vtkm::UInt32 seed = static_cast<vtkm::UInt32>(time(nullptr));
345 std::cout << "Seed: " << seed << std::endl;
346 g_RandomGenerator.seed(seed);
347
348 std::cout << "======== Float32 ==========================" << std::endl;
349 UniformTests<vtkm::Float32>();
350 std::cout << "======== Float64 ==========================" << std::endl;
351 UniformTests<vtkm::Float64>();
352 }
353
354 } // namespace DataSetBuilderUniformNamespace
355
UnitTestDataSetBuilderUniform(int argc,char * argv[])356 int UnitTestDataSetBuilderUniform(int argc, char* argv[])
357 {
358 using namespace DataSetBuilderUniformNamespace;
359 return vtkm::cont::testing::Testing::Run(TestDataSetBuilderUniform, argc, argv);
360 }
361