chombo-discharge
Loading...
Searching...
No Matches
Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
ItoSolver Class Reference

Base class for Ito diffusion particle models. More...

#include <CD_ItoSolver.H>

Collaboration diagram for ItoSolver:
Collaboration graph
[legend]

Public Types

enum class  WhichContainer {
  Bulk , EB , Domain , Source ,
  Covered , Scratch
}
 Enum class for distinguishing various types of particle containers. More...
 

Public Member Functions

 ItoSolver ()
 Constructor – user must subsequently set the realm and, parse class options, set the species etc.
 
virtual ~ItoSolver ()
 Destructor (does nothing).
 
 ItoSolver (const ItoSolver &)=delete
 Deleted copy constructor.
 
ItoSolveroperator= (const ItoSolver &)=delete
 Deleted copy assignment operator.
 
 ItoSolver (ItoSolver &&)=default
 Default move constructor.
 
ItoSolveroperator= (ItoSolver &&)=default
 Default move assignment operator.
 
virtual void setParticleCellMerger (const ParticleManagement::ParticleMerger< ItoMergeParticle > &a_particleCellMerger) noexcept
 Set the user-supplied per-cell particle merger used by merge_algorithm = external.
 
virtual std::string getName () const
 Get this solver's name.
 
virtual std::string getRealm () const
 Get the realm where this solver is registered.
 
virtual void setRealm (const std::string &a_realm)
 Set the realm where this solver will live.
 
virtual void parseOptions ()
 Parse class options.
 
virtual void parseRuntimeOptions ()
 Parse class runtime configurable options.
 
virtual EBIntersection getIntersectionAlgorithm () const noexcept
 Get the EB-particle intersection algorithm.
 
virtual void initialData ()
 Set the initial data.
 
virtual void generateParticlesFromDensity (ParticleContainer< ItoParticle > &a_particles, const std::function< Real(const RealVect x)> &a_densityFunc, const Vector< int > &a_maxParticlesPerCell) const noexcept
 Fill a particle container randomly with particles such that we obtain the target uniform density, with a per-level cap on the computational particle count.
 
virtual void generateParticlesFromDensity (ParticleContainer< ItoParticle > &a_particles, const std::function< Real(const RealVect x)> &a_densityFunc, int a_maxParticlesPerCell) const noexcept
 Fill a particle container randomly with particles such that we obtain the target uniform density.
 
virtual void regrid (int a_lmin, int a_oldFinestLevel, int a_newFinestLevel)
 Regrid this solver.
 
virtual void allocate ()
 Allocate internal storage.
 
virtual void clear (WhichContainer a_container)
 Clear a particle container – this will delete all the particles in the input container.
 
virtual void clear (ParticleContainer< ItoParticle > &a_particles) const
 Clear a particle container – this will delete all the particles in the input container.
 
virtual void depositConductivity (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles) const
 Deposit conductivities (i.e. mass*mobility / volume)
 
virtual void depositConductivity (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles, DepositionType a_deposition, CoarseFineDeposition a_coarseFineDeposition) const
 Deposit conductivities (i.e. mass*mobility / volume)
 
virtual void depositDiffusivity (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles) const
 Deposit diffusivity (i.e. mass*D/volume)
 
virtual void depositDiffusivity (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles, DepositionType a_deposition, CoarseFineDeposition a_coarseFineDeposition) const
 Deposit diffusivity (i.e. mass*D/volume)
 
virtual void depositEnergyDensity (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles) const
 Deposit energy densities (i.e. mass*energy/volume => total energy per unit volume)
 
virtual void depositEnergyDensity (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles, DepositionType a_deposition, CoarseFineDeposition a_coarseFineDeposition) const
 Deposit energy densities (i.e. mass*energy/volume => total energy per unit volume)
 
virtual void computeAverageMobility (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles) const
 Compute average mobility.
 
virtual void computeAverageDiffusion (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles) const
 Compute average diffusion coefficient.
 
virtual void computeAverageEnergy (EBAMRCellData &a_phi, ParticleContainer< ItoParticle > &a_particles) const
 Compute average particle energy..
 
virtual void depositParticles ()
 Deposit particles onto mesh.
 
virtual void depositParticles (WhichContainer a_container)
 Deposit particles on to mesh.
 
void depositWeightNGP (LevelData< EBCellFAB > &a_output, const ParticleContainer< ItoParticle > &a_particles, int a_level) const noexcept
 Do an NGP deposit of the SoA weight column on a specific grid level. Used for IO.
 
template<typename Gather >
void depositGatheredNGP (LevelData< EBCellFAB > &a_output, const ParticleContainer< ItoParticle > &a_particles, int a_level, Gather a_gather) const noexcept
 Do an NGP deposit of a gathered per-particle quantity on a specific grid level. Used for IO.
 
void coarsenAndFillGhosts (EBAMRCellData &a_phi) const
 Coarsen the input data and interpolate its ghost cells.
 
template<typename P , typename Traits >
void depositWeight (EBAMRCellData &a_phi, const ParticleContainer< P, Traits > &a_particles, DepositionType a_deposition, CoarseFineDeposition a_coarseFineDeposition) const
 Deposit the SoA weight column on the mesh (kappa-conservative + redistribution).
 
template<typename Gather >
void depositGathered (EBAMRCellData &a_phi, const ParticleContainer< ItoParticle > &a_particles, DepositionType a_deposition, CoarseFineDeposition a_coarseFineDeposition, Gather a_gather) const
 Deposit a gathered per-particle quantity on the mesh (kappa-conservative + redistribution).
 
virtual void removeCoveredParticles (EBRepresentation a_representation, Real a_tol)
 Remove particles that are inside the EB.
 
virtual void removeCoveredParticles (WhichContainer a_container, EBRepresentation a_representation, Real a_tol)
 Remove particles that are inside the EB.
 
virtual void removeCoveredParticles (ParticleContainer< ItoParticle > &a_particles, EBRepresentation a_representation, Real a_tol) const
 Remove particles that are inside the EB.
 
virtual void transferCoveredParticles (EBRepresentation a_representation, Real a_tol)
 Transfer particles that are covered (within a_tol distance from EB) to another container.
 
virtual void transferCoveredParticles (WhichContainer a_containerFrom, WhichContainer a_containerTo, EBRepresentation a_representation, Real a_tol)
 Transfer particles that are covered (within a_tol distance from EB) to another container.
 
virtual void transferCoveredParticles (ParticleContainer< ItoParticle > &a_particlesFrom, ParticleContainer< ItoParticle > &a_particlesTo, EBRepresentation a_representation, Real a_tol) const
 Transfer particles that are inside the EB to another container.
 
virtual void intersectParticles (const EBIntersection a_ebIntersection, const bool a_deleteParticles, const std::function< void(ParticleSoA< ItoParticle > &, std::size_t)> &a_nonDeletionModifier=[](ParticleSoA< ItoParticle > &, std::size_t) -> void { return;})
 Do boundary intersection tests.
 
virtual void intersectParticles (const WhichContainer a_particles, const WhichContainer a_ebParticles, const WhichContainer a_domainParticles, const EBIntersection a_ebIntersection, const bool a_deleteParticles, const std::function< void(ParticleSoA< ItoParticle > &, std::size_t)> &a_nonDeletionModifier=[](ParticleSoA< ItoParticle > &, std::size_t) -> void { return;})
 Do boundary intersection tests.
 
virtual void intersectParticles (ParticleContainer< ItoParticle > &a_particles, ParticleContainer< ItoParticle > &a_ebParticles, ParticleContainer< ItoParticle > &a_domainParticles, const EBIntersection a_ebIntersection, const bool a_deleteParticles, const std::function< void(ParticleSoA< ItoParticle > &, std::size_t)> &a_nonDeletionModifier=[](ParticleSoA< ItoParticle > &, std::size_t) -> void { return;})
 Do boundary intersection tests.
 
virtual void computeLoads (Vector< long int > &a_loads, const DisjointBoxLayout &a_dbl, int a_level)
 Compute particle load on a specific grid level – this will compute the number of particles in each box in the input grids.
 
virtual int getNumberOfPlotVariables () const
 Get number of plot variables.
 
virtual Vector< std::string > getPlotVariableNames () const
 Get output plot names.
 
virtual void writePlotData (LevelData< EBCellFAB > &a_output, int &a_comp, const std::string &a_outputRealm, int a_level) const noexcept
 Write plot data.
 
virtual unsigned long long getNumParticles (WhichContainer a_whichContainer, bool a_localOnly) const
 Get number of particles in a specified particle container.
 
virtual void registerOperators () const
 Register operators.
 
virtual void setComputationalGeometry (const RefCountedPtr< ComputationalGeometry > &a_computationalGeometry)
 Set computational geometry.
 
virtual void setAmr (const RefCountedPtr< AmrMesh > &a_amr)
 Set the AmrMesh object.
 
virtual void setPhase (phase::which_phase a_phase)
 Set phase where the particles will live.
 
virtual void setVerbosity (int a_verbosity)
 Set verbosity level for this solver.
 
virtual void setTime (int a_step, Real a_time, Real a_dt)
 Set the time for this solver.
 
virtual void setSpecies (const RefCountedPtr< ItoSpecies > &a_species)
 Set the species.
 
virtual void preRegrid (int a_lbase, int a_oldFinestLevel)
 Perform pre-regrid operations.
 
virtual bool isMobile () const
 Check if solver is mobile.
 
virtual bool isDiffusive () const
 Check if solver is diffusive.
 
virtual ParticleContainer< ItoParticle > & getParticles (WhichContainer a_container)
 Get a general particle container.
 
virtual const ParticleContainer< ItoParticle > & getParticles (WhichContainer a_container) const
 Get a general particle container.
 
virtual const RefCountedPtr< ItoSpecies > & getSpecies () const
 Get the species.
 
virtual EBAMRCellData & getPhi ()
 Get the mesh data.
 
virtual EBAMRCellData & getVelocityFunction ()
 Get cell-centered velocity mesh data.
 
virtual const EBAMRCellData & getVelocityFunction () const
 Get cell-centered velocity mesh data.
 
virtual EBAMRCellData & getDiffusionFunction ()
 Get the diffusion function.
 
virtual const EBAMRCellData & getDiffusionFunction () const
 Get the diffusion function.
 
virtual EBAMRCellData & getMobilityFunction ()
 Get mobility function.
 
virtual const EBAMRCellData & getMobilityFunction () const
 Get mobility function.
 
virtual void setDiffusionFunction (Real a_diffusionCoefficient)
 Utility function – set a constant diffusion coefficient.
 
virtual void setVelocityFunction (const RealVect &a_velocity)
 Utility function – set a constant velocity.
 
virtual void setParticleMobility (Real a_mobility)
 Sets mobility coefficient for all particles.
 
virtual void setParticleDiffusion (Real a_diffCo)
 Sets diffusion coefficient for all particles.
 
virtual void interpolateVelocities ()
 Interpolate the particle velocities.
 
virtual void interpolateVelocities (int a_lvl, const DataIndex &a_dit)
 Interpolate the particle velocities.
 
virtual void interpolateMobilities ()
 Interpolate mobilities.
 
virtual void updateMobilities ()
 Update mobilities parametrically from the particle energy.
 
virtual void interpolateDiffusion ()
 Interpolate the diffusion field to the particle positions.
 
