351 {
352
353//! Main SPADES particle container
354template <
355 int NType,
356 int NStructReal,
357 int NStructInt,
358 int NArrayReal,
359 int NArrayInt>
360class SpadesParticleContainer
361 : public amrex::NeighborParticleContainer<
362 NStructReal,
363 NStructInt,
364 NArrayReal,
365 NArrayInt>
366{
367public:
368 using ParticleType = typename amrex::NeighborParticleContainer<
369 NStructReal,
370 NStructInt,
371 NArrayReal,
372 NArrayInt>::ParticleType;
373 using ParticleTileType = typename amrex::NeighborParticleContainer<
374 NStructReal,
375 NStructInt,
376 NArrayReal,
377 NArrayInt>::ParticleTileType;
378 using IntVector = typename amrex::NeighborParticleContainer<
379 NStructReal,
380 NStructInt,
381 NArrayReal,
382 NArrayInt>::IntVector;
383 using RealVector = typename amrex::NeighborParticleContainer<
384 NStructReal,
385 NStructInt,
386 NArrayReal,
387 NArrayInt>::RealVector;
388
389 /**
390 @brief Class identifier name
391 @return class identifier
392 **/
393 static std::string identifier() { return "spades_particles"; }
394
395 /**
396 @brief Constructor
397 @param par_gdb [in] particle database
398 @param ngrow [in] number of grow cells
399 **/
400 explicit SpadesParticleContainer(amrex::AmrParGDB* par_gdb, int ngrow = 0);
401
402 /**
403 @brief Constructor
404 @param geom [in] geometry
405 @param dmap [in] distribution map
406 @param ba [in] box array
407 @param ngrow [in] number of grow cells
408 **/
409 explicit SpadesParticleContainer(
410 const amrex::Vector<amrex::Geometry>& geom,
411 const amrex::Vector<amrex::DistributionMapping>& dmap,
412 const amrex::Vector<amrex::BoxArray>& ba,
413 int ngrow = 0);
414
415 //! Initialize particle states (counts and offsets)
416 void initialize_state();
417
418 //! Delete particle states (counts and offsets)
419 void clear_state();
420
421 //! Update the particle counts and offsets
422 void update_counts();
423
424 //! Update the particle counts
425 void count_particles();
426
427 //! Update the particle offsets
428 void count_offsets();
429
430 /**
431 @brief Get the particle counts
432 @return particle counts
433 **/
434 const amrex::iMultiFab& counts() const { return m_counts; };
435
436 /**
437 @brief Get the particle offsets
438 @return particle offsets
439 **/
440 const amrex::iMultiFab& offsets() const { return m_offsets; };
441
442 /**
443 @brief Get the total number of particles of \p typ
444 @param typ [in] particle type
445 @return particle counts
446 **/
447 amrex::Long total_count(const int typ) const
448 {
449 BL_PROFILE("spades::SpadesParticleContainer::total_count()");
450 return m_counts.sum(typ);
451 }
452
453 /**
454 @brief Get the minimum number of particles of \p typ
455 @param typ [in] particle type
456 @return particle counts min
457 **/
458 amrex::Long min_count(const int typ) const
459 {
460 BL_PROFILE("spades::SpadesParticleContainer::min_count()");
461 return m_counts.min(typ);
462 }
463
464 /**
465 @brief Get the maximum number of particles of \p typ
466 @param typ [in] particle type
467 @return particle counts min
468 **/
469 amrex::Long max_count(const int typ) const
470 {
471 BL_PROFILE("spades::SpadesParticleContainer::max_count()");
472 return m_counts.max(typ);
473 }
474
475 //! Check the result of the sort operation
476 void check_sort(const amrex::MFIter& mfi);
477
478 //! Sort the particles
479 virtual void sort() = 0;
480
481 /**
482 @brief Sort the particles implementation
483 @param compare [in] comparison functor
484 **/
485 template <typename CompareFunctor>
486 void sort_impl(const CompareFunctor& compare);
487
488 /**
489 @brief Non-encoded sort the particles implementation
490 @param compare [in] comparison functor
491 **/
492 template <typename CompareFunctor>
493 void nonencoded_sort_impl(const CompareFunctor& compare);
494
495 //! Encoded sort the particles implementation
496 void encoded_sort_impl();
497
498 //! Print all the particles to screen
499 void print_messages(const std::string& header);
500
501 //! Reposition the particles inside a cell for visualization
502 void reposition_particles();
503
504 /**
505 @brief Write the particles to file
506 @param plt_filename [in] file name for the plot file
507 **/
508 virtual void write_plot_file(const std::string& plt_filename) = 0;
509
510 //! Number of grow cells
511 int ngrow() const { return m_ngrow; }
512
513 //! Level index
514 static constexpr int LEV{0};
515
516 //! Initialize variable names
517 virtual void initialize_variable_names() = 0;
518
519 /**
520 @brief Write the particles to file (implementation)
521 @param plt_filename [in] file name for the plot file
522 @param name [in] file name for the particle file
523 **/
524 void write_plot_file_impl(
525 const std::string& plt_filename, const std::string& name);
526
527 //! Read user parameters
528 virtual void read_parameters()
529 {
530 {
531 amrex::ParmParse pp("spades");
532 pp.query("sort_type", m_sort_type);
533 check_sort_type(m_sort_type);
534 }
535 }
536
537 //! Check valid sort type
538 void check_sort_type(const std::string& sort_type)
539 {
540 const amrex::Vector<std::string> valid_types = {
541 "nonencoded", "encoded"};
542 if (std::find(valid_types.cbegin(), valid_types.cend(), sort_type) ==
543 valid_types.cend()) {
544 amrex::Abort("Invalid sort type. Must be nonencoded or encoded");
545 }
546 }
547
548 ParticleArrays<NArrayReal, NArrayInt, ParticleType, RealVector, IntVector>
549 particle_arrays(ParticleTileType& pti) const
550 {
551 auto& aos = pti.GetArrayOfStructs();
552 auto& soa = pti.GetStructOfArrays();
553 return ParticleArrays<
554 NArrayReal, NArrayInt, ParticleType, RealVector, IntVector>(
555 aos.dataPtr(), soa.GetRealData(), soa.GetIntData());
556 }
557
558protected:
559 //! Number of grow cells
560 int m_ngrow;
561
562 //! Flags for real data to write to file
563 amrex::Vector<int> m_writeflags_real;
564
565 //! Flags for int data to write to file
566 amrex::Vector<int> m_writeflags_int;
567
568 //! Names for real data to write to file
569 amrex::Vector<std::string> m_real_data_names;
570
571 //! Names for int data to write to file
572 amrex::Vector<std::string> m_int_data_names;
573
574 //! Sort type
575 std::string m_sort_type{"nonencoded"};
576
577 //! Count of particles in each cell
578 amrex::iMultiFab m_counts;
579
580 //! Offsets of particles in each cell
581 amrex::iMultiFab m_offsets;
582
583 //! Minimum timestamp in each cell for each type
584 amrex::MultiFab m_min_timestamp;
585
586 //! Maximum timestamp in each cell for each type
587 amrex::MultiFab m_max_timestamp;
588};
589
590#include "SpadesParticleContainer.tpp"
591
592} // namespace spades::particles
593#endif