<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1 plus MathML 2.0//EN" "http://www.w3.org/Math/DTD/mathml2/xhtml-math11-f.dtd" [ <!ENTITY mathml "http://www.w3.org/1998/Math/MathML"> ]>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<title>C++ N-body Problem</title>
<meta http-equiv="Content-Type" content="text/xml; charset=utf-8" />
<meta http-equiv="Content-Style-Type" content="text/css" />
<link rel="stylesheet" type="text/css" href="../documentation/s011.css" />
<link rel='SHORTCUT ICON' href='../documentation/images/FrameHome.ico' />
</head>

<body>

<div class="message_right">
  <a href="http://validator.w3.org/check/referer">
    <img src="http://www.w3.org/Icons/valid-xhtml11" alt="Valid
	XHTML 1.1!" height="31" width="88" />
  </a>

  <a href="http://jigsaw.w3.org/css-validator/">
    <img style="width:88px;height:31px"
       src="http://jigsaw.w3.org/css-validator/images/vcss" 
       alt="Valid CSS!" />
  </a>
  <br />
  Created 2004-08-30 &nbsp;  Modified 
<!--UPDATE_DATE_BEGIN-->
2009-04-11<br />
<a class="reflocal" href="../../../../doc02.html">Chelton Evans</a>

<!--UPDATE_DATE_END-->
</div>

<h1> 
<a href="../doc.html">
<img alt="proj" src="../../../comsci/images/code.png" /> </a>
N-Body Problem 
<a href="../../../../index.html">
<img alt="home" src="../../../comsci/images/Frame.gif" /> </a>
</h1>


<p>
<a class="reflocal2" href="#Intro"> Intro </a> <br />
<a class="reflocal2" href="#Source"> Source </a> <br />
<a class="reflocal2" href="#The_Distribution_of_Molecular_Speeds"> The Distributions of Molecular Speeds </a> <br />
<a class="reflocal2" href="#lennard-jones"> Lennard-Jones Potential </a> <br />
<a class="reflocal2" href="#Code_History"> Code History </a> <br />
<a class="reflocal2" href="#Investigating_Algorithm_Complexity"> Investigating Algorithm Complexity </a> <br />
<a class="reflocal" href="../../../math/geometry/g034.xml#Implementation"> 
  Bucket Sort Theory</a><br />
<a class="reflocal2" href="#TODO">TODO</a>
</p>



<div class="float25">
<a id="Intro"> </a>
<h2> Intro </h2>

<p><b>STATUS:</b> Compiling. Needs cleaning up. Not presentable - needs work.</p>

<p>
Simulating 2D collisions with two collision methods:
 brute force and uniform grid.
</p>

<table>
<tr>
<td>
<a href="sim01.png"> <img src="sim01s.png" alt="sim01s.png" /> </a>
</td>
<td>
<a href="sim02.png"> <img src="sim02s.png" alt="sim02s.png" /> </a>
</td>

</tr>
</table>

<p> Recompile for different distributions. For other
 options supply arguments at the command line.
 -h for available options.
</p>

<h3> System </h3>

<p>
Red Hat Linux 9.0, dual PIII 700 MHz, 
 Leadtek G2 graphics card,
 Scussi Ultra 2 HDD Cheetah 15000rpms.
 256 Mb RAM.
</p>

</div>

