Export the particles to a file in the VTK zlib format.
182 {
183 std::ofstream ofs(path);
184 if (ofs.fail()) {
185 cerr << "cannot write " << path << endl;
186 std::exit(-1);
187 }
188
189 std::stringstream binaryData;
190
191
192 ofs << "<?xml version='1.0' encoding='UTF-8'?>" << endl;
193 ofs << "<VTKFile type=\"UnstructuredGrid\" version=\"1.0\" header_type=\"UInt64\" byte_order=\"";
195 ofs << "BigEndian";
196 } else {
197 ofs << "LittleEndian";
198 }
199 ofs << "\">" << endl;
200 ofs << "<UnstructuredGrid>" << endl
205 ofs << "<Points>" << endl;
206 ofs <<
dataArrayBegin(
"Float64",
"Position", 3,
"appended", binaryData.tellp()) << endl;
208 uint64_t length_points =
particles.
size() * 3 *
sizeof(double);
209 binaryData.write(reinterpret_cast<char*>(&length_points), sizeof(uint64_t));
211 double x = p.position.x();
212 double y = p.position.y();
213 double z = p.position.z();
214 binaryData.write(reinterpret_cast<char*>(&x), sizeof(double));
215 binaryData.write(reinterpret_cast<char*>(&y), sizeof(double));
216 binaryData.write(reinterpret_cast<char*>(&z), sizeof(double));
217 }
218 ofs << "</Points>" << endl;
219
220
221
222 ofs << "<PointData>" << endl;
223
224 ofs <<
dataArrayBegin(
"Int32",
"Particle Type", 1,
"appended", binaryData.tellp()) << endl;
226 uint64_t length_particle_type =
particles.
size() *
sizeof(int32_t);
227 binaryData.write(reinterpret_cast<char*>(&length_particle_type), sizeof(uint64_t));
229 int32_t type = static_cast<int32_t>(p.type);
230 binaryData.write(reinterpret_cast<char*>(&type), sizeof(int32_t));
231 }
232
233 ofs <<
dataArrayBegin(
"Float64",
"Velocity", 3,
"appended", binaryData.tellp()) << endl;
235 uint64_t length_velocity =
particles.
size() * 3 *
sizeof(double);
236 binaryData.write(reinterpret_cast<char*>(&length_velocity), sizeof(uint64_t));
238 double vx = p.velocity.x();
239 double vy = p.velocity.y();
240 double vz = p.velocity.z();
241 binaryData.write(reinterpret_cast<char*>(&vx), sizeof(double));
242 binaryData.write(reinterpret_cast<char*>(&vy), sizeof(double));
243 binaryData.write(reinterpret_cast<char*>(&vz), sizeof(double));
244 }
245
246 ofs <<
dataArrayBegin(
"Float64",
"Pressure", 1,
"appended", binaryData.tellp()) << endl;
248 uint64_t length_pressure =
particles.
size() *
sizeof(double);
249 binaryData.write(reinterpret_cast<char*>(&length_pressure), sizeof(uint64_t));
251 double pressure = p.pressure;
252 binaryData.write(reinterpret_cast<char*>(&pressure), sizeof(double));
253 }
254
255 ofs <<
dataArrayBegin(
"Float64",
"Number Density", 1,
"appended", binaryData.tellp()) << endl;
257 uint64_t length_number_density =
particles.
size() *
sizeof(double);
258 binaryData.write(reinterpret_cast<char*>(&length_number_density), sizeof(uint64_t));
260 double number_density = p.numberDensity;
261 binaryData.write(reinterpret_cast<char*>(&number_density), sizeof(double));
262 }
263
264 ofs <<
dataArrayBegin(
"Float64",
"Number Density Ratio", 1,
"appended", binaryData.tellp()) << endl;
266 uint64_t length_number_density_ratio =
particles.
size() *
sizeof(double);
267 binaryData.write(reinterpret_cast<char*>(&length_number_density_ratio), sizeof(uint64_t));
269 double number_density_ratio = p.numberDensity / n0ForNumberDensity;
270 binaryData.write(reinterpret_cast<char*>(&number_density_ratio), sizeof(double));
271 }
272
273 ofs <<
dataArrayBegin(
"Int32",
"Boundary Condition", 1,
"appended", binaryData.tellp()) << endl;
275 uint64_t length_boundary_condition =
particles.
size() *
sizeof(int32_t);
276 binaryData.write(reinterpret_cast<char*>(&length_boundary_condition), sizeof(uint64_t));
278 int32_t boundary_condition = static_cast<int32_t>(p.boundaryCondition);
279 binaryData.write(reinterpret_cast<char*>(&boundary_condition), sizeof(int32_t));
280 }
281
282 ofs <<
dataArrayBegin(
"Int32",
"Fluid Type", 1,
"appended", binaryData.tellp()) << endl;
284 uint64_t length_fluid_type =
particles.
size() *
sizeof(int32_t);
285 binaryData.write(reinterpret_cast<char*>(&length_fluid_type), sizeof(uint64_t));
287 int32_t fluid_type = p.fluidType;
288 binaryData.write(reinterpret_cast<char*>(&fluid_type), sizeof(int32_t));
289 }
290 ofs << "</PointData>" << endl;
294 ofs << "<Cells>" << endl;
295
296 ofs <<
dataArrayBegin(
"Int64",
"connectivity", 1,
"appended", binaryData.tellp()) << endl;
298 uint64_t length_connectivity =
particles.
size() *
sizeof(int64_t);
299 binaryData.write(reinterpret_cast<char*>(&length_connectivity), sizeof(uint64_t));
301 int64_t connectivity = i;
302 binaryData.write(reinterpret_cast<char*>(&connectivity), sizeof(int64_t));
303 }
304
305 ofs <<
dataArrayBegin(
"Int64",
"offsets", 1,
"appended", binaryData.tellp()) << endl;
308 binaryData.write(reinterpret_cast<char*>(&length_offset), sizeof(uint64_t));
310 int64_t offset = i + 1;
311 binaryData.write(reinterpret_cast<char*>(&offset), sizeof(int64_t));
312 }
313
314 ofs <<
dataArrayBegin(
"UInt8",
"types", 1,
"appended", binaryData.tellp()) << endl;
317 binaryData.write(reinterpret_cast<char*>(&length_types), sizeof(uint64_t));
319 uint8_t type = 1;
320 binaryData.write(reinterpret_cast<char*>(&type), sizeof(uint8_t));
321 }
322 ofs << "</Cells>" << endl;
323 ofs << "</Piece>" << endl;
324
325
326
327 ofs << "<FieldData>" << endl;
328 ofs << "<DataArray type=\"Float64\" Name=\"Time\" NumberOfTuples=\"1\" format=\"appended\" offset=\""
329 << binaryData.tellp() << "\"/>" << endl;
330
331 uint64_t length_time = sizeof(double);
332 binaryData.write(reinterpret_cast<char*>(&length_time), sizeof(uint64_t));
333 double time_copied = time;
334 binaryData.write(reinterpret_cast<char*>(&time_copied), sizeof(double));
335 ofs << "</FieldData>" << endl;
336 ofs << "</UnstructuredGrid>" << endl;
337
338
339
340 ofs << "<AppendedData encoding=\"raw\">" << endl;
341 ofs << "_" << binaryData.str() << endl;
342 ofs << "</AppendedData>" << endl;
343 ofs << "</VTKFile>" << endl;
344}