Dambreak Flow with an Obstacle - Ubbink (1997)


This notebook implements PROTEUS to develop a numerical solution to a problem first studied by Ubbink (1997), who used a level-set model for free surface flows. The problem consists of a 0.292m x 1.146m (height x width) column of water, initially at rest. A small obstacle (0.024m x 0.048m) is placed in the middle of the tank base. Under the action of gravity the water column interacts with the obstacle and collapses to a wall. The computational domain is a 2D rectangular box with dimensions 0.584m x 0.584m. The top of the domain is left open to the atmosphere, with the rest of boundaries acting as free slip walls. In the following figure, a sketch of the dambreak initial conditions is shown.

This case tests the ability of PROTEUS to simulate the free-surface evolution and during the interaction of the dambreak front with the obstacle. The results of the simulations can be visually compared with the data in the following references. For more details, see runfiles or references.

References

  • Ubbink, O. (1997) Numerical prediction of two fluid systems with sharp interfaces. PhD thesis, Department of Mechanical Engineering, Imperial College of Science, Technology & Medicine. PDF

Running the numerical model in the shell

The parun launcher is used to execute the split-operator module, in this case dambreak_Ubbink_so.py. Various arguments may also be implemented to define various runtime options. All available options are listed when executing parun -h in the command line. Common command-line options are as follows:

Option Description
-v Print logging information to standard output
-O PETSCOPTIONSFILE Text file of options to pass to Petsc library
-D DATADIR Set data directory for output storage
-l LOGLEVEL Store runtime information at the log level, 0 = none, 10 = everything
-b BATCHFILENAME Text file of auxiliary commands to execute along with main program
-G gatherArchive Collect data files into single file at end of simulation (will require more computational resources on large runs)
-H hotStart Use the last step in the archive as the initial condition and continue appending to the archive

Additionally, to run the case on more than one core, implement mpiexec -n <number of cores> before the use of parun on the command line.


In [1]:
!mpiexec -np 2 parun dambreak_Ubbink_so.py -l 5 -C "refinement=8" -O ../../../inputTemplates/petsc.options.superlu_dist


TriangleBaseMesh nbase=1 baseFlags= VApq30Dena0.00017745 
TriangleBaseMesh nbase=1 baseFlags= VApq30Dena0.00017745 
ApplyTriangulate flags= VApq30Dena0.00017745
Constructing Delaunay triangulation by divide-and-conquer method.
  Sorting vertices.
  Forming triangulation.
  Removing ghost triangles.
Delaunay milliseconds:  0
Recovering segments in Delaunay triangulation.
    Constructing mapping from vertices to triangles.
  Recovering PSLG segments.
Segment milliseconds:  0
Removing unwanted triangles.
  Marking concavities (external triangles) for elimination.
  Marking neighbors of marked triangles.
  Deleting marked triangles.
Spreading regional attributes.
Hole milliseconds:  0
Adding Steiner points to enforce quality.
  Looking for encroached subsegments.
  Making a list of bad triangles.
  Splitting bad triangles.
Quality milliseconds:  2

Writing vertices.
Writing triangles.
Writing segments.
Writing edges.
Writing neighbors.

Output milliseconds:  0
Total running milliseconds:  3

Statistics:

  Input vertices: 8
  Input segments: 8
  Input holes: 0

  Mesh vertices: 1600
  Mesh triangles: 3052
  Mesh edges: 4651
  Mesh exterior boundary edges: 146
  Mesh interior boundary edges: 0
  Mesh subsegments (constrained edges): 146

