N-Body Modeling with NBody.net
As part of keeping up to speed with some of the deliverables the patterns & practices teams are shipping, notably Enterprise Library, Unity and Prism as well as some of the latest development practices, like domain driven design. So in some ways the whole project is a test bed and showcase for lots of ideas and new ways of writing code.
In the end it’s turned out I’ve taken on a bunch of other challenges, like the Task Parallel Library and mixed language development with C#, F#, C++/CLI, C++, OpenMP and Nvidia’s CUDA platform to improve performance and DirectX 9 to get a better, faster visualization. While this is still very much a work in progress it’s now a fully working implementation.
Mixed language architecture
The underlying architecture hasn’t changed. It’s still a WPF application written using Prism 1.0 based modular approach and relies on Enterprise Library 4.1 for cross cutting concerns like logging, validation and configuration. The WPF UI and the domain model are built up using Unity’s dependency injection container which means a user can configure different initial setup criteria and integration engines on the fly.
The key is picking the appropriate parts of the application and the appropriate language to implement them in. The two big reasons are performance and access to APIs not exposed easily through managed code.
Calculation Engines – Almost all the CPU cycles are spent inside the integration code which calculates the forces and updates the position of each body in the model. See my series of posts on optimization for some more background on different serial and parallel C# and C++ implementations of the core integration engine. Some integration algorithms use complex recursive approaches and may lend themselves to implementation in other languages like F#.
The only requirement to create an integrator, in any language is that it implements the IIntegrate interface and uses the types defined in the (managed) domain model. This turns out to be fairly trivial.
Model Renderer – WPF’s viewport3D has a couple of issues. Firstly it supports a limited feature set; namely it only renders triangles. Secondly the performance isn’t sufficient to render thousands of items, especially then they’re made up of multiple triangles. The end result is that rendering the model becomes a bottleneck. Using DirectX from C++ allows better control over how the view is rendered and significantly improves performance. The DirectX surface is wrapped inside a WPF Image which in turn is part of a Prism module.
Hosting a Direct3D surface in WPF is actually covered in “Walkthrough: Hosting Direct3D9 Content in WPF” (MSDN). While pretty straightforward their implementation has a couple of annoying bugs.
Where’s the code?
You can download some of the source code from my NBody project on BitBucket. This includes most of the domain model and some example code on how to use it.