<!--UPDATE_SOURCE_TABLE-->
<!--UPDATE_SOURCE_TABLE_BEGIN-->
<div class="float25">
<a id="Source"> </a>
<h2> <a class="reflocal" href="../../download.html">Source</a> </h2>
<h3> Files </h3>
<a class="reflocal" href="Makefile">Makefile</a> <br/>
<a class="reflocal" href="boxcollision.cpp">boxcollision.cpp</a> <br/>
<a class="reflocal" href="boxcollision.h">boxcollision.h</a> <br/>
<a class="reflocal" href="cell.cpp">cell.cpp</a> <br/>
<a class="reflocal" href="cell.h">cell.h</a> <br/>
<a class="reflocal" href="d2toindex.cpp">d2toindex.cpp</a> <br/>
<a class="reflocal" href="d2toindex.h">d2toindex.h</a> <br/>
<a class="reflocal" href="integration.h">integration.h</a> <br/>
<a class="reflocal" href="main.cpp">main.cpp</a> <br/>
<a class="reflocal" href="particle.cpp">particle.cpp</a> <br/>
<a class="reflocal" href="particle.h">particle.h</a> <br/>
<a class="reflocal" href="particledisp.cpp">particledisp.cpp</a> <br/>
<a class="reflocal" href="particledisp.h">particledisp.h</a> <br/>
<a class="reflocal" href="particleranvd.cpp">particleranvd.cpp</a> <br/>
<a class="reflocal" href="particleranvd.h">particleranvd.h</a> <br/>
<a class="reflocal" href="particlesampler.cpp">particlesampler.cpp</a> <br/>
<a class="reflocal" href="particlesampler.h">particlesampler.h</a> <br/>
<br/>
<a class="reflocal" href="projcompile.txt">projcompile.txt</a> <br/>
<a class="reflocal" href="temp.txt">temp.txt</a> <br/>
<a class="reflocal" href="unittestsreport.txt">unittestsreport.txt</a> <br/>
<br/>
</div>
<div class="float25">
<h3> Doxygen </h3>
<a class="reflocal" href="../html/nbody_2main_8cpp.html">main.cpp</a> <br/>
<a class="reflocal" href="Makefile.html"> Makefile </a> <br/>
<a class="reflocal" href="../html/classboxcollision.html">boxcollision</a> <br/>
<a class="reflocal" href="../html/classcell.html">cell</a> <br/>
<a class="reflocal" href="../html/classd2toindex.html">d2toindex</a> <br/>
<a class="reflocal" href="../html/classintegration.html">integration</a> <br/>
<a class="reflocal" href="../html/classparticle.html">particle</a> <br/>
<a class="reflocal" href="../html/classparticledisp.html">particledisp</a> <br/>
<a class="reflocal" href="../html/classparticledistribution.html">particledistribution</a> <br/>
<a class="reflocal" href="../html/classparticleranvd.html">particleranvd</a> <br/>
<a class="reflocal" href="../html/classparticlesampler.html">particlesampler</a> <br/>
<a class="reflocal" href="../html/classparticlev0.html">particlev0</a> <br/>
<a class="reflocal" href="../html/classparticlev0spaced.html">particlev0spaced</a> <br/>
<a class="reflocal" href="../html/classparticlev0theta0.html">particlev0theta0</a> <br/>
</div>
<!--UPDATE_SOURCE_TABLE_END-->

<div class="spacer" />

<div class="float25">
<a id="The_Distribution_of_Molecular_Speeds"> </a>
<h2>The Distribution of Molecular Speeds </h2>




<h3> Speed of Velocity of Particle </h3>

<p>
Obtained Maxwells speed distribution. Well it looks like it
 anyway.  The choppy lines are variations in the discrete sampling buckets.

 Sampled the simulation
 over time and found that given any initial distribution over time
 converged to the Maxwell speed distribution.  This was visually
 confirmed by looking at the shape of the graph.
</p>

<p> Speed : r=0.02, numParticles=200, vmax=5.0, 81 histogram 
 divisions, vmax=5.0. Sampling every 100 timesteps. Box
 dimensions 10 by 10.
 The graphs are left to right, up to down. 
 The snapshots were taken though arbitrary time points.
 The initial distribution had random particle speeds up to vmax. </p>

</div>

<div class="float25">

<table>
<tr>
<td>
<a href="h200.png"> <img src="h200s.png" alt="h200s.png" /> </a>
</td>
<td>
<a href="h201.png"> <img src="h201s.png" alt="h201s.png" /> </a>
</td>
<td>
<a href="h202.png"> <img src="h202s.png" alt="h202s.png" /> </a>
</td>
</tr>

<tr>

<td>
<a href="h203.png"> <img src="h203s.png" alt="h203s.png" /> </a>
</td>
<td>
<a href="h204.png"> <img src="h204s.png" alt="h204s.png" /> </a>
</td>
</tr>

</table>


<p> Speed : vmax=2.0.  A different initial condition
 with all particles had the same initial speed.
</p>

<table>
<tr>
<td>
<a href="h400.png"> <img src="h400s.png" alt="h400s.png" /> </a>
</td>
<td>
<a href="h401.png"> <img src="h401s.png" alt="h401s.png" /> </a>
</td>
<td>
<a href="h402.png"> <img src="h402s.png" alt="h402s.png" /> </a>
</td>
</tr>
</table>

</div>

<div class="float25">

<p> Changing the box size to 4 by 2 still results in
 similar graph. </p>

<table>
<tr>
<td>
<a href="h501.png"> <img src="h501s.png" alt="h501s.png" /> </a>
</td>
</tr>
</table>

