📄 dsmcne.cpp
字号:
// dsmcne - Program to simulate a dilute gas using DSMC algorithm
// This version simulates planar Couette flow
#include "NumMeth.h"
#include "SortList.h"
#include "SampList.h"
double rand( long& seed );
double randn( long& seed );
int colider( Matrix& v, Matrix& crmax, double tau, long& seed,
Matrix& selxtra, double coeff, SortList& sD );
void sorter( Matrix& x, double L, SortList &sD );
void mover( Matrix& x, Matrix& v, int npart, double L,
double mpv, double vwall, double tau,
Matrix& strikes, Matrix& delv, long& seed );
void sampler( Matrix& x, Matrix& v, int npart, double L,
SampList& sampD );
void main() {
//* Initialize constants (particle mass, diameter, etc.)
const double pi = 3.141592654;
const double boltz = 1.3806e-23; // Boltzmann's constant (J/K)
double mass = 6.63e-26; // Mass of argon atom (kg)
double diam = 3.66e-10; // Effective diameter of argon atom (m)
double T = 273; // Temperature (K)
double density = 2.685e25; // Number density of argon at STP (m^-3)
double L = 1e-6; // System size is one micron
double Volume = L*L*L; // Volume of the system
cout << "Enter number of simulation particles: ";
int npart; cin >> npart;
double eff_num = density*L*L*L/npart;
cout << "Each particle represents " << eff_num << " atoms" << endl;
double mfp = Volume/(sqrt(2.0)*pi*diam*diam*npart*eff_num);
cout << "System width is " << L/mfp << " mean free paths" << endl;
double mpv = sqrt(2*boltz*T/mass); // Most probable initial velocity
cout << "Enter wall velocity as Mach number: ";
double vwall_m; cin >> vwall_m;
double vwall = vwall_m * sqrt(5./3. * boltz*T/mass);
cout << "Wall velocities are " << -vwall << " and "
<< vwall << " m/s" << endl;
//* Assign random positions and velocities to particles
long seed = 1; // Initial seed for rand (DO NOT USE ZERO)
Matrix x(npart), v(npart,3);
int i;
for( i=1; i<=npart; i++ ) {
x(i) = L*rand(seed); // Assign random positions
// Initial velocities are Maxwell-Boltzmann distributed
v(i,1) = sqrt(boltz*T/mass) * randn(seed);
v(i,2) = sqrt(boltz*T/mass) * randn(seed);
v(i,3) = sqrt(boltz*T/mass) * randn(seed);
// Add velocity gradient to the y-component
v(i,2) += vwall * 2*(x(i)/L - 0.5);
}
//* Initialize variables used for evaluating collisions
int ncell = 20; // Number of cells
double tau = 0.2*(L/ncell)/mpv; // Set timestep tau
Matrix vrmax(ncell), selxtra(ncell);
vrmax.set(3*mpv); // Estimated max rel. speed
selxtra.set(0.0); // Used by routine "colider"
double coeff = 0.5*eff_num*pi*diam*diam*tau/(L*L*L/ncell);
//* Declare object for lists used in sorting
SortList sortData(ncell,npart);
//* Initialize object and variables used in statistical sampling
SampList sampData(ncell);
double tsamp = 0; // Total sampling time
Matrix dvtot(2), dverr(2);
dvtot.set(0.0); // Total momentum change at a wall
dverr.set(0.0); // Used to find error in dvtot
//* Loop for the desired number of time steps
int colSum = 0; // Count total collisions
Matrix strikes(2), strikeSum(2);
strikeSum.set(0.0); // Count strikes on each wall
cout << "Enter total number of time steps: ";
int istep, nstep; cin >> nstep;
for( istep = 1; istep<=nstep; istep++ ) {
//* Move all the particles
Matrix delv(2); delv.set(0.0);
mover( x, v, npart, L, mpv, vwall,
tau, strikes, delv, seed );
strikeSum(1) += strikes(1);
strikeSum(2) += strikes(2);
//* Sort the particles into cells
sorter(x,L,sortData);
//* Evaluate collisions among the particles
int col = colider(v,vrmax,tau,seed,selxtra,coeff,sortData);
colSum += col; // Increment collision count
//* After initial transient, accumulate statistical samples
if(istep > nstep/10) {
sampler(x,v,npart,L,sampData);
// Cummulative velocity change for particles striking walls
dvtot(1) += delv(1); dvtot(2) += delv(2);
dverr(1) += delv(1)*delv(1); dverr(2) += delv(2)*delv(2);
tsamp += tau;
}
//* Periodically display the current progress
if( (istep%100) < 1 ) {
cout << "Done " << istep << " of " << nstep << " steps; " <<
colSum << " collisions" << endl;
cout << "Total wall strikes: " << strikeSum(1) << " (left) "
<< strikeSum(2) << " (right)" << endl;
}
}
//* Normalize the accumulated statistics
int nsamp = sampData.nsamp;
for( i=1; i<=ncell; i++ ) {
sampData.ave_n[i] *= (eff_num/(Volume/ncell))/nsamp;
sampData.ave_ux[i] /= nsamp;
sampData.ave_uy[i] /= nsamp;
sampData.ave_uz[i] /= nsamp;
sampData.ave_T[i] *= mass/(3*boltz*nsamp);
}
dverr(1) = dverr(1)/(nsamp-1) - (dvtot(1)/nsamp)*(dvtot(1)/nsamp);
dverr(1) = sqrt(dverr(1)*nsamp);
dverr(2) = dverr(2)/(nsamp-1) - (dvtot(2)/nsamp)*(dvtot(2)/nsamp);
dverr(2) = sqrt(dverr(2)*nsamp);
//* Compute viscosity from drag force on the walls
Matrix force(2), ferr(2);
force(1) = (eff_num*mass*dvtot(1))/(tsamp*L*L);
force(2) = (eff_num*mass*dvtot(2))/(tsamp*L*L);
ferr(1) = (eff_num*mass*dverr(1))/(tsamp*L*L);
ferr(2) = (eff_num*mass*dverr(2))/(tsamp*L*L);
cout << "Force per unit area is" << endl;
cout << "Left wall: " << force(1) << " +/- " << ferr(1) << endl;
cout << "Right wall: " << force(2) << " +/- " << ferr(2) << endl;
double vgrad = 2*vwall/L; // Velocity gradient
double visc = 0.5*(-force(1)+force(2))/vgrad; // Average viscosity
double viscerr = 0.5*(ferr(1)+ferr(2))/vgrad; // Error
cout << "Viscosity = " << visc << " +/- " << viscerr
<< "N s/m^2" << endl;
double eta = 5.*pi/32.*mass*density*(2./sqrt(pi)*mpv)*mfp;
cout << "Theoretical value of viscoisty is " << eta
<< "N s/m^2" << endl;
//* Print out the plotting variables:
// xcell, ave_n, ave_ux, ave_uy, ave_uz, ave_T
ofstream xcellOut("xcell.txt"), ave_nOut("ave_n.txt"),
ave_uxOut("ave_ux.txt"), ave_uyOut("ave_uy.txt"),
ave_uzOut("ave_uz.txt"), ave_TOut("ave_T.txt");
for( i=1; i<=ncell; i++ ) {
xcellOut << (i-0.5)*L/ncell << endl;
ave_nOut << sampData.ave_n[i] << endl;
ave_uxOut << sampData.ave_ux[i] << endl;
ave_uyOut << sampData.ave_uy[i] << endl;
ave_uzOut << sampData.ave_uz[i] << endl;
ave_TOut << sampData.ave_T[i] << endl;
}
}
/***** To plot in MATLAB; use the script below ********************
load xcell.txt; load ave_n.txt; load ave_ux.txt;
load ave_uy.txt; load ave_uz.txt; load ave_T.txt;
figure(1); clf;
plot(xcell,ave_n); xlabel('position'); ylabel('Number density');
figure(2); clf;
plot(xcell,ave_ux,xcell,ave_uy,xcell,ave_uz);
xlabel('position'); ylabel('Velocities');
legend('x-component','y-component','z-component');
figure(3); clf;
plot(xcell,ave_T); xlabel('position'); ylabel('Temperature');
******************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -