What we want is a narrow channel (4 x 1
What about boundary conditions? By default Gerris assumes that
boundaries are solid walls with slip conditions for the velocity
(i.e. the tangential stress on the wall is zero). For the moment we
then have defined a rectangular box closed on all sides by solid
walls.
What we really want is to specify an input velocity on the left side
of the box and some sort of output condition on the right side. We can
do that like this:
We see that GfsBoundaryInflowConstant takes one argument which is
the value of the (constant) normal velocity applied to this
boundary. All the other variables (pressure, tracer concentration
etc...) follow a zero gradient condition.
GfsBoundaryOutflow implements a simple outflow boundary condition
where the pressure is set to zero as well as the gradient of all other quantities.
We now have an empty ``wind tunnel'' with a constant inlet velocity of
norm unity. Gerris can deal with arbitrarily complex solid boundaries
embedded in the quad/octree mesh. The geometry of the solid boundaries
is described using GTS triangulated surfaces. In 2D, using 3D
triangulated surfaces seems overkill, as 2D curves would be
enough. However, Gerris being both a 2D and 3D code it deals with 2D
solid boundaries exactly as with 3D ones, even if the simulation is
done only on a 2D cross-section.
Creating 3D polygonal surfaces is not an easy job and is clearly
outside the scope of this tutorial. There are a number of utilities
you can use to do that, including big commercial CAD
packages. In general, once you have created a polygonal surface with
one of these tools it should be relatively easy to convert it to the
file format used by GTS. In particular, most CAD packages
can export to the STL (stereolithography) format which is easily
converted to the GTS file format using the stl2gts utility
which comes with the library.
This tutorial comes (handily) with one such file:
half-cylinder.gts. You can
visualise the surface it describes using a program
called
Geomview. To do this,
you first need to convert the GTS file to a format Geomview
understands. This can be done using the gts2oogl utility like
this:
We can now insert this object in the simulation domain like this:
Another new output object is GfsOutputBoundaries. This object
writes a geometrical summary (in OOGL/Geomview format) of the mesh
used, including boundary conditions, solid boundaries and so on.
We also initialise the velocity field on the whole domain
to a constant value (1,0,0). We could have left the
velocity field to its default value of (0,0,0) but, given that we
impose inflow boundary conditions, it would have meant that the
initial velocity would have been strongly divergent. Gerris always
starts a simulation by a projection step (to fix problems like this)
but it is always a good idea to start with the best possible velocity
field.
We can now run the code:
Each GfsBoundary object is colour-coded. From the colours in the
picture we see that we have indeed an inflow boundary condition on the
left side (blue) and an outflow boundary condition on the right side
(green).
You can also load in the full half-cylinder geometry we created
before: half-cylinder.oogl or visualise the PPM files using animate and display as in the previous example. By the way, a
useful feature of display is that you can zoom in by clicking on
the middle button in the image being displayed.
4 3 GfsSimulation GfsBox GfsGEdge {} {
GfsTime { end = 0 }
}
GfsBox {}
GfsBox {}
GfsBox {}
GfsBox {}
1 2 right
2 3 right
3 4 right
i.e. four boxes, box 1 connected to box 2 horizontally (to the right),
box 2 connected to box 3 horizontally and box 3 connected to box 4
horizontally. Box 1 is centered on the origin and is of size one. All
the other boxes are positioned accordingly. We now have our 4 x 1
3.1.1 Boundary conditions
4 3 GfsSimulation GfsBox GfsGEdge {} {
GfsTime { end = 0 }
}
GfsBox { left = GfsBoundaryInflowConstant 1 }
GfsBox {}
GfsBox {}
GfsBox { right = GfsBoundaryOutflow }
1 2 right
2 3 right
3 4 right
The whole left side of the first (leftmost) box is now defined to be a GfsBoundaryInflowConstant object and the whole right side of the last
(rightmost) box a GfsBoundaryOutflow object. Again, boundary
conditions objects are all derived from the GfsBoundary object
and, as initial conditions, new objects can be easily written by the
user (see also section 4.1).
3.1.2 Solid boundaries
% gts2oogl < half-cylinder.gts > half-cylinder.oogl
(OOGL is the file format used by Geomview). gts2oogl has a
number of options. You can have a short explanation of what they do by
typing:
% gts2oogl -h
If you now start geomview like this:
% geomview half-cylinder.oogl
and play around with the pan/rotate/zoom functions of Geomview (read the
manual for details), you should see something like the image on figure
3.
You can notice that this is a proper 3D object, even if we are only
going to simulate the flow in a 2D cross-section. It is also important
that the object is ``tall'' enough so that it spans the entire
``height'' of the 2D domain, as if we were going to simulate the flow
around it in a proper 3D channel with a square cross-section. The
orientation of the surface is also important to define what is inside
(the solid) and what is outside (the fluid).
4 3 GfsSimulation GfsBox GfsGEdge {} {
GfsTime { end = 0 }
GtsSurfaceFile half-cylinder.gts
}
GfsBox { left = GfsBoundaryInflowConstant 1 }
GfsBox {}
GfsBox {}
GfsBox { right = GfsBoundaryOutflow }
1 2 right
2 3 right
3 4 right
add what mesh refinement we want and a few things to output:
4 3 GfsSimulation GfsBox GfsGEdge {} {
GfsTime { end = 9 }
GfsRefine 6
GtsSurfaceFile half-cylinder.gts
GfsInit {} { U = 1 }
GfsOutputBoundaries {} boundaries
GfsOutputTime { step = 0.02 } stdout
GfsOutputProjectionStats { step = 0.02 } stdout
GfsOutputPPM { step = 0.02 } vorticity.ppm {
min = -100 max = 100 v = Vorticity
}
GfsOutputTiming { start = end } stdout
}
GfsBox { left = GfsBoundaryInflowConstant 1 }
GfsBox {}
GfsBox {}
GfsBox { right = GfsBoundaryOutflow }
1 2 right
2 3 right
3 4 right
I have added a new GfsOutput object we haven't seen yet: GfsOutputTiming. This object writes a summary of the time taken by
various parts of the solver. You might also have noticed the unusual
start = end bit ; this just specifies that this event will only
happen once at the end of the simulation.
% gerris2D half-cylinder.gfs
It is going to take a while to complete, but remember that you can
look at files while they are being generated. The first file which
will be generated is boundaries. If you load it in Geomview, you
should get something like figure 4 (you probably want
to disable automatic normalization in Geomview by selecting
Inspect
Next: 3.2 Saving the whole
Up: 3 A more complex
Previous: 3 A more complex
Contents