45 ProbabilityFunctionNegative,
47 <<
"Your probability density function in the particle generator "
48 "returned a negative value for the following position: "
49 << arg1 <<
". Please check your function expression.");
62 template <
int dim,
int spacedim = dim>
64 compute_local_cumulative_cell_weights(
69 std::vector<double> cumulative_cell_weights(
71 double cumulative_weight = 0.0;
87 for (
const auto &cell :
triangulation.active_cell_iterators())
89 if (cell->is_locally_owned())
91 fe_values.reinit(cell);
92 const double quadrature_point_weight =
93 probability_density_function.
value(
94 fe_values.get_quadrature_points()[0]);
97 ProbabilityFunctionNegative<dim>(
98 quadrature_formula.
point(0)));
101 cumulative_weight += quadrature_point_weight * fe_values.JxW(0);
103 cumulative_cell_weights[cell->active_cell_index()] =
107 return cumulative_cell_weights;
111 template <
int dim,
int spacedim>
115 const std::vector<
Point<dim>> & particle_reference_locations,
121#ifdef DEAL_II_WITH_MPI
122 if (
const auto tria =
127 tria->n_locally_owned_active_cells() *
128 particle_reference_locations.size();
132 const int ierr = MPI_Exscan(&n_particles_to_generate,
137 tria->get_communicator());
142 for (
const auto &cell :
triangulation.active_cell_iterators())
144 if (cell->is_locally_owned())
146 for (
const auto &reference_location :
147 particle_reference_locations)
167 template <
int dim,
int spacedim>
172 std::mt19937 & random_number_generator,
177 std::uniform_real_distribution<double> uniform_distribution_01(0, 1);
184 unsigned int iteration = 0;
185 const unsigned int maximum_iterations = 100;
187 while (iteration < maximum_iterations)
189 for (
unsigned int d = 0;
d < spacedim; ++
d)
191 particle_position[
d] =
192 uniform_distribution_01(random_number_generator) *
193 (cell_bounds.second[
d] - cell_bounds.first[
d]) +
194 cell_bounds.first[
d];
213 iteration < maximum_iterations,
215 "Couldn't generate a particle position within the maximum number of tries. "
216 "The ratio between the bounding box volume in which the particle is "
217 "generated and the actual cell volume is approximately: " +
220 (cell_bounds.second - cell_bounds.first).norm_square())));
227 template <
int dim,
int spacedim>
232 const bool random_cell_selection,
236 const unsigned int random_number_seed)
238 unsigned int combined_seed = random_number_seed;
239 if (
const auto tria =
243 const unsigned int my_rank =
245 combined_seed += my_rank;
247 std::mt19937 random_number_generator(combined_seed);
252 std::vector<types::particle_index> particles_per_cell(
258 const std::vector<double> cumulative_cell_weights =
261 probability_density_function);
264 double local_weight_integral = (cumulative_cell_weights.size() > 0) ?
265 cumulative_cell_weights.back() :
268 double global_weight_integral;
270 if (
const auto tria =
274 global_weight_integral =
276 tria->get_communicator());
280 global_weight_integral = local_weight_integral;
285 "The integral of the user prescribed probability "
286 "density function over the domain equals zero, "
287 "deal.II has no way to determine the cell of "
288 "generated particles. Please ensure that the "
289 "provided function is positive in at least a "
290 "part of the domain; also check the syntax of "
295 double local_start_weight = 0.0;
297#ifdef DEAL_II_WITH_MPI
298 if (
const auto tria =
302 const int ierr = MPI_Exscan(&local_weight_integral,
307 tria->get_communicator());
314 std::llround(
static_cast<double>(n_particles_to_create) *
315 local_start_weight / global_weight_integral);
319 std::llround(
static_cast<double>(n_particles_to_create) *
320 ((local_start_weight + local_weight_integral) /
321 global_weight_integral));
322 n_local_particles = end_particle_id - start_particle_id;
324 if (random_cell_selection)
329 std::uniform_real_distribution<double> uniform_distribution(
330 0.0, local_weight_integral);
334 current_particle_index < n_local_particles;
335 ++current_particle_index)
339 const double random_weight =
340 uniform_distribution(random_number_generator);
342 const std::vector<double>::const_iterator selected_cell =
344 cumulative_cell_weights.end(),
347 std::distance(cumulative_cell_weights.begin(), selected_cell);
358 for (
const auto &cell :
triangulation.active_cell_iterators())
359 if (cell->is_locally_owned())
363 static_cast<double>(n_local_particles) *
364 cumulative_cell_weights[cell->active_cell_index()] /
365 local_weight_integral);
370 particles_per_cell[cell->active_cell_index()] =
371 cumulative_particles_to_create - particles_created;
373 particles_per_cell[cell->active_cell_index()];
380 unsigned int current_particle_index = start_particle_id;
387 for (
const auto &cell :
triangulation.active_cell_iterators())
388 if (cell->is_locally_owned())
390 for (
unsigned int i = 0;
391 i < particles_per_cell[cell->active_cell_index()];
396 current_particle_index,
397 random_number_generator,
399 particles.emplace_hint(particles.end(),
401 std::move(particle));
402 ++current_particle_index;
412 template <
int dim,
int spacedim>
416 & global_bounding_boxes,
420 const std::vector<std::vector<double>> &properties)
422 const auto &fe = dof_handler.
get_fe();
429 std::map<types::global_dof_index, Point<spacedim>> support_points_map;
438 std::vector<Point<spacedim>> support_points_vec;
439 support_points_vec.reserve(support_points_map.size());
440 for (
auto const &element : support_points_map)
441 support_points_vec.push_back(element.second);
444 global_bounding_boxes,
449 template <
int dim,
int spacedim>
456 & global_bounding_boxes,
459 const std::vector<std::vector<double>> &properties)
461 const std::vector<Point<dim>> &particle_reference_locations =
463 std::vector<Point<spacedim>> points_to_generate;
466 for (
const auto &cell :
triangulation.active_cell_iterators())
468 if (cell->is_locally_owned())
470 for (
const auto &reference_location :
471 particle_reference_locations)
476 points_to_generate.push_back(position_real);
481 global_bounding_boxes,
487#include "generators.inst"
std::pair< Point< spacedim, Number >, Point< spacedim, Number > > & get_boundary_points()
unsigned int size() const
const FiniteElement< dim, spacedim > & get_fe(const unsigned int index=0) const
virtual RangeNumberType value(const Point< dim > &p, const unsigned int component=0) const
virtual Point< spacedim > transform_unit_to_real_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< dim > &p) const =0
virtual Point< dim > transform_real_to_unit_cell(const typename Triangulation< dim, spacedim >::cell_iterator &cell, const Point< spacedim > &p) const =0
void update_cached_numbers()
std::map< unsigned int, IndexSet > insert_global_particles(const std::vector< Point< spacedim > > &positions, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bounding_boxes, const std::vector< std::vector< double > > &properties={}, const std::vector< types::particle_index > &ids={})
void insert_particles(const std::multimap< typename Triangulation< dim, spacedim >::active_cell_iterator, Particle< dim, spacedim > > &particles)
particle_iterator insert_particle(const Particle< dim, spacedim > &particle, const typename Triangulation< dim, spacedim >::active_cell_iterator &cell)
const Point< dim > & point(const unsigned int i) const
const std::vector< Point< dim > > & get_points() const
#define DEAL_II_NAMESPACE_OPEN
#define DEAL_II_NAMESPACE_CLOSE
@ update_JxW_values
Transformed quadrature weights.
@ update_quadrature_points
Transformed quadrature points.
std::string to_string(const T &t)
#define AssertThrowMPI(error_code)
#define DeclException1(Exception1, type1, outsequence)
static ::ExceptionBase & ExcMessage(std::string arg1)
#define AssertThrow(cond, exc)
void probabilistic_locations(const Triangulation< dim, spacedim > &triangulation, const Function< spacedim > &probability_density_function, const bool random_cell_selection, const types::particle_index n_particles_to_create, ParticleHandler< dim, spacedim > &particle_handler, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()), const unsigned int random_number_seed=5432)
void dof_support_points(const DoFHandler< dim, spacedim > &dof_handler, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bounding_boxes, ParticleHandler< dim, spacedim > &particle_handler, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()), const ComponentMask &components=ComponentMask(), const std::vector< std::vector< double > > &properties={})
void quadrature_points(const Triangulation< dim, spacedim > &triangulation, const Quadrature< dim > &quadrature, const std::vector< std::vector< BoundingBox< spacedim > > > &global_bounding_boxes, ParticleHandler< dim, spacedim > &particle_handler, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()), const std::vector< std::vector< double > > &properties={})
Particle< dim, spacedim > random_particle_in_cell(const typename Triangulation< dim, spacedim >::active_cell_iterator &cell, const types::particle_index id, std::mt19937 &random_number_generator, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()))
void regular_reference_locations(const Triangulation< dim, spacedim > &triangulation, const std::vector< Point< dim > > &particle_reference_locations, ParticleHandler< dim, spacedim > &particle_handler, const Mapping< dim, spacedim > &mapping=(ReferenceCells::get_hypercube< dim >() .template get_default_linear_mapping< dim, spacedim >()))
SymmetricTensor< 2, dim, Number > d(const Tensor< 2, dim, Number > &F, const Tensor< 2, dim, Number > &dF_dt)
unsigned int this_mpi_process(const MPI_Comm &mpi_communicator)
T sum(const T &t, const MPI_Comm &mpi_communicator)
Iterator lower_bound(Iterator first, Iterator last, const T &val)
unsigned int particle_index
const ::parallel::distributed::Triangulation< dim, spacedim > * triangulation
#define DEAL_II_PARTICLE_INDEX_MPI_TYPE