</div>

<div class="float25">

<h3> Speed along the x-axis </h3>

<p>
What appears to be a normal distribution evolved as
 the time steps increased. 
</p>


<table>
<tr>
<td>
<a href="hnx100.png"> <img src="hnx100s.png" alt="hnx100s.png" /> </a>
</td>
<td>
<a href="hnx101.png"> <img src="hnx101s.png" alt="hnx101s.png" /> </a>
</td>
<td>
<a href="hnx102.png"> <img src="hnx102s.png" alt="hnx102s.png" /> </a>
</td>
<td>
<a href="hnx103.png"> <img src="hnx103s.png" alt="hnx103s.png" /> </a>
</td>

</tr>
</table>

<p> This was observed in the other axes too.
 It appeared independent of box dimensions.
</p>

<p>
By changing the box size reducing the space increased the
 number of collisions in time and accelerated the 
 system towards the steady states.
</p>


</div>

<div class="spacer" />

<div class="float25">
<a id="Code_History"> </a>
<h2> Code History </h2>

<p>
I borrowed heavily from Geoff Leeches particle collision
 code. Converting the brute force from C to C++.  Also using 
 the original code as a benchmark. If what I wrote performed
 badly it was rewritten.
</p>

<p>
The code was kept similar in parts to benchmark the speed differences between
 C and C++ and where different to see how the differences performed.
</p>


<ul>
<li> Wrote 2D collision with brute force and uniform grid in C++</li>
<li> Histogram and Sampler objects written </li>
<li> Support for different initial conditions by
 architecture where you can define a distribution to be 
 slotted in.
</li>
<li>
  Rewrote using poor mans collision test and gained much better 
 performance. Removed STL vector for it performed significantly
 worse than the ordinary C style array.  
  Geoff suggested STL interfering with cache.
 As a consequence I removed STL vectors and gained a performance
 boost.
</li>
</ul>
</div>

<div class="float25">
<ul>
<li> Added colored balls to make it more visually  interesting and
 for debugging purposes the first and last are red
 and green. Blue is every 10th not including
 the first. Able to follow a particles journey
 an verify what an individual particle is doing.
</li>
<li> Learned to use gprof frequently for looking at where time 
 was spent in the code, particularly with in line functions.
  Gained about 18% improvement in the brute force method over the C version 
 with the C++ version.  Mild success attributed to in lined functions.
</li>
<li>
  With the brute force in C++ code, I
  experimented with in line functions by timing a task with functions in lined
 and without.  Dramatic differences were noticed with nested in line calls
 performing worse the more nested the in lining was.  Sometimes many times worse!
</li>
<li> Sometimes member functions performed significantly worse
 than cutting and pasting the code at the point of evaluation,
 even just calling other functions. I suspect the compiler
 is the problem because almost the same code should be generated
 but this is not the case.
</li>
<li>
Conclusion: C++ as fast as C in theory and if in lining faster.  The inner
 maximum loaded code is in lined will produce the results.
</li>
<li>
In lining code needs to be profiled as a minor source change can have a 
 dramatic effect, usually in a negative sense if unaware.
</li>
</ul>
</div>

<div class="float25">
<ul>
<li>
Major achievement: the C++ uniform grid was about 9.4 times faster  
 than the C uniform grid implementation.
 Primarily by preallocating the memory and never reallocating it.
</li>

<li> Wrote non-linear solver to solve a minimization problem
 for curve fitting. It was interpolation for a particular
 type of polynomial. The approximations were not good enough
 and I fitted the curve by hand.
</li>

<li>
Verified kinetic energy by putting in code to sum and display
 the sum of the velocities in the console.
</li>

<li>
Added configurable parameters so that the code would not
 have to be recompiled.  The command line class does this
 and added -h for help to display available options.
 The client enters the options at the command line. eg <br />
<code>$ ./main numParticles=300 samplerstate=1 uniform=true -h
</code>

</li>

<li>
Lennard-Jones Potential added as option with
 the brute force method.  eg. <code>LJ=true</code>
Parameterized the sampler so can configure it
 at the command line too.
</li>


</ul>

</div>

<div class="spacer" />

<div class="float25">
<a id="Investigating_Algorithm_Complexity"> </a>
<h2> Investigating Algorithm Complexity </h2>

<p> Decoupled graphics from computation.  Timed one incrementation varying
 the number of particles for the two methods.  I expected polynomial time.
 This was shown by plotting log(number of particles ) vs log( time taken),
 which produces a straight lines for both methods.
 </p>