virtual void updateDiffusion ()
 Update mobilities parametrically from the particle energy.
 
virtual void organizeParticlesByCell (WhichContainer a_container)
 Sort the input particle container by cell.
 
virtual void organizeParticlesByPatch (WhichContainer a_container)
 Sort the input particle container by patch.
 
virtual void makeSuperparticles (WhichContainer a_container)
 Make superparticles for a full container, merging to the solver's configured target.
 
virtual void makeSuperparticles (WhichContainer a_container, int a_particlesPerCell)
 Make superparticles for a full container – this is the AMR version that users will usually call.
 
virtual void makeSuperparticles (WhichContainer a_container, const Vector< int > &a_particlesPerCell)
 Make superparticles for a full container – this is the AMR version that users will usually call.
 
virtual void makeSuperparticles (WhichContainer a_container, const Vector< int > &a_particlesPerCell, const ParticleManagement::ParticleMergeMethod a_method)
 Make superparticles with an explicitly chosen method, ignoring the configured merge_algorithm.
 
virtual const Vector< int > & getParticlesPerCell () const noexcept
 Get the configured target number of computational particles per cell, per AMR level.
 
virtual ParticleContainer< ItoMergeParticle > & getRegridParticles () noexcept
 Get the reduced holder the bulk particles ride across a regrid in.
 
virtual void remap ()
 Remap the bulk particle container.
 
virtual void remap (WhichContainer a_container)
 Remap all particles in the input container.
 
virtual void remapAll ()
 Remap all particle containers.
 
RealVect randomGaussian () const
 Draw a random N-dimensional Gaussian number from a normal distribution with zero with and unit standard deviation.
 
RealVect randomDirection () const
 Draw a random direction in N-dimensional space.
 
virtual Real computeDt () const
 Compute a time step for the advance – this calls the level function.
 
virtual Real computeDt (int a_lvl) const
 Compute a time step for the advance – this returns the maximum permitted time step on the input grid level.
 
virtual Real computeDt (int a_lvl, const DataIndex &a_dit) const
 Compute a time step for the advance – this returns the maximum permitted time step on the input grid patch.
 
virtual Real computeHopDt (Real a_maxCellsToMove) const
 Compute the largest possible time step such that the particles does not move more than a specified number of grid cells on any grid level.
 
virtual Real computeHopDt (Real a_maxCellsToMove, int a_lvl) const
 Compute the largest possible time step such that the particles does not move more than a specified number of grid cells on the input grid level.
 
virtual Real computeHopDt (Real a_maxCellsToMove, int a_lvl, const DataIndex &a_dit) const
 Compute the largest possible time step such that the particles does not move more than a specified number of grid cells on the input grid level.
 
virtual Real computeAdvectiveDt () const
 Compute advection time step dt = dx/vMax where vMax is the largest velocity component of the particle.
 
virtual Real computeAdvectiveDt (int a_lvl) const
 Compute the drift dt. This computes the minimum dt = dx/vMax on the input level.
 
virtual Real computeAdvectiveDt (int a_lvl, const DataIndex &a_dit) const
 Compute the drift dt. This computes the minimum dt = dx/vMax on one level and one box.
 
virtual Real computeDiffusiveDt () const
 Compute the diffusive dt. This computes dt = dx*dx/(2*SpaceDim*D) for all particles.
 
virtual Real computeDiffusiveDt (int a_lvl) const
 Compute the diffusive dt. This computes dt = dx*dx/(2*SpaceDim*D) for all particles on the input level.
 
virtual Real computeDiffusiveDt (int a_lvl, const DataIndex &a_dit) const
 Compute the diffusive dt. This computes dt = dx*dx/(2*SpaceDim*D) for all particles on the input grid patch.
 
DepositionType getDeposition () const
 Get deposition method.
 
CoarseFineDeposition getCoarseFineDeposition () const
 Get the coarse-fine deposition strategy.
 
phase::which_phase getPhase () const
 Return phase.
 

Protected Types

enum class  WhichCheckpoint { Particles , Numbers }
 How to checkpoint files. More...
 
enum class  WhichMobilityInterpolation { Direct , Velocity }
 Enum for deciding how to interpolate particle mobilities. More...
 
enum class  NnPairSearchBackend { Tree , Hash }
 Which EBGeometry point-cloud index backs mergeNnPairSearch()'s per-patch spatial search – see ParticleManagement::mergeNearestNeighborsTree()/mergeNearestNeighborsHash(). More...
 

Protected Member Functions

void parseRNG ()
 Parse RNG options – this parses the RNG seed and instantiates the distributions.
 
void parseTruncation ()
 Parse the normal distribution truncation level.
 
void parseDeposition ()
 Parse particle deposition methods.
 
void parseParticleMerger ()
 Parse the super-particle merger.
 
void mergeLite (ParticleContainer< ItoMergeParticle > &a_particles, const Vector< int > &a_particlesPerCell, ParticleManagement::ParticleMergeMethod a_method)
 Run one merge method over an already-extracted reduced-particle container.
 
void applyCellMerger (ParticleContainer< ItoMergeParticle > &a_particles, const Vector< int > &a_particlesPerCell, const ParticleManagement::ParticleMerger< ItoMergeParticle > &a_merger)
 Apply a per-cell merger over an entire reduced-particle container, cell by cell.
 
void invalidateParticleIDs (ParticleContainer< ItoMergeParticle > &a_particles) const
 Set every particle id in a reduced-particle container to ParticleSoA::s_invalidID.
 
void extractIntoMergeContainer (WhichContainer a_container, ParticleContainer< ItoMergeParticle > &a_merge)
 Extract a container's ItoParticles into a minimal ItoMergeParticle container on the same realm/patch, then clear the ItoParticles.
 
void splitFromMergeContainer (ParticleContainer< ItoMergeParticle > &a_merge, int a_numParticlesPerCellThresh)
 Split every under-full cell up to the target count.
 
void rebuildFromMergeContainer (WhichContainer a_container, ParticleContainer< ItoMergeParticle > &a_merge)
 Rebuild a container's ItoParticles from the reduced particles.
 
void mergeEqualWeightKD (ParticleContainer< ItoMergeParticle > &a_particles, const Vector< int > &a_particlesPerCell)
 Cell-based merge: equal-weight KD partition, one weighted-centroid particle per leaf.
 
void mergeReinitialize (ParticleContainer< ItoMergeParticle > &a_particles, const Vector< int > &a_particlesPerCell)
 Cell-based merge: redistribute each cell's physical particles into near-equal integer weights at random cell positions.
 
void mergeReinitializeBVH (ParticleContainer< ItoMergeParticle > &a_particles, const Vector< int > &a_particlesPerCell)
 Cell-based merge: as mergeEqualWeightKD(), with reinitialized leaf positions.
 
void mergeNnSfc (ParticleContainer< ItoMergeParticle > &a_particles, const Vector< int > &a_particlesPerCell)
 Cell-based merge: Hilbert-curve sort, then merge adjacent pairs down to the target.
 
template<NnPairSearchBackend Backend>
void mergeNnPairSearch (ParticleContainer< ItoMergeParticle > &merge, const Vector< int > &a_particlesPerCell)
 Whole-container merge: distributed nearest-neighbour pair merge – shared implementation behind the nn_pair_tree and nn_pair_hash selectors.
 
void mergeNnPairOneCell (ParticleContainer< ItoMergeParticle > &merge, const Vector< int > &a_particlesPerCell)
 Whole-container merge: distributed nearest-neighbour pair merge, per-cell PointCloudBVH search.
 
void mergeKDSkinNn (ParticleContainer< ItoMergeParticle > &merge, const Vector< int > &a_particlesPerCell)
 Whole-container merge: kd-tree with a nearest-neighbour skin (the kd_skin_nn selector).
 
void mergeKDImpl (ParticleContainer< ItoMergeParticle > &merge, const Vector< int > &a_particlesPerCell, bool a_enableBoundaryCarve)
 Whole-container merge: whole-patch kd-tree build – shared implementation behind the kd_carve and kd_patch selectors.
 
void parseIntersectionEB ()
 Parse EB intersection algorithms.
 
void parseVerbosity ()
 Parse class verbosity.
 
void parsePlotVariables ()
 Parse plot variables.
 
void parseDiffusionHop ()
 Parse diffusion hop.
 
void parseRedistribution ()
 Parse whether or not to use redistribution.
 
void parseDivergenceComputation ()
 Parse whether or not to compute a "non-conservative" divergence when redistributing mass.
 
void parseCheckpointing ()
 Parse checkpointing method.
 
void drawNewParticles (const LevelData< EBCellFAB > &a_particlesPerCell, int a_level, int a_newPPC)
 Restart particles from a specified number of particles in the grid cell.
 
virtual void redistributeAMR (EBAMRCellData &a_phi) const
 Redistribute mass in an AMR context.
 
virtual void depositNonConservative (EBAMRIVData &a_depositionNC, const EBAMRCellData &a_depositionKappaC) const
 Make the "non-conservative" kappa deposition – computing depositionNC = sum(kappa*depositionC)/sum(kappa) in a neighborhood around each vof.
 
virtual void depositHybrid (EBAMRCellData &a_depositionH, EBAMRIVData &a_massDifference, const EBAMRIVData &a_depositionNC) const
 Make the "hybrid" deposition phiH = kappa*phiC + (1-kappa)*phiNC. On input, a_depositionH should contain phiC.
 
virtual void interpolateMobilities (int a_lvl, const DataIndex &a_dit, const EBCellFAB &a_velocityMagnitude) noexcept
 Interpolate mobilities – this will switch between the two ways of computing the particle mobility.
 
virtual void interpolateMobilitiesDirect (int a_lvl, const DataIndex &a_dit) noexcept
 Directly interpolate mobilities. Interpolates for all particles in the specified grid patch.
 
virtual void interpolateMobilitiesVelocity (int a_lvl, const DataIndex &a_dit, const EBCellFAB &a_velocityMagnitude) noexcept
 Interpolate mobilities through the velocity. Interpolates for all particles in the specified grid patch.
 
virtual void updateMobilities (int a_level, const DataIndex &a_dit)
 Update mobilities parametrically from the particle energy.
 
virtual void interpolateDiffusion (int a_lvl, const DataIndex &a_dit)
 Interpolate the diffusion field to the particle positions.
 
virtual void updateDiffusion (int a_level, const DataIndex &a_dit)
 Update mobilities parametrically from the particle energy.
 
virtual void writeData (LevelData< EBCellFAB > &a_output, int &a_comp, const EBAMRCellData &a_data, const std::string &a_outputRealm, int a_level, bool a_interpToCentroids, bool a_interpGhost) const noexcept
 Write data to output. Convenience function.
 

Protected Attributes

WhichCheckpoint m_checkpointing
 How to checkpoint files. particles => write particles to HDF5. numbers => write numbers to HDF5.
 
WhichMobilityInterpolation m_mobilityInterp
 Switch for deciding how to interpolate mobilities, i.e. interpolating either mu*E or just mu (to the particle position)
 
ParticleManagement::ParticleMerger< ItoMergeParticlem_particleCellMerger
 User-supplied per-cell merger for merge_algorithm = external (set via setParticleCellMerger()). The built-in methods build their own merger locally in the corresponding mergeXxx().
 
