Peano
|
Legacy SPH implementation. More...
Namespaces | |
namespace | adiabaticIndex |
namespace | eos |
namespace | hydroDimensions |
namespace | kernelHydro |
Functions | |
template<typename Particle > | |
void | prepareDensity (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
Prepares a particle for the density calculation. | |
template<typename Particle > | |
void | prepareDensityWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | hydro_end_density (Particle *localParticle) |
Finishes the density calculation. | |
template<typename Particle > | |
void | endDensityCalculation (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | endDensityCalculationWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | density_kernel (Particle *localParticle, const Particle *activeParticle) |
The actual density kernel, which interacts a local particle and an active particle, and updates the local particle. | |
template<typename Particle > | |
bool | densityKernelPairEvaluationPredicate (const peano4::datamanagement::CellMarker &marker, const Particle &localParticle, const Particle &activeParticle) |
Predicate if two particles contribute towards the density checks. | |
template<typename Particle > | |
void | densityKernelWithoutChecks (const peano4::datamanagement::CellMarker &marker, Particle &localParticle, const Particle &activeParticle) |
Invoke density kernel without any outer additional admissibility checks. | |
template<typename Particle > | |
void | densityKernel (const peano4::datamanagement::CellMarker &marker, Particle &localParticle, const Particle &activeParticle) |
Density kernel. | |
template<typename Particle > | |
void | densityKernelWithMasking (const peano4::datamanagement::CellMarker &marker, Particle &localParticle, const Particle &activeParticle) |
template<typename Particle > | |
void | hydro_prepare_force (Particle *localParticle) |
Prepare a particle for the force calculation. | |
template<typename Particle > | |
void | prepareHydroForce (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | prepareHydroForceWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | hydro_reset_acceleration (Particle *localParticle) |
Reset acceleration fields of a particle. | |
template<typename Particle > | |
void | resetAcceleration (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | resetAccelerationWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | hydro_end_force (Particle *localParticle) |
Finishes the force calculation. | |
template<typename Particle > | |
void | endHydroForceCalculation (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | endHydroForceCalculationWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | force_kernel (Particle *localParticle, const Particle *activeParticle) |
The actual force kernel, which interacts a local particle and an active particle, and updates the local particle. | |
template<typename Particle > | |
void | forceKernel (const peano4::datamanagement::CellMarker &marker, Particle &localParticle, const Particle &activeParticle) |
template<typename Particle > | |
void | forceKernelWithMasking (const peano4::datamanagement::CellMarker &marker, Particle &localParticle, const Particle &activeParticle) |
Vectorised alternative implementation of forceKernel() | |
template<typename Particle > | |
void | predict_hyrdro (Particle *particle) |
Predict hydro terms (SWIFT) Relevant for inactive particles when using local-timestepping, but always used. | |
template<typename Particle > | |
void | predictHydro (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
bool | forceKernelDistanceCheck (Particle *__restrict__ localParticle, const Particle *__restrict__ activeParticle) |
Check distance between two particles. | |
template<typename ParticleContainer > | |
void | computeHydroForce_vectoriseAndMapDistanceChecksOntoMasking (const peano4::datamanagement::CellMarker &marker, const ParticleContainer &localVertices, const std::vector< int > &numberOfParticlesPerVertex, const ParticleContainer &activeParticles, const std::vector< int > &numberOfActiveParticlesPerVertex) |
Optimised alternative to computeHydroForce() | |
template<typename ParticleContainer > | |
void | computeHydroForce_vectoriseDistanceChecks (const peano4::datamanagement::CellMarker &marker, const ParticleContainer &localVertices, const std::vector< int > &numberOfParticlesPerVertex, const ParticleContainer &activeParticles, const std::vector< int > &numberOfActiveParticlesPerVertex) |
Two-step, vectorised interaction kernel. | |
template<typename Particle > | |
void | leapfrog_drift_global_time_step_size (Particle *particle) |
Update a particle with the leapfrog KDK integrator. | |
template<typename Particle > | |
void | leapfrogDriftWithGlobalTimeStepSize (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | hydro_predict_extra (Particle *localParticle) |
Predict additional particle fields forward in time when drifting. | |
template<typename Particle > | |
void | hydroPredictExtra (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | hydroPredictExtraWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | leapfrogDriftWithGlobalTimeStepSizeWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | leapfrog_kick_global_time_step_size (Particle *particle) |
Kick steps. | |
template<typename Particle > | |
void | leapfrogKickWithGlobalTimeStepSize (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | leapfrogKickWithGlobalTimeStepSizeWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | hydro_kick_extra_global_time_step_size (Particle *localParticle) |
Kick the additional variables. | |
template<typename Particle > | |
void | leapfrogKickExtraWithGlobalTimeStepSize (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | leapfrogKickExtraWithGlobalTimeStepSizeWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
@Todo No masking yet | |
template<typename Particle > | |
void | hydro_reset_predicted_values (Particle *localParticle) |
Sets the values to be predicted in the drifts to their values at a kick time. | |
template<typename Particle > | |
void | resetPredictedValues (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | resetPredictedValuesWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | hydro_update_smoothing_length_and_rerun_if_required (Particle *localParticle) |
Derive smoothing length from density. | |
template<typename Particle > | |
void | updateSmoothingLengthAndRerunIfRequired (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
Wrapper around hydro_update_smoothing_length_and_rerun_if_required() with only one argument. | |
template<typename Particle > | |
void | updateSmoothingLengthAndRerunIfRequiredWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &localParticle) |
template<typename Particle > | |
void | resetSmoothingLengthIterationCounter (const peano4::datamanagement::VertexMarker &marker, Particle &particle) |
Reset smoothing length iteration related flags on a particle. | |
template<typename Particle > | |
void | resetSmoothingLengthIterationCounterWithMasking (const peano4::datamanagement::VertexMarker &marker, Particle &particle) |
At this point, we just reset some flags and counters that are only required during a single time step. | |
template<typename Particle > | |
void | first_init_particle (Particle *particle) |
Initialise particles for the first time. | |
template<typename Particle > | |
void | firstInitParticle (const peano4::datamanagement::VertexMarker &marker, Particle &particle) |
template<typename Particle > | |
void | hydro_init_particle (Particle *particle) |
Prepares a particle for the density calculation. | |
template<typename Particle > | |
double | hydro_compute_timestep (Particle *particle) |
Computes the SPH time step size. | |
template<typename ParticleContainer > | |
void | computeNextTimestep (const peano4::datamanagement::VertexMarker &marker, ParticleContainer &assignedParticles) |
computes the next time step size for all particles associated to this vertex, and writes it into the particle species. | |
Legacy SPH implementation.
This implementation is very very close to the original Swift kernels. This can immediately be seen from the signature of the routines: The core routines all work solely with pointers.
For Swift 2 however, we need signatures which work with references and also evaluate predicates. So each routine actually comes along as pair: The core science with a pointer and then a wrapper around it.
The wrapper vs implementation distinction also is reflected in the naming conventions: The actual physics remain written in C/Swift style, whereas the wrappers follow the Peano's C++ convention.
This file contains only the functions that we actually want to use from the original swift codebase, and maintains their original name. The idea is to eventually use the SWIFT implementation of these functions. But for now, we keep a (modified) version of them here.
A second point to keep these functions separate is the fact that they do different things for each SPH flavour. So they are intended to be replaceable anyway.
There are some notable exceptions which are missing from this collection of functions. Firstly, we keep the particle-particle interactions separately. We are tinkering with them in Peano and optimizing them in a different way. They are defined in ParticleParticleInteraction.h. Secondly, anything related to the computation of the smoothing lengths is defined in SmoothingLengthComputation.h. The smoothing length computation is intimately tied to the neighbour search algorithms, and cannot be separated trivially from the underlying codebase and infrastructure. As such, we can't simply re-use what original SWIFT does, but need to provide our own algorithms. In particular, we differentiate between the search radius and the interaction radius/ compact support radius of particles, which original swift doesn't. We provide smoothing length computation algorithms for both a constant search radius as well as a varying search radius.
void swift2::kernels::legacy::computeHydroForce_vectoriseAndMapDistanceChecksOntoMasking | ( | const peano4::datamanagement::CellMarker & | marker, |
const ParticleContainer & | localVertices, | ||
const std::vector< int > & | numberOfParticlesPerVertex, | ||
const ParticleContainer & | activeParticles, | ||
const std::vector< int > & | numberOfActiveParticlesPerVertex ) |
Optimised alternative to computeHydroForce()
Semantically, this operation does exactly the same as computeHydroForce(). However, there are a few differences how the function runs through the particles. The routine can be used if and only if you use a memory pool as it is also discussed in the optimisation guidelines.
The routine knows way more about the internal ordering of the particles through the explicit arguments particlesAssociatedWithLocalVertices and numberOfParticlesPerLocalVertex. It implicitly knows how the particles are stored through the naming convention/the fact that you have to use it with a memory pool. The Python class peano4.toolbox.particles.UpdateParticle_MultiLevelInteraction_StackOfLists_ContiguousParticles.UpdateParticle_MultiLevelInteraction_StackOfLists_ContiguousParticles provides a lot of information how we construct the passed lists over particles.
Further to the optimised loops, the function calls forceKernelVectorised() instead of forceKernel() whenever it knows a priori that two particle ranges to not overlap. See forceKernelVectorised() for further remarks how we deliver vectorised kernels.
See also Creating new particle types (solvers) with new algorithmic steps Create new solvers "Swift's discussion how to vectorise kernels" for further details.
Consult computeHydroForce() for a discussion of the handling of multiscale relations. We can exploit the fact here that a set of continuous active particles all should have the same cut-off radius.
void swift2::kernels::legacy::computeHydroForce_vectoriseDistanceChecks | ( | const peano4::datamanagement::CellMarker & | marker, |
const ParticleContainer & | localVertices, | ||
const std::vector< int > & | numberOfParticlesPerVertex, | ||
const ParticleContainer & | activeParticles, | ||
const std::vector< int > & | numberOfActiveParticlesPerVertex ) |
Two-step, vectorised interaction kernel.
Alternative implementation of the hydro force which splits up the underlying algorithm into two steps:
In this variant, we assume that the first step is the part where the majority of the runtime is spent. After step 1 has completed we have a list of markers. Now we still try to vectorise over the markers holding a 1/true: We run trough the particle set once again with a while loop and look ahead N elements (typically N=8). If a reasonable amount of particles hold a 1 marker within this chunk, we process all of them with the vectorised kernel, i.e. accept that some of them might be masked out.
void swift2::kernels::legacy::computeNextTimestep | ( | const peano4::datamanagement::VertexMarker & | marker, |
ParticleContainer & | assignedParticles ) |
computes the next time step size for all particles associated to this vertex, and writes it into the particle species.
@TODO: this needs to be made threadsafe. @TODO: this needs to make use of the other forAll particleSetIterators. But for that, we need a new particleSetIterator that accepts a return value and a function to reduce the return value.
Definition at line 46 of file Timestep.cpph.
References hydro_compute_timestep(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
void swift2::kernels::legacy::density_kernel | ( | Particle * | localParticle, |
const Particle * | activeParticle ) |
The actual density kernel, which interacts a local particle and an active particle, and updates the local particle.
In this particle-particle interaction loop, we accumulate several quantities. For the subsequent force computation, we need to collect the density
\( \rho_i = \rho(\mathbf{x}_i) = \sum_j m_j W(r_{ij}, h_i)\)
and its derivative w.r.t. \( h \) :
\( \frac{\partial \rho_i}{\partial h} = \sum_j m_j \frac{\partial W(r_{ij}, h_i)}{\partial h} \)
(see the \(f_i\) in swift2::kernels::legacy::force_kernel to see where and how it is used) where \( m_j \) is the particle mass, \( r_{ij} \) is the distance between particle \(i \) and \( j \), \(h_i \) is the smoothing length of \(i \) and \( W(r, h) \) is the SPH kernel function we use.
Let
\( W = \frac{1}{h^\nu} f\left( \frac{r}{h}\right) \equiv \frac{1}{h^\nu} f( q ) \)
for \( \nu \) dimensions. Then
\( \frac{\partial W(r_{ij}, h_i)}{\partial h} = - \nu \frac{1}{h ^ {\nu + 1}} f(r/h) + \frac{1}{h^\nu} \frac{\partial f(q)}{\partial h} = - \nu \frac{1}{h ^ {\nu + 1}} f(q) + \frac{1}{h^\nu} \frac{\partial f(q)}{\partial q} \frac{\partial q}{\partial h} = - \frac{1}{h} \left( \nu W(q) + q \frac{\partial W(q)}{\partial q} \right) \)
which is a quantity we accumulate in the density interaction kernel for the estimate of \( \frac{\partial \rho_i}{\partial h} \).
Similarly, for the computation of the smoothing length, we require to accumulate the analgue number densities (and its derivative w.r.t. h):
\( n_i = \sum_j W(r_{ij}, h_i)\)
\( \frac{\partial n_i}{\partial h} = \sum_j \frac{\partial W(r_{ij}, h_i)}{\partial h} \)
Definition at line 142 of file Density.cpph.
References curlvr, tarch::la::dot(), dv, dvdr, dx, hi, hi_inv, kernel_deval(), mj, tarch::la::norm2(), r, and r_inv.
Referenced by densityKernel(), and densityKernelWithoutChecks().
void swift2::kernels::legacy::densityKernel | ( | const peano4::datamanagement::CellMarker & | marker, |
Particle & | localParticle, | ||
const Particle & | activeParticle ) |
Density kernel.
This routine forwards the function call to density_kernel(). Please consult this routine for additional information.
This kernel is to be used within swift2::kernels::coalesced::forAllParticlePairs. By default, testIfParticleCanBeUpdated is set and the routine hence uses densityKernelPredicate() and ::swift2::kernels::localParticleCanBeUpdatedInCellKernel<globaldata::HydroPart>(marker,localParticle) to find out if the particle is to be updated. If you can ensure that densityKernelPredicate() holds and ::swift2::kernels::localParticleCanBeUpdatedInCellKernel<globaldata::HydroPart>(marker,localParticle) holds as well, you can set testIfParticleCanBeUpdated to false.
Definition at line 19 of file Density.cpph.
References density_kernel(), densityKernelPairEvaluationPredicate(), and swift2::kernels::localParticleCanBeUpdatedInCellKernel().
Referenced by densityKernelWithMasking().
bool swift2::kernels::legacy::densityKernelPairEvaluationPredicate | ( | const peano4::datamanagement::CellMarker & | marker, |
const Particle & | localParticle, | ||
const Particle & | activeParticle ) |
Predicate if two particles contribute towards the density checks.
This predicate assumes that swift2::kernels::localParticleCanBeUpdatedInCellKernel() holds. It then evaluates if activeParticle contributes towards localParticle. Is used by the densityKernel() to find out if the actual density calculation is to be invoked, but can also be used as explicit check in combination with densityKernelWithoutChecks().
swift2::kernels::localParticleCanBeUpdatedInCellKernel<globaldata::HydroPart>
Definition at line 35 of file Density.cpph.
References assertion, dx, tarch::la::greater(), hi, swift2::kernels::localParticleCanBeUpdatedInCellKernel(), tarch::la::norm2Squared(), and tarch::la::smaller().
Referenced by densityKernel().
void swift2::kernels::legacy::densityKernelWithMasking | ( | const peano4::datamanagement::CellMarker & | marker, |
Particle & | localParticle, | ||
const Particle & | activeParticle ) |
Definition at line 222 of file Density.h.
References densityKernel().
void swift2::kernels::legacy::densityKernelWithoutChecks | ( | const peano4::datamanagement::CellMarker & | marker, |
Particle & | localParticle, | ||
const Particle & | activeParticle ) |
Invoke density kernel without any outer additional admissibility checks.
Similar to densityKernel(), but we assume that the predicates all hold, i.e. we do not check them anymore. As swift2::kernels::localParticleCanBeUpdatedInCellKernel(), we don't have to check anything and directly forward the call to the Swift 1 "legacy" kernel. It makes no sense to use this version in the generic pair-wise interactions, but it makes sense to combine it with coalesced memory accesses and a dedicated outer predicate.
That is, a vanilla density calculation equals
whereas we can use an optimised version such as
Definition at line 7 of file Density.cpph.
References assertion3, density_kernel(), and swift2::kernels::localParticleCanBeUpdatedInCellKernel().
void swift2::kernels::legacy::endDensityCalculation | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 56 of file Density.h.
References hydro_end_density(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by endDensityCalculationWithMasking().
void swift2::kernels::legacy::endDensityCalculationWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 67 of file Density.h.
References endDensityCalculation().
void swift2::kernels::legacy::endHydroForceCalculation | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 96 of file HydroForce.h.
References hydro_end_force(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by endHydroForceCalculationWithMasking().
void swift2::kernels::legacy::endHydroForceCalculationWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 110 of file HydroForce.h.
References endHydroForceCalculation().
void swift2::kernels::legacy::first_init_particle | ( | Particle * | particle | ) |
Initialise particles for the first time.
This method is intended to be called during startup only, not every simulation step.
Definition at line 5 of file Swift.cpph.
References hydro_init_particle(), and kernel_gamma_inv.
Referenced by firstInitParticle().
void swift2::kernels::legacy::firstInitParticle | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | particle ) |
Definition at line 60 of file Swift.h.
References first_init_particle(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
void swift2::kernels::legacy::force_kernel | ( | Particle * | localParticle, |
const Particle * | activeParticle ) |
The actual force kernel, which interacts a local particle and an active particle, and updates the local particle.
In this kernel, we accumulate the sums necessary for the force interactions between particles. In the "Minimal" SPH, by the end of it we're updating the velocity and the internal energy via
\( \frac{d\mathbf{v}_i}{dt} = - \sum_j m_j \left[ \frac{f_i P_i}{\rho_i^2} \nabla_x W(\mathbf{x}_{ij}, h_i) + \frac{f_j P_j}{\rho_j^2} \nabla_x W(\mathbf{x}_{ij}, h_j) + \nu_{ij} \overline{\nabla_x W_{ij}} \right] \)
and
\( \frac{du_i}{dt} = \sum_j m_j \left[ \frac{f_i P_i}{\rho_i^2} \mathbf{v}_{ij} \cdot \nabla_x W(\mathbf{x}_{ij}, h_i) + \frac{1}{2} \nu_{ij} \mathbf{v}_{ij} \cdot \overline{\nabla_x W_{ij}} \right] \)
where
\( \nu_{ij} = -\frac{1}{2} \frac{\alpha \mu_{ij} v_{sig,ij}}{\overline{\rho}_{ij}}\)
\( v_{sig,ij} = c_i + c_j - \beta \mu_{ij}\)
\( \mu_{ij} = \frac{\mathbf{v}_{ij} \cdot \mathbf{x}_{ij}}{|\mathbf{x}_{ij}|}\) if \( \mathbf{v}_{ij} \cdot \mathbf{x}_{ij} < 0\), or 0 otherwise
\( f_i = \left( 1 + \frac{h_i}{3 \rho_i} \frac{\partial \rho_i}{\partial h_i} \right)^{-1} \)
\( c_i\): soundspeed of particle i
\( P_i\): pressure of particle i
\( \mathbf{x}_{ij} = \mathbf{x}_{i} - \mathbf{x}_{j} \)
\( \mathbf{v}_{ij} = \mathbf{v}_{i} - \mathbf{v}_{j} \)
\( \alpha, \beta \): user set viscosity coefficient. Usually 0 and 3, respectively.
\( \overline{\rho}_{ij} = \frac{1}{2} (\rho_i + \rho_j) \)
\( \overline{\nabla_x W}_{ij} = \frac{1}{2} (\nabla_x W_i + \nabla_x W_j) \)
For a kernel
\( W(\mathbf{x}_{ij}, h) = \frac{1}{h^d} f \left( \frac{\mathbf{x}_{ij}}{h} \right) = \frac{1}{h^d} f \left( q \right) \)
in \( d \) dimensions, we have
\( \nabla_x W(\mathbf{x}_{ij}, h) = \frac{1}{h^{d+1}} \frac{\partial f(q)}{\partial q} \frac{\mathbf{x}_{ij}}{|\mathbf{x}_{ij}|} \)
This operation struggles to vectorise, as we have the statement
in there. This if statement encapsulates quite a lot of operations. The Intel compiler therefore cannot vectorise this routine anymore.
Definition at line 196 of file HydroForce.cpph.
References assertion3, assertion6, assertion9, tarch::la::dot(), dvdr, dx, tarch::la::greater(), tarch::la::isEntryNan(), kernel_deval(), mu_ij, tarch::la::norm2(), swift2::kernels::legacy::hydroDimensions::pow_dimension_plus_one(), r, r_inv, tarch::la::smaller(), and v_sig.
Referenced by forceKernel().
void swift2::kernels::legacy::forceKernel | ( | const peano4::datamanagement::CellMarker & | marker, |
Particle & | localParticle, | ||
const Particle & | activeParticle ) |
Definition at line 205 of file HydroForce.h.
References force_kernel(), and swift2::kernels::localParticleCanBeUpdatedInCellKernelFromAnyOtherParticle().
bool swift2::kernels::legacy::forceKernelDistanceCheck | ( | Particle *__restrict__ | localParticle, |
const Particle *__restrict__ | activeParticle ) |
Check distance between two particles.
First part of force kernel routine, where we check if two particles are close enough to actually interact. This routine also returns true if localParticle and activeParticle are the same. That is, it does not check for equality. Therefore, the routine has to be used with forceKernelVectorised() which in turn checks the distance interally but masks out zero distances.
void swift2::kernels::legacy::forceKernelWithMasking | ( | const peano4::datamanagement::CellMarker & | marker, |
Particle & | localParticle, | ||
const Particle & | activeParticle ) |
Vectorised alternative implementation of forceKernel()
The file names here are wrong. This is, to the best of my knowledge, not a legacy code, but new one.
This routine is a vectorised variant of forceKernel() which you can use if and only if you know that localParticle and activeParticle never ever can point to the same object, i.e. if you know that there is no aliasing. It is not clear if this operation is faster than forceKernel, but it delivers more flops due to the excessive vectorisation.
To make the function vectorisable, we had to apply a few tweaks compared to the non-vector counterpart. Most of these tweaks are now documented as part of Swift's genericsolver documentation".
As we know a priori that this function is only invoked on distinct chunks of particles, we know that we'll compare the same particle against each other. Consequently, we may assume that the radius is never 0. This additional check can be omitted.
Definition at line 377 of file HydroForce.cpph.
References assertion3, assertion6, assertion7, assertion9, tarch::la::dot(), dvdr, dx, tarch::la::greater(), tarch::la::isEntryNan(), kernel_deval(), mu_ij, tarch::la::norm2(), swift2::kernels::legacy::hydroDimensions::pow_dimension_plus_one(), r, r_inv, tarch::la::smaller(), and v_sig.
double swift2::kernels::legacy::hydro_compute_timestep | ( | Particle * | particle | ) |
Computes the SPH time step size.
May depend on SPH flavour.
@TODO: add cosmological factors.
Definition at line 9 of file Timestep.cpph.
References assertion1, assertion3, and v_sig.
Referenced by computeNextTimestep().
void swift2::kernels::legacy::hydro_end_density | ( | Particle * | localParticle | ) |
Finishes the density calculation.
Multiplies the density and number of neighbours by the appropiate constants and add the self-contribution term. Additional quantities such as velocity gradients will also get the final terms added to them here.
Also adds/multiplies the cosmological terms if need be. (Not implemented yet)
Definition at line 65 of file Density.cpph.
References assertion1, h_inv, kernel_root, and swift2::kernels::legacy::hydroDimensions::pow_dimension().
Referenced by endDensityCalculation().
void swift2::kernels::legacy::hydro_end_force | ( | Particle * | localParticle | ) |
Finishes the force calculation.
Multiplies the force and accelerations by the appropiate constants and add the self-contribution term. In most cases, there is little to do here.
Cosmological terms are also added/multiplied here.
localParticle | The particle to act upon |
Definition at line 144 of file HydroForce.cpph.
References _log, assertion2, double, and logWarning.
Referenced by endHydroForceCalculation().
void swift2::kernels::legacy::hydro_init_particle | ( | Particle * | particle | ) |
Prepares a particle for the density calculation.
Zeroes all the relevant arrays in preparation for the sums taking place in the various density loop over neighbours. Typically, all fields of the density sub-structure of a particle get zeroed in here.
Definition at line 59 of file Swift.cpph.
Referenced by first_init_particle(), and prepareDensity().
void swift2::kernels::legacy::hydro_kick_extra_global_time_step_size | ( | Particle * | localParticle | ) |
Kick the additional variables.
Additional hydrodynamic quantites are kicked forward in time here. These include thermal quantities (thermal energy or total energy or entropy, ...). The additional quantities being updated here depend on the exact SPH flavour being used.
Kick extra step, i.e. update some thermodynamic quantities forward in time. In particular, U is integrated forward in time treating it as the velocity.
Definition at line 137 of file Leapfrog.cpph.
References dt_kick_therm.
Referenced by leapfrog_kick_global_time_step_size(), and leapfrogKickExtraWithGlobalTimeStepSize().
void swift2::kernels::legacy::hydro_predict_extra | ( | Particle * | localParticle | ) |
Predict additional particle fields forward in time when drifting.
Additional hydrodynamic quantites are drifted forward in time here. These include thermal quantities (thermal energy or total energy or entropy, ...). Note that which and how quantities get updated depends on the specific SPH flavour.
Definition at line 27 of file Leapfrog.cpph.
References dt_therm, h_inv, pressure, and soundspeed.
Referenced by hydroPredictExtra().
void swift2::kernels::legacy::hydro_prepare_force | ( | Particle * | localParticle | ) |
Prepare a particle for the force calculation.
Convert some quantities coming from the density loop over neighbours into quantities ready to be used in the force loop over neighbours. Quantities are typically read from the density sub-structure and written to the force sub-structure. Examples of calculations done here include the calculation of viscosity term constants, thermal conduction terms, hydro conversions, etc.
Definition at line 6 of file HydroForce.cpph.
References _log, tarch::la::abs(), assertion1, assertion6, h_inv, logWarning, tarch::la::norm2(), and soundspeed.
Referenced by prepareHydroForce().
void swift2::kernels::legacy::hydro_reset_acceleration | ( | Particle * | localParticle | ) |
Reset acceleration fields of a particle.
Resets all hydro acceleration and time derivative fields in preparation for the sums taking place in the various force interactions.
Definition at line 130 of file HydroForce.cpph.
Referenced by resetAcceleration().
void swift2::kernels::legacy::hydro_reset_predicted_values | ( | Particle * | localParticle | ) |
Sets the values to be predicted in the drifts to their values at a kick time.
Definition at line 105 of file Leapfrog.cpph.
References pressure, and soundspeed.
Referenced by resetPredictedValues().
void swift2::kernels::legacy::hydro_update_smoothing_length_and_rerun_if_required | ( | Particle * | localParticle | ) |
Derive smoothing length from density.
This routine is to be called directly after hydro_end_density. It updates the smoothing length according to the updated density quantities and then decides if the smoothing length computation has terminated with something reasonable. If not, the routine triggers an iteration rerun on this species. The rerun will mean that we recalculate the density (as it depends on the smoothing length) and then check again if we have converged.
The smoothing length is defined by a user-set parameter \(\eta \) which specifies it in units of the (local) mean interparticle separation:
\( h = \eta \langle x \rangle = \eta \left(\frac{1}{n(\mathbf{x})} \right)^{1/\nu} \)
where \( n \) is the local number density of particles (which is the same as the inverse of volume), and \( \nu \) is the number of dimensions of the problem.
This is, however, a circular definition: The local number density of particles is estimated via the smoothing length as
\( n_i = \sum_j W(r_{ij}, h_i)\) .
So we must solve this problem iteratively. We can rewrite the equation above as:
\( h^\nu n = \eta^\nu \Rightarrow h^\nu n - \eta^\nu = 0 \)
And use this equation as a function whose root we're trying to find: Let \( f(h) \) be
\( f(h) = h^\nu \sum_j W(r_{ij}, h_i) - \eta^\nu \)
It has an analytic derivative:
\( \frac{\partial f(h)}{\partial h} = \nu h^{\nu-1} \sum_j W(r_{ij}, h_i) + h^\nu \sum_j \frac{\partial W(r_{ij}, h_i)}{\partial h} \)
With an analytic function and its derivative, we make use of the Newton-Raphson iterative root finding method to find the \(h\) for which \( f(h) = 0 \).
Definition at line 6 of file SmoothingLength.cpph.
References _log, std::abs(), assertion4, assertion9, f(), kernel_root, logError, logWarning, swift2::kernels::legacy::hydroDimensions::pow_dimension(), temp, and wcount.
Referenced by updateSmoothingLengthAndRerunIfRequired().
void swift2::kernels::legacy::hydroPredictExtra | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 73 of file Leapfrog.h.
References hydro_predict_extra(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by hydroPredictExtraWithMasking().
void swift2::kernels::legacy::hydroPredictExtraWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 84 of file Leapfrog.h.
References hydroPredictExtra().
void swift2::kernels::legacy::leapfrog_drift_global_time_step_size | ( | Particle * | particle | ) |
Update a particle with the leapfrog KDK integrator.
The code should invoke this routine only in touchVertexLastTime(). It should never change the particle position throughout the mesh traversal, as it might introduce inconsistent particle data structure.
We do not update all particles but merely those which are labelled as local. Virtual particles are mere copies from another tree. We should not alter their states or positions. Any neighbour who is in charge of the particle should do this, and we then expect such a rank to send over a new copy. Drift step.
In this, we move the particles by a full time-step using:
\( {\bf x}^{n+1} = {\bf x}^{n} + {\bf v}^{n+1/2}{\Delta t} \)
Notice that this operation modifies the particle topology and hence particles must be re-sorted before further operations can be executed.
It's important to take the "V_full" here, not the fluid velocity V. V_full doesn't get touched outside of kicks. V will be interpolated/ integrated in time as the time step progresses. V_full is the correct choice here.
Note that original SWIFT predicts the velocities at this point. We moved that into hydroPredictExtra().
Definition at line 11 of file Leapfrog.cpph.
References assertion1, and tarch::la::isEntryFinite().
Referenced by leapfrogDriftWithGlobalTimeStepSize().
void swift2::kernels::legacy::leapfrog_kick_global_time_step_size | ( | Particle * | particle | ) |
Kick steps.
There are two kick steps in the KDK scheme, in which we update the particle velocity by a half-timestep using:
Kick1: \( {\bf v}^{n+\frac{1}{2}} = {\bf v}^{n} + {\bf a}^{n}\frac{\Delta t}{2} \)
Kick2: \( {\bf v}^{n+1} = {\bf v}^{n+\frac{1}{2}} + {\bf a}^{n+1}\frac{\Delta t}{2} \)
Additionally, thermal quantities are being updated. In the case of "Minimal" SPH, we update
Kick1: \( {u}^{n+\frac{1}{2}} = u^{n} + \frac{\partial u}{\partial t}^{n}\frac{\Delta t}{2} \)
Kick2: \( {u}^{n+1} = u^{n+\frac{1}{2}} + \frac{\partial u}{\partial t}^{n+1}\frac{\Delta t}{2} \)
The update of thermal quantities has been separated into hydro_kick_extra_global_time_step_size as it depends on the SPH flavour used, and needs to be replaceable.
Notice that the last kick in this sequence is implicit if \({\bf a}\) depends on \({\bf v}\) (e.g. due to artificial viscosity terms), which in principle requires extra treatments (see e.g. Price et al. 2017).
While the time integration scheme should be kick1 - drift - kick2, we do a slightly different sequence. First, we do a kick1 during initialization. Then every subsequent normal simulation step does a drift - kick2 - kick1 sequence. The reason for that is to permit individual time step sizes for individual particles: By starting the particle time step with a drift, we can always drift neighbours to their correct positions, even when they are inactive (= not being updated in the current step). The drifts are linear operations which in principle can be concatenated in any number, provided the total time a particle is being drifted sums up to the correct value. So for example, it should be equivalent to compute
\( K_1(\Delta t/2) \circ D(\Delta t) \circ K_2(\Delta t/2) \)
or
\( K_1(\Delta t/2) \circ D(\Delta t/4) \circ D(\Delta t/4) \circ D(\Delta t/4) \circ D(\Delta t/4) \circ K_2(\Delta t/2) \).
Once the kick2 operation is complete, the "predicted" values stemming from the "prediction" step in hydro_predict_extra() after a drift need to be reset to up-to-date current values that the particle carries. So after a kick2, we reset them using hydro_reset_predicted_values().
So in total, there are two additional steps that you have to add afterwards.
This version is tailored towards the SPH time integration, where we access additional particle fields which are otherwise not present, such as the time derivative of the internal energy.
Definition at line 89 of file Leapfrog.cpph.
References hydro_kick_extra_global_time_step_size().
Referenced by leapfrogKickWithGlobalTimeStepSize().
void swift2::kernels::legacy::leapfrogDriftWithGlobalTimeStepSize | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 54 of file Leapfrog.h.
References leapfrog_drift_global_time_step_size(), and swift2::kernels::localParticleCanBeUpdatedAndMovedInVertexKernel().
Referenced by leapfrogDriftWithGlobalTimeStepSizeWithMasking().
void swift2::kernels::legacy::leapfrogDriftWithGlobalTimeStepSizeWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 93 of file Leapfrog.h.
References leapfrogDriftWithGlobalTimeStepSize().
void swift2::kernels::legacy::leapfrogKickExtraWithGlobalTimeStepSize | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 188 of file Leapfrog.h.
References hydro_kick_extra_global_time_step_size(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by leapfrogKickExtraWithGlobalTimeStepSizeWithMasking().
void swift2::kernels::legacy::leapfrogKickExtraWithGlobalTimeStepSizeWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
@Todo No masking yet
Definition at line 198 of file Leapfrog.h.
References leapfrogKickExtraWithGlobalTimeStepSize().
void swift2::kernels::legacy::leapfrogKickWithGlobalTimeStepSize | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 157 of file Leapfrog.h.
References leapfrog_kick_global_time_step_size(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by leapfrogKickWithGlobalTimeStepSizeWithMasking().
void swift2::kernels::legacy::leapfrogKickWithGlobalTimeStepSizeWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 167 of file Leapfrog.h.
References leapfrogKickWithGlobalTimeStepSize().
void swift2::kernels::legacy::predict_hyrdro | ( | Particle * | particle | ) |
Predict hydro terms (SWIFT) Relevant for inactive particles when using local-timestepping, but always used.
Referenced by predictHydro().
void swift2::kernels::legacy::predictHydro | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 270 of file HydroForce.h.
References swift2::kernels::localParticleCanBeUpdatedInVertexKernel(), and predict_hyrdro().
void swift2::kernels::legacy::prepareDensity | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Prepares a particle for the density calculation.
Definition at line 19 of file Density.h.
References hydro_init_particle(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by prepareDensityWithMasking().
void swift2::kernels::legacy::prepareDensityWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 33 of file Density.h.
References prepareDensity().
void swift2::kernels::legacy::prepareHydroForce | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 28 of file HydroForce.h.
References hydro_prepare_force(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by prepareHydroForceWithMasking().
void swift2::kernels::legacy::prepareHydroForceWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 42 of file HydroForce.h.
References prepareHydroForce().
void swift2::kernels::legacy::resetAcceleration | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 59 of file HydroForce.h.
References hydro_reset_acceleration(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by resetAccelerationWithMasking().
void swift2::kernels::legacy::resetAccelerationWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 74 of file HydroForce.h.
References resetAcceleration().
void swift2::kernels::legacy::resetPredictedValues | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 210 of file Leapfrog.h.
References hydro_reset_predicted_values(), and swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by resetPredictedValuesWithMasking().
void swift2::kernels::legacy::resetPredictedValuesWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 220 of file Leapfrog.h.
References resetPredictedValues().
void swift2::kernels::legacy::resetSmoothingLengthIterationCounter | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | particle ) |
Reset smoothing length iteration related flags on a particle.
Definition at line 111 of file SmoothingLength.h.
References swift2::kernels::localParticleCanBeUpdatedInVertexKernel().
Referenced by resetSmoothingLengthIterationCounterWithMasking().
void swift2::kernels::legacy::resetSmoothingLengthIterationCounterWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | particle ) |
At this point, we just reset some flags and counters that are only required during a single time step.
So we don't need to pass any checks whether to work on a particle.
Definition at line 128 of file SmoothingLength.h.
References resetSmoothingLengthIterationCounter().
void swift2::kernels::legacy::updateSmoothingLengthAndRerunIfRequired | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Wrapper around hydro_update_smoothing_length_and_rerun_if_required() with only one argument.
Further to that, it also adds some consistency checks as discussed in the context of genericalgorithm remarks".
Definition at line 73 of file SmoothingLength.h.
References assertion2, hydro_update_smoothing_length_and_rerun_if_required(), swift2::kernels::localParticleCanBeUpdatedInVertexKernel(), and tarch::la::min().
Referenced by updateSmoothingLengthAndRerunIfRequiredWithMasking().
void swift2::kernels::legacy::updateSmoothingLengthAndRerunIfRequiredWithMasking | ( | const peano4::datamanagement::VertexMarker & | marker, |
Particle & | localParticle ) |
Definition at line 100 of file SmoothingLength.h.
References updateSmoothingLengthAndRerunIfRequired().