<p>
When log X vs log Y graphs produce a straight line the relationship
 is a geometric curve of the following form.

</p>


<p class="equ">
<math xmlns="&mathml;">
  <mi>y</mi>
  <mo>(</mo>
  <mi>x</mi>
  <mo>)</mo>
  <mo>=</mo>
  <mi>a</mi>
  <mi>x</mi>
  <msup>
    <mi></mi>
    <mrow><mi>b</mi></mrow>
  </msup>
</math>
<br />
<math xmlns="&mathml;">
  <mi>a</mi>
</math>
 &nbsp; and &nbsp; 
<math xmlns="&mathml;">
  <mi>b</mi>
</math>
  &nbsp; are constants.
</p>



<h3> Brute Force </h3>

<div class="float">
<a href="B01.png"> <img src="B01s.png" alt="B01s.png" />
</a>
<br />
<div class="centered">
<h5>
Number of Particles vs Time(s) for 1 time step
</h5>

</div>
</div>

<div class="spacer" />

<div class="float">
<a href="B02.png"> <img src="B02s.png" alt="B02s.png" />
</a>
<br />
<div class="centered">
<h5> log(Number of Particles) vs log(Time(s)) for 1 time step </h5>
</div>
</div>

<div class="spacer">
 &nbsp;
</div>

<h3> Uniform Grid </h3>

<p>
A straight line relationship is observed from the graph.  
 Then the uniform grid is performing with O(n) complexity.
</p>


<div class="float">
<a href="U01.png"> <img src="U01s.png" alt="U01s.png" />
</a>
<br />
<div class="centered">
<h5>
Number of Particles vs Time(s) for 1 time step
</h5>

</div>
</div>

<div class="float">
<a href="U02.png"> <img src="U02s.png" alt="U02s.png" />
</a>
<br />
<div class="centered">
<h5> log(Number of Particles) vs log(Time(s)) for 1 time step </h5>
</div>
</div>

<div class="spacer">
 &nbsp;
</div>



<p> So I then needed statistical software to minimize the following curve
 and solve for a and b.
</p>

<p> Anyway I thought that this is not too difficult to solve, so
 I will solve it myself. Big mistake. Well not for a learning 
 perspective, it really is work acquiring a good stats program
 as its worth its weight in gold.  (I am a theoretic mathematician
 so I am ever so slowly discovering numerical approaches, but
 almost every engineer I encounter has done no algebra!)
</p>

<p>
Wrote a non-linear equation solver, used it to get best solution over
 a grid region. Plotted the curve with GnuPlot and not happy with the
 approximation : curve not bound to points so while accurate was
 not the correct shape.
</p>

<p>
Improvised and fitted a curve through trial and error which took all of
 60 seconds, and fitted a much better curve.  I found the brute force
 method to be approximately quadratic in order because a quadratic 
 fitted through its data points.
</p>

<h3> Brute Force Curve Fitted </h3>
<img src="B03.png" alt="B03.png" />


<h2> Prediction of Simulation Time with Brute Force </h2>

<table>

<tr>
<td> &nbsp;  </td>
<td> 1e3 particles </td>
<td> 1e4 particles </td>
<td> 1e5 particles </td>
<td> 1e6 particles </td>
</tr>

<tr>
<td> 1e3 timesteps  </td>
<td> 5.7*10^1 s </td>
<td> 5.7*10^3 s</td>
<td> 5.7*10^5 s</td>
<td> 5.7*10^7 s</td>
</tr>


<tr>
<td> 1e4 timesteps  </td>
<td> 5.7*10^2 s </td>
<td> 5.7*10^4 s</td>
<td> 5.7*10^6 s</td>
<td> 5.7*10^8 s</td>
</tr>


<tr>
<td> 1e5 timesteps  </td>
<td> 5.7*10^3 s </td>
<td> 5.7*10^5 s</td>
<td> 5.7*10^7 s</td>
<td> 5.7*10^9 s</td>
</tr>


<tr>
<td> 1e6 timesteps  </td>
<td> 5.7*10^4 s </td>
<td> 5.7*10^6 s</td>
<td> 5.7*10^8 s</td>
<td> 5.7*10^10 s</td>
</tr>


</table>

</div>

<div class="spacer" />

<div class="float25">
<a id="lennard-jones"> </a>
<h2> Lennard-Jones Potential </h2>