ParticleManagement::ParticleMergeMethod m_mergeMethod = ParticleManagement::ParticleMergeMethod::EqualWeightKD
 The configured merge method (which specific algorithm).
 
Vector< int > m_particlesPerCell
 Target number of computational particles per cell, per AMR level.
 
std::optional< ParticleManagement::ParticleMergeMethodm_regridMergeMethod
 Which merge method to run inside ItoSolver::regrid(), or nullopt for "whatever merge_algorithm says".
 
bool m_nnPairIterate = true
 nn_pair_tree/nn_pair_onecell/nn_pair_hash: iterate the local trivial tier to convergence within each round.
 
int m_nnPairFallback = 1
 nn_pair_tree/nn_pair_onecell/nn_pair_hash: number of fallback candidates per query. The k-nearest search is done with k = 1 + this. Only used for nn_pair_tree/nn_pair_onecell/nn_pair_hash.
 
int m_nnPairMaxCellDistance = -1
 nn_pair_tree/nn_pair_hash: maximum merge distance in whole cells (Chebyshev). A negative value means unbounded (std::nullopt). Only used for nn_pair_tree/nn_pair_hash – nn_pair_onecell's merge distance is structurally fixed at 1 and does not read this.
 
int m_nnPairMaxRounds = 3
 nn_pair_tree/nn_pair_onecell/nn_pair_hash: maximum number of drain rounds run per makeSuperparticles() call.
 
Real m_kdSplitWeightLeafDx = 1.0
 Leaf size, in cell widths, at or below which the tree build switches from count-median to weight-median splitting.
 
int m_restartPPC
 Number of particles used when restarting a simulation – this is relevant only when restarting from a "fluid" checkpoint file.
 
std::string m_realm
 Realm where this solve lives.
 
RefCountedPtr< ComputationalGeometrym_computationalGeometry
 Computational geometry.
 
RefCountedPtr< AmrMeshm_amr
 AMR; needed for grid stuff.
 
RefCountedPtr< ItoSpeciesm_species
 Species that this solver solves for.
 
phase::which_phase m_phase
 Phase where this solver lives.
 
std::string m_name
 Solver name.
 
std::string m_className
 Class name.
 
Real m_normalDistributionTruncation
 Truncation value for normal distribution.
 
Real m_bisectionStep
 Bisection step size to use for particle intersection tests with EBs.
 
int m_verbosity
 Verbosity level for this solver.
 
int m_timeStep
 Time step.
 
Real m_time
 Current time.
 
Real m_dt
 Time step.
 
bool m_forceIrregDepositionNGP
 NGP deposition in cut cells or not.
 
bool m_forceIrregInterpolationNGP
 NGP interpolation in cut cells or not.
 
bool m_forceHaloNGP
 Force usage of NGP when depositing "halo" particles.
 
bool m_useRedistribution
 Use mass redistribution or not.
 
bool m_blendConservation
 Flag for blending the deposition clouds with the "non-conservative" divergence.
 
bool m_isDiffusive
 If true, solver is diffusive.
 
bool m_isMobile
 If true, solver is mobile, i.e. advection is turned on.
 
bool m_plotPhi
 Flag for outputting m_phi to plot files.
 
bool m_plotVelocity
 Flag for outputting m_velocityFunction to plot files.
 
bool m_plotDiffCo
 Flag for outputting m_diffusionFunction to plot files.
 
bool m_plotParticles
 Flag for depositing and plotting the bulk particles on the mesh.
 
bool m_plotParticlesEB
 Flag for depositing and plotting the EB particles on the mesh.
 
bool m_plotParticlesDomain
 Flag for depositing and plotting the domain particles on the mesh.
 
bool m_plotParticlesSource
 Flag for depositing and plotting the source particles on the mesh.
 
bool m_plotParticlesCovered
 Flag for depositing and plotting the covered particles on the mesh.
 
bool m_plotEnergyDensity
 Flag for plotting the energy density on the mesh.
 
bool m_plotAverageEnergy
 Flag for plotting the average particle energy on the mesh.
 
DepositionType m_deposition
 Deposition method when depositing particles to the mesh.
 
CoarseFineDeposition m_coarseFineDeposition
 Coarse-fine deposition strategy.
 
DepositionType m_plotDeposition
 Deposition method when depositing particles to mesh during plotting.
 
EBAMRCellData m_phi
 Storage for particle mesh data.
 
EBAMRCellData m_mobilityFunction
 Mobility function – used when interpolating particle mobilities.
 
EBAMRCellData m_velocityFunction
 Cell-centered field used for interpolating velocities.
 
EBAMRCellData m_diffusionFunction
 Diffusion-centerer field used for interpolating diffusion coefficients.
 
EBAMRFAB m_kdMergeCellHistogram
 Per-cell occupancy scratch for the kd merges (see ParticleManagement::mergeKDCarve).
 
EBAMRFAB m_kdMergeLeafQuota
 Per-cell merge-quota scratch for the kd merges. Same lifetime as m_kdMergeCellHistogram.
 
EBAMRIVData m_depositionNC
 Scratch storage for holding the non-conservative deposition.
 
EBAMRIVData m_massDiff
 Scratch storage for holding the mass difference when using hybrid deposition.
 
std::map< WhichContainer, ParticleContainer< ItoParticle > > m_particleContainers
 Various particle containers with identifiers.
 
ParticleContainer< ItoMergeParticlem_regridParticles
 The bulk particles, in reduced form, between preRegrid() and regrid().
 
EBIntersection m_intersectionAlg
 Algorithm for EB intersection.
 

Static Protected Attributes

static constexpr int m_comp = 0
 Default component in data holders (do not touch).
 
static constexpr int m_nComp = 1
 Default number of component in data holders (do not touch).
 

Detailed Description

Base class for Ito diffusion particle models.

This is a particle class for solving Ito diffusion problems dX = v*dt + sqrt(2*D)*dW_t (dW_t is a Wiener process over dt) over an AMR hierarchy. The diffusion coefficient is related to the hydrodynamic diffusion coefficient by D(fluid) = sqrt(2*D(Ito)).

Note
To use this class, the user must add a species and set the realm and phase where the solver will live.

Member Enumeration Documentation

◆ NnPairSearchBackend

enum class ItoSolver::NnPairSearchBackend
strongprotected

Which EBGeometry point-cloud index backs mergeNnPairSearch()'s per-patch spatial search – see ParticleManagement::mergeNearestNeighborsTree()/mergeNearestNeighborsHash().

Enumerator
Tree 

EBGeometry::PointCloudBVH – ParticleManagement::mergeNearestNeighborsTree().

Hash 

EBGeometry::PointCloudHashGrid – ParticleManagement::mergeNearestNeighborsHash().

◆ WhichCheckpoint

enum class ItoSolver::WhichCheckpoint
strongprotected

How to checkpoint files.

Particles => Write particles to HDF5. Numbers => Write particle numbers to HDF5 (and lose information)

◆ WhichContainer

enum class ItoSolver::WhichContainer
strong

Enum class for distinguishing various types of particle containers.

This exists because the ItoSolver can partition particles into various containers, which is very useful when one wants to add particles from a source term, remove particles that fall inside the EB, or parse boundary conditions on the EB and domain faces. Here, Bulk = "Active" particles, EB = Particles on the EBs , Domain = Particles on the domain sides, Source = Source particles – used to e.g. add new particles to the bulk particles, Covered = Particles inside the EB, Scratch = Scratch particles

◆ WhichMobilityInterpolation

enum class ItoSolver::WhichMobilityInterpolation
strongprotected

Enum for deciding how to interpolate particle mobilities.

Direct => Interpolate particle mobilities from the mesh. Velocity => Set particle mobilitys by computing mu = |v|/|V| where v is the particle velocity and V is the "velocity field".

Member Function Documentation

◆ allocate()

void ItoSolver::allocate ( )
virtual

Allocate internal storage.

This will allocate the required mesh data as well as all the particle data holders.

Note
Storage for diffusion and advection fields are only allocate if the species is diffusive/mobile.

◆ applyCellMerger()

void ItoSolver::applyCellMerger ( ParticleContainer< ItoMergeParticle > &  a_particles,
const Vector< int > &  a_particlesPerCell,
const ParticleManagement::ParticleMerger< ItoMergeParticle > &  a_merger 
)
protected

Apply a per-cell merger over an entire reduced-particle container, cell by cell.

Shared machinery for every cell-based merge: the container is cell-sorted here (organizeParticlesByCell()); for each non-empty cell the particles are extracted, passed to a_merger with the cell's CellInfo and target count, and the result rebuilt into the leaf.

Parameters
[in,out]a_particlesReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count per cell (per-level; the last entry applies to any finer level).
[in]a_mergerThe per-cell merger to apply.

◆ clear() [1/2]

void ItoSolver::clear ( ParticleContainer< ItoParticle > &  a_particles) const
virtual

Clear a particle container – this will delete all the particles in the input container.

Parameters
[in]a_particlesParticle container to be emptied.

◆ clear() [2/2]

void ItoSolver::clear ( WhichContainer  a_container)
virtual

Clear a particle container – this will delete all the particles in the input container.

Parameters
[in]a_containerContainer

◆ coarsenAndFillGhosts()

void ItoSolver::coarsenAndFillGhosts ( EBAMRCellData &  a_phi) const

Coarsen the input data and interpolate its ghost cells.

This is the AMR synchronization that a deposit does not do for itself. Whether it is wanted depends on what the caller does next: a deposit that is the final state of a field needs it, whereas a deposit that is one term in a sum does not – there, only the assembled sum needs synchronizing, and doing it per term produces values that are immediately overwritten. Deposits therefore leave it to the caller.

Parameters
[in,out]a_phiCell-centered mesh data (one component).

◆ computeAdvectiveDt() [1/3]

Real ItoSolver::computeAdvectiveDt ( ) const
virtual

Compute advection time step dt = dx/vMax where vMax is the largest velocity component of the particle.

Returns
Computed advective dt

◆ computeAdvectiveDt() [2/3]

Real ItoSolver::computeAdvectiveDt ( int  a_lvl) const
virtual

Compute the drift dt. This computes the minimum dt = dx/vMax on the input level.

Parameters
[in]a_lvlGrid level
Returns
Computed advective dt

◆ computeAdvectiveDt() [3/3]

Real ItoSolver::computeAdvectiveDt ( int  a_lvl,
const DataIndex &  a_dit 
) const
virtual

Compute the drift dt. This computes the minimum dt = dx/vMax on one level and one box.

Parameters
[in]a_lvlGrid level
[in]a_ditGrid index
Returns
Computed advective dt

◆ computeAverageDiffusion()

void ItoSolver::computeAverageDiffusion ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles 
) const
virtual

Compute average diffusion coefficient.

This computes the average diffusion coefficient as D_avg = sum(mass*D)/sum(mass) by depositing on the mesh.

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data

◆ computeAverageEnergy()

void ItoSolver::computeAverageEnergy ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles 
) const
virtual

Compute average particle energy..

This computes the average energy as E_avg = sum(mass*energy)/sum(mass) by depositing on the mesh.

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data

◆ computeAverageMobility()

void ItoSolver::computeAverageMobility ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles 
) const
virtual

Compute average mobility.

This computes the average mobility as mu_avg = sum(mass*mu)/sum(mass) by depositing on the mesh.

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data

◆ computeDiffusiveDt() [1/3]

