6 #ifndef PORTAGE_SWARM_SWARM_H_ 7 #define PORTAGE_SWARM_SWARM_H_ 23 #include "wonton/support/Point.h" 25 namespace Portage {
namespace Meshfree {
51 num_local_points_(points_.size())
54 #ifdef PORTAGE_ENABLE_THRUST 62 num_local_points_(points_.size())
76 unsigned user_seed = 0,
77 double x_min = 0.0,
double x_max = 0.0,
78 double y_min = 0.0,
double y_max = 0.0,
79 double z_min = 0.0,
double z_max = 0.0);
88 template<
typename Mesh>
89 Swarm(Mesh
const& mesh, Wonton::Entity_kind entity);
98 template<
typename Mesh>
99 Swarm(std::vector<Mesh*>
const& meshes, Wonton::Entity_kind entity);
149 Wonton::Point<dim> point = points_[index];
161 Entity_type
const type = Wonton::ALL)
const {
163 assert(kind == Wonton::PARTICLE);
175 Entity_type
const type = Wonton::ALL)
const {
177 assert(kind == Wonton::PARTICLE);
186 points_.insert(points_.end(), new_pts.begin(), new_pts.end());
194 int num_local_points_ = 0;
200 double x_min,
double x_max,
204 assert(num_particles > 0);
205 assert(0 <= distribution and distribution <= 2);
208 points_.resize(num_particles);
212 std::random_device device;
213 std::mt19937 engine { user_seed ? user_seed : device() };
214 std::uniform_real_distribution<double> generator(0.0, 1.0);
217 if (distribution == 0) {
218 for (
auto&& current : points_)
219 current = Wonton::Point<1>(x_min + (x_max - x_min) * generator(engine));
222 double const h = (x_max - x_min) / (num_particles - 1);
224 points_[i] = Wonton::Point<1>(x_min + i * h);
226 if (distribution == 2) {
228 Wonton::Point<1> current = points_[i];
229 current[0] += 0.25 * h * (2 * generator(engine) - 1);
230 points_[i] = Wonton::Point<1>(std::max(x_min, std::min(x_max, current[0])));
239 double x_min,
double x_max,
240 double y_min,
double y_max,
243 assert(num_particles > 0);
244 assert(0 <= distribution and distribution <= 2);
247 std::random_device device;
248 std::mt19937 engine { user_seed ? user_seed : device() };
249 std::uniform_real_distribution<double> generator(0.0, 1.0);
251 if (distribution == 0) {
254 points_.resize(num_local_points_);
256 for (
auto&& current : points_) {
259 double const noise[] = { generator(engine),
262 current = Wonton::Point<2>(x_min + (x_max - x_min) * noise[0],
263 y_min + (y_max - y_min) * noise[1]);
267 int const num_per_dim = std::floor(std::sqrt(num_particles));
268 num_local_points_ = num_per_dim * num_per_dim;
269 points_.resize(num_local_points_);
270 double const hx = (x_max - x_min) / (num_per_dim - 1);
271 double const hy = (y_max - y_min) / (num_per_dim - 1);
275 for (
int i = 0; i < num_per_dim; i++)
276 for (
int j = 0; j < num_per_dim; ++j)
277 points_[k++] = Wonton::Point<2>(x_min + i * hx, y_min + j * hy);
279 if (distribution == 2) {
280 for (
auto&& current : points_) {
283 double const noise[] = { generator(engine),
286 Wonton::Point<2> copy = current;
287 copy[0] += 0.25 * hx * (2 * noise[0] - 1);
288 copy[1] += 0.25 * hy * (2 * noise[1] - 1);
289 current = Wonton::Point<2>(std::max(x_min, std::min(x_max, copy[0])),
290 std::max(y_min, std::min(y_max, copy[1])));
299 double x_min,
double x_max,
300 double y_min,
double y_max,
301 double z_min,
double z_max) {
303 assert(num_particles > 0);
304 assert(0 <= distribution and distribution <= 2);
307 std::random_device device;
308 std::mt19937 engine { user_seed ? user_seed : device() };
309 std::uniform_real_distribution<double> generator(0.0, 1.0);
311 if (distribution == 0) {
314 points_.resize(num_local_points_);
319 double const noise[] = { generator(engine),
323 points_[i] = Wonton::Point<3>(x_min + (x_max - x_min) * noise[0],
324 y_min + (y_max - y_min) * noise[1],
325 z_min + (z_max - z_min) * noise[2]);
329 auto const cubic_root = std::pow(num_particles, 1./3.);
330 auto const num_per_dim =
static_cast<int>(std::ceil(cubic_root));
331 auto const hx = (x_max - x_min) / (cubic_root - 1);
332 auto const hy = (y_max - y_min) / (cubic_root - 1);
333 auto const hz = (z_max - z_min) / (cubic_root - 1);
336 num_local_points_ = num_per_dim * num_per_dim * num_per_dim;
337 points_.resize(num_local_points_);
341 for (
int i = 0; i < num_per_dim; i++)
342 for (
int j = 0; j < num_per_dim; ++j)
343 for (
int k = 0; k < num_per_dim; ++k)
344 points_[n++] = Wonton::Point<3>(x_min + i * hx,
348 if (distribution == 2) {
349 for (
auto&& current : points_) {
352 double const noise[] = { generator(engine),
356 Wonton::Point<3> copy = current;
357 copy[0] += 0.25 * hx * (2 * noise[0] - 1);
358 copy[1] += 0.25 * hy * (2 * noise[1] - 1);
359 copy[2] += 0.25 * hz * (2 * noise[2] - 1);
360 current = Wonton::Point<3>(std::max(x_min, std::min(x_max, copy[0])),
361 std::max(y_min, std::min(y_max, copy[1])),
362 std::max(z_min, std::min(z_max, copy[2])));
370 template<
typename Mesh>
374 num_local_points_ = mesh.num_owned_nodes();
375 points_.resize(num_local_points_);
376 Wonton::Point<dim> coord;
377 for (
int i = 0; i < num_local_points_; ++i) {
378 mesh.node_get_coordinates(i, &coord);
383 num_local_points_ = mesh.num_owned_cells();
384 points_.resize(num_local_points_);
386 for (
int i = 0; i < num_local_points_; ++i) {
387 mesh.cell_centroid(i, ¢roid);
391 default:
throw std::runtime_error(
"unsupported entity");
397 template<
typename Mesh>
403 case Wonton::NODE:
for (
auto&& mesh : meshes) n += mesh->num_owned_nodes();
break;
404 case Wonton::CELL:
for (
auto&& mesh : meshes) n += mesh->num_owned_cells();
break;
405 default:
throw std::runtime_error(
"unsupported entity");
408 num_local_points_ = n;
409 points_.resize(num_local_points_);
414 for (
auto&& mesh : meshes) {
415 int const num_nodes = mesh->num_owned_nodes();
416 Wonton::Point<dim> coord;
417 for (
int i = 0; i < num_nodes; i++) {
418 mesh->node_get_coordinates(i, &coord);
419 points_[n++] = coord;
424 for (
auto&& mesh : meshes) {
425 int const num_cells = mesh->num_owned_cells();
427 for (
int i = 0; i < num_cells; i++) {
428 mesh->cell_centroid(i, ¢roid);
440 #endif // PORTAGE_SWARM_SWARM_H_ std::vector< T > vector
Definition: portage.h:238
Swarm(Portage::vector< Wonton::Point< dim >> const &points)
Create a particle field from a given list.
Definition: swarm.h:49
Wonton::Point< OP::dim > centroid(const typename OP::points_t &apts)
Definition: operator.h:616
int num_ghost_particles() const
Get ghost particles count.
Definition: swarm.h:126
counting_iterator end(Entity_kind const kind=Wonton::PARTICLE, Entity_type const type=Wonton::ALL) const
Get an iterator at last element of the particle field.
Definition: swarm.h:174
int space_dimension() const
Get the dimension.
Definition: swarm.h:112
int num_owned_particles() const
Get owned particles count.
Definition: swarm.h:119
~Swarm()=default
Destructor.
Swarm()=default
Create an empty particle field.
void extend_particle_list(std::vector< Wonton::Point< dim >> const &new_pts)
Extend the particle field.
Definition: swarm.h:185
Definition: coredriver.h:42
An effective "mesh" class for a collection disconnected points (particles).
Definition: swarm.h:35
constexpr std::vector< Point< oper::dimension(domain)> > points()
Definition: operator_references.h:29
counting_iterator begin(Entity_kind const kind=Wonton::PARTICLE, Entity_type const type=Wonton::ALL) const
Get an iterator at first element of the particle field.
Definition: swarm.h:160
counting_iterator make_counting_iterator(unsigned int const i)
Definition: portage.h:244
boost::counting_iterator< unsigned int > counting_iterator
Definition: portage.h:243
int num_particles(Wonton::Entity_type type=Wonton::ALL) const
Get particles count.
Definition: swarm.h:134
Wonton::Point< dim > get_particle_coordinates(int index) const
Get the coordinates of the particle.
Definition: swarm.h:148