At the coarsest level, the source code can be structured into targets (libraries and executables) and their dependencies. The graphical user interface is completely decoupled from the engine. For example, it would be possible to implement a different backend instead of CUDA.
The Base
library is used by all others and therefore is not separately marked with dependency arrows.
The main classes of the engine libraries and their relationships are shown in the following diagram. The CUDA code is completely encapsulated in the EngineGpuKernels
library.
The simulation code for calculating the next time step is located in SimulationKernelsLauncher
.
The data for a simulation are encapsulated in different sets of classes/structs on the CPU as well as GPU side. For the data transfer in both directions, the DataConverter
translates the Description
objects into separate transfer objects (TOs) consisting of C arrays, and vice versa.
For some use cases it is more convenient to utilize a ClusteredDataDescription
instead of a DataDescription
on the CPU side. The difference is that the ClusteredDataDescription
consists of ClusterDescriptions
, which in turn contain CellDescriptions
that are connected to each other.
The user interface is developed with Dear Imgui. All windows and dialogs that can be displayed are encapsulated in independent classes. The controller classes manage processes in the background or further windows. MVC patterns are not used in order not to unnecessarily bloat the code.