Real ItoSolver::computeDiffusiveDt ( ) const
virtual

Compute the diffusive dt. This computes dt = dx*dx/(2*SpaceDim*D) for all particles.

Returns
Computed diffusive dt

◆ computeDiffusiveDt() [2/3]

Real ItoSolver::computeDiffusiveDt ( int  a_lvl) const
virtual

Compute the diffusive dt. This computes dt = dx*dx/(2*SpaceDim*D) for all particles on the input level.

Parameters
[in]a_lvlGrid level
Returns
Computed diffusive dt

◆ computeDiffusiveDt() [3/3]

Real ItoSolver::computeDiffusiveDt ( int  a_lvl,
const DataIndex &  a_dit 
) const
virtual

Compute the diffusive dt. This computes dt = dx*dx/(2*SpaceDim*D) for all particles on the input grid patch.

Parameters
[in]a_lvlGrid level
[in]a_ditGrid index
Returns
Computed diffusive dt

◆ computeDt() [1/3]

Real ItoSolver::computeDt ( ) const
virtual

Compute a time step for the advance – this calls the level function.

This computes the time step differently whether or not diffusion and advection are active. The Ito particle model does not have a fundamental time step limitation, so these limits "replicate" the time step selections in a 1D fluid model. If we only use advection advection the time step is computed as dt = dx/sum(|V_i|) = dtA. If only diffusion is active the time step is computed as dt = (dx*dx)/(2*SpaceDim*D) = dtD. If both advection and diffusion are active the time step is computed as dt = 1/(1/dtA + 1/dtD).

Returns
Computed dt

◆ computeDt() [2/3]

Real ItoSolver::computeDt ( int  a_lvl) const
virtual

Compute a time step for the advance – this returns the maximum permitted time step on the input grid level.

This computes the time step differently whether or not diffusion and advection are active. The Ito particle model does not have a fundamental time step limitation, so these limits "replicate" the time step selections in a 1D fluid model. If we only use advection advection the time step is computed as dt = dx/Vmax = dtA, where Vmax is the largest velocity component along any of the directions. If only diffusion is active the time step is computed as dt = (dx*dx)/(2*SpaceDim*D) = dtD. If both advection and diffusion are active the time step is computed as dt = 1/(1/dtA + 1/dtD).

Parameters
[in]a_lvlGrid level
Returns
Computed dt

◆ computeDt() [3/3]

Real ItoSolver::computeDt ( int  a_lvl,
const DataIndex &  a_dit 
) const
virtual

Compute a time step for the advance – this returns the maximum permitted time step on the input grid patch.

This computes the time step differently whether or not diffusion and advection are active. The Ito particle model does not have a fundamental time step limitation, so these limits "replicate" the time step selections in a 1D fluid model. If we only use advection advection the time step is computed as dt = dx/Vmax = dtA, where Vmax is the largest velocity component along any of the directions. If only diffusion is active the time step is computed as dt = (dx*dx)/(2*SpaceDim*D) = dtD. If both advection and diffusion are active the time step is computed as dt = 1/(1/dtA + 1/dtD).

Parameters
[in]a_lvlGrid level
[in]a_ditGrid index
Returns
Computed dt

◆ computeHopDt() [1/3]

Real ItoSolver::computeHopDt ( Real  a_maxCellsToMove) const
virtual

Compute the largest possible time step such that the particles does not move more than a specified number of grid cells on any grid level.

This computes the time step differently whether or not diffusion and advection are active. The Ito particle model does not a fundamental time step limitation, so this function does its best at computing a time step such that the particles do not move more than the specified amount of grid cells. If only advection is active the time step is computed as dt = a_maxCellsToMove * dx/vMax where vMax is the largest velocity component. If only diffusion is active the usual kernel is dX = dWt which yields a "hop" of length L_d = sqrt(2*D*dt)*N0 where N0 is the diffusion hop in one of the coordinates. We do not need to worry about SpaceDim-related corrections because the hops in each direction are independent, so solving for dt we find dtD = L_d^2/(2*D*N0^2). If both advectino and diffusion are active then we can move up to L_d = v_d*dt + sqrt(2*D*dt)*N0 in any one coordinate direction (this is the usual Ito kernel). This requires a solution to a quadratic equation. Fortunately, this is easy to solve for.

Parameters
[in]a_maxCellsToMove
Returns
Computed hop dt

◆ computeHopDt() [2/3]

Real ItoSolver::computeHopDt ( Real  a_maxCellsToMove,
int  a_lvl 
) const
virtual

Compute the largest possible time step such that the particles does not move more than a specified number of grid cells on the input grid level.

This computes the time step differently whether or not diffusion and advection are active. The Ito particle model does not a fundamental time step limitation, so this function does its best at computing a time step such that the particles do not move more than the specified amount of grid cells. If only advection is active the time step is computed as dt = a_maxCellsToMove * dx/vMax where vMax is the largest velocity component. If only diffusion is active the usual kernel is dX = dWt which yields a "hop" of length L_d = sqrt(2*D*dt)*N0 where N0 is the diffusion hop in one of the coordinates. We do not need to worry about SpaceDim-related corrections because the hops in each direction are independent, so solving for dt we find dtD = L_d^2/(2*D*N0^2). If both advectino and diffusion are active then we can move up to L_d = v_d*dt + sqrt(2*D*dt)*N0 in any one coordinate direction (this is the usual Ito kernel). This requires a solution to a quadratic equation. Fortunately, this is easy to solve for.

Parameters
[in]a_maxCellsToMoveMaximum number of cells to move with a standard Ito kernel dX = v*dt + sqrt(2*D*dt)*N
[in]a_lvlGrid level
Returns
Computed hop dt

◆ computeHopDt() [3/3]

Real ItoSolver::computeHopDt ( Real  a_maxCellsToMove,
int  a_lvl,
const DataIndex &  a_dit 
) const
virtual

Compute the largest possible time step such that the particles does not move more than a specified number of grid cells on the input grid level.

This computes the time step differently whether or not diffusion and advection are active. The Ito particle model does not a fundamental time step limitation, so this function does its best at computing a time step such that the particles do not move more than the specified amount of grid cells. If only advection is active the time step is computed as dt = a_maxCellsToMove * dx/vMax where vMax is the largest velocity component. If only diffusion is active the usual kernel is dX = dWt which yields a "hop" of length L_d = sqrt(2*D*dt)*N0 where N0 is the diffusion hop in one of the coordinates. We do not need to worry about SpaceDim-related corrections because the hops in each direction are independent, so solving for dt we find dtD = L_d^2/(2*D*N0^2). If both advectino and diffusion are active then we can move up to L_d = v_d*dt + sqrt(2*D*dt)*N0 in any one coordinate direction (this is the usual Ito kernel). This requires a solution to a quadratic equation. Fortunately, this is easy to solve for.

Parameters
[in]a_maxCellsToMoveMaximum number of cells to move with a standard Ito kernel dX = v*dt + sqrt(2*D*dt)*N
[in]a_lvlGrid level
[in]a_ditGrid index
Returns
Computed hop dt

◆ computeLoads()

void ItoSolver::computeLoads ( Vector< long int > &  a_loads,
const DisjointBoxLayout &  a_dbl,
int  a_level 
)
virtual

Compute particle load on a specific grid level – this will compute the number of particles in each box in the input grids.

Parameters
[out]a_loadsLoads on each grid patch. This follows the order from a_dbl.boxArray()
[in]a_dblGrids
[in]a_levelGrid level

◆ depositConductivity() [1/2]

void ItoSolver::depositConductivity ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles 
) const
virtual

Deposit conductivities (i.e. mass*mobility / volume)

This deposits mass*mobility (not multiplied by charge)

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data

◆ depositConductivity() [2/2]

void ItoSolver::depositConductivity ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles,
DepositionType  a_deposition,
CoarseFineDeposition  a_coarseFineDeposition 
) const
virtual

Deposit conductivities (i.e. mass*mobility / volume)

This deposits mass*mobility (not multiplied by charge)

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data
[in]a_depositionDeposition method
[in]a_coarseFineDepositionCoarse-fine deposition method.

◆ depositDiffusivity() [1/2]

void ItoSolver::depositDiffusivity ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles 
) const
virtual

Deposit diffusivity (i.e. mass*D/volume)

This deposits mass*diffusion (not multiplied by charge)

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data
Note
Calls the other versions with a_deposition = m_deposition

◆ depositDiffusivity() [2/2]

void ItoSolver::depositDiffusivity ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles,
DepositionType  a_deposition,
CoarseFineDeposition  a_coarseFineDeposition 
) const
virtual

Deposit diffusivity (i.e. mass*D/volume)

This deposits mass*mobility (not multiplied by charge)

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data
[in]a_depositionDeposition method
[in]a_coarseFineDepositionCoarse-fine deposition method.

◆ depositEnergyDensity() [1/2]

void ItoSolver::depositEnergyDensity ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles 
) const
virtual

Deposit energy densities (i.e. mass*energy/volume => total energy per unit volume)

This deposits mass*energy

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data
Note
Calls the other versions with a_deposition = m_deposition

◆ depositEnergyDensity() [2/2]

void ItoSolver::depositEnergyDensity ( EBAMRCellData &  a_phi,
ParticleContainer< ItoParticle > &  a_particles,
DepositionType  a_deposition,
CoarseFineDeposition  a_coarseFineDeposition 
) const
virtual

Deposit energy densities (i.e. mass*energy/volume => total energy per unit volume)

This deposits mass*energy

Parameters
[out]a_phiMesh data
[in]a_particlesParticle data
[in]a_depositionDeposition method
[in]a_coarseFineDepositionCoarse-fine deposition method.

◆ depositGathered()

template<typename Gather >
void ItoSolver::depositGathered ( EBAMRCellData &  a_phi,
const ParticleContainer< ItoParticle > &  a_particles,
DepositionType  a_deposition,
CoarseFineDeposition  a_coarseFineDeposition,
Gather  a_gather 
) const

Deposit a gathered per-particle quantity on the mesh (kappa-conservative + redistribution).

Parameters
[out]a_phiMesh data – must have exactly one component.
[in]a_particlesSoA particles to be deposited.
[in]a_depositionDeposition method.
[in]a_coarseFineDepositionCoarse-fine deposition strategy.
[in]a_gatherPer-particle value gatherer (leaf, index) -> Real.
Template Parameters
GatherCallable (const ParticleSoA<ItoParticle>&, std::size_t) -> Real.
Note
This leaves coarse levels un-averaged and ghost cells stale. Call coarsenAndFillGhosts() afterwards unless the result is a term in a sum that the caller synchronizes itself.

◆ depositGatheredNGP()

template<typename Gather >
void ItoSolver::depositGatheredNGP ( LevelData< EBCellFAB > &  a_output,
const ParticleContainer< ItoParticle > &  a_particles,
int  a_level,
Gather  a_gather 
) const
noexcept

Do an NGP deposit of a gathered per-particle quantity on a specific grid level. Used for IO.

Parameters
[out]a_outputContains NGP deposition of the gathered quantity. Ignores cut-cells.
[in]a_particlesSoA particles.
[in]a_levelGrid level.
[in]a_gatherPer-particle value gatherer (leaf, index) -> Real.
Template Parameters
GatherCallable (const ParticleSoA<ItoParticle>&, std::size_t) -> Real.

