In this tutorial on FXGear FluX I want to show you how to create a breaking dam.
Let's start by creating a new project: File -> New Project (Ctrl+N)
In the appeared window, enter a name for the project and the path in which the project will be:
Once all of the data and the project are created, you can create the basic simulation. To start, double click on the Global node.
Global node is the core of it and will build our logical tree. The main parameters of the Global node:
CFL – “Courant–Friedrichs–Lewy condition”. The CFL condition relates the length of the time step to a function interval lengths of each spatial variable.
CFL determines the sub step value in one frame. For example, if the CFL value is 2, and the instant maximum travel distance of the particle is 6 times of the grid cell size, 6/2=3 times the sub step is to turn. It is good to set the CFL value small for the accurate simulation, but the simulation time will increase. Therefore, it is necessary to determine the appropriate value of CFL.
In the case of VAR Solver, The CFL dependence of the simulation accuracy is low so the CFL value may be set high (CFL more than 10)
FrameRate – The number of frames per second (FPS)
(The higher the Frame Rate, you can get the result of the high-speed filming effect)
CellSize – The size of each individual cell (voxel), the main component of the container.
Resolution – Resolution container (size).
(The higher the simulation resolution, you can get more detailed result. However, a lot of time and memories are required.)
StartFrame/EndFrame – the first frame of the simulation \ the last frame of the simulation
Let's set the desired size of the container, while leaving the rest of the default settings:
Change the Resolution size of X and Y to 40. This will increase the length and the height of the container:
After changing the parameters of the container, click on the viewport to see the changes. The container is longer and higher, as we asked.
Next, create a particle emitter.
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, let's create a BoxShape node from the Shape in NodeGraphEditor:
We define the location and the volume that we will give to the main emitter, in a following graphs:
inBoxMinPosition – minimum input (start) position X, Y, Z.
inBoxMaxPosition – maximum input (final) position X, Y, Z.
Both of these parameters describe the volume of a cube, set the following options:
inBoxMinPosition -> 0, 0, 0 (for X, Y, Z, respectively)
inBoxMaxPosition -> 1, 2, 3 (for X, Y, Z, respectively)
In the viewport you will see that the cube has acquired a value from 0 to 1 in length from 0 to 2 in height, and from 0 to 3 in width. That is properly sized for the main grid.
Once we have determined the position, we need to pass these same values in the output data, so they can be passed on to future emitter. This is done in columns:
outBoxMinPosition – output minimum (starting) position X, Y, Z.
outBoxMaxPosition – maximum output (final) position X, Y, Z.
Just repeat the previously entered parameters:
outBoxMinPosition -> 0, 0, 0 (for X, Y, Z, respectively).
outBoxMaxPosition -> 1, 2, 3 (for X, Y, Z, respectively).
Now when we have defined the main container size and position of the particle emitter, move on to building a logical chain that will make our simulation.
Let's create a particle emitter, adding an ImplicitBox node from the Primitive:
By default, the created node will be assigned to the main parameters of the Global node.
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 ImplicitBox node, then connect the output outBoxMaxPosition of the BoxShape node to the input inBoxMaxPosition of the ImplicitBox node.
Double-click the ImplicitBox node. You will see that you can’t change the minimum and the maximum positions, because they are link and inherit all the parameters which we passed from the BoxShape node.
Our emitter ready.
Create a Particle node from the Primitive.
By defaults the Particle node will be connected with global values from Global node.
The next step should be to add a series of nodes that will be our main container with the fluid velocity vectors, with the specified TimeStep.
Create a FluidContainer node from the Primitive:
By defaults FluidContainer will be connected to the Global node and will inherit the data, such as CellSize, Resolution and SubdomainDimension.
The MaxBufferSize parameter disappears.
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.
So we have created a series of three nodes that allow us to create a flow of particles. Now we are ready to go to the settings of the particles.
Add the EmitParticleFromLevelSet node from the Particle:
The main parameters of the EmitParticleFromLevelSet node:
Density – the number of particles per voxel
Depth – means the depth limited value of the creating particles. For example, if the depth is 2, the particles will be created only the depth of 2 times bigger the grid cellsize from the surface of liquid.
StartFrame – starting frame of the simulation
RepeatInterval –RepeatInterval – repeatedly creates particles as interval. If its value is 0, particles will be created only in first time. 1 = every frame. 4 = every 4th frame.
SurfaceDetail –SurfaceDetail – determines the particle density at the surface of the water. For example, if the value is 2, the number of particles at the surface of the water will be 2 times bigger than the particles inside the water.
The parameter is changed.
EmitDirection – an emitting direction of created particles.
EmitDirectionRandomRadius – adds a random element to particle emit direction. If the value is small, the emit direction of the particles will become uniform, and if the value is big, the emit direction of the particles will become random.
UseGradient – determines the emit direction to the graident direction if Levelset.
GradientScale – scales the speed value of the gradient direction of LevelSet.
Connect the Particle output of the Particle node to the input inParticle of the EmitParticleFromLevelSet node, then connect the output LevelSet of the ImplicitBox node to the input inLevelSet of the EmitParticleFromLevelSet node and finally connect the output outDT of the ComputeTimeStep node to the input DT of the EmitParticleFromLevelSet node.
The next step is to add the solver for computing the flow of particles:
Add the VARSolver node from the Particle:
The main parameters of the VARSolver node:
ParticleRadius – the radius of the particle
ParticleRadius – means the particle radius of influence and the value that is based on the cell size. The bigger the value, the simulation speed decreases, and the motion of the particles tend to be equalized.
SolidVelocityScale – speed multiplier with respect to the object of the collisions.
ParticleDrag – the value of drag force.
DensityDependentDrag – the amount of the drag force of the dense areas of the simulation.
Gravity – magnitude of the force of gravity.
Connect the output outParticle node of the EmitParticleFromLevelSet 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.
Connect the output SolidLevelSet of the FluidContainer node to the input SolidLevelSet of the VARSolver node (in our case, we do not have an object for the collisions and the container will perform its function, otherwise, if we have imported object for the collisions, we will use it for setting SolidLevelSet of the VARSolver node).
Connect the output OutDT of the ComputeTimeStep node to the input DT of the VARSolver node.
As part of this tutorial, I'll demonstrate how to create an animation curve, which I will use to control Drag force in VARSolver node.
To do this, create a KeyBezierInterpolation node from the Channel:
For creating animated values, I used the following parameters:
NumOfValue – number of the keys of animation
ActiveValue(1-5) – value of the animated parameter in the key animation
Frame(1-5) – frame number for the key of animation
I have created an animation curve which increases the strength of the drag force from 0 in the frame 15 to 0.015 in the frame 25 and then decreases again to the value of 0 in frame 30.
Connect the output InterpolatedValue of the KeyBezierInterpolation node to the input ParticleDrag of the VARSolver node.
Now we have to create a node that will cache our particles to the hard disk and node to display the particles in the viewport.
Create a Cache node from File:
Enter the path for cache files in FileName, for example:
Your disc://your project folder/Cache/BreakingDam.%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 VARSolver 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.
TIP: The output DT of the ComputeTimeStep node can be connected at the end of building your tree of simulation. By clicking on the DT output you will see all the inputs for connection.
Now, create a ParticleShape node from the Shape to display the particles in the viewport:
Let’s set the R/G/B = 0.1/0.2/1.0
This will draw our particles in a blueish color.
MaxSpeed parameter specifies how the gradient distributed from blue to white, depending on the maximum flow rate of particles.
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.
Now you can see how the particles are arranged in exactly the right volume:
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 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