Mesh quality statistics:

  Smallest area:       3.6961e-05   |  Largest area:       0.00017741
  Shortest edge:         0.009125   |  Longest edge:         0.026865
  Shortest altitude:    0.0058629   |  Largest aspect ratio:   3.1631

  Triangle aspect ratio histogram:
  1.1547 - 1.5       :      1260    |     15 - 25         :         0
     1.5 - 2         :      1258    |     25 - 50         :         0
       2 - 2.5       :       442    |     50 - 100        :         0
     2.5 - 3         :        87    |    100 - 300        :         0
       3 - 4         :         5    |    300 - 1000       :         0
       4 - 6         :         0    |   1000 - 10000      :         0
       6 - 10        :         0    |  10000 - 100000     :         0
      10 - 15        :         0    | 100000 -            :         0
  (Aspect ratio is longest edge divided by shortest altitude)

  Smallest angle:          30.086   |  Largest angle:          115.39

  Angle histogram:
      0 -  10 degrees:         0    |     90 - 100 degrees:       298
     10 -  20 degrees:         0    |    100 - 110 degrees:       126
     20 -  30 degrees:         0    |    110 - 120 degrees:        17
     30 -  40 degrees:       712    |    120 - 130 degrees:         0
     40 -  50 degrees:      1954    |    130 - 140 degrees:         0
     50 -  60 degrees:      2296    |    140 - 150 degrees:         0
     60 -  70 degrees:      2150    |    150 - 160 degrees:         0
     70 -  80 degrees:       913    |    160 - 170 degrees:         0
     80 -  90 degrees:       690    |    170 - 180 degrees:         0

Memory allocation statistics:

  Maximum number of vertices: 1600
  Maximum number of triangles: 3052
  Maximum number of subsegments: 146
  Maximum number of encroached subsegments: 2
  Maximum number of bad triangles: 2613
  Maximum number of stacked triangle flips: 5
  Approximate heap memory use (bytes): 431424

Algorithmic statistics:

  Number of incircle tests: 13391
  Number of 2D orientation tests: 8740
  Number of triangle circumcenter computations: 1590

ApplyTriangulate done
now destroying triangulateio
/home/jovyan/proteus/proteus/TriangleUtils.py:92: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if nodes == None: #ok to do nothing of nodes is empy
/home/jovyan/proteus/proteus/TriangleUtils.py:116: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if markers != None:
/home/jovyan/proteus/proteus/TriangleUtils.py:146: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if elems == None: #ok to do nothing of nodes is empy
/home/jovyan/proteus/proteus/TriangleUtils.py:167: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if attrib != None:
/home/jovyan/proteus/proteus/TriangleUtils.py:206: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if nodes == None: #ok to do nothing of nodes is empy
/home/jovyan/proteus/proteus/TriangleUtils.py:208: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if segments == None:
/home/jovyan/proteus/proteus/TriangleUtils.py:244: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if pmarkers != None:
/home/jovyan/proteus/proteus/TriangleUtils.py:264: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if smarkers != None:
/home/jovyan/proteus/proteus/TriangleUtils.py:289: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if regions != None:
/home/jovyan/proteus/proteus/TriangleUtils.py:360: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if edges == None: #ok to do nothing if elemAreas is empty
/home/jovyan/proteus/proteus/TriangleUtils.py:380: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if markers != None:
/home/jovyan/proteus/proteus/TriangleUtils.py:407: FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
  if neigs == None: #ok to do nothing if elemAreas is empty
now destroying triangulateio
now destroying triangulateio
now destroying triangulateio
now destroying triangulateio
WARNING! There are options you set that were not used!
WARNING! could be spelling mistake, etc!
Option left: name:-dissipation_ksp_type value: preonly
Option left: name:-dissipation_pc_factor_mat_solver_package value: superlu_dist
Option left: name:-dissipation_pc_type value: lu
Option left: name:-kappa_ksp_type value: preonly
Option left: name:-kappa_pc_factor_mat_solver_package value: superlu_dist
Option left: name:-kappa_pc_type value: lu
Option left: name:-mesh_ksp_type value: preonly
Option left: name:-mesh_pc_factor_mat_solver_package value: superlu_dist
Option left: name:-mesh_pc_type value: lu

Post-process the numerical solution


In [3]:
import helpers
helpers.CreateFig()

In [5]:
!rm -f dambreakUbbink.mp4; avconv -i phi%4d.png -vcodec libx264 dambreakUbbink.mp4 -loglevel quiet


avconv: /home/jovyan/proteus/linux2/lib/liblzma.so.5: no version information available (required by /lib/x86_64-linux-gnu/libsystemd.so.0)

Display the solution


In [6]:
from IPython.core.display import HTML
data_uri_mp4 = open("dambreakUbbink.mp4", "rb").read().encode("base64").replace("\n", "")
video_tag = """<video controls>
<source type ="video/mp4" src="data:video/mp4;base64,{mp4}"/>
Your browser does not support the video tag
</video>""".format(mp4=data_uri_mp4)
HTML(data=video_tag)


Out[6]:

In [ ]: