Skip to content

An attempt at implementing an efficient n-body simulation in rust

License

Notifications You must be signed in to change notification settings

mshawke/rust-n-body

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

27 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Mallory S. Hawke
CS410P, Spring 2021
Homework 4

N-Body-Sim

Intro

Hey there! Welcome to my final project for Bart Massey's Introduction to Rust class.

This is a very bare-bones, open source under the MIT License, code base which focuses on implementing methods to calculate newtonian gravitational interactions between some user-defined number of bodies, n, and then display the results of those calculations graphically.


n-body
N-Body-Sim in Action


The inspiration for this project was a YouTube video of an ASCII Simulation of Colliding Galaxies, the codebase for which can be found at DinoZ1729's Github.

So, what does it actually do?

At a macro level, the crate will do the following:

  • Allow the user to calculate newtonian gravitational interactions between some specified number of bodies, n, using either:
    • The bruteforce algorithm
    • The Barnes-Hut / OctTree algorithm
  • Display the results of those operations, graphically, in pseudo-3D (2D rendering with 3D calculations, utilizing colour and size of particles to indicate depth / distance)

Currently, the reasonable limit for n using my naive solution is n = ~500, while the barnes-hut implementation begins to chug pretty heavily around n = 2000~3000; these values could likey be significantly increased by using a proper vector / matrix multiplication library, CPU multithreading, or GPU-based calculations.

What Went Wrong?

Originally, the intent with this project was to develop a solution to the N-Body problem with the following characterstics:
  • Able to support n > 10,000
  • Rendered in 3D
  • Could create large interacting bodies such as galaxies
  • Utilizes GPU for calculations
  • Utilizes Barnes-Hut algorithm

However, going into project this I had little-to-no experience:

  • Working with graphical libraries, either 2D or 3D.
  • Calculating gravitational interactions between bodies.
  • Creating large Rust projects from whole cloth
  • Performing GPU computations

So, given that I had basically no idea what I was doing, and that nearly all of the work was performed in the last week-and-a-half of the term due to other assignments taking short-term precedence, it should come as no surprise that I didn't manage to hit all of the (honestly, very hubristic) goals I'd set for myself.

In particular, GPU calculations, true 3D, and the n = 10,000 target had to be droppped.

Also, I'll be honest; while the code as written appears to work, I can't claim to be confident that the math comports with reality.

Still, I managed to hit enough of my goals that I'm proud of what I managed to produce in such a short time. If nothing else, this was an incredible learning experience, and I fully intend to continue my work on this far past the assignments due date in an attempt to reach those goals I hadn't managed to hit.

How do I run it?

Pretty simple, honestly. Just clone it, go to that directory, and enter on your command line:

cargo run (x) (y)

  • The first argument, x, must be either 1 or 2; 1 indicates that you want to use the naive / brute force method for calculating interactions between bodies, and 2 indicates that you want to use the barnes-hut / oct tree.
  • The second argument, y, must be a positive integer less than 2^32. While it is otherwise unbounded, it may be useful to note that numbers larger than ~1000 for the naive

TLDR:

  1. Clone the repository to your computer
  2. Change your directory to the directory you cloned the repository to
  3. In the command line type: cargo run (x) (y) (where x is an integer from 1 to 2, and y is a positive integer < 2^32)

How do we know it works/doesn't break?

I mean, we don't. Not without, ideally, formal verification, which is far, far beyond the scope of either my abilities or this project. Still, I've managed to implement a fair number of unit tests for most things, which should at least ensure that the foundational items work as intended:

  • Vec3D: Has tests which generate pseudo-random values and perform local calculations to check that the implemented ops, the sum of squares function, and the scalar (basically just returns DT / dist^2) return the correct values.

  • Nbodies: Implements tests which try to make sure that the algorithm's won't attempt to update a body if the thing it's updating against is that same body.

  • Parsearg and parsenum: The argument parser and number parser functions implement a huge battery of tests which try to make sure that there isn't

  • Body: The only function really implemented for body is the bounds function, and so that is what the sole unit test here focuses on; a body is created and its position values are generated at random, but are positive. The coordinates are then increased to beyond the allowable values

  • OctTree: Ah, yeah. This one. Honestly, there doesn't really appear to be any clear options for unit tests here; they likely exist, but I'm not currently clever enough to think of them within the time remaining.

Acknowledgements and Citations

I came into this project feeling pretty overwhelmed by the scope of what I'd agreed to, especially considering I've never worked on anything grapical besides some ncurses, my practical understanding of the physics involved was initially lacking, and the time I had to dedicate to the project was miniscule. In fact, it was only within the last week-and-a-half that I was able to focus on it with any regularity, as my other classes kept me very much on my toes with a consistent barrage of assignments.

Thus, it was necessary for me to consult other, similar, projects for inspiration:

About

An attempt at implementing an efficient n-body simulation in rust

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages