# Title: Boussinesq flow generated by a heated cylinder
#
# Description:
#
# The classical Boussinesq approximation is applied to solve the flow
# generated by a heated cylinder. 
#
# A source term proportional to a diffusive tracer is added to the
# vertical component of the velocity field.
#
# Adaptivity is used to generate a "sponge" outflow condition on the
# top boundary.
#
# The turbulent plume obtained is illustrated on Figure \ref{tracer}.
#
# The movie is generated using the scripting mode of GfsView.
#
# \begin{figure}[htbp]
# \caption{\label{tracer}MPEG movie of the tracer field.}
# \begin{center}
# \htmladdnormallinkfoot{\includegraphics[width=0.3\hsize]{t.eps}}{t.mpg}
# \end{center}
# \end{figure}
#
# Author: St\'ephane Popinet
# Command: gerris2D boussinesq.gfs | gfsview2D boussinesq.gfv | ppm2mpeg > t.mpg
# Version: 1.1.2
# Required files: boussinesq.gfv
# Running time: 60 minutes
# Generated files: t.mpg t.eps
#
3 2 GfsSimulation GfsBox GfsGEdge {} {
  # Limit the maximum timestep to 1e-2 so that the initial diffusion
  # is properly resolved
  Time { end = 20 dtmax = 1e-2 }

  # Use an initial refinement of 8 levels around the solid boundary
  RefineSolid 8

  # Insert the solid boundary defined implicitly by the 
  # ellipse() function
  Solid (ellipse(0.,-0.15,1./16.,1./16.))

  # Add a passive tracer called T
  VariableTracer T

  # Add diffusion to tracer T
  SourceDiffusion T 0.0001
 
  # Add a source term to the vertical velocity component equal to T
  Source V T

  # Dirichlet boundary condition for T on the cylinder
  SurfaceBc T Dirichlet 1

  # Adapt the mesh using the vorticity criterion at every timestep
  # down to a maximum level of 8 if y is smaller than 1.5, 0
  # otherwise.  The topmost part of the domain will not be refined and
  # will act as a very efficient "sponge" layer to damp any eddies
  # before they exit the domain.
  AdaptVorticity { istep = 1 } { maxlevel = (y > 1.5 ? 0 : 8) cmax = 1e-2 }

  # Also adapt according to the tracer gradient
  AdaptGradient { istep = 1 } { maxlevel = 8 cmax = 5e-2 } T

  # Writes the time and timestep every 10 timesteps on standard error
  OutputTime { istep = 10 } stderr

  # Writes the simulation size every 10 timesteps on standard error
  OutputBalance { istep = 10 } stderr

  # Writes info about the convergence of the Poisson solver on standard error
  OutputProjectionStats { istep = 10 } stderr

  # Outputs profiling information at the end of the simulation to standard error
  OutputTiming { start = end } stderr

  # Outputs the simulation every 4 timesteps
  OutputSimulation { istep = 4 } stdout
 
  # Every 4 timesteps, GfsView will read the following command, after having read
  # the simulation file and will output a PPM screenshot on its standard output
  EventScript { istep = 4 } { echo "Save stdout { width = 256 height = 512 }" }
 
  # At t = 19, GfsView will create the PPM file used in the doc.
  EventScript { start = 19 } { echo "Save t.ppm { width = 256 height = 512 }" }

  # At the end of the simulation this file is converted to EPS.
  EventScript { start = end } { convert -colors 256 t.ppm t.eps ; rm -f t.ppm }
}
# The bottom boundary will also allow inflow (despite its name)
GfsBox { bottom = BoundaryOutflow }
GfsBox {}
# The top boundary is a simple outflow condition. This could cause problems
# (eddies getting stuck on the boundary) if the adaptive "sponge" layer was not
# used.
GfsBox { top = BoundaryOutflow }
1 2 top
2 3 top
