peclet-dem
Performance-portable XPBD Discrete Element Method (Kokkos + ArborX)
Loading...
Searching...
No Matches
io.hpp
Go to the documentation of this file.
1
6#ifndef DEM_IO_HPP
7#define DEM_IO_HPP
8
9#include <algorithm>
10#include <cstdio>
11#include <fstream>
12#include <iomanip>
13#include <limits>
14#include <string>
15#include <vector>
16
17namespace peclet::dem {
18
19// LAMMPS "dump custom" (Ovito): id type x y z radius vx vy vz qw qx qy qz.
20// pos/vel are flat [n*3]; quat is flat [n*4] in (x,y,z,w) order; radii is [n]. Bounds: explicit box
21// if provided, else computed from the particle AABBs + a 5% margin (matches
22// io/Exporter.cpp::compute_bounds).
23inline void writeLammpsDump(const std::string& filename, int step, const std::vector<float>& pos,
24 const std::vector<float>& vel, const std::vector<float>& quat,
25 const std::vector<float>& radii, const float* boxMin,
26 const float* boxMax, bool pbcEnabled) {
27 const std::size_t n = pos.size() / 3;
28 float bmin[3], bmax[3];
29 if (boxMin && boxMax) {
30 for (int d = 0; d < 3; ++d) {
31 bmin[d] = boxMin[d];
32 bmax[d] = boxMax[d];
33 }
34 } else if (n == 0) {
35 for (int d = 0; d < 3; ++d)
36 bmin[d] = bmax[d] = 0.0f;
37 } else {
38 for (int d = 0; d < 3; ++d) {
39 bmin[d] = std::numeric_limits<float>::max();
40 bmax[d] = -std::numeric_limits<float>::max();
41 }
42 for (std::size_t i = 0; i < n; ++i) {
43 const float r = (i < radii.size()) ? radii[i] : 0.0f;
44 for (int d = 0; d < 3; ++d) {
45 bmin[d] = std::min(bmin[d], pos[3 * i + d] - r);
46 bmax[d] = std::max(bmax[d], pos[3 * i + d] + r);
47 }
48 }
49 for (int d = 0; d < 3; ++d) {
50 const float m = 0.05f * (bmax[d] - bmin[d]);
51 bmin[d] -= m;
52 bmax[d] += m;
53 }
54 }
55
56 std::ofstream file(filename);
57 if (!file)
58 throw std::runtime_error("Could not open file for writing: " + filename);
59 file << "ITEM: TIMESTEP\n" << step << "\n";
60 file << "ITEM: NUMBER OF ATOMS\n" << n << "\n";
61 file << "ITEM: BOX BOUNDS " << (pbcEnabled ? "pp pp pp" : "ff ff ff") << "\n";
62 for (int d = 0; d < 3; ++d)
63 file << bmin[d] << " " << bmax[d] << "\n";
64 file << "ITEM: ATOMS id type x y z radius vx vy vz qw qx qy qz\n";
65 file << std::fixed << std::setprecision(6);
66 for (std::size_t i = 0; i < n; ++i) {
67 const float r = (i < radii.size()) ? radii[i] : 1.0f;
68 const float vx = (3 * i + 2 < vel.size()) ? vel[3 * i] : 0.0f;
69 const float vy = (3 * i + 2 < vel.size()) ? vel[3 * i + 1] : 0.0f;
70 const float vz = (3 * i + 2 < vel.size()) ? vel[3 * i + 2] : 0.0f;
71 float qx = 0, qy = 0, qz = 0, qw = 1; // (x,y,z,w) input
72 if (4 * i + 3 < quat.size()) {
73 qx = quat[4 * i];
74 qy = quat[4 * i + 1];
75 qz = quat[4 * i + 2];
76 qw = quat[4 * i + 3];
77 }
78 file << (i + 1) << " 1 " << pos[3 * i] << " " << pos[3 * i + 1] << " " << pos[3 * i + 2] << " "
79 << r << " " << vx << " " << vy << " " << vz << " " << qw << " " << qx << " " << qy << " "
80 << qz << "\n";
81 }
82}
83
84// Scalar-SDF ImageData VTI (ParaView), x-fastest grid [rx*ry*rz], origin = domain min, spacing =
85// extent/res.
86inline void writeSdfVti(const std::string& filename, const std::vector<float>& grid, int rx, int ry,
87 int rz, const float* minB, const float* maxB) {
88 const double sx = rx > 1 ? (double(maxB[0]) - minB[0]) / (rx - 1) : 1.0;
89 const double sy = ry > 1 ? (double(maxB[1]) - minB[1]) / (ry - 1) : 1.0;
90 const double sz = rz > 1 ? (double(maxB[2]) - minB[2]) / (rz - 1) : 1.0;
91 std::ofstream out(filename);
92 if (!out)
93 throw std::runtime_error("Could not open file for writing: " + filename);
94 out << "<?xml version=\"1.0\"?>\n";
95 out << "<VTKFile type=\"ImageData\" version=\"0.1\" byte_order=\"LittleEndian\">\n";
96 out << " <ImageData WholeExtent=\"0 " << (rx - 1) << " 0 " << (ry - 1) << " 0 " << (rz - 1)
97 << "\" Origin=\"" << minB[0] << " " << minB[1] << " " << minB[2] << "\" Spacing=\"" << sx
98 << " " << sy << " " << sz << "\">\n";
99 out << " <Piece Extent=\"0 " << (rx - 1) << " 0 " << (ry - 1) << " 0 " << (rz - 1) << "\">\n";
100 out << " <PointData Scalars=\"sdf\">\n";
101 out << " <DataArray type=\"Float32\" Name=\"sdf\" format=\"ascii\">\n";
102 for (float v : grid)
103 out << v << " ";
104 out << "\n </DataArray>\n";
105 out << " </PointData>\n";
106 out << " </Piece>\n";
107 out << " </ImageData>\n";
108 out << "</VTKFile>\n";
109 std::printf("Exported SDF VTI: %s\n", filename.c_str());
110}
111
112} // namespace peclet::dem
113
114#endif // DEM_IO_HPP
void writeLammpsDump(const std::string &filename, int step, const std::vector< float > &pos, const std::vector< float > &vel, const std::vector< float > &quat, const std::vector< float > &radii, const float *boxMin, const float *boxMax, bool pbcEnabled)
Definition io.hpp:23
void writeSdfVti(const std::string &filename, const std::vector< float > &grid, int rx, int ry, int rz, const float *minB, const float *maxB)
Definition io.hpp:86