Integration of FLUIDS v.2 (SPH Fluids)

rtrius
Posts: 43
Joined: Sat May 26, 2012 1:09 am

Re: Integration of FLUIDS v.2 (SPH Fluids)

Post by rtrius »

Found the issue with the contact point recalculation. I forgot that the broadphase adds rigid bodies
with intersecting AABBs to each btFluidSph. If internalClearRigidContacts() is called, it will also clear
those AABBs so that there is no input to the narrowphase.

Try replacing:
m_fluidSph->internalClearRigidContacts();
with:
m_fluidSph->internalGetRigidContacts().clear();

As a more efficient alternative, I've also added a mid-tick callback.


The 'invalid type conversion' error is due to the fact that btFluidSph::getSolverData() returns const void*
and the static_cast cannot remove const; add const to the pointer types to fix it.

Each particle has a neighbor table, so the loop would access solverData->m_neighborTable.
getNeighborIndex() is called on each entry in the neighbor table( btFluidSphNeighbors::size() ),
so a different index(not i) would be used to loop through it. In the example and also in much of
the BulletFluids code, i and n are used as indices for fluid particles.

If the 'distance-vector' to other particles is needed, it would need to be recalculated. Additionally,
the performance benefit over using surface tension would be much less. Currently, the surface tension
increases the time for each frame by a factor of ~1.5x on the CPU. Using a cheaper method might increase
the frame time by ~1.1-1.2x.

Code: Select all

btFluidSphSolverDefault::SphParticles* solverData = static_cast<btFluidSphSolverDefault::SphParticles*>(m_fluidSph->getSolverData());    //add const to pointers

btAlignedObjectArray<int> numParticlesInSphRadius;   //1 entry per particle
for(each particle)   //index i
{
   const btFluidSphNeighbors& table = solverData->m_neighborTable[i];
   for(each entry in neighbor table)    //index j
   {
      int n = table.getNeighborIndex(j);

      //Each entry in the neighbor table contains a pair of particles
      //(for neighbor table of particle i, index i is implicit)
      numParticlesInSphRadius[i] += 1;
      numParticlesInSphRadius[n] += 1;
   }
}
Rvo
Posts: 21
Joined: Fri Nov 01, 2013 1:44 pm

Re: Integration of FLUIDS v.2 (SPH Fluids)

Post by Rvo »

Thanks for the explanations and code update. As for performance, for your library I can understand you'd want most performance possible for your methods. However for my personal goals I'd just like to do a quick fix for my sticky force and some 'clumping' of the fluid. Since each entry in the neighbor table contains a pair of particles, can I just ask the position of those 2 particles via fluid->getPosition(index) and calculate their distance vectors? I think I can, but yeah, maybe there's something wrong about doing it there in the whole update()-loop. It's nowhere better than any semi-optimized surface tension method but since I'm experimenting this is also something I can bring up in my findings.

I will take a look at the mid-tick and see how that works out for the latest hitpoints for the particles :)
-Edit: did that and looks good, doing the narrowphase in there now, doesn't slow it down too much -

I know we discussed the following before but I'm a bit puzzled.

I set the simulation scale by doing the following:

Code: Select all

btFluidSphParametersGlobal FG = m_fluidWorld->getGlobalParameters();
FG.m_simulationScale *= (1/PARTICLE_RADIUS);
Now the following results for PARTICLE_RADIUS set as 0.25f and 0.125f (so the latter half the size of the first) are:
Image
Image
Now, I've not changed anything about the initial settings just to make sure. The boundary is large enough, as you can see in the first image. I'm just adding a volume of particles to the scene, nothing special, via sphFluid->addVolume(). The simulation scale for the 0.125f particle radius is acting quite odd(?) compared to the 0.25f particle radius. The added volume depends on the parameters I give, this is when all the particles are stacked in a single rows on top of eachother like 50x50x1 (similar as in the image). I'd expect them to be able to go sideways but they don't. If I add a volume for particles with 0.125f radius in a volume like 50x50x2 then they "fall apart" again like in the first image. It's not really a deal breaker but it's kind of odd to see it happen, to me anyways.
rtrius
Posts: 43
Joined: Sat May 26, 2012 1:09 am

Re: Integration of FLUIDS v.2 (SPH Fluids)

Post by rtrius »

The mid-tick callback is called right after the contacts are computed, so the call to
performNarrowphase() can be avoided.

Using fluid->getPosition() with the neighbor table is fine. Since the neighbor table contains pairs,
the result for both particles should be computed in each iteration of the loop. That is, create an
array initialized to (0,0,0) and add the 'distance vector' to both particles during each iteration.

If both the positions and velocities of particles are perfectly aligned with a plane, as in the last
image, then the SPH force will also be confined to that plane. For example, if the positions and
velocities are (0, y, z) then the SPH force will also be (0, y, z) and the particles will not separate
unless a force is applied or the particles touch another particle that is not in the plane. It should
not be related to the simulation scale.
Rvo
Posts: 21
Joined: Fri Nov 01, 2013 1:44 pm

Re: Integration of FLUIDS v.2 (SPH Fluids)

Post by Rvo »

Hey rtrius,

Any chance you could elaborate on the surface tension you implemented (in the documentation perhaps)? I've done my own version but it's nice to experiment with your implementation as well.

Thanks!
rtrius
Posts: 43
Joined: Sat May 26, 2012 1:09 am

Re: Integration of FLUIDS v.2 (SPH Fluids)

Post by rtrius »

The surface tension method in the repository is based on the paper
"Versatile Surface Tension and Adhesion for SPH Fluids"(2013), which can be found at:
http://cg.informatik.uni-freiburg.de/publications.htm
(btFluidSphLocalParameters.m_surfaceTension == gamma of equations 1 and 3 in the paper)

Another good resource is "Lagrangian Fluid Dynamics Using Smoothed Particle Hydrodynamics"
(see page 24 in particular): http://image.diku.dk/projects/media/kelager.06.pdf


To give a short explanation, the surface tension force as described in the paper is a
combination of 2 forces: a cohesion force and a curvature force. The cohesion force is
just a force that causes particles to attract, but the curvature force is a bit more complicated.

The curvature force acts to minimize the surface area of the fluid. It does this by defining a scalar
field, called the 'color field' that is 1 at SPH particles and 0 elsewhere. When SPH is used to
approximate the gradient of this color field, the result is that each SPH particle near the surface of
the fluid has a vector that points inwards(towards the fluid), while each particle that is inside the
fluid(completely surrounded by particles) has a vector that is 0 or near 0. By applying a force that
is roughly the same as the color field gradient(see eq. 3 in the paper), the particles are pushed together
until a sphere/ellipsoid is formed, as that shape causes the curvature forces to balance out.