◆ depositHybrid()

void ItoSolver::depositHybrid ( EBAMRCellData &  a_depositionH,
EBAMRIVData &  a_massDifference,
const EBAMRIVData &  a_depositionNC 
) const
protectedvirtual

Make the "hybrid" deposition phiH = kappa*phiC + (1-kappa)*phiNC. On input, a_depositionH should contain phiC.

Parameters
[in,out]a_depositionHOn input, contains phiC. On output, contain phiH
[out]a_massDifferenceOn output, contains mass loss in each cut-cell.
[in]a_depositionNCThe "non-conservative" deposited variable.

◆ depositNonConservative()

void ItoSolver::depositNonConservative ( EBAMRIVData &  a_depositionNC,
const EBAMRCellData &  a_depositionKappaC 
) const
protectedvirtual

Make the "non-conservative" kappa deposition – computing depositionNC = sum(kappa*depositionC)/sum(kappa) in a neighborhood around each vof.

Parameters
[out]a_depositionNCNon-conservative deposition
[in]a_depositionKappaCConserved deposition

◆ depositParticles() [1/2]

void ItoSolver::depositParticles ( )
virtual

Deposit particles onto mesh.

This will deposit the mass (i.e., computational weight) "bulk" particles into m_phi.

Note
Calls the other version with a_container = WhichContainer::Bulk

◆ depositParticles() [2/2]

void ItoSolver::depositParticles ( WhichContainer  a_container)
virtual

Deposit particles on to mesh.

Parameters
[in]a_containerWhich container to deposit.

This will deposit mass (i.e., computational weight) of the the input particle container particles onto the classes member 'm_phi'.

Note
Calls the general version with arguments: m_phi, m_particles.at(a_container), m_deposition.

◆ depositWeight()

template<typename P , typename Traits >
void ItoSolver::depositWeight ( EBAMRCellData &  a_phi,
const ParticleContainer< P, Traits > &  a_particles,
DepositionType  a_deposition,
CoarseFineDeposition  a_coarseFineDeposition 
) const

Deposit the SoA weight column on the mesh (kappa-conservative + redistribution).

The container payload is a template parameter so that auxiliary point-particle containers – e.g. the rho-dagger and conductivity particles carried by the semi-implicit time steppers – deposit through exactly the same pipeline as the solver's own particles. This includes the cut-cell deposition flag and the redistribution, both of which must be identical if the deposited densities are to be in the same normalization.

Note
This leaves coarse levels un-averaged and ghost cells stale. Call coarsenAndFillGhosts() afterwards unless the result is a term in a sum that the caller synchronizes itself.
Parameters
[out]a_phiMesh data – must have exactly one component.
[in]a_particlesSoA particles to be deposited.
[in]a_depositionDeposition method.
[in]a_coarseFineDepositionCoarse-fine deposition strategy.
Template Parameters
PPayload type of the container.
TraitsColumn descriptor for the payload.

◆ depositWeightNGP()

void ItoSolver::depositWeightNGP ( LevelData< EBCellFAB > &  a_output,
const ParticleContainer< ItoParticle > &  a_particles,
int  a_level 
) const
noexcept

Do an NGP deposit of the SoA weight column on a specific grid level. Used for IO.

Parameters
[out]a_outputContains NGP deposition of particle weights. Ignores cut-cells.
[in]a_particlesSoA particles.
[in]a_levelGrid level.

◆ drawNewParticles()

void ItoSolver::drawNewParticles ( const LevelData< EBCellFAB > &  a_particlesPerCell,
int  a_level,
int  a_newPPC 
)
protected

Restart particles from a specified number of particles in the grid cell.

This will instantiate the bulk particles by randomly drawing new particles in each grid cell.

Parameters
[in]a_particlesPerCellMesh data showing how many particles are in each cell.
[in]a_levelGrid level.
[in]a_newPPCDesired number of computational particles per cell

◆ extractIntoMergeContainer()

void ItoSolver::extractIntoMergeContainer ( WhichContainer  a_container,
ParticleContainer< ItoMergeParticle > &  a_merge 
)
protected

Extract a container's ItoParticles into a minimal ItoMergeParticle container on the same realm/patch, then clear the ItoParticles.

Copies position + weight + particleID + energy only; velocity/mobility/diffusion are dropped (they are recomputed from the field after the merge). No remap is needed since positions/ownership are unchanged. Ghost particles are cleared first – the copy loop has no isGhost() test and would promote a ghost to an owned particle. Each source leaf's arena is released as soon as its reduced copy exists, so the two representations overlap by one patch rather than one level.

Parameters
[in]a_containerWhich container to extract from.
[out]a_mergeThe resulting minimal-payload container, allocated on m_realm.

◆ generateParticlesFromDensity() [1/2]

void ItoSolver::generateParticlesFromDensity ( ParticleContainer< ItoParticle > &  a_particles,
const std::function< Real(const RealVect x)> &  a_densityFunc,
const Vector< int > &  a_maxParticlesPerCell 
) const
virtualnoexcept

Fill a particle container randomly with particles such that we obtain the target uniform density, with a per-level cap on the computational particle count.

The per-level form of the overload below. Used by initialData(), which seeds at ItoSolver.particles_per_cell – a per-level vector – so that a cold start and the first merge agree on the target by construction instead of seeding high and immediately merging back down.

Parameters
[in,out]a_particlesParticle container to fill. Particles already in the container will be kept.
[in]a_densityFuncDensity function.
[in]a_maxParticlesPerCellMaximum computational particles generated per cell, per level; the last entry applies to any finer level.

◆ generateParticlesFromDensity() [2/2]

void ItoSolver::generateParticlesFromDensity ( ParticleContainer< ItoParticle > &  a_particles,
const std::function< Real(const RealVect x)> &  a_densityFunc,
int  a_maxParticlesPerCell 
) const
virtualnoexcept

Fill a particle container randomly with particles such that we obtain the target uniform density.

Parameters
[in,out]a_particlesParticle container to fill. Particles already in the container will be kept.
[in]a_densityFuncDensity function.
[in]a_maxParticlesPerCellMaximum number of computational particles generated per cell.

◆ getCoarseFineDeposition()

CoarseFineDeposition ItoSolver::getCoarseFineDeposition ( ) const

Get the coarse-fine deposition strategy.

Returns
Coarse fine deposition

◆ getDeposition()

DepositionType ItoSolver::getDeposition ( ) const

Get deposition method.

Returns
Returns m_deposition

◆ getDiffusionFunction() [1/2]

EBAMRCellData & ItoSolver::getDiffusionFunction ( )
virtual

Get the diffusion function.

Returns
m_diffusionFunction

◆ getDiffusionFunction() [2/2]

const EBAMRCellData & ItoSolver::getDiffusionFunction ( ) const
virtual

Get the diffusion function.

Returns
m_diffusionFunction

◆ getIntersectionAlgorithm()

EBIntersection ItoSolver::getIntersectionAlgorithm ( ) const
virtualnoexcept

Get the EB-particle intersection algorithm.

Returns
Intersection algorithm

◆ getMobilityFunction() [1/2]

EBAMRCellData & ItoSolver::getMobilityFunction ( )
virtual

Get mobility function.

Returns
m_mobilityFunction

◆ getMobilityFunction() [2/2]

const EBAMRCellData & ItoSolver::getMobilityFunction ( ) const
virtual

Get mobility function.

Returns
m_mobilityFunction

◆ getName()

std::string ItoSolver::getName ( ) const
virtual

Get this solver's name.

Returns
Returns m_name

◆ getNumberOfPlotVariables()

int ItoSolver::getNumberOfPlotVariables ( ) const
virtual

Get number of plot variables.

Returns
Returns the number of plot variables (Note: Scalars-> one variable and vectors -> SpaceDim variables).

◆ getNumParticles()

unsigned long long ItoSolver::getNumParticles ( WhichContainer  a_whichContainer,
bool  a_localOnly 
) const
virtual

Get number of particles in a specified particle container.

Parameters
[in]a_whichContainerContainer
[in]a_localOnlyOnly report local particles (i.e. not reduced over MPI ranks)
Returns
Num particles

◆ getParticles() [1/2]

ParticleContainer< ItoParticle > & ItoSolver::getParticles ( WhichContainer  a_container)
virtual

Get a general particle container.

Parameters
[in]a_containerWhich container to fetch.
Returns
Particles

◆ getParticles() [2/2]

const ParticleContainer< ItoParticle > & ItoSolver::getParticles ( WhichContainer  a_container) const
virtual

Get a general particle container.

Parameters
[in]a_containerWhich container to fetch.
Returns
Particles

◆ getParticlesPerCell()

const Vector< int > & ItoSolver::getParticlesPerCell ( ) const
virtualnoexcept

Get the configured target number of computational particles per cell, per AMR level.

ItoSolver.particles_per_cell. Exposed because a load estimator has to assume the same target the merge will actually reduce to – BrownianWalkerStepper's mesh balancer clamps its per-cell physical count with it. Index it with the same clamp the merge uses: entry lvl if the vector is long enough, otherwise the last entry.

Returns
The per-level target particle count.

◆ getPhase()

phase::which_phase ItoSolver::getPhase ( ) const

Return phase.

Returns
Returns m_phase

◆ getPhi()

EBAMRCellData & ItoSolver::getPhi ( )
virtual

Get the mesh data.

Returns
Returns m_phi

◆ getPlotVariableNames()

Vector< std::string > ItoSolver::getPlotVariableNames ( ) const
virtual

Get output plot names.

Returns
Returns a string of all variables that this solver can add to plot files.

◆ getRealm()

std::string ItoSolver::getRealm ( ) const
virtual

Get the realm where this solver is registered.

Returns
m_realm

◆ getRegridParticles()

ParticleContainer< ItoMergeParticle > & ItoSolver::getRegridParticles ( )
virtualnoexcept

Get the reduced holder the bulk particles ride across a regrid in.

Only meaningful between preRegrid() and regrid(); the bulk ItoParticle container is empty over that window, and this is where its particles actually are. Exposed for load balancers that need to count or trial-regrid the population between those two calls – see BrownianWalkerStepper::loadBalanceBoxesParticles(). Reading getParticles(Bulk) there instead yields zero loads and a valid but unbalanced layout, with nothing to indicate anything went wrong.

Returns
The reduced-particle regrid holder.

◆ getSpecies()

const RefCountedPtr< ItoSpecies > & ItoSolver::getSpecies ( ) const
virtual

Get the species.

Returns
Returns m_species

◆ getVelocityFunction() [1/2]

EBAMRCellData & ItoSolver::getVelocityFunction ( )
virtual

Get cell-centered velocity mesh data.

Returns
m_velocityFunction

◆ getVelocityFunction() [2/2]

const EBAMRCellData & ItoSolver::getVelocityFunction ( ) const
virtual

Get cell-centered velocity mesh data.

Returns
m_velocityFunction

◆ initialData()

void ItoSolver::initialData ( )
virtual

Set the initial data.

This will add the initial particles and deposit them.

◆ interpolateDiffusion() [1/2]

void ItoSolver::interpolateDiffusion ( )
virtual

Interpolate the diffusion field to the particle positions.

This computes D_p = Df(X_p) where Df is the diffusion field on the mesh.

◆ interpolateDiffusion() [2/2]

