1 #include "vtkNew.h"
2 #include <string>
3
4 #include <vtkCell.h>
5 #include <vtkIdList.h>
6 #include <vtkMultiProcessController.h>
7 #include <vtkPoints.h>
8 #include <vtkUnstructuredGrid.h>
9 #include <vtkTestUtilities.h>
10 #include <vtkXMLUnstructuredGridReader.h>
11 #include <vtkXMLPUnstructuredGridWriter.h>
12 #include <vtkXMLPUnstructuredGridReader.h>
13
14 using namespace std;
15
CompareGrids(vtkUnstructuredGrid * s,vtkUnstructuredGrid * t)16 bool CompareGrids(vtkUnstructuredGrid *s, vtkUnstructuredGrid *t)
17 {
18 if (s->GetNumberOfCells() != t->GetNumberOfCells())
19 {
20 cerr << "The number of cells does not match: " << s->GetNumberOfCells() << " != " << t->GetNumberOfCells() << endl;
21 return false;
22 }
23 for(vtkIdType i = 0; i < s->GetNumberOfCells(); ++i)
24 {
25 if (s->GetCellType(i) != t->GetCellType(i))
26 {
27 cerr << "The cell type does not match: " << s->GetCellType(i) << " != " << t->GetCellType(i) << endl;
28 return false;
29 }
30 vtkNew<vtkIdList> sIds, tIds;
31 if (s->GetCellType(i) == VTK_POLYHEDRON)
32 {
33 s->GetFaceStream(i, sIds.GetPointer());
34 t->GetFaceStream(i, tIds.GetPointer());
35 }
36 else
37 {
38 s->GetCellPoints(i, sIds.GetPointer());
39 t->GetCellPoints(i, tIds.GetPointer());
40 }
41 if (sIds->GetNumberOfIds() != tIds->GetNumberOfIds())
42 {
43 cerr << "Cell type : " << s->GetCellType(i) << endl;
44 cerr << "The number of ids does not match: " << sIds->GetNumberOfIds() << " != " << tIds->GetNumberOfIds() << endl;
45 return false;
46 }
47
48 for(vtkIdType j = 0; j < sIds->GetNumberOfIds(); ++j)
49 {
50 vtkIdType sId = sIds->GetId(j);
51 vtkIdType tId = tIds->GetId(j);
52
53 if(sId != tId)
54 {
55 cerr << "Cell type : " << s->GetCellType(i) << endl;
56 cerr << "The id at position " << j << " does not match: " << sId << " != " << tId << endl;
57 return false;
58 }
59 }
60 }
61
62 return true;
63 }
64
TestParallelUnstructuredGridIO(int argc,char * argv[])65 int TestParallelUnstructuredGridIO(int argc, char* argv[])
66 {
67 vtkNew<vtkPoints> points;
68
69 points->InsertNextPoint(0, 0, 0);
70 points->InsertNextPoint(1, 0, 0);
71 points->InsertNextPoint(1, 1, 0);
72 points->InsertNextPoint(0, 1, 0);
73
74 points->InsertNextPoint(0, 0, 1);
75 points->InsertNextPoint(1, 0, 1);
76 points->InsertNextPoint(1, 1, 1);
77 points->InsertNextPoint(0, 1, 1);
78
79 points->InsertNextPoint(.5, .5, 2);
80 points->InsertNextPoint(.5, .5, -1);
81
82 vtkNew<vtkUnstructuredGrid> ug;
83 ug->SetPoints(points);
84
85 ug->Allocate(3); // allocate for 3 cells
86
87 vtkNew<vtkIdList> ids;
88
89 // add a hexahedron of the first 8 points (i.e. a cube)
90 ids->InsertNextId(0);
91 ids->InsertNextId(1);
92 ids->InsertNextId(2);
93 ids->InsertNextId(3);
94 ids->InsertNextId(4);
95 ids->InsertNextId(5);
96 ids->InsertNextId(6);
97 ids->InsertNextId(7);
98 ug->InsertNextCell(VTK_HEXAHEDRON, ids.GetPointer());
99 ids->Reset();
100
101 // add a polyhedron comprise of the top hexahedron face
102 // and four triangles to the 9th point
103 ids->InsertNextId(4);
104 ids->InsertNextId(5);
105 ids->InsertNextId(6);
106 ids->InsertNextId(7);
107 ids->InsertNextId(8);
108
109 vtkNew<vtkIdList> faces;
110 // top face of four points
111 faces->InsertNextId(4);
112
113 faces->InsertNextId(4);
114 faces->InsertNextId(5);
115 faces->InsertNextId(6);
116 faces->InsertNextId(7);
117
118 // four triangle side faces, each of three points
119 faces->InsertNextId(3);
120 faces->InsertNextId(4);
121 faces->InsertNextId(5);
122 faces->InsertNextId(8);
123
124 faces->InsertNextId(3);
125 faces->InsertNextId(5);
126 faces->InsertNextId(6);
127 faces->InsertNextId(8);
128
129 faces->InsertNextId(3);
130 faces->InsertNextId(6);
131 faces->InsertNextId(7);
132 faces->InsertNextId(8);
133
134 faces->InsertNextId(3);
135 faces->InsertNextId(7);
136 faces->InsertNextId(4);
137 faces->InsertNextId(8);
138
139 // insert the polyhedron cell
140 ug->InsertNextCell(VTK_POLYHEDRON, 5, ids.GetPointer()->GetPointer(0), 5, faces.GetPointer()->GetPointer(0));
141
142 // put another pyramid on the bottom towards the 10th point
143 faces->Reset();
144 ids->Reset();
145
146 // the list of points that the pyramid references
147 ids->InsertNextId(0);
148 ids->InsertNextId(1);
149 ids->InsertNextId(2);
150 ids->InsertNextId(3);
151 ids->InsertNextId(9);
152
153 // bottom face of four points
154 faces->InsertNextId(4);
155
156 faces->InsertNextId(0);
157 faces->InsertNextId(1);
158 faces->InsertNextId(2);
159 faces->InsertNextId(3);
160
161 // four side faces, each of three points
162 faces->InsertNextId(3);
163 faces->InsertNextId(0);
164 faces->InsertNextId(1);
165 faces->InsertNextId(9);
166
167 faces->InsertNextId(3);
168 faces->InsertNextId(1);
169 faces->InsertNextId(2);
170 faces->InsertNextId(9);
171
172 faces->InsertNextId(3);
173 faces->InsertNextId(2);
174 faces->InsertNextId(3);
175 faces->InsertNextId(9);
176
177 faces->InsertNextId(3);
178 faces->InsertNextId(3);
179 faces->InsertNextId(0);
180 faces->InsertNextId(9);
181
182 // insert the cell. We now have two pyramids with a cube in between
183 ug->InsertNextCell(VTK_POLYHEDRON, 5, ids.GetPointer()->GetPointer(0), 5, faces.GetPointer()->GetPointer(0));
184
185 vtkMultiProcessController* ctrl = vtkMultiProcessController::GetGlobalController();
186 vtkNew<vtkXMLPUnstructuredGridWriter> w;
187 w->SetController(ctrl);
188 w->SetInputData(ug);
189 w->SetUseSubdirectory(true);
190 char* tempDir = vtkTestUtilities::GetArgOrEnvOrDefault("-T", argc, argv,
191 "VTK_TEMP_DIR",
192 "Testing/Temporary");
193 std::string dir(tempDir);
194 std::string fn = dir + "/ug.pvtu";
195 w->SetFileName(fn.c_str());
196 w->SetDataModeToAscii();
197 w->Update();
198
199 ifstream f(fn.c_str());
200 if (!f.good())
201 {
202 std::cerr << "File " << fn << " does not exist." << std::endl;
203 return EXIT_FAILURE;
204 }
205
206 vtkNew<vtkXMLUnstructuredGridReader> r;
207 std::string piece = dir + "/ug/ug_0.vtu";
208 r->SetFileName(piece.c_str());
209 r->Update();
210
211 // first try reading the piece with a non-parallel reader
212 vtkUnstructuredGrid* read = r->GetOutput();
213 cout << "Comparing original with .vtu" << endl;
214 if (!CompareGrids(ug.GetPointer(), read)) return EXIT_FAILURE;
215
216 // now read the .pvtu file with the paralle reader
217 vtkNew<vtkXMLPUnstructuredGridReader> pr;
218 pr->SetFileName(fn.c_str());
219 // this will give a SIGSEGV on vtkXMLPUnstructuredGridReader::ReadPieceData()
220 pr->Update();
221
222 read = pr->GetOutput();
223 cout << "Comparing original with .pvtu" << endl;
224 if (!CompareGrids(ug.GetPointer(), read)) return EXIT_FAILURE;
225
226 return EXIT_SUCCESS;
227
228 }
229