22// it under the terms of the GNU General Public License as published by
33// the Free Software Foundation, either version 3 of the License, or
44// (at your option) any later version.
5-
65// This program is distributed in the hope that it will be useful,
76// but WITHOUT ANY WARRANTY; without even the implied warranty of
87// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
98// GNU General Public License for more details.
10-
119// You should have received a copy of the GNU General Public License
1210// along with this program. If not, see <http://www.gnu.org/licenses/>.
1311
1715#include < string>
1816#include < vector>
1917#include < stdexcept>
20-
21- // HDF5 C API
2218#include < hdf5.h>
2319
24- // Helper: load one PartType group into particles
20+ /* *
21+ * @brief Helper: load one PartType group from HDF5 into the SoA Particle database.
22+ */
2523void LoadPartType (hid_t file,
2624 const std::string& group,
2725 int internalType,
28- std::vector< Particle>& particles)
26+ Particle& p) // p is now the SoA container
2927{
30- // Coordinates
28+ // Coordinates Check
3129 if (H5Lexists (file, (group + " /Coordinates" ).c_str (), H5P_DEFAULT ) <= 0 )
3230 return ;
3331
@@ -36,63 +34,84 @@ void LoadPartType(hid_t file,
3634
3735 hsize_t dims[2 ];
3836 H5Sget_simple_extent_dims (space_coords, dims, NULL );
39- size_t N = dims[0 ]; // number of particles
37+ size_t N = dims[0 ];
4038
41- std::vector<float > coords (N*3 );
42- H5Dread (dset_coords, H5T_NATIVE_FLOAT , H5S_ALL , H5S_ALL , H5P_DEFAULT , coords.data ());
43-
44- H5Dclose (dset_coords);
45- H5Sclose (space_coords);
39+ // Temporary buffers for HDF5 read
40+ std::vector<float > coords (N * 3 );
41+ std::vector<float > vels (N * 3 );
42+ std::vector<float > masses (N);
4643
47- // Velocities
44+ // Read everything from HDF5
45+ H5Dread (dset_coords, H5T_NATIVE_FLOAT , H5S_ALL , H5S_ALL , H5P_DEFAULT , coords.data ());
46+
4847 hid_t dset_vels = H5Dopen (file, (group + " /Velocities" ).c_str (), H5P_DEFAULT );
49- std::vector<float > vels (N*3 );
5048 H5Dread (dset_vels, H5T_NATIVE_FLOAT , H5S_ALL , H5S_ALL , H5P_DEFAULT , vels.data ());
51- H5Dclose (dset_vels);
52-
53- // Masses
49+
5450 hid_t dset_masses = H5Dopen (file, (group + " /Masses" ).c_str (), H5P_DEFAULT );
55- std::vector<float > masses (N);
5651 H5Dread (dset_masses, H5T_NATIVE_FLOAT , H5S_ALL , H5S_ALL , H5P_DEFAULT , masses.data ());
57- H5Dclose (dset_masses);
5852
59- // Convert into Particle structs
53+ // --- RE-FILL SoA LANES ---
54+ // We reserve space to avoid multiple reallocations
55+ size_t current_size = p.x .size ();
56+ p.x .resize (current_size + N);
57+ p.y .resize (current_size + N);
58+ p.z .resize (current_size + N);
59+ p.vx .resize (current_size + N);
60+ p.vy .resize (current_size + N);
61+ p.vz .resize (current_size + N);
62+ p.m .resize (current_size + N);
63+ p.type .resize (current_size + N);
64+
6065 for (size_t i = 0 ; i < N; i++) {
61- Particle p;
62- p.x = coords[3 *i+0 ];
63- p.y = coords[3 *i+1 ];
64- p.z = coords[3 *i+2 ];
65- p.vx = vels[3 *i+0 ];
66- p.vy = vels[3 *i+1 ];
67- p.vz = vels[3 *i+2 ];
68- p.m = masses[i];
69- p.type = internalType;
70- particles.push_back (p);
66+ size_t idx = current_size + i;
67+ p.x [idx] = coords[3 *i+0 ];
68+ p.y [idx] = coords[3 *i+1 ];
69+ p.z [idx] = coords[3 *i+2 ];
70+ p.vx [idx] = vels[3 *i+0 ];
71+ p.vy [idx] = vels[3 *i+1 ];
72+ p.vz [idx] = vels[3 *i+2 ];
73+ p.m [idx] = masses[i];
74+ p.type [idx] = internalType;
7175 }
76+
77+ // Cleanup
78+ H5Dclose (dset_coords);
79+ H5Dclose (dset_vels);
80+ H5Dclose (dset_masses);
81+ H5Sclose (space_coords);
7282}
7383
74- std::vector<Particle> LoadParticlesFromFile (const std::string& filename)
84+ /* *
85+ * @brief Loads the Particle database from file.
86+ */
87+ Particle LoadParticlesFromFile (const std::string& filename)
7588{
76- std::vector< Particle> p;
89+ Particle p; // The SoA container
7790
7891 // --- Try HDF5 first ---
7992 hid_t file = H5Fopen (filename.c_str (), H5F_ACC_RDONLY , H5P_DEFAULT );
8093 if (file >= 0 ) {
81- // Load PartType1 (DM → internal type=1)
82- LoadPartType (file, " PartType1" , 1 , p);
83-
84- // Load PartType4 (Stars → internal type=0)
85- LoadPartType (file, " PartType4" , 0 , p);
86-
94+ LoadPartType (file, " PartType1" , 1 , p); // DM
95+ LoadPartType (file, " PartType4" , 0 , p); // Stars
8796 H5Fclose (file);
8897 return p;
8998 }
9099
91100 // --- Fallback: plain text loader ---
92101 std::ifstream in (filename);
93- Particle temp;
94- while (in >> temp.x >> temp.y >> temp.z >> temp.vx >> temp.vy >> temp.vz >> temp.m >> temp.type ) {
95- p.push_back (temp);
102+ real tx, ty, tz, tvx, tvy, tvz, tm;
103+ int tt;
104+
105+ // Read column by column and push into SoA lanes
106+ while (in >> tx >> ty >> tz >> tvx >> tvy >> tvz >> tm >> tt) {
107+ p.x .push_back (tx);
108+ p.y .push_back (ty);
109+ p.z .push_back (tz);
110+ p.vx .push_back (tvx);
111+ p.vy .push_back (tvy);
112+ p.vz .push_back (tvz);
113+ p.m .push_back (tm);
114+ p.type .push_back (tt);
96115 }
97116 return p;
98117}
0 commit comments