Guest User

Untitled

a guest
May 27th, 2010
368
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.07 KB | None | 0 0
  1. // dsmc3d - Program to simulate a dilute gas using DSMC algorithm
  2. // This version simulates planar Couette flow
  3.  
  4. #include "NumMeth.h"
  5. #include "SortList3d.h"
  6. #include "SampList3d.h"
  7.  
  8. double rand( long& seed );
  9. double randn( long& seed );
  10. int colider3d( Matrix3d& v, Matrix3d crmax, double tau, long& seed,
  11.               Matrix3d selxtra, double coeff, SortList3d& sD );
  12. void sorter3d( Matrix3d& position, double L, SortList3d &sD );
  13. void mover3d( Matrix3d& position, Matrix3d& v, int npart, double L,
  14.             double mpv, double vwall, double tau,
  15.             Matrix3d& strikes, Matrix3d& delv, long& seed );
  16. void sampler3d( Matrix3d& position, Matrix3d& v, int npart, double L,
  17.             SampList3d& sampD );
  18.  
  19. int main() {
  20.  
  21.   //* Initialize constants  (particle mass, diameter, etc.)
  22.   const double pi = 3.141592654;
  23.   const double boltz = 1.3806e-23;    // Boltzmann's constant (J/K)
  24.   double mass = 6.63e-26;       // Mass of argon atom (kg)
  25.   double diam = 3.66e-10;       // Effective diameter of argon atom (m)
  26.   double T = 273;               // Temperature (K)
  27.   double density = 2.685e25;    // Number density of argon at STP (m^-3)
  28.   double L = 5.0e-6;              // System size is one micron
  29.   double Volume = L*L*L;        // Volume of the system
  30.   cout << "Enter number of simulation particles: ";
  31.   int npart; cin >> npart;
  32.   double eff_num = density*L*L*L/npart;
  33.   cout << "Each particle represents " << eff_num << " atoms" << endl;
  34.   double mfp = Volume/(sqrt(2.0)*pi*diam*diam*npart*eff_num);
  35.   cout << "System width is " << L/mfp << " mean free paths" << endl;
  36.   double mpv = sqrt(2*boltz*T/mass);  // Most probable initial velocity
  37. //Not needed anymore:
  38. //  cout << "Enter wall velocity as Mach number: ";
  39. //  double vwall_m; cin >> vwall_m;
  40. //  double vwall = vwall_m * sqrt(5./3. * boltz*T/mass);
  41. //  cout << "Wall velocities are " << -vwall << " and "
  42. //      << vwall << " m/s" << endl;
  43. double vwall = 0;
  44.  
  45.   //* Assign random positions and velocities to particles
  46.   long seed = 1;       // Initial seed for rand (DO NOT USE ZERO)
  47.   //Matrix3d x(npart); //Replaced with a position matrix
  48.   Matrix3d position(npart,3), v(npart,3);
  49.   int i;
  50.   for( i=1; i<=npart; i++ ) {
  51.     //x(i) = L*rand(seed);        // Assign random positions
  52.     position(i,1) = L*rand(seed);//x coord
  53.     position(i,2) = L*rand(seed);//y coord
  54.     position(i,3) = L*rand(seed);//z coord
  55.     // Initial velocities are Maxwell-Boltzmann distributed
  56.     v(i,1) = sqrt(boltz*T/mass) * randn(seed);
  57.     v(i,2) = sqrt(boltz*T/mass) * randn(seed);
  58.     v(i,3) = sqrt(boltz*T/mass) * randn(seed);
  59.     //Not what we need anymore
  60.     // Add velocity gradient to the y-component
  61.     //v(i,2) += vwall * 2*(x(i)/L - 0.5);
  62.   }
  63.  
  64.   //* Initialize variables used for evaluating collisions
  65.   int ncell_x = 20;                       // Number of cells
  66.   int ncell_y = 20;                       // Number of cells
  67.   int ncell_z = 20;                       // Number of cells
  68.   int ncell_total = ncell_x*ncell_y*ncell_z;                       // Number of cells
  69.   double tau = 0.2*(L/ncell_total)/mpv;       // Set timestep tau
  70.   //Matrix3d vrmax(ncell_total), selxtra(ncell_total);  //We can't use Matrix3d here, we need an actual 3d matrix for these.
  71.   //vrmax.set(3*mpv);    // Estimated max rel. speed
  72.   //selxtra.set(0.0);       // Used by routine "colider"
  73.   Matrix3d vrmax(ncell_x,ncell_y,ncell_z);
  74.   Matrix3d selxtra(ncell_x,ncell_y,ncell_z);
  75.  
  76.   vrmax.set(3*mpv);
  77.   selxtra.set(0);
  78.  
  79.   double coeff = 0.5*eff_num*pi*diam*diam*tau/(L*L*L/ncell_total);
  80.  
  81.   //* Declare object for lists used in sorting
  82.   SortList3d sortData(ncell_x, ncell_y, ncell_z, npart);
  83.  
  84.     //Ignoring this for now.
  85.   // Initialize object and variables used in statistical sampling
  86.   SampList3d sampData(ncell_x,ncell_y,ncell_z);
  87.   double tsamp = 0;             // Total sampling time
  88.   Matrix3d dvtot(2), dverr(2);
  89.   dvtot.set(0.0);               // Total momentum change at a wall
  90.   dverr.set(0.0);               // Used to find error in dvtot
  91.  
  92.   //* Loop for the desired number of time steps
  93.   int colSum = 0;         // Count total collisions
  94.   Matrix3d strikes(2), strikeSum(2);
  95.   strikeSum.set(0.0);     // Count strikes on each wall
  96.   cout << "Enter total number of time steps: ";
  97.   int istep, nstep; cin >> nstep;
  98.   int col;
  99.   for( istep = 1; istep<=nstep; istep++ ) {
  100.  
  101.     //* Move all the particles
  102.     Matrix3d delv(2);  delv.set(0.0);
  103.     mover3d( position, v, npart, L, mpv, vwall,
  104.            tau, strikes, delv, seed );
  105.     strikeSum(1) += strikes(1);
  106.     strikeSum(2) += strikes(2);
  107.  
  108.     //* Sort the particles into cells
  109.     sorter3d(position,L,sortData);
  110.  
  111.     //* Evaluate collisions among the particles
  112.     col = colider3d(v,vrmax,tau,seed,selxtra,coeff,sortData);
  113.     colSum += col;  // Increment collision count
  114.  
  115.     //* After initial transient, accumulate statistical samples
  116.     if(istep > nstep/10) {
  117.       sampler3d(position,v,npart,L,sampData);
  118.       // Cummulative velocity change for particles striking walls
  119.       dvtot(1) += delv(1);          dvtot(2) += delv(2);
  120.       dverr(1) += delv(1)*delv(1);  dverr(2) += delv(2)*delv(2);
  121.       tsamp += tau;
  122.     }
  123.  
  124.     //* Periodically display the current progress
  125.     if( (istep%1000) < 1 )  {
  126.       cout << "Done " << istep << " of " << nstep << " steps; " <<
  127.              colSum << " collisions" << endl;
  128.       cout << "Total wall strikes: " << strikeSum(1) << " (left) "
  129.            << strikeSum(2) << " (right)" << endl;
  130.     }
  131.   }
  132.  
  133.   //* Normalize the accumulated statistics
  134.   int nsamp = sampData.nsamp;
  135.  
  136. /*  //Ignore for now.  
  137. for( i=1; i<=ncell; i++ ) {
  138.     sampData.ave_n[i] *= (eff_num/(Volume/ncell))/nsamp;
  139.     sampData.ave_ux[i] /= nsamp;
  140.     sampData.ave_uy[i] /= nsamp;
  141.     sampData.ave_uz[i] /= nsamp;
  142.     sampData.ave_T[i] *= mass/(3*boltz*nsamp);
  143.   }
  144. */
  145.  
  146.  
  147.   dverr(1) = dverr(1)/(nsamp-1) - (dvtot(1)/nsamp)*(dvtot(1)/nsamp);
  148.   dverr(1) = sqrt(dverr(1)*nsamp);
  149.   dverr(2) = dverr(2)/(nsamp-1) - (dvtot(2)/nsamp)*(dvtot(2)/nsamp);
  150.   dverr(2) = sqrt(dverr(2)*nsamp);
  151.  
  152.   //* Compute viscosity from drag force on the walls
  153.   Matrix3d force(2), ferr(2);
  154.   force(1) = (eff_num*mass*dvtot(1))/(tsamp*L*L);
  155.   force(2) = (eff_num*mass*dvtot(2))/(tsamp*L*L);
  156.   ferr(1) = (eff_num*mass*dverr(1))/(tsamp*L*L);
  157.   ferr(2) = (eff_num*mass*dverr(2))/(tsamp*L*L);
  158.   cout << "Force per unit area is" << endl;
  159.   cout << "Left wall:  " << force(1) << " +/- " << ferr(1) << endl;
  160.   cout << "Right wall: " << force(2) << " +/- " << ferr(2) << endl;
  161.   double vgrad = 2*vwall/L;    // Velocity gradient
  162.   double visc = 0.5*(-force(1)+force(2))/vgrad;  // Average viscosity
  163.   double viscerr = 0.5*(ferr(1)+ferr(2))/vgrad;  // Error
  164.   cout << "Viscosity = " << visc << " +/- " << viscerr
  165.        << "N s/m^2" << endl;
  166.   double eta = 5.*pi/32.*mass*density*(2./sqrt(pi)*mpv)*mfp;
  167.   cout << "Theoretical value of viscoisty is " << eta
  168.        << "N s/m^2" << endl;
  169.  
  170. /*  //Ignore for now until we know what to do about this.
  171.   // Print out the plotting variables:
  172.   //    xcell, ave_n, ave_ux, ave_uy, ave_uz, ave_T
  173.   ofstream xcellOut("xcell.txt"), ave_nOut("ave_n.txt"),
  174.            ave_uxOut("ave_ux.txt"), ave_uyOut("ave_uy.txt"),
  175.            ave_uzOut("ave_uz.txt"), ave_TOut("ave_T.txt");
  176.   for( i=1; i<=ncell; i++ ) {
  177.     xcellOut << (i-0.5)*L/ncell << endl;
  178.     ave_nOut << sampData.ave_n[i] << endl;
  179.     ave_uxOut << sampData.ave_ux[i] << endl;
  180.     ave_uyOut << sampData.ave_uy[i] << endl;
  181.     ave_uzOut << sampData.ave_uz[i] << endl;
  182.     ave_TOut << sampData.ave_T[i] << endl;
  183.   }
  184. */
  185.  
  186.  
  187.  
  188. }
  189. /***** To plot in MATLAB; use the script below ********************
  190. load xcell.txt;  load ave_n.txt;     load ave_ux.txt;
  191. load ave_uy.txt; load ave_uz.txt;    load ave_T.txt;
  192. figure(1); clf;
  193. plot(xcell,ave_n); xlabel('position');  ylabel('Number density');
  194. figure(2); clf;
  195. plot(xcell,ave_ux,xcell,ave_uy,xcell,ave_uz);
  196. xlabel('position');  ylabel('Velocities');
  197. legend('x-component','y-component','z-component');
  198. figure(3); clf;
  199. plot(xcell,ave_T); xlabel('position');  ylabel('Temperature');
  200. ******************************************************************/
Advertisement
Add Comment
Please, Sign In to add comment