Advertisement
phystota

Thermalization

Mar 20th, 2025
181
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.77 KB | None | 0 0
  1. #include <iostream>
  2. #include <random>
  3. #include <fstream>
  4. #include <math.h>
  5.  
  6. #define n_e 50000
  7. #define V_0 30000.0     // max velocity using to generate random distribution ---- doesn't work -> produces skew distribution???
  8. #define Emin 0.0
  9. #define Emax 100.0
  10. #define bin_width 0.1
  11. #define m_e 9.1E-31 // electron mass in kg
  12. #define k_b 1.38E-23 // Boltzmann constant
  13. #define q 1.6E-19 // elementary charge    
  14. #define N ( (int)((Emax-Emin)/bin_width) + 1 ) // add 1 to include E_max
  15. #define P 0.5
  16. #define steps 10000
  17.  
  18. int main() {
  19.  
  20.     double electron_vel[3*n_e];
  21.     double electron_e[n_e];
  22.     int histo_random[N] = {0};
  23.     int histo_maxwell[N] = {0};
  24.     bool collided[n_e] = {0};
  25.     bool paired[n_e] = {0};
  26.     double collisionProbability = 0.5;
  27.  
  28.  
  29.     for (int i = 0; i < 3*n_e; i++){
  30.         electron_vel[i] = 0.0;
  31.     }    
  32.  
  33.     for (int i = 0; i < n_e; i++){
  34.         electron_e[i] = 0.0;
  35.     }    
  36.  
  37.  
  38.     std::ofstream file("velocities.dat");    
  39.     if (!file.is_open()) {
  40.         std::cerr << "Error opening file!" << std::endl;
  41.         return 1;
  42.     }
  43.  
  44.     std::ofstream file1("energies.dat");    
  45.     if (!file.is_open()) {
  46.         std::cerr << "Error opening file!" << std::endl;
  47.         return 1;
  48.     }
  49.    
  50.     std::ofstream file2("energies_redistribute.dat");    
  51.     if (!file.is_open()) {
  52.         std::cerr << "Error opening file!" << std::endl;
  53.         return 1;
  54.     }
  55.  
  56.     std::ofstream file3("histo_random.dat");    
  57.     if (!file.is_open()) {
  58.         std::cerr << "Error opening file!" << std::endl;
  59.         return 1;
  60.     }
  61.    
  62.     std::ofstream file4("histo_maxwell.dat");    
  63.     if (!file.is_open()) {
  64.         std::cerr << "Error opening file!" << std::endl;
  65.         return 1;
  66.     }                
  67.  
  68.     std::random_device rd;
  69.     std::mt19937 gen(rd());
  70.     std::uniform_real_distribution<double> dis(0.0, 1.0);
  71.  
  72.     std::random_device rd1;
  73.     std::mt19937 gen1(rd1());
  74.     std::uniform_int_distribution<int> pair(0, n_e-1);
  75.  
  76.  
  77.  
  78.     for (int i = 0; i < 3*n_e; i = i + 3){
  79.  
  80.         double phi = 2*M_PI*dis(gen);
  81.         double sinTheta = dis(gen);
  82.         double cosTheta = sqrt(1.0 - sinTheta*sinTheta);
  83.        
  84.         double energy = Emax*dis(gen);
  85.         double speed = sqrt(2*energy*k_b/m_e);
  86.  
  87.         electron_vel[i] = speed * sinTheta * cos(phi); // x component
  88.         electron_vel[i+1] = speed * sinTheta * sin(phi); // y component
  89.         electron_vel[i+2] = speed * cosTheta; // z component
  90.        
  91. //        energy = (electron_vel[i]*electron_vel[i] + electron_vel[i+1]*electron_vel[i+1] + electron_vel[i+2]*electron_vel[i+2]) * m_e / (2.0*k_b);
  92.  
  93.         electron_e[i/3] = energy;
  94.  
  95.         file << electron_vel[i] << " " << electron_vel[i+1] << " " << electron_vel[i+2]  << "\n";
  96.  
  97.         file1 << i/3 << " " << electron_e[i/3] << "\n";
  98. //        file2 << i/3 << " " << energy << "\n";
  99.  
  100.         energy = 0.0;
  101.     }
  102.  
  103.     for (int i = 0; i < n_e; i++){
  104.         int bin = (int)( (electron_e[i] - Emin)/bin_width );
  105.         if (bin >=0 && bin < N)
  106.             histo_random[bin]++;
  107.     }
  108.  
  109.     for (int i = 0; i < N; i++){
  110.         double bin_start = Emin + i*bin_width;
  111. //        printf("%5.1f - %5.1f\t%d\n", bin_start, bin_start + bin_width, histo_random[i]);
  112.         file3 << i*bin_width << " " <<  histo_random[i] << "\n";
  113.     }
  114.  
  115.  
  116.     for (int t = 0; t < steps; t++){
  117.  
  118.         // setting flags to false each timestep
  119.         for (int j = 0; j < n_e; j++){
  120.             collided[j] = false;
  121.         }
  122.  
  123.         for (int i = 0 ; i < n_e; i++){
  124.             if (dis(gen) < P) {
  125.                 int partner = -1;
  126.                 int attempts = 0;
  127.  
  128.                 while (attempts < n_e){
  129.                     int candidate = pair(gen1);
  130.                     if (candidate != i && !collided[candidate]){
  131.                         partner = candidate;
  132.                         break;
  133.                     }
  134.                     attempts++;
  135.                 }
  136.  
  137.                 if (partner != -1) {
  138.                     collided[i] = true;
  139.                     collided[partner] = true;
  140.                 }
  141.  
  142.                 // //Collision energy redistribution
  143.  
  144.                 // double totalEnergy = electron_e[i] + electron_e[partner];
  145.                 // double fraction = dis(gen);
  146.                 // electron_e[i] = totalEnergy*fraction;
  147.                 // electron_e[partner] = totalEnergy*(1.0 - fraction);
  148.  
  149.                 // first particle X Y Z initial velocities
  150.                 double V0_x_1 = electron_vel[i*3 + 0];
  151.                 double V0_y_1 = electron_vel[i*3 + 1];
  152.                 double V0_z_1 = electron_vel[i*3 + 2];
  153.  
  154.                 // second particle X Y Z initial velocities
  155.                 double V0_x_2 = electron_vel[partner*3 + 0];
  156.                 double V0_y_2 = electron_vel[partner*3 + 1];
  157.                 double V0_z_2 = electron_vel[partner*3 + 2];
  158.  
  159.                 // initial relative velocity X Y Z (must be equal to final relative velocity in center-of-mass frame)
  160.  
  161.                 double V0_rel_x = (V0_x_1 - V0_x_2)/2.0;
  162.                 double V0_rel_y = (V0_y_1 - V0_y_2)/2.0;
  163.                 double V0_rel_z = (V0_z_1 - V0_z_2)/2.0;
  164.  
  165.                 double V0_rel = sqrt(V0_rel_x*V0_rel_x + V0_rel_y*V0_rel_y + V0_rel_z*V0_rel_z);
  166.  
  167.                 // center-of-mass frame initial velocity (magnitude of it must be equal to the counterpart in this frame)
  168.  
  169.                 double V_cm_x = (V0_x_1 + V0_x_2)/2.0;
  170.                 double V_cm_y = (V0_y_1 + V0_y_2)/2.0;
  171.                 double V_cm_z = (V0_z_1 + V0_z_2)/2.0;
  172.  
  173.                 double V_cm = sqrt(V_cm_x*V_cm_x + V_cm_y*V_cm_y + V_cm_z*V_cm_z);
  174.  
  175.                 // generating random variables to calculate random direction of center-of-mass after the collision
  176.  
  177.                 double R1 = dis(gen);
  178.                 double R2 = dis(gen);
  179.  
  180.                 // calculating spherical angles for center-of-mass random direction
  181.                 double theta = acos(1.0- 2.0*R1);
  182.                 double phi = 2*M_PI*R2;
  183.  
  184.                 //calculating final relative velocity with random direction
  185.  
  186.                 double V_rel_x = V0_rel*sin(theta)*cos(phi);
  187.                 double V_rel_y = V0_rel*sin(theta)*sin(phi);
  188.                 double V_rel_z = V0_rel*cos(theta);
  189.  
  190.                 double V_rel = sqrt(V_rel_x*V_rel_x + V_rel_y*V_rel_y + V_rel_z*V_rel_z);
  191.  
  192.                 //calculating final velocity of first particle
  193.  
  194.                 double V_x_1 = V_cm_x + V_rel_x/2.0;
  195.                 double V_y_1 = V_cm_y + V_rel_y/2.0;
  196.                 double V_z_1 = V_cm_z + V_rel_z/2.0;
  197.  
  198.                 double V_1 = sqrt(V_x_1*V_x_1 + V_y_1*V_y_1 + V_z_1*V_z_1);
  199.  
  200.                 //calculating final velocity of second particle
  201.  
  202.                 double V_x_2 = V_cm_x - V_rel_x/2.0;
  203.                 double V_y_2 = V_cm_y - V_rel_y/2.0;
  204.                 double V_z_2 = V_cm_z - V_rel_z/2.0;
  205.  
  206.                 double V_2 = sqrt(V_x_2*V_x_2 + V_y_2*V_y_2 + V_z_2*V_z_2);\
  207.  
  208.                 // calculating final energies of first and second colliding particles
  209.  
  210.                 electron_e[i] = V_1*V_1*m_e/(2.0*k_b);
  211.                 electron_e[partner] = V_2*V_2*m_e/(2.0*k_b);              
  212.  
  213.             }
  214.         }
  215.     }
  216.  
  217.     for (int i = 0; i < n_e; i++){
  218.         int bin = (int)( (electron_e[i] - Emin)/bin_width );
  219.         if (bin >=0 && bin < N)
  220.             histo_maxwell[bin]++;
  221.     }
  222.  
  223.     for (int i = 0; i < N; i++){
  224.         double bin_start = Emin + i*bin_width;
  225. //        printf("%5.1f - %5.1f\t%d\n", bin_start, bin_start + bin_width, histo_maxwell[i]);
  226.         file4 << i*bin_width << " " <<  histo_maxwell[i] << "\n";
  227.     }
  228.  
  229.  
  230.     file.close();
  231.     file1.close();
  232.     file2.close();
  233.     file3.close();
  234.     file4.close();
  235.  
  236.     std::cout << "Energies written successfuly\n";
  237.  
  238.  
  239.     return 0;
  240.  
  241.  
  242. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement