What Is Monte Carlo?
Example 1 - Monte Carlo Integration To Estimate Pi
Example 2 - Monte Carlo solutions of Poisson's Equation
Example 3 - Monte Carlo Estimates of Thermodynamic Properties
General Remarks on Parallel Monte Carlo Radiation transport Operations research Nuclear criticality Design of nuclear reactors Design of nuclear weapons Statistical physics Phase transitions Wetting and growth of thin films Atomic wave functions and Intranuclear cascade reactions eigenvalues Thermodynamic properties Long chain coiling polymers Reaction kinetics Partial differential equations Large sets of linear equations Numerical integration Uncertainty analysis Development of statistical tests Cell population studies Combinatorial problems Search and optimization Signal detection WarGames
Read N
Set SumG = 0.0
Do While i < N
Pick two random numbers xi and yi
If (xi*xi + yi*yi £ 1) then
SumG = SumG + 1
Endif
Enddo
Gbar = SumG / N
SigGbar = Sqrt(Gbar - Gbar2)
Print N, Gbar, SigGbar
Number of Batch CPU Standard True
Processors Size Time(sec) Deviation Error
--------------------------------------------------------
1 100,000 0.625 0.005 0.0018
2 50,000 0.25 0.005 0.0037
4 25,000 0.81 0.005 0.0061
--------------------------------------------------------
% cd
% cp -r /usr/local/mc .
% cd mc/mcpi
% run
1. Creating the random number generators
for ( int i=0; i < num_dimension; i++) { // create r.n. generator
// the seeds are different for the processors
seed = (myRank + 1) * 100 + i * 10 + 1;
if ( seed == 0 )
rand[i] = new RandomStream(RANDOMIZE);
else
rand[i] = new RandomStream( seed );
}
2. Each processors will run num_random / numProcs random walks
for ( i=myRank; i < num_random; i+=numProcs ) { // N random walks
2a. Generating random numbers
for ( int i1=0; i1 < num_dimension; i1++) {
ran[i1] = rand[i1]- > next();
}
2b. Calculating for integration
if ( inBoundary( ran, num_dimension ) ) {
myPi += f( ran, num_dimension ) * pdf( ran, num_dimension );
count++;
}
}
3. Calculating Pi from each processor
myPi = 4 * myPi / num_random;
MPI_Reduce(&myPi, &pi, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
4. Output the results and standard deviation, sigma
if (myRank == 0) {
cout << "pi is = " << pi
<< " sigma = " << 4 * sqrt( (pi/4 - (pi/4)*(pi/4)) / num_random)
<< " Error = " << abs(pi - PI25DT) << endl;
}
Number of Walks/ CPU Standard
Processors Point Time u(20,20) Deviation
-----------------------------------------------------
1 1000 400 0.0483 0.00016
2a 1000 270 0.0480 0.00020
4a 1000 165 0.0485 0.00020
=====================================================
2b 1000 313 0.0477 0.00020
4b 1000 234 0.0480 0.00029
----------------------------------------------------
a - Update all processors at same time
b - Only update whthin individual processor
% cd % cd mc/poisson4 % run
1. // Set boundary condition
boundary(nx, ny);
2. Devide the initial region into 4 sub-region if necessary
2.a Evaluate the virtual parallel inner boundary line
2.b Evaluate the virtual vertical inner boundary line
2.c Initialize boundary for each sub-region
3. // Calcalute u for (ix,iy) of each region
while ( 1 ) {
3.a // Calculate u[ix][iy] for a point (ix,iy), and send it to others
sendU( rand, ix, iy, delta );
3.b // Receives u[iix][iiy] from the other processors
for ( int i = 0; i < numProcs; i++) {
if (i != myRank) {
MPI_Recv(&uRec, 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD,&status);
if (uRec <= -1000) flag = 1;
else {
ixp = ix + (i - myRank); // the index of inner boundary,
iyp = iy; // u at this cell received from
// another processor
if ( ixp > (nx2[iRegion] - 1) ) {
ixp = nx1[iRegion] + (ixp - nx2[iRegion]) + 1;
iyp = iy + 1;
}
3.c // Set this point as a boundary
u[ixp][iyp] = uRec;
onBoundary[ixp][iyp] = 1;
}
}
3.d // Set ix, iy of next node for the processor
ix += numProcs;
if ( ix > (nx2[iRegion] - 1) ) {
ix = nx1[iRegion] + (ix - nx2[iRegion]) + 1;
iy++;
}
assert( ((ix < nx) && (iy < ny)), " out of given domain");
}
Number of CPU Time CPU Time
Processors 1000 Walks 100,000 walks
------------------------------------------
1 0.44 3.06
2 0.5 2.5
4 0.5 1.4
------------------------------------------
% cd
% cd mc/point
% run
1. // Set boundary condition
2. // Set the points which are evaluated.
for (int i=0; i < numPoint; i++) {
x[i] = (i + 1.) / ( numPoint + 1. );
y[i] = (i + 1.) / ( numPoint + 1. );
}
3. Evaluate each point
for ( i=0; i < numPoint; i++ ) {
... ...
3.a All processors run for one same point
for ( int ir=myRank; ir < num_random; ir+=numProcs ) {
// initilaizing the position of the point for each random walk
xx = x[i];
yy = y[i];
while (1) {
// calculating the minimum distance of selected point
// to the boundary
minDist = MinDist(xx, yy, side);
if ( minDist < acceptDist ) break;
// each processor generates a random number, and make a random
// move, the point moves randomly to any point at the circle
// with a radius of minDist, and centered at (xx, yy)
double ran = rand->next();
xx += minDist * sin(2*pi*ran);
yy += minDist * cos(2*pi*ran);
}
// sum
tempU = EvalPoint( xx, yy, side );
myU += tempU;
mysqU += tempU * tempU;
} // end of a ramdom walk
myU /= num_random;
mysqU /= num_random;
3.b // Sum the results from all processors
MPI_Reduce(&myU, &u, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
MPI_Reduce(&mysqU, &sqU, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
3.c // print out
if ( myRank == 0 )
cout << "At the point of " << x[0] << ", " << y[0]
<< " , u is = " << u
<< " , sigma = " << sqrt( (sqU - u*u) / num_random);
must goto zero; that is Pn(C) must be the steady state function P(C)
and
P(C)T(C->C') = P(C')T(C'->C)
spin = -1 (down)
% cd
% cd mc/ising
% run
1. // Set the parameters and initialize
initialize( l, h, v );
2. // Each processor evaluates the properties of system at a temperature
for (int i=myRank; i < num_runs; i += numProcs) {
double tau = tauMin + i * delTau;
2.a // Make the atoms of system random distributed
for (int j=0; j < 100*l*l; j++ ) {
ran1 = rand1->next();
ran2 = rand2->next();
makeMove( l, h, v, ran1, ran2, tau );
}
2.b // Go to random walks, and add the energy of each state
for ( int i1=0; i1 < num_random; i1++ ) {
ran1 = rand1->next();
ran2 = rand2->next();
makeMove( l, h, v, ran1, ran2, tau );
sumM += abs(m);
sumM2 += m * m;
sumE += e;
sumE2 += e * e;
}
2.c Calculate the thermal properties
double aveM = sumM / num_random;
double aveM2 = sumM2 / num_random;
double aveE = sumE / num_random;
double aveE2 = sumE2 / num_random;
double delSqM = aveM2 - aveM * aveM;
double delSqE = aveE2 - aveE * aveE;
aveM /= l * l;
aveE /= l * l;
double temp = tau * tau * l * l;
double chi = delSqM / temp;
double specHeat = delSqE / temp;