Pin37 movie
Contents
Overview
This movie was composed of four main parts:
- Animating over time while zoomed in. (The zoom in view is referred to as "J3".)
- This section is referred to as "J3", because J3 is a location in the volume.
- Animating over time again while animating the camera
- This section is referred to as "fly"
- Animating over time while zoomed out
- This section is referred to as "starwars"
- Animating a clip plane while animating in time
- This section is referred to as "clip"
The simulation is of turbulent flow in a nuclear reactor. Because it is so turbulent, we decided to loop the time-varying data over and over. So each section is repeating the same data.
Also, because it takes so long to read in each time slice, we rendered each of the four movie sections (J3, fly, starwars, & clip) while the time slice was in memory.
Script
# *****************************************************************************
# Script: 37pin.py
#
# Purpose:
# Makes a movie of a turbulence simulation.
#
# Notes:
# (1) This script should be run as:
# /soft/apps/visit/bin/visit -cli -nowin -verbose -s 37pin.py
# (2) Frequent parameters to change are:
# I. The views (located in StarWarsView, J3View, and FlyView)
# II. The volume transfer function (located in AddVolumePlot)
# III. The window size (located in the SaveWindowAttributes)
# IV. The number of processors (located in LaunchComputeEngine)
#
# Author: Hank Childs
# Creation: November 2008
#
# *****************************************************************************
import os
import sys
def LaunchComputeEngine():
OpenComputeEngine("localhost", ("-l", "qsub/mpirun", "-t", "1200", "-np", "160", "-nn", "80", "-machinefile", "$COBALT_NODEFILE", "-lb-stride"))
# This allows us to have acceleration, which makes the transition between
# effects like fly-throughs and clips not feel jumpy.
def SineParameterize(nFrames, curFrame, ramp):
# We are going to construct a function that has sine curves at either
# end and a flat ramp in the middle. We will then parameterize space
# by determining what portion of the total area has been covered by
# frame "curFrame".
nFrames -= 1
if 2*ramp > nFrames:
print "Ramp too large -- correcting"
ramp = nFrames / 2
if ramp <= 0:
return 1.
if nFrames <= 0:
return 1.
nNonRamp = nFrames - 2*ramp
# determine the height of our function
height=1./(float(nNonRamp) + 4*float(ramp)/math.pi)
if curFrame < ramp:
factor=2*height*ramp/math.pi
eval=math.cos((math.pi/2.)*(float(curFrame)/float(ramp)))
return (1. - eval)*factor
elif curFrame > nFrames-ramp:
amount_left = nFrames-curFrame
factor=2*height*ramp/math.pi
eval=math.cos((math.pi/2.)*(float(amount_left)/float(ramp)))
return 1. - (1. - eval)*factor
else:
amount_in_quad=curFrame-ramp
quad_part=amount_in_quad*height
curve_part=height*(2*ramp)/math.pi
return quad_part+curve_part
# Turn off annotation, set up colors
def GeneralSetup():
r = RenderingAttributes()
r.scalableActivationMode = r.Always
SetRenderingAttributes(r)
a = GetAnnotationAttributes()
a.axes3D.visible = 0
a.axes3D.bboxFlag = 0
a.axes3D.triadFlag = 0
a.userInfoFlag = 0
a.databaseInfoFlag = 0
a.legendInfoFlag = 0
a.backgroundColor = (0, 0, 0, 255)
a.foregroundColor = (0, 0, 0, 255)
a.gradientBackgroundStyle = a.Radial
a.gradientColor1 = (0, 0, 0, 255)
a.gradientColor2 = (0, 0, 0, 255)
a.backgroundMode = a.Solid # Solid, Gradient, Image, ImageSphere
SetAnnotationAttributes(a)
l = GetLight(1)
l.enabledFlag = 1
l.type = l.Ambient
l.brightness = 0.25
SetLight(1, l)
# We need to clip away part of the volume to see inside.
def ApplyClip():
AddOperator("Clip")
c = ClipAttributes()
c.quality = c.Accurate # Fast, Accurate
c.funcType = c.Plane # Plane, Sphere
c.plane1Status = 1
c.plane2Status = 1
c.plane3Status = 1
c.plane1Origin = (0, 3.58, 0)
c.plane2Origin = (2.91, 2.11, 0)
c.plane3Origin = (2.91, -2.11, 0)
c.plane1Normal = (0, -1, 0)
c.plane2Normal = (-1.73, -1, 0)
c.plane3Normal = (-1.73, 1, 0)
c.planeInverse = 1
SetOperatorOptions(c)
def ApplyIsosurface():
AddOperator("Isosurface")
i = IsosurfaceAttributes()
i.contourMethod = i.Value
i.variable = "z_velocity"
i.contourValue = (0.001)
SetOperatorOptions(i)
def AddPseudocolorPlot():
AddPlot("Pseudocolor", "pressure")
pc = PseudocolorAttributes()
pc.minFlag = 1
pc.maxFlag = 1
pc.min = -1.5
pc.max = 0.75
pc.colorTableName = "bluehot"
SetPlotOptions(pc)
# This volume plot was made in the GUI and then copied over.
# (Actually, I then tweaked it again from the CLI.)
def AddVolumePlot():
AddPlot("Volume", "z_velocity")
v = VolumeAttributes()
v.legendFlag = 1
#v.lightingFlag = 1
v.lightingFlag = 0
v.GetColorControlPoints().RemoveControlPoints(4)
v.colorControlPoints.GetControlPoints(0).colors = (255, 255, 0, 0)
v.colorControlPoints.GetControlPoints(0).position = 0
v.colorControlPoints.GetControlPoints(1).colors = (255, 255, 0, 0)
v.colorControlPoints.GetControlPoints(1).position = 0.75
v.colorControlPoints.GetControlPoints(2).colors = (128, 0, 0, 0)
v.colorControlPoints.GetControlPoints(2).position = 0.875
v.colorControlPoints.GetControlPoints(3).colors = (255, 0, 0, 0)
v.colorControlPoints.GetControlPoints(3).position = 1
v.colorControlPoints.smoothingFlag = 1
v.colorControlPoints.equalSpacingFlag = 0
v.colorControlPoints.discreteFlag = 0
v.colorControlPoints.externalFlag = 0
v.opacityAttenuation = 0.3
v.freeformFlag = 1
#controlPoints does not contain any GaussianControlPoint objects.
v.opacityVariable = "default"
v.freeformOpacity = (0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 8, 12, 16, 20, 24, 28, 32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80, 84, 88, 92, 96, 100, 104, 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 148, 152, 156, 160, 164, 168, 172, 176, 180, 184, 188, 192, 196, 200, 204, 208, 212, 216, 220, 224, 228, 232, 236, 240, 244, 248, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255)
v.useColorVarMin = 1
v.colorVarMin = 0
v.useColorVarMax = 1
v.colorVarMax = 2
v.samplesPerRay = 2500
v.rendererType = v.RayCasting # Splatting, Texture3D, RayCasting, RayCastingIntegration, SLIVR
SetPlotOptions(v)
def StarWarsView():
v = GetView3D()
v.viewNormal = (0.377094, 0.128091, 0.917275)
v.focus = (0, 0, 13.3203)
v.viewUp = (-0.123671, 0.988485, -0.0871936)
v.viewAngle = 30
v.parallelScale = 14.4013
v.nearPlane = -15.8026
v.farPlane = 15.8026
v.imagePan = (0.0330559, 0.0411823)
v.imageZoom = 2.60908
v.perspective = 1
v.eyeAngle = 2
v.centerOfRotationSet = 0
v.centerOfRotation = (0, 0, 13.3203)
SetView3D(v)
def J3View():
v = GetView3D()
v.viewNormal = (0.377094, 0.128091, 0.917275)
v.focus = (0, 0, 13.3203)
v.viewUp = (-0.123671, 0.988485, -0.0871936)
v.viewAngle = 30
v.parallelScale = 14.4013
v.nearPlane = -15.8026
v.farPlane = 15.8026
v.imagePan = (-0.0865573, -0.0752562)
v.imageZoom = 20
v.perspective = 1
v.eyeAngle = 2
v.centerOfRotationSet = 0
v.centerOfRotation = (0, 0, 13.3203)
SetView3D(v)
# Sets the view based on interpolating a spline
def FlyView(i, N):
v1 = GetView3D()
v1.viewNormal = (0.377094, 0.128091, 0.917275)
v1.focus = (0, 0, 13.3203)
v1.viewUp = (-0.123671, 0.988485, -0.0871936)
v1.viewAngle = 30
v1.parallelScale = 14.4013
v1.nearPlane = -15.8026
v1.farPlane = 15.8026
v1.imagePan = (-0.0865573, -0.0752562)
v1.imageZoom = 20
v1.perspective = 1
v1.eyeAngle = 2
v1.centerOfRotationSet = 0
v1.centerOfRotation = (0, 0, 13.3203)
# J3View, looking over to the side
v2 = GetView3D()
v2.viewNormal = (0.167224, 0.0931997, 0.981504)
v2.focus = (-1.13302, -0.27483, 12.4838)
v2.viewUp = (-0.121935, 0.989834, -0.073216)
v2.viewAngle = 30
v2.parallelScale = 14.4013
v2.nearPlane = -15.8026
v2.farPlane = 15.8026
v2.imagePan = (-0.0865573, -0.0752562)
v2.imageZoom = 20
v2.perspective = 1
v2.eyeAngle = 2
v2.centerOfRotationSet = 1
v2.centerOfRotation = (2.78494, 2.32635, 7.55293)
# Zoomed in, translated all the way over
v3 = GetView3D()
v3.viewNormal = (0.208352, 0.105336, 0.972365)
v3.focus = (-1.48394, -0.369883, 12.6931)
v3.viewUp = (-0.122478, 0.989167, -0.0809122)
v3.viewAngle = 30
v3.parallelScale = 14.4013
v3.nearPlane = -15.8026
v3.farPlane = 15.8026
v3.imagePan = (-0.0768782, -0.0593683)
v3.imageZoom = 7.16773
v3.perspective = 1
v3.eyeAngle = 2
v3.centerOfRotationSet = 1
v3.centerOfRotation = (2.97878, 1.991, 20.8292)
# Star wars view
v4 = GetView3D()
v4.viewNormal = (0.377094, 0.128091, 0.917275)
v4.focus = (0, 0, 13.3203)
v4.viewUp = (-0.123671, 0.988485, -0.0871936)
v4.viewAngle = 30
v4.parallelScale = 14.4013
v4.nearPlane = -15.8026
v4.farPlane = 15.8026
v4.imagePan = (0.0330559, 0.0411823)
v4.imageZoom = 2.60908
v4.perspective = 1
v4.eyeAngle = 2
v4.centerOfRotationSet = 0
v4.centerOfRotation = (0, 0, 13.3203)
vpts = (v1, v2, v3, v4)
x = [0, 0.25, 0.5, 1.0]
pos=SineParameterize(N, i, 32)
v = EvalCubicSpline(pos, x, vpts)
SetView3D(v)
def Beep():
print "\a"
print "\a"
print "\a"
# Used to animate a Clip across the volume
def ApplyXClip(i, N):
c = ClipAttributes()
c.quality = c.Accurate
c.funcType = c.Plane
c.plane1Status = 1
c.plane2Status = 0
c.plane3Status = 0
pos=SineParameterize(N, i, 32)
X = -8.0*(pos) + 4.0
c.plane1Origin = (X, 0, 0)
c.plane1Normal = (1, 0, 0)
c.planeInverse = 0
SetActivePlots((0,1))
SetDefaultOperatorOptions(c)
AddOperator("Clip")
def SetUpPlots():
AddPseudocolorPlot()
ApplyIsosurface()
ApplyClip()
AddVolumePlot()
# Always launch the engine before opening a file.
# When you open a file, VisIt will try to launch an engine if one does not already exist
# and it will probably do a bad job.
LaunchComputeEngine()
OpenDatabase("/gpfs/home/fischer/p37/Fl/p37l.nek3d")
GeneralSetup()
for i in range((TimeSliderGetNStates()/2)+1):
timestep = 2*i
print "\n\n\nTimestep is %d\n\n\n" %(timestep)
names = [ "starwars", "j3_", "fly", "clip" ]
needOne=False
for j in range(len(names)):
fullname = "%s%04d.tif" %(names[j], timestep)
if not os.path.exists(fullname):
needOne=True
if not needOne:
print "\n\n\nSKIPPING %d\n\n\n" %(timestep)
continue
else:
print "\n\n\nDoing timestep %d\n\n\n" %(timestep)
TimeSliderSetState(timestep)
SetUpPlots()
DrawPlots()
Beep()
for j in range(4):
name = "%s%04d.tif" %(names[j], timestep)
if os.path.exists(name):
print "\n\n\nSKIPPING %s\n\n\n" %(name)
continue
else:
print "\n\n\nDOING %s\n\n\n" %(name)
if j == 0:
StarWarsView()
elif j == 1:
J3View()
elif j == 2:
FlyView(timestep, TimeSliderGetNStates())
elif j == 3:
ApplyXClip(timestep, TimeSliderGetNStates())
DrawPlots()
StarWarsView()
sw = SaveWindowAttributes()
sw.fileName = "%s%04d" %(names[j], timestep)
sw.family = 0
sw.width = 1920
sw.height = 1080
sw.resConstraint = sw.NoConstraint
SetSaveWindowAttributes(sw)
SaveWindow()
Beep()
DeleteAllPlots()
SymLinks
Since the frames created by this script cannot be input directly to a movie encoder, we need to rename them so they can. I do this with symlinks.
#!/bin/ksh
rm -rf f????.ppm
X=0
Y=0
while (( Y <= 324 )) ; do
Y4=$(printf %04d $Y)
X4=$(printf %04d $X)
ln -s small_j3_${Y4}.tif f${X4}.ppm
(( X += 1 ))
(( Y += 2 ))
done
Y=0
while (( Y <= 324 )) ; do
Y4=$(printf %04d $Y)
X4=$(printf %04d $X)
ln -s small_j3_${Y4}.tif f${X4}.ppm
(( X += 1 ))
(( Y += 2 ))
done
Y=0
while (( Y <= 324 )) ; do
Y4=$(printf %04d $Y)
X4=$(printf %04d $X)
ln -s small_fly${Y4}.tif f${X4}.ppm
(( X += 1 ))
(( Y += 2 ))
done
Y=0
while (( Y <= 324 )) ; do
Y4=$(printf %04d $Y)
X4=$(printf %04d $X)
ln -s small_starwars${Y4}.tif f${X4}.ppm
(( X += 1 ))
(( Y += 2 ))
done
Y=0
while (( Y <= 324 )) ; do
Y4=$(printf %04d $Y)
X4=$(printf %04d $X)
ln -s small_starwars${Y4}.tif f${X4}.ppm
(( X += 1 ))
(( Y += 2 ))
done
Y=0
while (( Y <= 324 )) ; do
Y4=$(printf %04d $Y)
X4=$(printf %04d $X)
ln -s small_clip${Y4}.tif f${X4}.ppm
(( X += 1 ))
X4=$(printf %04d $X)
ln -s small_clip${Y4}.tif f${X4}.ppm
(( X += 1 ))
(( Y += 2 ))
done
Movie encoding
See here