Batch Processing in Paraview¶
Batch processing is the automated processing of data without user intervention. This may occur on a local desktop machine or on a remote server, where jobs are submitted and managed through command-line access via SSH. Batch processing output data can lend itself to highly efficient work flows and eliminate repeated manual processing using GUI tools.
Quick Start¶
This section will quickly get you started with batch processing M-Star results using Paraview. A ready-to-run script is provided so you can immediately get started. This script automatically processes all slice data and outputs images for available data from the last time step.
Prerequisites¶
M-Star simulation results have been created in a directory called
out.Paraview is installed.
Guide¶
Download
this paraview scriptand place it in a case directory.Find the Paraview install path, and make note of the full path to the
/path/to/paraview/bin/pvpythonexecutable.Open a new command prompt or terminal and navigate to your case directory that contains the solver input files and
outdirectory.Run the following command. Replace the pvpython path with your Paraview install location noted from step (2).
/path/to/paraview/bin/pvpython post_slices.py
You should see some output from the script as it is running.
Results are output to a directory
out/Renders.
Bare Bones Script¶
This section will provide a minimal starting script for your own development. Additional explanation is given about Paraview scripting itself and general concepts.
Setup¶
First you will need to import the paraview.simple python module and create a view:
from paraview.simple import *
view = CreateRenderView()
view.ViewSize = (600,400)
Loading and Showing Data¶
The following code loads in a out/Output/SliceY_0.250.pvd data file and shows it in the rendering view. The field_reader is a Paraview source proxy. It handles loading the data into the Paraview pipeline. A field_display variable is returned from the Show call. This object can be used to change how the object is displayed. This same pattern is used for all Paraview pipeline objects.
field_reader = PVDReader(FileName="out/Output/SliceY_0.250.pvd")
field_display = Show(field_reader, view)
Adding a Text Annotation¶
To further illustrate the data and display property object pairing, we have created a text object and displayed it in the view. The field_text is the Paraview pipeline object that handles the data, in this case a text string Velocity. The field_text_display variable returned from the Show call can be used to change the font size and position in the render view.
field_text = Text(Text="Velocity")
field_text_display = Show(field_text, view)
field_text_display.FontSize = 12
field_text_display.WindowLocation = "LowerLeftCorner"
Handling the Camera Position¶
The camera position determines the perspective of the displayed view. This can be tricky to get exactly right. In our example, the camera is positioned above the 3D slice. By default, the camera “focal point”—what the camera is pointed at—is (0,0,0), so we do not need to change it here. The ResetCamera function makes sure the entire scene is visible in the view. By default, the 3D rendering view camera uses a perspective mode. This type of view attempts to convey 3D scene depth by making close objects appear larger using a vanishing point at a finite distance.
camera = view.GetActiveCamera()
camera.SetPosition(0,1,0)
ResetCamera(view)
Coloring Slices by Field Data¶
This is a main reason we go to all the effort to load our data into Paraview. We want to see it colored by a specified color scale to show flow structures or help us understand complex flow problems. The general approach to field coloring is to first change to the last time step, create our coloring scale from that data range, and apply our desired color scale.
Here we are coloring by velocity magnitude, which is associated with the cell Paraview data. Most M-Star data will output data as cell-centered, so you typically want to show coloring by cell centers. The “GetColorTransferFunction” returns the color scale itself for a given data channel. Here we instruct Paraview to use the Viridis color scale. The selection of color scale can be a topic of discussion all on its own. The Viridis color scale was developed by visualization experts and tends to look good. It also has the advantage of being accessible by color-blind individuals.
Finally, the color bar itself is added to the 3D window. Positioning, font, and sizing can all be controlled by interacting with the “bar” variable here.
# Change to last time before creating the color scale
view.ViewTime = field_reader.TimestepValues[-1]
Render()
# Color the field data by a given cell data channel
ColorBy(rep=field_display, value=("CELLS", "Velocity Magnitude (m/s)"))
# Change the coloring preset to use the "Viridis" preset.
lt = GetColorTransferFunction("Velocity Magnitude (m/s)", field_display)
lt.ApplyPreset("Viridis (matplotlib)", True)
# Add the color scalar bar to the view
bar = CreateScalarBar(LookupTable=lt)
view.Representations.append(bar)
Interacting with Time¶
To change the time shown in the rendering window, set the view.ViewTime field to the specified time. The available times can be accessed on the source data itself. Here we are using the last time step available. After changing the time step, you must call Render.
view.ViewTime = field_reader.TimestepValues[-1]
Render(view)
Saving Rendered Images¶
Once you have set up the rendered view, you can save the image to disk. It is good practice to specify the image resolution explicitly, as we have done here. This allows arbitrary-sized images to be created. In the following code, we are preserving the aspect ratio of the rendering view window, and outputing a large image with a width of 1080 pixels. This approach will help avoid upscaling low resolution images. Instead we will have larger images which will get downsampled when embedded in presentations or reports.
# Specify the output size of the images
aspect_ratio = float(view.ViewSize[1]) / float(view.ViewSize[0])
output_width = 1080
output_height = int(aspect_ratio * output_width)
SaveScreenshot("image.png", view, ImageResolution=(output_width, output_height))
Full Bare Bones Script¶
from paraview.simple import *
# This is the rendering view where the visualization appears
view = CreateRenderView()
view.ViewSize = (600,400)
# Load in the static walls stl file
stl_reader = STLReader(FileNames="out/Output/Walls.stl")
stl_display = Show(stl_reader, view)
stl_display.Representation = "Surface"
stl_display.Opacity = 0.2
# Load in the moving body PVD file
solid_reader = PVDReader(FileName="out/Output/SliceMovingBody_Moving Body.pvd")
solid_display = Show(solid_reader, view)
# Load in the field data file
field_reader = PVDReader(FileName="out/Output/SliceY_0.250.pvd")
field_display = Show(field_reader, view)
# Add a simple time annotation
annotime = AnnotateTimeFilter(Input=field_reader)
annotime_display = Show(annotime, view)
annotime_display.FontSize = 12
# Add a simple text annotation
field_text = Text(Text="Velocity")
field_text_display = Show(field_text, view)
field_text_display.FontSize = 12
field_text_display.WindowLocation = "LowerLeftCorner"
# Change the camera to look at the Y plane and then fit the view to the displayed data
camera = view.GetActiveCamera()
camera.SetPosition(0,1,0)
ResetCamera(view)
# Change to last time before creating the color scale
view.ViewTime = field_reader.TimestepValues[-1]
Render()
# Color the field data by a given cell data channel
ColorBy(rep=field_display, value=("CELLS", "Velocity Magnitude (m/s)"))
# Change the coloring preset to use the "Viridis" preset.
lt = GetColorTransferFunction("Velocity Magnitude (m/s)", field_display)
lt.ApplyPreset("Viridis (matplotlib)",True)
# Add the color scalar bar to the view
bar = CreateScalarBar(LookupTable=lt)
view.Representations.append(bar)
# Specify the output size of the images
aspect_ratio = float(view.ViewSize[1]) / float(view.ViewSize[0])
output_width = 1080
output_height = int(aspect_ratio * output_width)
# Specify the time steps to output
time_steps_to_render = []
time_steps_to_render = [ field_reader.TimestepValues[-1] ]
#time_steps_to_render = field_reader.TimestepValues
count = 0
for t in time_steps_to_render:
fn = "output_{0}.png".format(count)
view.ViewTime = t
Render(view)
SaveScreenshot(fn, view, ImageResolution=(output_width, output_height))
count += 1
Additional Resources¶
See the official Python Paraview Documentation.
The Paraview Guide is a great resource. It is available on the download page of any Paraview release. Look for a “ParaViewGuide-5.X.Y.pdf” file in the Documentation section.
A lot can be learned by exporting Python state files directly from Paraview. To do this, create an interesting visualization manually in Paraview. Then go to File-Save State, and change the file type to “Python state file”. This will write out a Python script that creates the view you just created.
Use the Python Shell in Paraview to learn about objects and the API itself. Open that with View-Python Shell. The shell opens up in the window. You can then interrogate your loaded data and see what fields are available. After loading some data into Paraview, type each command into the Python Shell:
d = GetActiveSource()
# What object do we have?
d
# What can I do with this object?
help(d)
# What cell arrays are available?
d.CellArrays