In this tutorial on FXGear FluX I will show you how to create a simple waterfall.
Let’s start by creating a new project: File->New Project or Ctrl+N.
First, let’s import the proxy geometry of our cliff. Create a Cache node, set its option to Read Files mode and choose your geometry sequence:
Set the Interpolation mode to On. Create a MeshShape node, connect the output outData of the Cache node to the input inDstMesh of the MeshShape node to see the geometry in a viewport (press refresh button on a playback panel in a right bottom corner).
The next step is to fit our Container according our geometry. Select GlobalNode and set your CellSize and Resolution to make the Container around the mesh.
Now we are ready to build fluid system.
Create a Particle node from the Primitive. By defaults the Particle node will be connected with global values from Global node.
Create a FluidContainer node from the Primitive. By defaults FluidContainer will be connected to Global node and will inherit the data, such as CellSize, Resolution and SubdomainDimension. And MaxBufferSize will be gone. Then, create a GetMaxSpeed node from the Field. Connect the output VectorField of the FluidContainer node to the input VelocityField of the GetMaxSpeed node.
Then, create a ComputeTimeStep node from the Misc. Connect the output MaxSpeed of the GetMaxSpeed node to the input MaxSpeed of the ComputeTimeStep node.
Ok, the basic Fluid Container and Particle Primitive are created, now we need to create a stream of particles which will be our waterfall.
To create this we will use the EmitParticleFromBox node from the Particle.
TIP: Because the standard particle emitter is invisible and we can’t see where the particles as long as they are not cached, I will use a BoxShape node, to visualize the size and location of the emitter.
So, I used the BoxShape node to find a better location for the emitter. To submit our data about the position and volume of the box in the emitter, connect the output outBoxMinPosition of the BoxShape node to the input inBoxMinPosition of the EmitParticleFromBox node, then connect the output outBoxMaxPosition of the BoxShape node to the input inBoxMaxPosition of the EmitParticleFromBox node. The next is to connect output outDT of the ComputeTimeStep node to the input DT of the EmitParticleFromBox node.
Our emitter is ready. The main controls of the EmitParticleFromBox node:
Rate –The number of generated particles per time step;
Radius - The radius of particles in 'Emitter' will be added to be used later but it doesn't affect at all currently.
InitialVelocity –The initial velocity of the particles in X/Y/Z axis.
Set your desired parameters and let’s go for further steps.
Add the VARSolver node from the Particle:
Connect the output outParticle node of the EmitParticleFromBox node to the input inParticle of the VARSolver node.
Connect the output VectorField of the FluidContainer node to the input inVelocityField of the VARSolver node.
Connect the output SolidVectorField of the FluidContainer node to the input SolidVelocityField of the VARSolver node.
To complete the connections with VARSolver, we should to convert our imported mesh to level set. Then we will have a possibility to use our mesh as a solid level set (that will identify that we have a collisions in our simulation).
Create a MeshToLevelSet node from Converter.
Connect the output outData of the Cache node to the input Mesh of the MeshToLevelSet node.
Connect the output LevelSet of the MeshToLevelSet node to the input SolidLevelSet of the VARSolver.
Connect the output outData of the Cache node to the input SolidMesh of the VARSolver node.
Connect the output OutDT of the ComputeTimeStep node to the input DT of the VARSolver node.
Next, create a CollideParticleToMesh node from Particle:
The main parameters of the CollideParticleToMesh node:
Elasticity – how strong particles will bounce from geometry;
Friction – how strong particles will frictionize on geometry;
MaxIteration – number of the collision iterations.
Connect the output outData of the Cache node to the input Mesh of the CollideParticleToMesh node.
Connect the output outParticle of the VARSolver node to the input inParticle of the CollideParticleToMesh node.
Connect the output outDT of the ComputeTimeStep node to the input DT of the CollideParticleToMesh node.
Next step is to create a particles kill helper at the bottom of the container to avoid its filling by particles.
As usual I used the BoxShape node to find a better location for the volume, which I will use for particles dying. Next, I sent position parameters to the ImplicitBox node and used it as a Level Set in the RemoveParticleByLevelSet node from Particle:
Connect the output outParticle of the CollideParticleToMesh node to the input inParticle of the RemoveParticleByLevelSet node.
Connect the output LevelSet of the ImplicitBox node to the input LevelSet of the RemoveParticleByLevelSet node.
So, our scene is ready for simulation. All we need to do is just to create a node to cache our particles to hard drive and one node to draw particles in the viewport.
Create the Cache node from File:
Enter the path for cache files in FileName, for example:
Your disc://your project folder/Cache/Waterfall.%4d.%4d.fxp
Double padding.% 4d.% 4d.fxp is required for the simulation on multiple cores.
Option mode ‘Write Files’ to write files to the disk, and in the mode ‘Read Files’, will read files from disc.
Connect the output outParticle of the RemoveParticleByLevelSet node to the input inData of the Cache node.
Connect the output outDT of the ComputeTimeStep node to the input DT of the Cache node.
Now, create a ParticleShape node from the Shape to display the particles in the viewport:
Connect the output outData of the Cache node to the input inDstParticle of the ParticleShape node.
Click the Refresh button on the Playback panel to create particles in the first frame of the simulation and display them in the viewport.
Created particles in a given frame is already cached on the hard drive.
For the simulation using a single core of your computer, use the Play button of the Playback panel.
To use multithreading - use MPI Simulation of the Server Setting Window, using the Local Mode for simulation on the local computer:
If you are using a large amount of particles and the simulation is performed through MPI Simulation, it is recommended to disable Auto Read, so as not to overload the viewport.
After completing the simulation, make sure that the Cache node is set to 'Read Files'.
SubDomainList will be automatically determined based on the number of cores involved in the simulation.
That is all,
Written by Mikhail Korovyansky