Program Listing for File track_particle.cpp¶
↰ Return to documentation for file (src/particle/track_particle/track_particle.cpp)
#include "track_particle.hpp"
#include <iomanip>
#include <iostream>
#include <sstream>
#include "fields.hpp"
#include "hdf5.h"
#include "mesh.hpp"
namespace lili::particle {
void TrackParticles::InitializeTrackParticles() {
// Initialize the particles
track_particles = Particles(n_track_);
// Allocate memory for the tracked particles
idtrack_ = new ulong[n_track_ * dtrack_save_]();
xtrack_ = new double[n_track_ * dtrack_save_]();
ytrack_ = new double[n_track_ * dtrack_save_]();
ztrack_ = new double[n_track_ * dtrack_save_]();
utrack_ = new double[n_track_ * dtrack_save_]();
vtrack_ = new double[n_track_ * dtrack_save_]();
wtrack_ = new double[n_track_ * dtrack_save_]();
extrack_ = new double[n_track_ * dtrack_save_]();
eytrack_ = new double[n_track_ * dtrack_save_]();
eztrack_ = new double[n_track_ * dtrack_save_]();
bxtrack_ = new double[n_track_ * dtrack_save_]();
bytrack_ = new double[n_track_ * dtrack_save_]();
bztrack_ = new double[n_track_ * dtrack_save_]();
}
void TrackParticles::SaveTrackedParticles(Particles& particles) {
// Copy tracked particles to the current cache
SelectParticles(particles, track_particles, ParticleStatus::Tracked);
if (track_particles.npar() != n_track_) {
std::cerr << "Error: number of tracked particles is not correct"
<< std::endl;
exit(1);
}
// Move the data to the dump cache
for (int i_track = 0; i_track < n_track_; ++i_track) {
idtrack_[i_track_ * n_track_ + i_track] = track_particles.id(i_track);
xtrack_[i_track_ * n_track_ + i_track] = track_particles.x(i_track);
ytrack_[i_track_ * n_track_ + i_track] = track_particles.y(i_track);
ztrack_[i_track_ * n_track_ + i_track] = track_particles.z(i_track);
utrack_[i_track_ * n_track_ + i_track] = track_particles.u(i_track);
vtrack_[i_track_ * n_track_ + i_track] = track_particles.v(i_track);
wtrack_[i_track_ * n_track_ + i_track] = track_particles.w(i_track);
}
// Increment the tracking index
++i_track_;
// Save the tracked particles if the tracking index reaches the save number
if (i_track_ >= dtrack_save_) {
DumpTrackedParticles();
}
}
void TrackParticles::SaveTrackedParticles(Particles& particles,
mesh::Fields& fields) {
// Copy tracked particles to the current cache
SelectParticles(particles, track_particles, ParticleStatus::Tracked);
if (track_particles.npar() != n_track_) {
std::cout << "Error: number of tracked particles is not correct"
<< std::endl;
exit(1);
}
// Move the data to the dump cache
for (int i_track = 0; i_track < n_track_; ++i_track) {
idtrack_[i_track_ * n_track_ + i_track] = track_particles.id(i_track);
double xloc = track_particles.x(i_track);
double yloc = track_particles.y(i_track);
double zloc = track_particles.z(i_track);
xtrack_[i_track_ * n_track_ + i_track] = xloc;
ytrack_[i_track_ * n_track_ + i_track] = yloc;
ztrack_[i_track_ * n_track_ + i_track] = zloc;
utrack_[i_track_ * n_track_ + i_track] = track_particles.u(i_track);
vtrack_[i_track_ * n_track_ + i_track] = track_particles.v(i_track);
wtrack_[i_track_ * n_track_ + i_track] = track_particles.w(i_track);
// Move the particle location to the mesh coordinate
xloc = (xloc - fields.size.x0) / fields.size.lx * fields.size.nx;
yloc = (yloc - fields.size.y0) / fields.size.ly * fields.size.ny;
zloc = (zloc - fields.size.z0) / fields.size.lz * fields.size.nz;
// Store the fields
extrack_[i_track_ * n_track_ + i_track] =
fields.ex.Interpolation(xloc, yloc, zloc);
eytrack_[i_track_ * n_track_ + i_track] =
fields.ey.Interpolation(xloc, yloc, zloc);
eztrack_[i_track_ * n_track_ + i_track] =
fields.ez.Interpolation(xloc, yloc, zloc);
bxtrack_[i_track_ * n_track_ + i_track] =
fields.bx.Interpolation(xloc, yloc, zloc);
bytrack_[i_track_ * n_track_ + i_track] =
fields.by.Interpolation(xloc, yloc, zloc);
bztrack_[i_track_ * n_track_ + i_track] =
fields.bz.Interpolation(xloc, yloc, zloc);
}
// Increment the tracking index
++i_track_;
// Save the tracked particles if the tracking index reaches the save number
if (i_track_ >= dtrack_save_) {
DumpTrackedParticles();
}
}
void TrackParticles::DumpTrackedParticles() {
// Set filename and create file
std::stringstream ss;
ss << std::setw(5) << std::setfill('0') << i_dump_;
std::string filename = prefix_ + "_" + ss.str() + ".h5";
std::cout << "Dumping tracked particles to " << filename << std::endl;
hid_t file_id =
H5Fcreate(filename.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, H5P_DEFAULT);
// Create dataspace to store particles
if (i_track_ != dtrack_save_) {
std::cout << "Different number TP dump: " << i_track_ << " " << dtrack_save_
<< std::endl;
}
hsize_t dims[2] = {static_cast<hsize_t>(i_track_),
static_cast<hsize_t>(n_track_)};
hid_t dataspace_id = H5Screate_simple(2, dims, NULL);
// Write the particle IDs
hid_t dataset_id = H5Dcreate(file_id, "id", H5T_NATIVE_ULONG, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_ULONG, H5S_ALL, H5S_ALL, H5P_DEFAULT,
idtrack_);
H5Dclose(dataset_id);
// Write the particle coordinates
dataset_id = H5Dcreate(file_id, "x", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
xtrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "y", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
ytrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "z", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
ztrack_);
H5Dclose(dataset_id);
// Write the particle velocities
dataset_id = H5Dcreate(file_id, "u", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
utrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "v", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
vtrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "w", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
wtrack_);
H5Dclose(dataset_id);
// Write the particle local fields
dataset_id = H5Dcreate(file_id, "ex", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
extrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "ey", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
eytrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "ez", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
eztrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "bx", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
bxtrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "by", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
bytrack_);
H5Dclose(dataset_id);
dataset_id = H5Dcreate(file_id, "bz", H5T_NATIVE_DOUBLE, dataspace_id,
H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT);
H5Dwrite(dataset_id, H5T_NATIVE_DOUBLE, H5S_ALL, H5S_ALL, H5P_DEFAULT,
bztrack_);
H5Dclose(dataset_id);
// Close dataspace and file
H5Sclose(dataspace_id);
H5Fclose(file_id);
// Add the dump index and clear the tracking index
++i_dump_;
i_track_ = 0;
}
} // namespace lili::particle