University of North Carolina at Asheville

CSCI 273: Mathematical Programming

Lab 13

Case Study: N-body Simulation

[Introduction] [Instructions] [What To Submit]


In this lab you will work with a physics-oriented simulation that traces the orbits of multiple celestial bodies (planets, stars, asteroids, whatever) as they move in response to their mutual gravitational attraction. This project is in fact a Case Study developed in Section 3.4 of your text.

But do not panic just yet, at least not because you read the word physics above. You really do not need to know much physics at all to get through this project. In fact all the essential class definitions involved in this simulation have been completely implemented by your textbook authors, and the methods in these classes already incorporate all the required physics dealing with gravitational forces, accelerations, and so forth. So as usual, your first tasks will be essentially just tests of the framework already provided for the Case Study.

Of course you will eventually be asked to take on some more challenging tasks. But these will really be programming problems, not physics problems.


To complete this project, follow the steps listed below:

  1. Login to your home directory and launch a terminal window. Use the cd command to change your default directory to csci/273.002/labs. Keep this window open for future reference.
  2. Launch the NetBeans IDE and raise the New Project dialog. Define the project to be a Java Application named Lab13. Make sure that the project folder will be created within your csci/273.002/labs folder. As in your previous labs, you should also uncheck the Create Main Class checkbox before you click Finish.
  3. Some of the classes you will be downloading or creating for this lab are clients of library classes in the JAR file Booksite.jar. So your next task is to make all those library classes available to your Lab13 project. First make sure that your version of Booksite.jar is still in your csci/273.002/labs folder. If not, download the equivalent archive Booksite.jar into csci/273.002/labs now. Then repeat the same procedure in the NetBeans IDE that you first performed as Step 6 in Lab 08.

  4. Find and download the plain-text versions of the Booksite demos (Program 3.3.3), (Program 3.4.1) and (Program 3.4.2) into the default directory for your Lab13 project. Each of these source files are fully implemented and ready for use in this project. However, it will be a good idea to describe each of these classes and their roles before you actually attempt to build and run Lab13.
  5. To understand what the Vector class is all about, you might first want to scan pp. 430-433 of your text or check out the description near the end of Section 3.3 on the Booksite. But in a nutshell, the Vector class is designed to represent N-dimensional vectors. In this lab you will work only with 2D (planar) vectors. However, note that the general N-body problem involves motion in full-fledged 3D space, in which the orbits need not all be restricted to lie within a single plane.

    After you have read a description of the Vector class, open in the NetBeans editor and try to familiarize yourself with its contents. If you started by reading the textbook version, you should note that the actual source code is a bit more extensive than the textbook listing on page 432. But all you really want to do now is to understand the API well enough to see how it is used by the other two classes in this project. Since these textbook classes lack complete external documentation, you may frequently have to consult the source code itself as you proceed.

  6. The class Body is used to model objects that physicists might also refer to as particles or mass points. As these terms suggest, such objects are fully characterized by specifying their mass, position, and velocity (or alternatively, momentum) at each instant of time. In other words, for this problem the class Body does not have to model other conceivable properties such as size, shape, or color.

    In this N-body simulation the Body objects might model individual celestial bodies (hence the name). These can include stars, planets, asteroids, and comets, as well as exotic objects like neutron stars or black holes. And of course all manner of combinations are possible, such as planets orbiting neutron stars or neutron stars orbiting each other (both of which have actually been observed).

    You should now take a moment to scan pp. 457-460 in your text, or the equivalent Booksite discussion for Section 3.4. Then open in the NetBeans editor. You should note that the instance variables for a Body object include its mass (a double value) and two Vector objects, representing its location r and velocity v respectively.

    You might also note that the actual API defined by is almost identical to the printed listing on page 460 of your text, except for a method named forceTo(). The textbook listing names this method forceFrom(), but in fact the bodies of the two methods are identical. The difference is really one of perspective: forceTo() returns the gravitational force exerted by the calling object (aka this) on some other Body object b. In the printed listing the method forceFrom() is supposed to return the force exerted by object b on the calling object. But unfortunately, that version has a sign error, which would make the gravitational force repulsive. So you will want to stick with the Booksite version here, not the textbook listing.

  7. Finally, you should scan pp. 461-465 in your text or the equivalent online discussion in Section 3.4 for background information on the rather grandiose-sounding class Universe. Then open and scan its contents. In particular, note that the Universe constructor actually reads its initializing data from standard input. This data includes the number N of mutually interacting Body objects, followed by the (2D) position, (2D) velocity, and mass of each Body. All of these quantities are given in SI units, which means that lengths are measured in meters, time is measured in seconds, and masses are in kilograms. Of course the data for each N-body simulation will actually be stored in a separate textfile and read by redirecting the standard input stream.

    You should also be sure to look over the key method increaseTime(). This method first computes the total vector sum of the gravitational forces on each Body due to all the other Body objects. Then it makes use of Newton's second law of motion, which just states that the acceleration of a mass point is given by the net force acting on it divided by its mass. Following this law, increaseTime() causes each Body to advance along its path by an amount determined by its computed acceleration over a small fixed time interval.

  8. At this point, Build the project and run Universe from the terminal window. For starters, you might try the sample input textfile 2body.txt which is available from Section 3.4 of the Booksite. Note that you will also need to supply the time-increment interval (in seconds!) as a command-line argument suggested in the program header comments. You might try entering 10000 for the input file suggested above. This value may not seem like a "small" time increment to you, but the values in the input textfile are appropriate for typical planetary motions (where the time scales should really be measured in months or years rather than seconds).

  9. At this point you should create a new subfolder named data in your Lab13 project folder, and use it to hold other sample input textfiles that you can download from the Booksite. Then you should take a few moments to run these simulations and see just how quickly things get complicated as N increases. In particular, be sure to check out 3body.txt and 4body.txt, which provide examples of 3- and 4-body problems respectively.
  10. For your next project in this lab, try your hand at writing your own input data file for a 2-body simulation that models the Earth orbiting the Sun. You might name this file "earthorbit.txt", and you should just add it to the textbook examples in your data subfolder. To simplify things, try to set this up so that the orbit is very nearly circular (which in fact it is).

    Note that you can easily find the required masses, distances, and so forth using Google. Just remember to get these quantities in MKS units (meters-kilograms-seconds). You might also want to remember that Newton's second law of motion, F = ma, can be combined with his law of gravitation to get ma = GMm/r2. Also note that circular acceleration is related to velocity and radius by the formula a = v2/r. And finally, if you find yourself in need of a calculator, remember there is one available on your system (look under accessories).

    When you get this simulation running to your satisfaction, show your results to your lab instructor.

  11. On page 465 of your text (and in the matching online discussion in Section 3.4 ), you will find examples of images that track N-body orbits. Your next task in this lab is to create a modified version of Universe, named of course MyUniverse, which displays images of this type. You can find some semi-helpful hints on how to do this near the top of page 464 in your text. But you can definitely get more explicit help from your lab instructor.

    In any event, your first test of your new code should be made with a simple 2-body simulation such as 2body.txt. For this file, your version of MyUniverse should at least initially resemble the following image:

    But note that if you let your program run for much longer times, the image might begin to look more like this:

    Can you come up with an explanation for this behavior? Hint: you might try running your program again with, say, half the original time increment but for twice as long in real time. Do you get the essentially the same image?

    To complete the formalities, show your results to your lab instructor.

What To Submit

When your project is complete and working correctly, demonstrate it to your lab instructor. Then, before you exit NetBeans, clean your Lab13 project. Finally, before you logout, switch back to your terminal and set your default directory back to csci/273.002/labs. Then create a JAR file of your Lab13 project folder, using the command

jar cf Lab13Project.jar Lab13
Please leave both your Lab13 project folder and Lab13Project.jar in your csci/273.002/labs directory for the remainder of the semester.