Constructs a grid with the given minimum grid coordinates and grid length.
If you need periodic boundaries you have to use this constructor to set the correct length to use for wrapping particles around the borders.
106 :
length_(min_and_length.second) {
107 const auto min_position = min_and_length.first;
108 const SizeType particle_count = particles.size();
116 cells_.emplace_back(particles.copy_to_vector());
127 const int max_cells =
129 ? std::cbrt(particle_count)
130 : std::max(2,
static_cast<int>(std::cbrt(particle_count)));
135 std::array<double, 3> index_factor = {1. / max_interaction_length,
136 1. / max_interaction_length,
137 1. / max_interaction_length};
142 :
static_cast<int>(std::floor(
length_[i] * index_factor[i]));
154 std::string error_box_too_small =
155 "Input error: Your box is too small for the grid.\n"
156 "The minimal length of the box is given by: " +
157 std::to_string(2 * max_interaction_length) +
158 " fm with the given timestep size.\n"
159 "If you have large timesteps please reduce them.\n"
160 "A larger box or the use of testparticles also helps.\n"
161 "Please take a look at your config.";
162 throw std::runtime_error(error_box_too_small);
170 if (
length_[i] >= max_interaction_length) {
175 index_factor[i] = std::nextafter(index_factor[i], 0.);
191 " cells. Therefore the Grid falls back to a single cell / "
196 cells_.front().reserve(particles.size());
197 std::copy_if(particles.begin(), particles.end(),
198 std::back_inserter(
cells_.front()),
199 [&](
const ParticleData &
p) {
200 return p.xsec_scaling_factor(timestep_duration) > 0.0;
212 "\nindex_factor: ", index_factor);
223 auto &&cell_index_for = [&](
const ParticleData &
p) {
225 std::floor((
p.position()[1] - min_position[0]) * index_factor[0]),
226 std::floor((
p.position()[2] - min_position[1]) * index_factor[1]),
227 std::floor((
p.position()[3] - min_position[2]) * index_factor[2]));
230 for (
const auto &
p : particles) {
231 if (
p.xsec_scaling_factor(timestep_duration) > 0.0) {
232 const auto idx = cell_index_for(
p);
237 "\nan out-of-bounds access would be necessary for the "
239 p,
"\nfor a grid with the following parameters:\nmin: ",
240 min_position,
"\nlength: ",
length_,
242 "\ncells_.size: ",
cells_.size(),
"\nrequested index: ", idx);
243 throw std::runtime_error(
"out-of-bounds grid access on construction");
int SizeType
A type to store the sizes.
const std::array< double, 3 > length_
The 3 lengths of the complete grid. Used for periodic boundary wrapping.
std::array< int, 3 > number_of_cells_
The number of cells in x, y, and z direction.
double cell_volume_
The volume of a single cell.
std::vector< ParticleList > cells_
The cell storage.
SizeType make_index(SizeType x, SizeType y, SizeType z) const
#define SMASH_SOURCE_LOCATION
Hackery that is required to output the location in the source code where the log statement occurs.
std::array< einhard::Logger<>, std::tuple_size< LogArea::AreaTuple >::value > logg
An array that stores all pre-configured Logger objects.
@ ParticleNumber
Limit the number of cells to the number of particles.
bool all_of(Container &&c, UnaryPredicate &&p)
Convenience wrapper for std::all_of that operates on a complete container.
@ Normal
Without ghost cells.
@ PeriodicBoundaries
With ghost cells for periodic boundaries.
static constexpr int LGrid
@ Largest
Make cells as large as possible.