<p>
I have not got very far with this one. Lets discuss
 the equation. The majority of the time for simulations
 the simulation explodes (the kinetic energy goes
 to infinity).
 This is attributed to when two particles get too 
 close they are shot away from each other at high speeds.
</p>

<p>
Since the force is so great when two particles are
 near (a power of 13 repulsion) they shoot away.
 Now the new particles have much greater speed and
 are much more likely to collide with other particles
 head on - generating even more kinetic energy.
 This continues and the system breaks down.
</p>

<p>
Its clear that low velocities are needed so this
 situation does not arise, and particles can not
 get close to other particles centers because of
 the energy released. Hence the slow velocity
 so the particle can be repelled.
</p>

<p>
Onto of this is the inherent nature of hard sphere 
 collision systems
 to produce particles with high velocities. Only one
 of these particles is needed to send the system
 into anarchy.
</p>

</div>

<div class="float25">

<p>
So for a stable system hard sphere collisions can not
 occur. From the graph of Lennard-Jones Potential
 its clear that a minimum energy state occurs where
 attraction and repulsion are equal. But what does it
 mean here where the equation is applied to every
 other particle.
</p>

<p>
I tried to get a lattice thinking that would be
 the minimum state. The equation even hints that
 this is the case. By taking the derivative and
 solving for zero we get the following expression.
</p>

<p class="equ">
<math xmlns="&mathml;">
  <mi>r</mi>
  <mo>=</mo>
  <mi>2</mi>
  <msup>
    <mi></mi>
    <mrow>
      <mfrac>
        <mrow>
          <mi>1</mi>
        </mrow>
        <mrow>
          <mi>6</mi>
        </mrow>
      </mfrac>
    </mrow>
  </msup>
  <mi>&sigma;</mi>
</math>

</p>

<p>
In a lattice I imagine the forces balancing each other
 and the particles being about this distance away
 from each others centers. However I could not
 come up with the numbers and I don't know how to
 relate this to how many particles should be in a given
 area. 
</p>

<p>
The much more obtainable situation was where the particles
 went about but stayed away from each others centers
 (no hard sphere collision).
 Even for this I had to use very low speeds (compared
 to hard sphere collision case).
</p>

</div>


<div class="float25">

<p>
Because of the systems inherent instability I created
 a distribution where the spheres are spaced
 apart - to avoid the dramatic situation of particles
 speeding away from each other at the start and breaking
 the system.
</p>

<code>
$ ./main numParticles=15 x1=0.5 y1=0.5 vmax=0.005 LJ=true LJpsi=.000005 LJsigma=.01510 radius=.01 h=.1 samplerstate=1 histhigh=0.015
</code>

<table>
<tr>
<td>
<a href="h600.png"> <img src="h600s.png" alt="h600s.png" /> </a>
</td>
<td>
<a href="h601.png"> <img src="h601s.png" alt="h601s.png" /> </a>
</td>
<td>
<a href="h602.png"> <img src="h602s.png" alt="h602s.png" /> </a>
</td>
<td>
<a href="h603.png"> <img src="h603s.png" alt="h603s.png" /> </a>
</td>
<td>
<a href="h604.png"> <img src="h604s.png" alt="h604s.png" /> </a>
</td>
</tr>
</table>

<code>
$ ./main numParticles=15 x1=0.5 y1=0.5 vmax=0.005 LJ=true LJpsi=.000005 LJsigma=.01510 radius=.01 h=.1 samplerstate=2 histhigh=0.015
</code>

<table>
<tr>
<td>
<a href="h700.png"> <img src="h700s.png" alt="h700s.png" /> </a>
</td>
<td>
<a href="h701.png"> <img src="h701s.png" alt="h701s.png" /> </a>
</td>
<td>
<a href="h702.png"> <img src="h702s.png" alt="h702s.png" /> </a>
</td>
<td>
<a href="h703.png"> <img src="h703s.png" alt="h703s.png" /> </a>
</td>
<td>
<a href="h704.png"> <img src="h704s.png" alt="h704s.png" /> </a>
</td>
</tr>
</table>

<p>
It appears that the same distributions for the hard
 sphere collisions are being produced by the Lennard-Jones
 potential. ie normal for speed along axes, maxwell
 distribution for speed of velocity.
</p>

</div>

<div class="float25">
<a id="TODO"></a>
<h2>TODO</h2>

<ul>
<li>zpr option removed, reimplement it.</li>
<li>Document code with Doxygen style comments.</li>

</ul>

</div>

</body>
</html>




