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.
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.
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.
- 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.
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:
- Clone the repository to your computer
- Change your directory to the directory you cloned the repository to
- 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)
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.
Thus, it was necessary for me to consult other, similar, projects for inspiration:
- Piston's Spinning Square Tutorial was helpful in showing me how to set up and use piston.
- Dileban's nbody-simulation provided an understanding of the basics of gravitational interactions.
- Zongzhengli's n-body was absolutely instrumental in understanding the barnes-hut algorithm.