For the moment our simulation is not very well resolved. We could always change the GfsRefine 6 line to something bigger but it would not make really good use of the quadtree approach used in Gerris. A code using a simple regular Cartesian grid approach would be faster and would produce the same results. Instead we are going to use dynamic adaptive mesh refinement, where the quadtree structure of the discretisation is used to adaptively follow the small structures of the flow, thus concentrating the computational effort on the area where it is most needed.
This is done using yet another object class: GfsAdapt, also derived from GfsEvent. Various criteria can be used to determine where refinement is needed. In practice, each criterium will be defined through a different object derived from GfsAdapt. If several GfsAdapt objects are specified in the same simulation file, refinement will occur whenever at least one of the criteria is verified.
For this first example, we will use a simple criterium based on the local value of the vorticity. A cell will be refined whenever
The general syntax for an GfsAdapt object is:
[GfsEvent] { minlevel = 1 maxlevel = 10 }where minlevel specifies the level below which it is not possible to coarsen a cell and maxlevel, the level above which it is not possible to refine a cell. The default values are 0 for minlevel and infinite for maxlevel. An important point is that, for the moment, it is not possible to dynamically refine solid boundaries. A simple solution to this restriction is to always refine the solid boundary with the maximum resolution at the start of the simulation and to restrict the refinement using the maxlevel identifier in GfsAdapt.
Following this we can modify our simulation file:
4 3 GfsSimulation GfsBox GfsGEdge {} { GfsTime { end = 9 } GfsRefine 7 GtsSurfaceFile half-cylinder.gts GfsInitFlowConstant {} { U = 1 } # GfsOutputBoundaries {} boundaries GfsAdaptVorticity { istep = 1 } { maxlevel = 7 } 1e-2 GfsOutputTime { step = 0.02 } stdout GfsOutputBalance { step = 0.02 } stdout GfsOutputProjectionStats { step = 0.02 } stdout GfsOutputPPM { step = 0.02 } vorticity.ppm { min = -100 max = 100 v = Vorticity } GfsOutputSimulation { step = 0.1 } half-cylinder-%3.1f.sim { variables = U,V,P } GfsOutputTiming { start = end } stdout } GfsBox { left = GfsBoundaryInflowConstant 1 } GfsBox {} GfsBox {} GfsBox { right = GfsBoundaryOutflow } 1 2 right 2 3 right 3 4 rightWe have added two lines and commented out (using #) the line outputting the boundaries (we don't need that anymore, we have the simulation files).
The first line we added says that we want to refine dynamically the
mesh through the GfsAdaptVorticity object applied every timestep
(istep = 1). The GfsAdaptVorticity object takes one
(compulsory) parameter (equal to 10-2 in our file).
The second line we added is a new GfsOutput object which displays the ``balance'' of the domain sizes across the different processes (when Gerris is ran in parallel). We will use this to monitor how the number of cells evolves with time as the simulation refines or coarsens the mesh according to our vorticity criterium.
We can now run this new simulation. If the previous simulation did not complete yet, don't be afraid to abort it (Ctrl-C), this one is going to be better (and faster).
% rm -f half-cylinder-*.sim *.ppm boundaries ; gerris2D half-cylinder.simIf we now look at the balance summary written by GfsOutputBalance, we see that initially (step: 0) the total number of cells (on all levels) is 86966, which corresponds to a constant resolution of 4 x 27 x 27 = 512 x 128. At step 10 the number of cells is down to 990 with a corresponding increase in computational speed. If we now look at the first simulation file we saved, using:
% gfs2oogl2D < half-cylinder-0.1.sim > boundaries % gfs2oogl2D -S -z 0 -c Vorticity < half-cylinder-0.1.sim > squares.ooglwe obtain figure 7 showing not only the domain boundaries as usual, but also the boundaries (thin black lines) between different levels of refinement. We see that the mesh is very refined around the solid and around the two vortices developing at the trailing edge and very coarse (one cell per box only) on the downstream part of the domain. If you are not sure what these thin black lines represent, just switch on the edge representation in Geomview (using the Inspect
% convert vorticity.ppm vorticity.mpgwhich will produce a much smaller MPEG video file, suitable for distribution through the network.