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