void ItoSolver::interpolateDiffusion ( int  a_lvl,
const DataIndex &  a_dit 
)
protectedvirtual

Interpolate the diffusion field to the particle positions.

This computes D_p = Df(X_p) where Df is the diffusion field on the mesh.

Parameters
[in]a_lvlGrid level
[in]a_ditGrid index

◆ interpolateMobilities() [1/2]

void ItoSolver::interpolateMobilities ( )
virtual

Interpolate mobilities.

This will switch between the two ways of computing the particle mobility.

◆ interpolateMobilities() [2/2]

void ItoSolver::interpolateMobilities ( int  a_lvl,
const DataIndex &  a_dit,
const EBCellFAB &  a_velocityMagnitude 
)
protectedvirtualnoexcept

Interpolate mobilities – this will switch between the two ways of computing the particle mobility.

Parameters
[in]a_lvlGrid level.
[in]a_ditGrid index.
[in]a_velocityMagnitudeVelocity magnitude.

◆ interpolateMobilitiesDirect()

void ItoSolver::interpolateMobilitiesDirect ( int  a_lvl,
const DataIndex &  a_dit 
)
protectedvirtualnoexcept

Directly interpolate mobilities. Interpolates for all particles in the specified grid patch.

Parameters
[in]a_lvlGrid level.
[in]a_ditGrid index.

◆ interpolateMobilitiesVelocity()

void ItoSolver::interpolateMobilitiesVelocity ( int  a_lvl,
const DataIndex &  a_dit,
const EBCellFAB &  a_velocityMagnitude 
)
protectedvirtualnoexcept

Interpolate mobilities through the velocity. Interpolates for all particles in the specified grid patch.

Parameters
[in]a_lvlGrid level.
[in]a_ditGrid index.
[in]a_velocityMagnitudeVelocity magnitude.

◆ interpolateVelocities() [1/2]

void ItoSolver::interpolateVelocities ( )
virtual

Interpolate the particle velocities.

This will compute the particle velocities as v = mu * V(Xp) where mu is the particle mobility and V(Xp) is the interpolation of m_velocityFunction to the particle position.

◆ interpolateVelocities() [2/2]

void ItoSolver::interpolateVelocities ( int  a_lvl,
const DataIndex &  a_dit 
)
virtual

Interpolate the particle velocities.

This will compute the particle velocities as v = mu * V(Xp) where mu is the particle mobility and V(Xp) is the interpolation of m_velocityFunction to the particle position.

Parameters
[in]a_lvlGrid level
[in]a_ditGrid index

◆ intersectParticles() [1/3]

void ItoSolver::intersectParticles ( const EBIntersection  a_ebIntersection,
const bool  a_deleteParticles,
const std::function< void(ParticleSoA< ItoParticle > &, std::size_t)> &  a_nonDeletionModifier = [](ParticleSoA<ItoParticle>&, std::size_t) -> void { return; } 
)
virtual

Do boundary intersection tests.

This will intersect the particles in the "bulk" particles data holder with the domain faces and EBs. If a particle crossed the EB it will be put into the "EB" particle data holder and likewise for the particles that crossed the domain side.

Parameters
[in]a_ebIntersectionEnum for switching between various types of intersection tests.
[in]a_deleteParticlesIf true, the origin particle will also be removed from the bulk particle data holder.
[in]a_nonDeletionModifierOptional input argument for letting the user manipulate particles that were intersected but not deleted
Note
This will call the other version with WhichContainer::Bulk, WhichContainer::EB, and WhichContainer::Domain.

◆ intersectParticles() [2/3]

void ItoSolver::intersectParticles ( const WhichContainer  a_particles,
const WhichContainer  a_ebParticles,
const WhichContainer  a_domainParticles,
const EBIntersection  a_ebIntersection,
const bool  a_deleteParticles,
const std::function< void(ParticleSoA< ItoParticle > &, std::size_t)> &  a_nonDeletionModifier = [](ParticleSoA<ItoParticle>&, std::size_t) -> void { return; } 
)
virtual

Do boundary intersection tests.

This will intersect the particles in the a_particles data holder with the domain faces and EBs. If a particle crossed the EB it will be put into the a_eb_particles particle data holder and likewise for the particles that crossed the domain side.

Parameters
[in]a_particlesWhich particle container to use for the "active" particles
[in]a_ebParticlesWhich particle container to put the EB particles
[in]a_domainParticlesWhich particle container to put the domain particles
[in]a_ebIntersectionEnum for switching between various types of intersection tests.
[in]a_deleteParticlesIf true, the origin particle will also be removed from the bulk particle data holder.
[in]a_nonDeletionModifierOptional input argument for letting the user manipulate particles that were intersected but not deleted
Note
This will look up the ParticleContainer and call the other version.

◆ intersectParticles() [3/3]

void ItoSolver::intersectParticles ( ParticleContainer< ItoParticle > &  a_particles,
ParticleContainer< ItoParticle > &  a_ebParticles,
ParticleContainer< ItoParticle > &  a_domainParticles,
const EBIntersection  a_ebIntersection,
const bool  a_deleteParticles,
const std::function< void(ParticleSoA< ItoParticle > &, std::size_t)> &  a_nonDeletionModifier = [](ParticleSoA<ItoParticle>&, std::size_t) -> void { return; } 
)
virtual

Do boundary intersection tests.

This will intersect the particles in the a_particles data holder with the domain faces and EBs. If a particle crossed the EB it will be put into the a_eb_particles particle data holder and likewise for the particles that crossed the domain side.

Parameters
[in]a_particlesWhich particle container to use for the "active" particles
[in]a_ebParticlesWhich particle container to put the EB particles
[in]a_domainParticlesWhich particle container to put the domain particles
[in]a_ebIntersectionEnum for switching between various types of intersection tests.
[in]a_deleteParticlesIf true, the origin particle will also be removed from the bulk particle data holder.
[in]a_nonDeletionModifierOptional input argument for letting the user manipulate particles that were intersected but not deleted

◆ invalidateParticleIDs()

void ItoSolver::invalidateParticleIDs ( ParticleContainer< ItoMergeParticle > &  a_particles) const
protected

Set every particle id in a reduced-particle container to ParticleSoA::s_invalidID.

Run by mergeLite() after the whole-container methods, whose ids come from a rank-local counter that restarts every drain round. Those are merge scratch, not particle identity, and are indistinguishable from real ids downstream – where they would reach H5Part output. "No id" is the honest answer for a particle a merge produced, and is what an append()-built particle carries.

Parameters
[in,out]a_particlesContainer whose id column is reset.

◆ isDiffusive()

bool ItoSolver::isDiffusive ( ) const
virtual

Check if solver is diffusive.

Returns
Returns m_isDiffusive

◆ isMobile()

bool ItoSolver::isMobile ( ) const
virtual

Check if solver is mobile.

Returns
Returns m_isMobile

◆ makeSuperparticles() [1/4]

void ItoSolver::makeSuperparticles ( WhichContainer  a_container)
virtual

Make superparticles for a full container, merging to the solver's configured target.

The usual entry point: the target is ItoSolver.particles_per_cell and the method is ItoSolver.merge_algorithm, so a caller that has no opinion about either does not have to carry one.

Parameters
[in]a_containerWhich container to repartition into new superparticles.

◆ makeSuperparticles() [2/4]

void ItoSolver::makeSuperparticles ( WhichContainer  a_container,
const Vector< int > &  a_particlesPerCell 
)
virtual

Make superparticles for a full container – this is the AMR version that users will usually call.

Parameters
[in]a_containerWhich container to repartition into new superparticles
[in]a_particlesPerCellTarget number of particles per cell. Vector indicates grid levels.

◆ makeSuperparticles() [3/4]

void ItoSolver::makeSuperparticles ( WhichContainer  a_container,
const Vector< int > &  a_particlesPerCell,
const ParticleManagement::ParticleMergeMethod  a_method 
)
virtual

Make superparticles with an explicitly chosen method, ignoring the configured merge_algorithm.

Lets a caller run a different method than the solver's own (e.g. a stepper choosing a regrid-time merge). Routes through mergeLite(); ParticleMergeMethod::None is a no-op.

Parameters
[in]a_containerWhich container to repartition.
[in]a_particlesPerCellTarget particle count per cell (per-level; the last entry applies to any finer level).
[in]a_methodThe merge method to run.

◆ makeSuperparticles() [4/4]

void ItoSolver::makeSuperparticles ( WhichContainer  a_container,
int  a_particlesPerCell 
)
virtual

Make superparticles for a full container – this is the AMR version that users will usually call.

Parameters
[in]a_containerWhich container to repartition into new superparticles
[in]a_particlesPerCellTarget number of particles per cell

◆ mergeEqualWeightKD()

void ItoSolver::mergeEqualWeightKD ( ParticleContainer< ItoMergeParticle > &  a_particles,
const Vector< int > &  a_particlesPerCell 
)
protected

Cell-based merge: equal-weight KD partition, one weighted-centroid particle per leaf.

Recursively partitions each cell into at most a_particlesPerCell equal-weight KD leaves and reduces each to one weighted-centroid particle. Requires particle weights >= 1 to split. Honours the per-level target.

Parameters
[in,out]a_particlesReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count per cell (per-level).

◆ mergeKDImpl()

void ItoSolver::mergeKDImpl ( ParticleContainer< ItoMergeParticle > &  merge,
const Vector< int > &  a_particlesPerCell,
bool  a_enableBoundaryCarve 
)
protected

Whole-container merge: whole-patch kd-tree build – shared implementation behind the kd_carve and kd_patch selectors.

A single, non-iterative pass: no drain loop, and no nn_pair_iterate/nn_pair_fallback/ nn_pair_max_cell_dist equivalents, since there is no configurable search radius or convergence loop. With a_enableBoundaryCarve the merge fills a width-1 particle ghost mask (which must be registered on this realm) and arbitrates leaves straddling a patch boundary; without it the merge is patch-local – no ghosts, no communication, and a cell straddled by two patches is reduced by each patch independently. Needs no cell sorting. Uses a single crowding threshold – the coarsest level's a_particlesPerCell entry. Drains over-full cells only; mergeLite() splits afterwards.

Parameters
[in,out]mergeReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count (only the first entry is used).
[in]a_enableBoundaryCarveTrue to fill ghosts and run the carve tier, false for the patch-local merge.

◆ mergeKDSkinNn()

void ItoSolver::mergeKDSkinNn ( ParticleContainer< ItoMergeParticle > &  merge,
const Vector< int > &  a_particlesPerCell 
)
protected

Whole-container merge: kd-tree with a nearest-neighbour skin (the kd_skin_nn selector).

Same tree build and per-cell quota as mergeKDImpl(), but the boundary tier is the nearest-neighbour pair merge instead of the carve arbitration. The particles are split across two containers: ParticleManagement::mergeKDInterior() commits every leaf holding no ghost into one, and what is left – the contested skin – is drained from the other by ParticleManagement::mergeNearestNeighborsOneCell(), whose search radius is fixed at Chebyshev cell distance 1 and so matches the width-1 halo exactly. The skin tier drains each cell to what remains of its target after the interior results are counted against it, so the two tiers share one budget. Fills a width-1 particle ghost mask itself, which must be registered on this realm. Tuned by nn_pair_iterate/nn_pair_fallback/nn_pair_max_rounds, shared with the nn_pair family; nn_pair_max_cell_dist does not apply. Drains over-full cells only; mergeLite() splits afterwards.

