CPP-snippets 0.0.1
A silly C++ project to use for demonstrating code integration
Loading...
Searching...
No Matches
Simulation Class Reference

Main driver class coordinating IO, Poisson solve, particle push, and data storage for a 1D PIC simulation. More...

#include <simulation.hpp>

Public Member Functions

 Simulation (const IOInterface *interface)
 Construct the simulation from an IO interface.
 
void run ()
 Execute the complete PIC time integration loop.
 
void postprocess ()
 Write simulation results to output files.
 

Detailed Description

Main driver class coordinating IO, Poisson solve, particle push, and data storage for a 1D PIC simulation.

Definition at line 16 of file simulation.hpp.

Constructor & Destructor Documentation

◆ Simulation()

Simulation ( const IOInterface * interface)
explicit

Construct the simulation from an IO interface.

Parameters
interfacePointer to configuration and IO handler.

Definition at line 17 of file simulation.cpp.

17 : m_interface(interface) {
18
19 std::cout << " -> Initializing simulation ..." << std::endl;
20
21 // reproducable "random" numbers
22 m_rng.seed(12345);
23
24 // Init Poisson field solver
25 Eigen::Vector4d pos = m_interface->load_vector<Eigen::Vector4d>("geometry.positions");
26 Eigen::Vector4d pots = m_interface->load_vector<Eigen::Vector4d>("geometry.potentials");
27 Eigen::Vector3i cells = m_interface->load_vector<Eigen::Vector3i>("discretization.space.cells");
28 m_poisson = new PoissonSolver(pos, pots, cells);
29
30 // Init particle storage
31 double sp_weight = m_interface->load_scalar<double>("solve.particles.weight");
32 m_particles = new Particles(0, constants::q_e, constants::m_e, sp_weight);
33
34 // Init solution storage
35 double t_final = m_interface->load_scalar<double>("discretization.time.t_final");
36 double dt = m_interface->load_scalar<double>("discretization.time.dt");
37 m_cellnumber = cells.sum();
38 m_timesteps = static_cast<int>(std::ceil(t_final / dt));
39
40 m_time = Eigen::VectorXd::LinSpaced(m_timesteps, 0, m_timesteps * dt);
41 m_phi = Eigen::MatrixXd::Zero(m_timesteps, m_cellnumber+1);
42 m_rho = Eigen::MatrixXd::Zero(m_timesteps, m_cellnumber+1);
43 m_efield = Eigen::MatrixXd::Zero(m_timesteps, m_cellnumber+1);
44
45 // Init postproc storage
46 m_bins = m_interface->load_scalar<int>("discretization.energy.bins");
47 m_energy_dist = Eigen::MatrixXd::Zero(m_timesteps, m_bins);
48 m_fluxes = Eigen::MatrixX4d::Zero(m_timesteps, 4);
49
50};

Member Function Documentation

◆ postprocess()

void postprocess ( )

Write simulation results to output files.

Definition at line 116 of file simulation.cpp.

116 {
117
118 std::cout << " -> Postprocessing results ..." << std::endl;
119
120 // export results
121 std::string comment = " | Time discretization";
122 m_interface->write2csv("time_vec.csv", m_time, comment);
123
124 comment = " | Cell sizes";
125 m_interface->write2csv("dx_vec.csv", m_poisson->m_dx, comment);
126 comment = " | Node positions";
127 m_interface->write2csv("nodes_vec.csv", m_poisson->m_nodes, comment);
128
129 comment = " | Charge density on nodes (rows: timesteps, cols: nodes)";
130 m_interface->write2csv("rho_mat.csv", m_rho, comment);
131 comment = " | Electric potential on nodes (rows: timesteps, cols: nodes)";
132 m_interface->write2csv("phi_mat.csv", m_phi, comment);
133 comment = " | Electric field in cells (rows: timesteps, cols: cells)";
134 m_interface->write2csv("efield_mat.csv", m_efield, comment);
135 comment = " | Electrode currents (rows: timesteps, cols: {1-Fil, 2-CE, 3-AG, 4-IC})";
136 m_interface->write2csv("currents_mat.csv", m_fluxes, comment);
137 comment = " | Electron kinetic energy distribution (rows: timesteps, cols: equidist. bins)";
138 m_interface->write2csv("energy_mat.csv", m_energy_dist, comment);
139
140};

◆ run()

void run ( )

Execute the complete PIC time integration loop.

Definition at line 52 of file simulation.cpp.

52 {
53
54 std::cout << " -> Running the simulation ..." << std::endl;
55 // general
56
57 double source_flux_avg = m_interface->load_scalar<double>("solve.particles.source_flux");
58 double initial_energy = m_interface->load_scalar<double>("solve.particles.init_energy");
59 // collsions
60 double p_ce = m_interface->load_scalar<double>("solve.collisions.prob_ce");
61 double p_ag = m_interface->load_scalar<double>("solve.collisions.prob_ag");
62 // max histogram energy
63 double energy_max = m_interface->load_scalar<double>("discretization.energy.max");
64
65
66 // Electron source with poisson distribution
67 double dt = m_time[1] - m_time[0];
68 std::poisson_distribution<int> pois(source_flux_avg * dt / m_particles->m_weight);
69 double N_emit; // average number of electrons to emit over each timestep
70
71 // Initial laplace solution
72 std::cout << "[0] Solving initial Laplace " << std::endl;
73 Eigen::VectorXd rho = Eigen::VectorXd::Zero(m_cellnumber+1);
74 Eigen::VectorXd phi = m_poisson->solve_potential(rho);
75 Eigen::VectorXd efield = m_poisson->solve_efield(phi);
76 Eigen::VectorXd energies = Eigen::VectorXd::Zero(m_bins);
77 Eigen::Vector4d fluxes = Eigen::Vector4d::Zero(4);
78 m_phi.row(0) = phi.transpose();
79 m_efield.row(0) = efield.transpose();
80
81 // loop over rest of timestep here ...
82 for (int i = 1; i < m_timesteps; i++) {
83
84 std::cout << "["<< i << "] Solving timestep " << std::endl;
85
86 // Emit on x=0 with boltzmann distributed velocities and poisson dist particle count
87 N_emit = pois(m_rng);
88 m_particles->emit(
89 N_emit, 0, dt, initial_energy,
90 m_poisson->m_nodes, efield, m_rng
91 );
92 // Move particles in efield solution
93 m_particles->push_leapfrog(dt, m_poisson->m_nodes, efield);
94 // Check for absorbtion
95 fluxes = m_particles->fluxes(m_poisson->m_cap_xpos, m_rng, p_ce, p_ag);
96 energies = m_particles->energy_distribution(m_bins, energy_max);
97 // Deposite charge on grid
98 rho = m_particles->deposit_charge(m_poisson->m_nodes, m_poisson->m_dx);
99 // Update field solution w. Poisson solver
100 phi = m_poisson->solve_potential(rho);
101 efield = m_poisson->solve_efield(phi);
102
103 // Save step quantities
104 m_rho.row(i) = rho.transpose();
105 m_phi.row(i) = phi.transpose();
106 m_efield.row(i) = efield.transpose();
107 m_fluxes.row(i) = fluxes.transpose();
108 m_energy_dist.row(i) = energies.transpose();
109
110 }
111
112 std::cout << " Finished simulation run " << std::endl;
113};

The documentation for this class was generated from the following files: