PyFoam
HTML5
-capable browser
F
for fullscreen. ESC
for overview
PyFoam
swak4Foam
How much water is the optimum?
We'd like to find the ideal spot with OpenFOAM
We need a cool snake
BTW: that was Snake Plissken from John Carpenters Escape from New York
Python
- the friendly snakenumpy
and matplotlib
give functionality equivalent to MATLAB
scipy
adds numerical methods like ODE-integration and
optimization
pandas
adds a layer for data analysis
PyFoam
@swakPyFoam
blockMesh
for the basic mesh (half bottle)
makeAxialMesh
to use the axial symmetry of the bottle
compressibleInterFoam
is used
ParsedParameterFile
This class is the "workhorse" of PyFoam
If setFieldsDict
looks like this
pInit 5e5; fillHeight 0.15; defaultFieldValues ( volScalarFieldValue alphawater 1 volScalarFieldValue p_rgh $pInit volScalarFieldValue p $pInit );
Then the values can be easily changed like this
from PyFoam.RunDictionary.ParsedParameterFile import ParsedParameterFile setF=ParsedParameterFile(path.join(self.casedir(),"system","setFieldsDict")) setF["pInit"]=7e5 setF["fillHeight"]=0.2*0.5 setF.writeFile()
PyFoam
-utility is implemented as a class
pyFoamRunner.py --clear --progress simpleFoam
we can run it from a Python
-script like this
from PyFoam.Applications.Runner import Runner data=Runner(args=["--clear","--progress", "simpleFoam","-case",caseName]).getData()
and the variable data
then holds the analyzed data from that run
ClusterJob
-script
ClusterJob
is a class in PyFoam
that
def setup(self,parameters): self.execute("rm -rf 0") self.execute("cp -r 0.orig 0") self.templateFile("constant/polyMesh/blockMeshDict") self.foamRun("blockMesh") self.foamRun("makeAxialMesh",foamArgs=["-overwrite"]) self.foamRun("collapseEdges",foamArgs=["-overwrite"]) setF=ParsedParameterFile(path.join(self.casedir(),"system","setFieldsDict")) setF["pInit"]=parameters["p"] setF["fillHeight"]=parameters["frac"]*0.2 setF.writeFile() self.foamRun("setFields")
Note: scaling of pressure is different
PyFoam
PyFoam
analysis the screen output of the solver
We've added an expression in swak4Foam
to output the current
acceleration of the bottle
like this
Expression acceleration : min=20.443693
In a file customRegexp
we add
bottleAcceleration { theTitle "Acceleration of the bottle"; expr "Expression acceleration : min=(%f%)"; titles ( a ); }
and PyFoam
extracts these values and writes them to disc
swak4Foam
also integrates
to
PyFoam
extracts that data for us as well ….
(blue line is position without gravity)
PyFoam
is not picky:
OpenFOAM
:
sample
probes
swak4Foam
?)
Python
-libraries like numpy
and pandas
ParaView
…
PyFoam
can read the analyzed data into Paraview
First we build a database from the cases
pyFoamAddCaseDataToDatabase.py runDatabase.db BottleRocket*/PyFoamRunner.compressibleInterFoam.analyzed/pickledData --create
Then we dump the data to an Excel-file (not that we're going to use that):
pyFoamDumpRunDatabaseToCSV.py runDatabase.db rawRuns.xls --excel --disable=".+Text" --panda --interactive-after
And get dropped to an ipython
-shell:
%pylab du=self.dump p=du.pivot("parameters//frac","parameters//p") p["analyzed//Custom//maxHeight//maximum height"].plot(marker="o") savefig("heightWithoutDrag.png")
Later we could put that into a script ….
Function of initial pressure and filling ratio
Modification of the differential equations
Would make a recalculation of all 190 cases necessary.
But: we already have all the necessary data
scipy
Write a script that reads the data
from PyFoam.Applications.RedoPlot import RedoPlot d=RedoPlot(args=["--pickle-file", path.join(d,"PyFoamRunner.compressibleInterFoam.analyzed","pickledPlots"), "--numpy"]).plotNumpy
Builds interpolated function from it
from scipy.interpolate import interp1d from numpy import insert t=insert(d["bottleAcceleration"]["time"],0,[0]) a=insert(d["bottleAcceleration"]["a"],0,[0]) aFunc=interp1d(t,a,bounds_error=False,fill_value=0)
And integrates the new ODE
from scipy.integrate import odeint def func(x,t): dragForce=0.5*drag*area*x[1]*abs(x[1])/mFunc(t) return [x[1], aFunc(t)-grav-dragForce] sol=odeint(func,[0,0],t)
… and put it into a loop over all cases
data=Unpickler(open(pickPath)).load() my={"dragHeight":sol[:,0].max(), peakTime":t[sol[:,0].argmax()]} data["analyzed"]["Custom"]["drag"]=my p=Pickler(open(pickPath+".addedVel","w")) p.dump(data)
d=self.dump p=d[d["analyzed//Custom//drag//dragHeight"]<100].pivot("parameters//frac","parameters//p") p["analyzed//Custom//drag//dragHeight"].plot(marker="o") plot(p["analyzed//Custom//drag//dragHeight"].idxmax(),p["analyzed//Custom//drag//dragHeight"].max(),'r',linewidth=4)
snappyHexMesh
)
PyFoam
supports the setup, running and data collection
PyFoam
PyFoam
can serve as the basis for more complex applications
FoamCommandCenter
PyFoam
)
django
PyFoam
does the OpenFOAM
-specific stuff
PyFoam
Was written with
HTML5
-framework for presentation
XKCD
-style plots always look serious