Parameters
[in,out]mergeReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count (only the first entry is used).

◆ mergeLite()

void ItoSolver::mergeLite ( ParticleContainer< ItoMergeParticle > &  a_particles,
const Vector< int > &  a_particlesPerCell,
ParticleManagement::ParticleMergeMethod  a_method 
)
protected

Run one merge method over an already-extracted reduced-particle container.

The single place that knows the shape of each merge method, so that no caller has to. Two shapes exist and they are not interchangeable:

  • cell-based (equal_weight_kd, reinitialize, reinitialize_bvh, nn_sfc, external): reduce each cell to at most its per-level target, refilling only within that same per-cell budget. These must NOT be followed by the container-wide split.
  • whole-container (kd_carve, kd_patch, kd_skin_nn, nn_pair_{tree,onecell,hash}): drain over-full cells against one crowding threshold for the whole hierarchy, then split under-full cells back up to it. These MUST split, and they mint scratch ids that are invalidated afterwards. ParticleMergeMethod::None does neither – not even the split, which would otherwise refill every under-full cell in the domain at every regrid. Getting that wrong is silent: nothing fails, the population simply grows.
    Parameters
    [in,out]a_particlesReduced-particle container to merge in place.
    [in]a_particlesPerCellTarget particle count per cell (per-level for the cell-based methods; the whole-container methods use the first entry only).
    [in]a_methodWhich merge method to run.

◆ mergeNnPairOneCell()

void ItoSolver::mergeNnPairOneCell ( ParticleContainer< ItoMergeParticle > &  merge,
const Vector< int > &  a_particlesPerCell 
)
protected

Whole-container merge: distributed nearest-neighbour pair merge, per-cell PointCloudBVH search.

As mergeNnPairSearch(), but the merge distance is structurally fixed at Chebyshev cell distance 1 (own cell and Moore-adjacent neighbours only), so nn_pair_max_cell_dist is not honoured by this method. Requires a width-1 particle ghost mask registered on this realm. Drains over-full cells only; mergeLite() splits afterwards.

Parameters
[in,out]mergeReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count (only the first entry is used).

◆ mergeNnPairSearch()

template<ItoSolver::NnPairSearchBackend Backend>
void ItoSolver::mergeNnPairSearch ( ParticleContainer< ItoMergeParticle > &  merge,
const Vector< int > &  a_particlesPerCell 
)
protected

Whole-container merge: distributed nearest-neighbour pair merge – shared implementation behind the nn_pair_tree and nn_pair_hash selectors.

Whole-container, cross-patch/cross-rank AMR merge. Identical in every respect between the two backends (callbacks, id allocation, drain loop); only the ParticleManagement::mergeNearestNeighborsTree()/mergeNearestNeighborsHash() call inside the drain loop differs, selected at compile time via Backend. Requires the particle ghost mask registered on this realm (see registerOperators()); it does its own ghost fill and needs no cell sorting. Uses a single crowding threshold – the coarsest level's a_particlesPerCell entry. Drains over-full cells only; mergeLite() splits afterwards.

Template Parameters
BackendWhich point-cloud index to search with (see NnPairSearchBackend).
Parameters
[in,out]mergeReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count (only the first entry is used).

◆ mergeNnSfc()

void ItoSolver::mergeNnSfc ( ParticleContainer< ItoMergeParticle > &  a_particles,
const Vector< int > &  a_particlesPerCell 
)
protected

Cell-based merge: Hilbert-curve sort, then merge adjacent pairs down to the target.

Splits the heaviest particle when a cell is below target, so unlike the other cell-based methods it does refill – but per cell against the per-level target, which is why mergeLite() must still not run the container-wide split after it. Does not require integer weights.

Parameters
[in,out]a_particlesReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count per cell (per-level).

◆ mergeReinitialize()

void ItoSolver::mergeReinitialize ( ParticleContainer< ItoMergeParticle > &  a_particles,
const Vector< int > &  a_particlesPerCell 
)
protected

Cell-based merge: redistribute each cell's physical particles into near-equal integer weights at random cell positions.

All output particles carry the same weight-averaged energy. Requires integer weights. Honours the per-level target.

Parameters
[in,out]a_particlesReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count per cell (per-level).

◆ mergeReinitializeBVH()

void ItoSolver::mergeReinitializeBVH ( ParticleContainer< ItoMergeParticle > &  a_particles,
const Vector< int > &  a_particlesPerCell 
)
protected

Cell-based merge: as mergeEqualWeightKD(), with reinitialized leaf positions.

Cut-cells use the weighted centroid (to stay inside the EB); full cells draw a random point in the leaf bounding box. Honours the per-level target.

Parameters
[in,out]a_particlesReduced-particle container to repartition.
[in]a_particlesPerCellTarget particle count per cell (per-level).

◆ operator=()

ItoSolver & ItoSolver::operator= ( ItoSolver &&  )
default

Default move assignment operator.

Returns
Reference to this object

◆ organizeParticlesByCell()

void ItoSolver::organizeParticlesByCell ( WhichContainer  a_container)
virtual

Sort the input particle container by cell.

Parameters
[in]a_containerContainer to be sorted.

◆ organizeParticlesByPatch()

void ItoSolver::organizeParticlesByPatch ( WhichContainer  a_container)
virtual

Sort the input particle container by patch.

Parameters
[in]a_containerContainer to be sorted.

◆ preRegrid()

void ItoSolver::preRegrid ( int  a_lbase,
int  a_oldFinestLevel 
)
virtual

Perform pre-regrid operations.

Parameters
[in]a_lbaseCoarsest level that changed during regrid.
[in]a_oldFinestLevelFinest grid level before the regrid operation.
Note
This caches the bulk particles.

◆ randomDirection()

RealVect ItoSolver::randomDirection ( ) const
inline

Draw a random direction in N-dimensional space.

We use the algorithm by Marsaglia (1972).

Returns
Return value

◆ randomGaussian()

RealVect ItoSolver::randomGaussian ( ) const
inline

Draw a random N-dimensional Gaussian number from a normal distribution with zero with and unit standard deviation.

Note
The distribution is truncated at m_normalDistributionTruncation – values above that threshold will be replaced by m_normalDistributionTruncation.
Returns
Return value

◆ rebuildFromMergeContainer()

void ItoSolver::rebuildFromMergeContainer ( WhichContainer  a_container,
ParticleContainer< ItoMergeParticle > &  a_merge 
)
protected

Rebuild a container's ItoParticles from the reduced particles.

Rebuilds into the same patch (no remap); velocity/mobility/diffusion default to zero and are recomputed from the field before use. particleID is carried across. Each reduced leaf's arena is released as its ItoParticle copy is built. Leaves a_container patch-organized.

Parameters
[in]a_containerWhich container to rebuild into.
[in,out]a_mergeThe reduced-particle container to consume.

◆ redistributeAMR()

void ItoSolver::redistributeAMR ( EBAMRCellData &  a_phi) const
protectedvirtual

Redistribute mass in an AMR context.

We will have deposited particles into each cell, i.e. phi_i = m_i/dx^3. To obtain the true density in an EB context we need to divide by kappa such that phi_i = m_i/(kappa_i*dx^3). Unfortunately, this is numerically unstable because kappa_i can be arbitrarily small. We can set the density as phi_i = m_i/dx^3 but we will be missing a mass m_i*(1-kappa_i) from the cell. This mass can be smooshed into neighboring cells such as to make the total scheme conservative. As an option, we can also use a "non-conservative" divergence but the scheme is not guaranteed to be non-negative. All of this is just to say that we take the mass that fell inside the EB and put it back into the domain.

Parameters
[in,out]a_phiQuantity to be redistributed.

◆ registerOperators()

void ItoSolver::registerOperators ( ) const
virtual

Register operators.

This will register the required operators for running this class.

◆ regrid()

void ItoSolver::regrid ( int  a_lmin,
int  a_oldFinestLevel,
int  a_newFinestLevel 
)
virtual

Regrid this solver.

Parameters
[in]a_lminCoarsest level where grids did not change.
[in]a_oldFinestLevelFinest AMR level before the regrid.
[in]a_newFinestLevelFinest AMR level after the regrid.

◆ remap()

void ItoSolver::remap ( WhichContainer  a_container)
virtual

Remap all particles in the input container.

Parameters
[in]a_containerParticle container

◆ removeCoveredParticles() [1/3]

void ItoSolver::removeCoveredParticles ( EBRepresentation  a_representation,
Real  a_tol 
)
virtual

Remove particles that are inside the EB.

Parameters
[in]a_tolTolerance – removes particles if they are less than a_tol*dx away from the boundary.

Calls the other version with m_particles.

Parameters
[in]a_representationRepresentation

◆ removeCoveredParticles() [2/3]

void ItoSolver::removeCoveredParticles ( ParticleContainer< ItoParticle > &  a_particles,
EBRepresentation  a_representation,
Real  a_tol 
) const
virtual

Remove particles that are inside the EB.

Parameters
[in]a_particlesParticles to remove.
[in]a_tolTolerance – removes particles if they are less than a_tol*dx away from the boundary.
[in]a_representationRepresentation

◆ removeCoveredParticles() [3/3]

void ItoSolver::removeCoveredParticles ( WhichContainer  a_container,
EBRepresentation  a_representation,
Real  a_tol 
)
virtual

Remove particles that are inside the EB.

Parameters
[in]a_containerWhich particle container to remove particles from
[in]a_tolTolerance – removes particles if they are less than a_tol*dx away from the boundary.
Note
Calls the other version with ParticleContainer = m_particles.at(a_container)
Parameters
[in]a_representationRepresentation

◆ setAmr()

void ItoSolver::setAmr ( const RefCountedPtr< AmrMesh > &  a_amr)
virtual

Set the AmrMesh object.

Parameters
[in]a_amrAmrMesh object.

◆ setComputationalGeometry()

void ItoSolver::setComputationalGeometry ( const RefCountedPtr< ComputationalGeometry > &  a_computationalGeometry)
virtual

Set computational geometry.

Parameters
[in]a_computationalGeometryComputational geometry.

◆ setDiffusionFunction()

void ItoSolver::setDiffusionFunction ( Real  a_diffusionCoefficient)
virtual

Utility function – set a constant diffusion coefficient.

Parameters
[in]a_diffusionCoefficientDiffusion coefficient

◆ setParticleCellMerger()

void ItoSolver::setParticleCellMerger ( const ParticleManagement::ParticleMerger< ItoMergeParticle > &  a_particleCellMerger)
virtualnoexcept

Set the user-supplied per-cell particle merger used by merge_algorithm = external.

The built-in merge methods build their own per-cell merger internally; this one is used only when merge_algorithm = external, applied cell-by-cell by makeSuperparticles().

Note
The merger runs on ItoMergeParticle, not ItoParticle: every merge in this solver operates on the reduced particle, and a per-cell merger sees exactly the columns a merge is entitled to change (position, weight, energy). Out-of-tree mergers written against ItoParticle break at compile time.
Parameters
[in]a_particleCellMergerPer-cell particle merger.

◆ setParticleDiffusion()

void ItoSolver::setParticleDiffusion ( Real  a_diffCo)
virtual

Sets diffusion coefficient for all particles.

