Creating Scenes

Loading the empty scene

Right now the easiest way to create a custom scene without specifying a Scene.json file, is to load the predefined empty scene.

import pysplishsplash as sph
import pysplishsplash.Utilities.SceneLoaderStructs as Scenes

base = sph.Exec.SimulatorBase()
base.init(sceneFile=Scenes.Empty)

This scene will set the default simulation method to be DFSPH and some other default values, which can all be changed later on.

Recreating the double dam break scenario

In order to recreate the double dam break scenario, we need to add a bounding box as well as two fluid cubes. The bounding box can be added as follows

scene = base.getScene()
scene.boundaryModels.append(Scenes.BoundaryData(meshFile="../models/UnitBox.obj", translation=[0., 3.0, 0.], scale=[4., 6., 4.], color=[0.1, 0.4, 0.5, 1.0], isWall=True, mapInvert=True, mapResolution=[25, 25, 25]))

The two fluid blocks can at the end be added using

scene.fluidBlocks.append(Scenes.FluidBlock(id='Fluid', box=Scenes.Box([-1.5, 0.0, -1.5], [-0.5, 2.0, -0.5]), mode=0, initialVelocity=[0.0, 0.0, 0.0]))
scene.fluidBlocks.append(Scenes.FluidBlock(id='Fluid', box=Scenes.Box([0.5, 0.0, 0.5], [1.5, 2.0, 1.5]), mode=0, initialVelocity=[0.0, 0.0, 0.0]))

This will recreate a somewhat larger scene than the default double dam break.

Putting it all together

The following shows a script detailing how to build and run a custom double dam break. Follow the instruction from before to activate/ deactivate the GUI.

import pysplishsplash as sph
import pysplishsplash.Utilities.SceneLoaderStructs as Scenes

def main():
    # Set up the simulator
    base = sph.Exec.SimulatorBase()
    base.init(useGui=True,  sceneFile=sph.Extras.Scenes.Empty)

    # Create a simulator
    gui = sph.GUI.Simulator_GUI_imgui(base)
    base.setGui(gui)

    # Get the scene and add objects
    scene = base.getScene()
    scene.boundaryModels.append(Scenes.BoundaryData(meshFile="../models/UnitBox.obj", translation=[0., 3.0, 0.], scale=[4., 6., 4.], color=[0.1, 0.4, 0.5, 1.0], isWall=True, mapInvert=True, mapResolution=[25, 25, 25]))
    scene.fluidBlocks.append(Scenes.FluidBlock(id='Fluid', box=Scenes.Box([-1.5, 0.0, -1.5], [-0.5, 2.0, -0.5]), mode=0, initialVelocity=[0.0, 0.0, 0.0]))
    scene.fluidBlocks.append(Scenes.FluidBlock(id='Fluid', box=Scenes.Box([0.5, 0.0, 0.5], [1.5, 2.0, 1.5]), mode=0, initialVelocity=[0.0, 0.0, 0.0]))

    # Run the GUI
    base.run()

if __name__ == "__main__":
    main()

Changing parameters of the simulation

The command base.run() at the end of the example above is a shortcut for the commands:

   base.initSimulation()       # init simulation, fluid models, time step, ...
   base.runSimulation()        # start the simulation
   base.cleanup()              # cleanup everything after the simulation

If you want to change the parameters of the fluid model or the simulation, you first have to initialize the scene. Therefore, exchange base.run() by the three commands above. Then, you can change the parameters after the call of base.initSimulation().

Here is an example:

    base.initSimulation()

    # change rest density of first fluid model
	fluid = sim.getFluidModel(0)
	fluid.setValueFloat(fluid.DENSITY0, 800.0)

    # change viscosity coefficient
    visco = fluid.getViscosityBase()
	visco.setValueFloat(visco.VISCOSITY_COEFFICIENT, 0.015)

    base.runSimulation()
    base.cleanup()

Loading a scene from file

Loading a scene from a file is as simple as simply specifying a custom scene file in the init function. This must be an absolute path!

custom_scene = os.path.abspath("scene.json")
base.init(sceneFile=custom_scene)

If you want to use a gui to locate the scene file you may want to use tkinter

import tkinter as tk
from tkinter import filedialog

tk.Tk().withdraw() # Dont show main window
custom_scene = filedialog.askopenfilename()
base.init(sceneFile=custom_scene)