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