Parameters
[in]a_diffCoParticle diffusion value.

◆ setParticleMobility()

void ItoSolver::setParticleMobility ( Real  a_mobility)
virtual

Sets mobility coefficient for all particles.

Parameters
[in]a_mobilityParticle mobility.

◆ setPhase()

void ItoSolver::setPhase ( phase::which_phase  a_phase)
virtual

Set phase where the particles will live.

Parameters
[in]a_phasePhase

◆ setRealm()

void ItoSolver::setRealm ( const std::string &  a_realm)
virtual

Set the realm where this solver will live.

Parameters
[in]a_realmRealm name.

◆ setSpecies()

void ItoSolver::setSpecies ( const RefCountedPtr< ItoSpecies > &  a_species)
virtual

Set the species.

Parameters
[in]a_speciesSpecies to be solved for.

◆ setTime()

void ItoSolver::setTime ( int  a_step,
Real  a_time,
Real  a_dt 
)
virtual

Set the time for this solver.

Parameters
[in]a_stepTime step number
[in]a_timeTime (in seconds)
[in]a_dtTime step increment
Note
This sets m_step=a_step, m_time=a_time, m_dt=a_dt

◆ setVelocityFunction()

void ItoSolver::setVelocityFunction ( const RealVect &  a_velocity)
virtual

Utility function – set a constant velocity.

Parameters
[in]a_velocityVelocity

◆ setVerbosity()

void ItoSolver::setVerbosity ( int  a_verbosity)
virtual

Set verbosity level for this solver.

Parameters
[in]a_verbosityVerbosity level.

◆ splitFromMergeContainer()

void ItoSolver::splitFromMergeContainer ( ParticleContainer< ItoMergeParticle > &  a_merge,
int  a_numParticlesPerCellThresh 
)
protected

Split every under-full cell up to the target count.

The whole-container merge/drain phase only reduces over-full cells; this brings cells below the target back up to it via greedy heaviest-particle splitting (same rule as nn_sfc). Called only from mergeLite(), and only for the methods whose shape calls for it – see there.

Parameters
[in,out]a_mergeReduced-particle container to split (cell-sorted internally).
[in]a_numParticlesPerCellThreshTarget particle count per cell.

◆ transferCoveredParticles() [1/3]

void ItoSolver::transferCoveredParticles ( EBRepresentation  a_representation,
Real  a_tol 
)
virtual

Transfer particles that are covered (within a_tol distance from EB) to another container.

Calls the other version with m_particles and m_coveredParticles

Parameters
[in]a_tolTolerance – removes particles if they are less than a_tol*dx away from the boundary.
[in]a_representationRepresentation

◆ transferCoveredParticles() [2/3]

void ItoSolver::transferCoveredParticles ( ParticleContainer< ItoParticle > &  a_particlesFrom,
ParticleContainer< ItoParticle > &  a_particlesTo,
EBRepresentation  a_representation,
Real  a_tol 
) const
virtual

Transfer particles that are inside the EB to another container.

Parameters
[in]a_particlesFromWhich particle container to transfer particles from
[in]a_particlesToWhich particle container to move particles into
[in]a_tolTolerance – removes particles if they are less than a_tol*dx away from the boundary.
[in]a_representationRepresentation

◆ transferCoveredParticles() [3/3]

void ItoSolver::transferCoveredParticles ( WhichContainer  a_containerFrom,
WhichContainer  a_containerTo,
EBRepresentation  a_representation,
Real  a_tol 
)
virtual

Transfer particles that are covered (within a_tol distance from EB) to another container.

Parameters
[in]a_containerFromWhich particle container to transfer particles from
[in]a_tolTolerance – removes particles if they are less than a_tol*dx away from the boundary.
[in]a_containerToContainer to
[in]a_representationRepresentation

◆ updateDiffusion() [1/2]

void ItoSolver::updateDiffusion ( )
virtual

Update mobilities parametrically from the particle energy.

This calls the diffusion function implemented by ItoSpecies. The particle diffusion is set D = f(p.energy()) where f is the diffusion function in ItoSpecies

◆ updateDiffusion() [2/2]

void ItoSolver::updateDiffusion ( int  a_level,
const DataIndex &  a_dit 
)
protectedvirtual

Update mobilities parametrically from the particle energy.

This calls the diffusion function implemented by ItoSpecies. The particle diffusion is set D = f(p.energy()) where f is the diffusion function in ItoSpecies

Parameters
[in]a_levelGrid level
[in]a_ditGrid index

◆ updateMobilities() [1/2]

void ItoSolver::updateMobilities ( )
virtual

Update mobilities parametrically from the particle energy.

This calls the mobility function implemented by ItoSpecies. The particle mobility is set mu = f(p.energy()) where f is the mobility function in ItoSpecies

◆ updateMobilities() [2/2]

void ItoSolver::updateMobilities ( int  a_level,
const DataIndex &  a_dit 
)
protectedvirtual

Update mobilities parametrically from the particle energy.

This calls the mobility function implemented by ItoSpecies. The particle mobility is set mu = f(p.energy()) where f is the mobility function in ItoSpecies

Parameters
[in]a_levelGrid level
[in]a_ditGrid index

◆ writeData()

void ItoSolver::writeData ( LevelData< EBCellFAB > &  a_output,
int &  a_comp,
const EBAMRCellData &  a_data,
const std::string &  a_outputRealm,
int  a_level,
bool  a_interpToCentroids,
bool  a_interpGhost 
) const
protectedvirtualnoexcept

Write data to output. Convenience function.

Parameters
[in,out]a_outputOutput data holder.
[in]a_dataData to write.
[in]a_outputRealmRealm where a_output belongs
[in]a_levelGrid level
[in]a_interpToCentroidsIf true, a_data will be interpolated to cell centroids before writing to a_output.
[in]a_interpGhostIf true, interpolate ghost cells
[in]a_compComp

◆ writePlotData()

void ItoSolver::writePlotData ( LevelData< EBCellFAB > &  a_output,
int &  a_comp,
const std::string &  a_outputRealm,
int  a_level 
) const
virtualnoexcept

Write plot data.

Parameters
[in,out]a_outputOutput data holder.
[in]a_outputRealmRealm where a_output belongs
[in]a_levelGrid level
Note
This will write the plot data in this solver to a_output, starting on a_comp
Parameters
[in]a_compComp

Member Data Documentation

◆ m_className

std::string ItoSolver::m_className
protected

Class name.

ItoSolver for parent class – derived classes might be named something else.

◆ m_kdMergeCellHistogram

EBAMRFAB ItoSolver::m_kdMergeCellHistogram
protected

Per-cell occupancy scratch for the kd merges (see ParticleManagement::mergeKDCarve).

Owned here, not by the merge, so the allocation happens once per regrid rather than once per merge call. Allocated and released with the other mesh fields, in allocate()/regrid() and preRegrid() respectively.

◆ m_kdSplitWeightLeafDx

Real ItoSolver::m_kdSplitWeightLeafDx = 1.0
protected

Leaf size, in cell widths, at or below which the tree build switches from count-median to weight-median splitting.

Forwarded to the a_splitWeightLeafDx argument of ParticleManagement::mergeKDCarve() and mergeKDPatch() – see those functions' own docs. Larger values apply the weight median to bigger leaves, giving more uniform super-particle weights at some cost to how evenly leaves are apportioned between cells; 0 disables it entirely. Governs the shared tree build, so it applies to both kd_carve and kd_patch.

◆ m_mergeMethod

The configured merge method (which specific algorithm).

Set by parseParticleMerger() from ItoSolver.merge_algorithm. makeSuperparticles() dispatches on this to run the right algorithm. Defaults to EqualWeightKD (the default merge_algorithm).

◆ m_nnPairIterate

bool ItoSolver::m_nnPairIterate = true
protected

nn_pair_tree/nn_pair_onecell/nn_pair_hash: iterate the local trivial tier to convergence within each round.

Forwarded to ParticleManagement::mergeNearestNeighborsTree()/mergeNearestNeighborsOneCell()/ mergeNearestNeighborsHash(). Only used for nn_pair_tree/nn_pair_onecell/nn_pair_hash.

◆ m_nnPairMaxRounds

int ItoSolver::m_nnPairMaxRounds = 3
protected

nn_pair_tree/nn_pair_onecell/nn_pair_hash: maximum number of drain rounds run per makeSuperparticles() call.

Each round merges nearest-neighbor pairs and roughly halves an over-full cell's surplus; the loop also stops early once a round merges nothing. This caps the round count so the cost stays bounded and predictable rather than running to full convergence. Only used for nn_pair_tree/nn_pair_onecell/nn_pair_hash.

◆ m_normalDistributionTruncation

Real ItoSolver::m_normalDistributionTruncation
protected

Truncation value for normal distribution.

This is used when drawing numbers from the Gaussian distribution, replacing all values above m_normalDistributionTruncation by m_normalDistributionTruncation.

◆ m_particlesPerCell

Vector<int> ItoSolver::m_particlesPerCell
protected

Target number of computational particles per cell, per AMR level.

Set by parseParticleMerger() from ItoSolver.particles_per_cell. The solver owns this because the solver is where merging happens – it is the target every merge reduces to, the count initialData() seeds the bulk container at, and (through getParticlesPerCell()) the number a particle-count load estimate has to assume. A time stepper still owns when to merge during a run (ItoKMCStepper.merge_interval); it no longer owns what to merge to.

Per-level, for compatibility with the ItoKMCStepper key it replaces. Only the cell-based methods honour it per level; the whole-container methods use one crowding threshold for the whole hierarchy and read entry 0, so parseParticleMerger() aborts on a non-uniform vector rather than silently truncating it.

◆ m_regridMergeMethod

std::optional<ParticleManagement::ParticleMergeMethod> ItoSolver::m_regridMergeMethod
protected

Which merge method to run inside ItoSolver::regrid(), or nullopt for "whatever merge_algorithm says".

Set by parseParticleMerger() from ItoSolver.regrid_superparticles. A separate knob from merge_algorithm because the two are genuinely independent: the regrid merge runs once per regrid on a population that has just been redistributed, and a run may reasonably want a cheaper (or no) method there than it uses per step. ParticleMergeMethod::None turns the regrid merge off; the extract/rebuild round-trip still happens, since preRegrid() has already reduced the particles by then.

◆ m_regridParticles

ParticleContainer<ItoMergeParticle> ItoSolver::m_regridParticles
protected

The bulk particles, in reduced form, between preRegrid() and regrid().

At a de-refining regrid 2^D fine cells collapse into one coarse cell, so between the redistribution and the merge each rank transiently holds up to 2^D times the target particles per cell. This container is what that spike is held in: preRegrid() extracts the bulk container into it, the redistribution and load balancing happen on it, and regrid() merges it and only then rebuilds ItoParticles. 53 B per particle in 3-D instead of 149 B, and the merge runs before the population is ever materialised at the larger size.

Bulk only. The EB/Domain/Source/Covered/Scratch containers keep the plain ParticleContainer::preRegrid() path – they are small, none of them is merged, and Scratch is never populated.

Live only across a regrid: regrid() releases it before returning. It is a member rather than a local because preRegrid() and regrid() are separate calls with the load-balancing phase between them, and because BrownianWalkerStepper's particle load balancer has to count it.


The documentation for this class was generated from the following files: