|
Orrery
A GPU-accelerated N-body gravitational simulator
|
Turning a configuration into the objects that run it. More...
#include <iosfwd>#include <memory>#include "orrery/backend/executor.hpp"#include "orrery/core/particle_data.hpp"#include "orrery/integrators/integrator.hpp"#include "orrery/sim/configuration.hpp"#include "orrery/sim/run_output.hpp"#include "orrery/sim/simulation.hpp"#include "orrery/solvers/force_solver.hpp"Go to the source code of this file.
Functions | |
| core::ParticleData | orrery::sim::make_initial_conditions (const Configuration &configuration) |
| Sample or construct the configuration the run starts from. | |
| core::Index | orrery::sim::primary_galaxy_count (const Configuration &configuration) |
| How many of the particles belong to the first of a collision's two galaxies. | |
| std::unique_ptr< integrators::Integrator > | orrery::sim::make_integrator (const Configuration &configuration) |
| std::unique_ptr< backend::Executor > | orrery::sim::make_executor (const Configuration &configuration) |
| The scheduler the CPU solvers divide their work with. | |
| std::unique_ptr< solvers::ForceSolver > | orrery::sim::make_solver (const Configuration &configuration, backend::Executor *executor, std::ostream &report) |
| The solver, given the executor it will refer to. | |
| Simulation | orrery::sim::assemble (const Configuration &configuration, std::unique_ptr< RunOutput > output, std::ostream &report) |
| Everything above, assembled into a run that has not yet taken a step. | |
Turning a configuration into the objects that run it.
This is the one file in the project that knows every solver, every integrator and every initial condition by name. That is the point of it: the alternative is each of the application, the test suite and any later binding growing its own chain of comparisons against the same strings, and three such chains agree until one of them is extended.
The functions are separate rather than folded into assemble because the pieces are wanted separately. A test that measures a solver builds one without sampling a million particles first, and a run that resumes from a checkpoint builds everything except the initial conditions, which it is about to overwrite with the state it read.
A configuration naming a SYCL solver is asking for one. The device may be absent, may not support the precision this build was configured for, or the backend may not have been compiled in at all, and none of those is a broken machine. So make_solver falls back to the CPU solver that computes the same thing, writes a line to report saying it has, and only refuses when the configuration set allow_cpu_fallback to false. A measurement whose whole point is the hardware it ran on sets that; an ordinary run does not, and gets its answer more slowly rather than not at all.
|
nodiscard |
Sample or construct the configuration the run starts from.
Throws std::invalid_argument from the generators for parameters they refuse. problems_with catches every such case first, so reaching one of those means a caller assembled a configuration it had not checked.
|
nodiscard |
How many of the particles belong to the first of a collision's two galaxies.
Zero for every other configuration, which is the answer to "where does the first group end" for a configuration that has only one group.
It is here rather than in initial_conditions/ because the split is a property of how this layer divides a requested count between two galaxies, not of what a galaxy is. The renderer uses it to tint the two apart, which is what makes it possible to see which material in a merged remnant came from where, and make_initial_conditions uses it so that the two answers cannot differ.
|
nodiscard |
The scheduler the CPU solvers divide their work with.
Never null, including for the serial choice, which is a real executor that runs the range on the calling thread. That keeps the reporting uniform: a run can always say which scheme it used and how many workers it had.
|
nodiscard |
The solver, given the executor it will refer to.
executor must outlive the returned solver, which is why this takes a pointer to one the caller is holding rather than making its own.
Writes to report when it does not return what was asked for. Throws std::runtime_error when a GPU solver was demanded and no device can provide one.
|
nodiscard |
Everything above, assembled into a run that has not yet taken a step.
Costs one force evaluation, which the simulation's constructor spends establishing the acceleration invariant, and for a sampled configuration the time to draw it.