Gerris is a Partial Differential Solver (PDS) over the time-dependent incompressible variable-density Euler, Stokes or Navier-Stokes equations (and some variants). Gerris is also a progammation language and we begin now over the same basic concepts.

+

Gerris is a Partial Differential Equations Solver (PDES) for the

+

time-dependent incompressible variable-density Euler, Stokes or

+

Navier-Stokes equations (and some variants). Gerris is also a programming

+

language and we begin now with some basic concepts.

= Gerris as a language =

= Gerris as a language =

-

When we learn a language we begin always with words, then syntax, and then semantic.

+

When we learn a language we begin with words, then syntax, and then

+

semantic.

-

Gerris language is composed by words that reflect the internal structure of the code. The Gerris code is written en C language with inheritances.

+

The Gerris language is composed by words that reflect the internal structure

+

of the code. The Gerris code is written in C with inheritance.

-

Gerris language is an inheritance language where the root of each word has a component of their parent.

+

The Gerris language is an inheritance language where the root of each word

+

is a component of its parent.

-

By the way

+

For example

-

* GfsOutputTiming (write summary of time consuming of the simulation)

+

* [[GfsOutputTiming]] (write summary of time consumption of the simulation)

-

* GfsOutputTime (write the model time, timestep, CPU time and real time)

+

* [[GfsOutputTime]] (write the model time, timestep, CPU time and real time)

-

* GfsOutputSimulation (write the whole simulation data)

+

* [[GfsOutputSimulation]] (write the whole simulation data)

-

have the same parent '''GfsOutput''' which ''write simulation data''. If we understand the inheritance we do a big step forward.

+

have the same parent '''[[GfsOutput]]''' which ''write simulation data''. If

+

we understand the inheritance we make a big step forward.

-

In practice we write a code on a script line by line following the Gerris syntax and the Gerris solver interpret it.

+

In practice we write a code on a script line by line following the Gerris

+

syntax and the Gerris solver interprets it.

-

== Sample code : box ==

+

== Sample code: box ==

Simplest Gerris code doing nothing!!!

Simplest Gerris code doing nothing!!!

-

1 0 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

1 0 GfsSimulation GfsBox GfsGEdge {} {

-

// Code Gerris here!!

+

Refine 5

-

}

+

# Code Gerris here!!

-

GfsBox {

+

OutputSimulation { step = 1 } stdout

-

// Boundary conditions here!!

+

}

-

}

+

GfsBox {

+

# Boundary conditions here!!

+

}

+

</source>

-

Gerris uses box of lenght L=1 (in 2D) or cubes (in 3D) to build a domain, in this case we use the 2D solver. We have

+

Gerris uses a box of length L=1 (in 2D) or a cube (in 3D) to build a domain,

+

in this case we use the 2D solver. We have

1 0 GfsSimulation GfsBox GfsGEdge {} {

1 0 GfsSimulation GfsBox GfsGEdge {} {

-

1 0 says one box (1) not connected (0) and the other words (GfsSimulation GfsBox GfsGEdge) are Gerris reserved words.

We note that we can use here : U, V, P as variables and every C function (including time t and espace x and y) like

+

We note that we can use here: U, V, P as variables and every C function

+

(including time t and space x and y) like

-

GfsBox {

+

<source gfs>

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U ( sin(2.*M_PI*0.05*t) )

+

left = Boundary {

-

}

+

BcDirichlet U ( sin(2.*M_PI*0.05*t) )

-

right = BoundaryOutflow

+

}

-

}

+

right = BoundaryOutflow

+

}

+

</source>

-

a sinusoidal velocity at the lef side and outflow condition at the right side.

+

a sinusoidal velocity at the left side and an outflow condition at the right

+

side.

-

== Sample code : first try ==

+

== Sample code: first try ==

-

We can build now a simulation file for a box of length L=1, with a mesh of 32x32 (Refine 5) and with a input velocity equal to 1.

+

We can build now a simulation file for a box of length L=1, with a mesh of

+

32x32 (Refine 5) and with an input velocity equal to 1.

-

1 0 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

1 0 GfsSimulation GfsBox GfsGEdge {} {

-

}

+

Refine 5

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U 1

+

left = Boundary {

-

}

+

BcDirichlet U 1

-

right = BoundaryOutflow

+

}

-

}

+

right = BoundaryOutflow

+

}

+

</source>

We save the file as tutorial1.gfs and a console we run the simulation

We save the file as tutorial1.gfs and a console we run the simulation

-

gerris2D tutorial1.gfs

+

gerris2D tutorial1.gfs

and nothing happens.

and nothing happens.

Line 150:

Line 182:

== Sample code : intermezzo ==

== Sample code : intermezzo ==

-

We need to define necessarily the computational time and the output values of data.

+

We need to define the computational time and the data we want to output.

-

* the Gerris word '''GfsTime''' defines the physical and the computational time (number of time steps performed) By default both the physical time and the time step number are zero when the program starts. It is possible to set different values using for example

+

The Gerris word '''GfsTime''' defines the physical and the computational

-

GfsTime { t = 1.4 i = 32}

+

time (number of time steps performed). By default both the physical time

-

where i is the time step number and t is the physical time. The end identifier specifies that the simulation should stop when the physical time reaches the given value. It is also possible to stop the simulation when a specified number of time steps is reached, using the iend identifier. If both end and iend are specified, the simulation stops when either of these are reached. By default, both end and iend values are infinite.

+

and the time step number are zero when the program starts. It is possible

-

GfsTime {end = 2 iend = 32}

+

to set different values using for example

+

[[GfsTime]] { t = 1.4 i = 32 }

+

where i is the time step number and t is the physical time. The end

+

identifier specifies that the simulation should stop when the physical time

+

reaches the given value. It is also possible to stop the simulation

+

when a specified number of time steps is reached, using the iend identifier.

+

If both end and iend are specified, the simulation stops when either of

+

these are reached. By default, both end and iend values are infinite.

+

[[GfsTime]] { end = 2 iend = 32 }

-

* Gerris comes with a number of objects allowing to output specific data of the simulation. For that we need take a look to the '''GfsOutput''' a generic member which rely a given family (parent and childrens)

+

Gerris comes with a number of objects allowing to output specific data of

+

the simulation. For that we need take a look at '''[[GfsOutput]]'''. A

+

generic object which defines a given family (parent and childrens).

-

The parent of '''GfsOutput''' is '''GfsEvent''' which are used to control any action which needs to be performed at a given time during a simulation. The key words for '''GfsEvent''' are

+

The parent of '''[[GfsOutput]]''' is '''[[GfsEvent]]''' which is used to

+

control any action which needs to be performed at a given time during a

+

simulation. The keywords for '''[[GfsEvent]]''' are

-

'''start''' Physical starting time (default is zero). The "end" keyword can be used to indicate the end of the simulation.

+

;start: Physical starting time (default is zero). The "end" keyword can be used to indicate the end of the simulation.

-

'''istart''' Time step starting time (default is zero).

+

;istart: Time step starting time (default is zero).

-

'''step''' Repeat every step physical time units (default is infinity).

+

;step: Repeat every step physical time units (default is infinity).

-

'''istep''' Repeat every istep time steps (default is infinity).

+

;istep: Repeat every istep time steps (default is infinity).

-

'''end''' Stop at or before this physical time (default is infinity).

+

;end: Stop at or before this physical time (default is infinity).

-

'''iend''' Stop at or before this number of time steps (default is infinity).

+

;iend: Stop at or before this number of time steps (default is infinity).

-

The children of '''GfsOutput''' are .. a lot ... (rabbit family) we talk about many

+

The children of '''GfsOutput''' are .. many ... (a rabbit family). Here are

+

a few

-

* '''GfsOutputSimulation''' which write the whole simulation

+

* '''[[GfsOutputSimulation]]''' which writes the whole simulation. The syntax is

-

the syntax is

+

-

'''GfsOutputSimulation''' {''inheritance of GfsOutput, then of GfsEvent''} file.gts

+

'''[[GfsOutputSimulation]]''' {''inheritance of GfsOutput, then of GfsEvent''}

-

by the way

+

For example

-

'''GfsOutputSimulation''' { start = 0.6 step = 0.3 } file.gts

+

'''[[GfsOutputSimulation]]''' { start = 0.6 step = 0.3 } file.gfs

-

which says, we write into a file ''file.gts'' every 0.3 of physical time starting from 0.6. The data format '''gts''' is a Gerris format and we will talk about later. Note that you can save data in your habitual format if you want.

+

which says, we write into a file ''file.gfs'' every 0.3 of physical time

+

starting from 0.6. The data format '''gfs''' is a Gerris format and we will

+

talk about it later. Note that you can save data in other formats if you

+

want.

-

* '''GfsOutputLocation''' which write the values of variables at specified locations

+

* '''[[GfsOutputLocation]]''' which write the values of variables at specified locations

the syntax is

the syntax is

-

'''GfsOutputLocation''' {''inheritance of GfsOutput, then of GfsEvent''} data positionXYZ

+

'''[[GfsOutputLocation]]''' {''inheritance of GfsOutput, then of

-

by the way

+

GfsEvent''} positionXYZ

+

For example

-

'''GfsOutputLocation''' { step = 1 } data positionXYZ

+

'''[[GfsOutputLocation]]''' { step = 1 } data positionXYZ

-

which says ''do every physical step'' the following : write in file '''data''' the numerical values of the dynamical variables at positions given by the input file '''positionXYZ'''. The input file is a ascii file with the three columns of coordinates (x y z)

+

which says ''do every unit time'' the following: write in file '''data'''

+

the numerical values of the dynamical variables at positions given by the

+

input file '''positionXYZ'''. The input file is an ascii file with three

+

columns of coordinates (x y z)

0 -0.5 0

0 -0.5 0

Line 206:

Line 257:

== Sample code : second try ==

== Sample code : second try ==

-

Finally we do the second try

Finally we do the second try

-

1 0 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

1 0 GfsSimulation GfsBox GfsGEdge {} {

-

GfsTime {end = 5}

+

Refine 5

-

GfsOutputLocation { step = 1 } data positionXYZ

+

GfsTime { end = 5 }

-

}

+

GfsOutputLocation { step = 1 } data positionXYZ

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U 1

+

left = Boundary {

-

}

+

BcDirichlet U 1

-

right = BoundaryOutflow

+

}

-

}

+

right = BoundaryOutflow

+

}

+

</source>

-

this Gerris script do the following :

+

this Gerris script does the following:

-

# it stops the run at 5 physical times ''GfsTime {end = 5}'' ,

+

# it stops the run at physical time 5 ''GfsTime { end = 5 }'' ,

-

# write the results into the file ''data'' at the given positions by the file ''positionXYZ'',

+

# writes the results into the file ''data'' at the positions given by the

-

# the boundary conditions are imposed pressure at both ends

+

# file ''positionXYZ'',

+

# the boundary conditions are an imposed pressure at both ends

-

We save the file as tutorial2.gfs and a console we run the simulation

+

We save the file as tutorial2.gfs and in a console we run the simulation

We forget the viscosity!!! we take now a look to the Gerris documentation

+

We forgot the viscosity!!! we take now take a look at the Gerris

+

documentation

-

By default, the density is unity and the molecular viscosity is zero (i.e. there is no explicit viscous term in the momentum equation).

+

:By default, the density is unity and the molecular viscosity is zero (i.e. there is no explicit viscous term in the momentum equation). In practice, it does not mean that there is no viscosity at all however, because any discretization scheme always has some numerical viscosity. However, keep in mind that the only relevant parameter for the (constant density) Navier-Stokes equations is the Reynolds number. If you do not include any explicit viscous term the (theoretical) Reynolds number is always infinite.

-

In practice, it does not mean that there is no viscosity at all however, because any discretization scheme always has some numerical viscosity.

+

-

However, keep in mind that the only relevant parameter for the (constant density) Navier-Stokes equations is the Reynolds number.

+

-

If you do not include any explicit viscous term the (theoretical) Reynolds number is always infinite.

+

-

So our script is wrong, good syntax but bad semantic!!! That says us that we have to think about the physical problem before!!!

+

So our script is wrong, good syntax but bad semantic!!! That tels us that we

+

have to think about the physical problem first!!!

-

We need set the viscosity, '''GfsSourceViscosity''' can do it

+

We need to set the viscosity, '''[[GfsSourceViscosity]]''' can do it

-

'''GfsSourceViscosity''' 'value or function'

+

'''[[GfsSourceViscosity]]''' 'value or function'

-

for instance if we decide to do the simulation in a dimensionless variables (the good procedure) we can set the viscosity as 1/Re where Re is the Reynolds number

+

for instance if we decide to do the simulation in dimensionless variables

+

(the good procedure) we can set the viscosity as 1/Re where Re is the

+

Reynolds number

-

'''GfsSourceViscosity''' 1.

+

'''GfsSourceViscosity''' 1.

where the Reynolds number is now 1.

where the Reynolds number is now 1.

-

== Sample code : third try ==

== Sample code : third try ==

Line 257:

Line 310:

We write now

We write now

-

1 0 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

1 0 GfsSimulation GfsBox GfsGEdge {} {

-

GfsTime {end = 5}

+

Refine 5

-

GfsSourceViscosity 1

+

GfsTime { end = 5 }

-

GfsOutputLocation { step = 1 } data positionXYZ

+

GfsSourceViscosity 1

-

}

+

GfsOutputLocation { step = 1 } data positionXYZ

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U 1

+

left = Boundary {

-

}

+

BcDirichlet U 1

-

right = BoundaryOutflow

+

}

-

}

+

right = BoundaryOutflow

+

}

+

</source>

-

this Gerris script do the following :

+

this Gerris script does the following :

-

# it stops the run at 5 physical times ''GfsTime {end = 5}'' ,

+

# it stops the run at 5 physical times ''GfsTime { end = 5 }'' ,

-

# set the Reynolds number to 1.

+

# sets the Reynolds number to 1.

-

# write the results into the file ''data'' at the given positions by the file ''positionXYZ'',

+

# writes the results into the file ''data'' at the positions given by the file ''positionXYZ'',

-

# the boundary conditions are imposed pressure at both ends

+

# the boundary conditions are imposed pressure at both ends

We save the file as tutorial3.gfs and a console we run the simulation

We save the file as tutorial3.gfs and a console we run the simulation

-

gerris2D tutorial2.gfs

+

gerris2D tutorial3.gfs

and it works!!

and it works!!

-

We take a look the the file '''data''', there are several columns and the first line give the label of each column

+

We take a look at the file '''data''', there are several columns and the

+

first line gives the label of each column

-

# 1:t 2:x 3:y 4:z 5:P 6:Pmac 7:U 8:V 9:T

+

# 1:t 2:x 3:y 4:z 5:P 6:Pmac 7:U 8:V

-

Using gnuplot (plot [0:0.1] "./data.dat" i 5 u 7:3 w lp) we can do a graph of the final time (t=5)

+

Using gnuplot (plot [0:0.1] "./data.dat" i 5 u 7:3 w lp) we can do a graph

+

of the final time (t=5)

-

[[File:plan.jpg|200px]]

+

[[Image:plan.jpg|200px]]

-

and the velocity U is constant!!! and where is our classical parabolic profile??

+

and the velocity U is constant!!! Where is our classical parabolic profile??

== Sample code : fourth try ==

== Sample code : fourth try ==

-

We set now all boundary conditions (top and bottom are set to zero)

+

We now set all boundary conditions (top and bottom are set to zero)

-

1 0 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

1 0 GfsSimulation GfsBox GfsGEdge {} {

-

GfsTime {end = 5}

+

Refine 5

-

SourceViscosity 1.

+

Time {end = 5}

-

GfsOutputLocation { step = 1 } data positionXYZ

+

SourceViscosity 1.

-

OutputSimulation { step = 1 } tt.gfs

+

OutputLocation { step = 1 } data positionXYZ

-

}

+

OutputSimulation { step = 1 } tt.gfs

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U 1

+

left = Boundary {

-

}

+

BcDirichlet U 1

-

right = BoundaryOutflow

+

}

-

top = Boundary {

+

right = BoundaryOutflow

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

}

+

}

+

}

+

</source>

-

We save the file as tutorial4.gfs and a console we run the simulation

+

We save the file as tutorial4.gfs and in a console we run the simulation

gerris2D tutorial4.gfs

gerris2D tutorial4.gfs

-

and using gnuplot (plot [0:0.1] "./data.dat" i 5 u 7:3 w lp) we can do a graph of the final time (t=5)

+

and using gnuplot (plot [0:0.1] "./data.dat" i 5 u 7:3 w lp) we can do a

+

graph of the final time (t=5)

-

[[File:Parab1.jpg|200px]]

+

[[Image:Parab1.jpg|200px]]

-

Its better but it is not exactly a parabolic profile. Shear layer? We can look near the exit at coordinates (x = 0.45), recall that domain is [-0.5:0.5].

+

It's better but it is not exactly a parabolic profile. Shear layer? We can

+

look near the exit at coordinates (x = 0.45), recall that domain is

+

[-0.5:0.5].

Using awk we modify the file positionXYZ to translate it toward the end

Using awk we modify the file positionXYZ to translate it toward the end

Line 329:

Line 391:

awk '{print $1+0.45 " " $2 " " $3 }' positionXYZ > positionX0.45YZ

awk '{print $1+0.45 " " $2 " " $3 }' positionXYZ > positionX0.45YZ

-

and now we write

+

and we now write

-

1 0 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

1 0 GfsSimulation GfsBox GfsGEdge {} {

-

GfsTime {end = 5}

+

Refine 5

-

SourceViscosity 1.

+

Time {end = 5}

-

GfsOutputLocation { step = 1 } data positionXYZ

+

SourceViscosity 1.

-

GfsOutputLocation { step = 1 } data0.45 positionX0.45YZ

+

OutputLocation { step = 1 } data positionXYZ

-

}

+

OutputLocation { step = 1 } data0.45 positionX0.45YZ

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U 1

+

left = Boundary {

-

}

+

BcDirichlet U 1

-

right = BoundaryOutflow

+

}

-

top = Boundary {

+

right = BoundaryOutflow

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

}

+

}

+

}

+

</source>

where we generate two files data and data0.45. the results are

where we generate two files data and data0.45. the results are

-

[[File:parab2.jpg|200px]]

+

[[Image:parab2.jpg|200px]]

-

humm we will add a box

+

humm, we will add a box.

-

== Sample code : adding a box ==

+

== Sample code: adding a box ==

-

Now we add a box a right side of the our first box (the domain is now 2x1), 2 in x coordinates [(0.5:1.5)]. We generate also a new file positionX1.45YZ to study the profile at the end of the two boxes. We modify the Gerris file as following

+

Now we add a box to the right of our first box (the domain is now 2x1), 2 in

+

x coordinates [(0.5:1.5)]. We generate also a new file positionX1.45YZ to

+

study the profile at the end of the two boxes. We modify the Gerris file as

+

follows

-

'''2''' '''1''' GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

2 1 GfsSimulation GfsBox GfsGEdge {} {

-

GfsTime {end = 5}

+

Refine 5

-

SourceViscosity 1.

+

Time { end = 5 }

-

GfsOutputLocation { step = 1 } data positionXYZ

+

SourceViscosity 1.

-

GfsOutputLocation { step = 1 } data0.45 positionX0.45YZ

+

OutputLocation { step = 1 } data positionXYZ

-

GfsOutputLocation { step = 1 } data1.45 positionX1.45YZ

+

OutputLocation { step = 1 } data0.45 positionX0.45YZ

-

}

+

OutputLocation { step = 1 } data1.45 positionX1.45YZ

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U 1

+

left = Boundary {

-

}

+

BcDirichlet U 1

-

top = Boundary {

+

}

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

GfsBox {

+

}

-

right = BoundaryOutflow

+

}

+

GfsBox {

+

right = BoundaryOutflow

top = Boundary {

top = Boundary {

-

BcDirichlet U 0

+

BcDirichlet U 0

-

BcDirichlet V 0

+

BcDirichlet V 0

-

}

+

-

bottom = Boundary {

+

-

BcDirichlet U 0

+

-

BcDirichlet V 0

+

}

}

-

'''1 2 right'''

+

bottom = Boundary {

+

BcDirichlet U 0

+

BcDirichlet V 0

+

}

+

}

+

1 2 right

+

</source>

-

We have in the first line '''2 1''' which want say two (2) boxes with one (1) connection, and we add two '''GfsBox''' one for each box with the corresponding boundary conditions. The new line

+

We have in the first line '''2 1''' which says two (2) boxes with one (1)

+

connection, and we add two '''GfsBox''' one for each box together with the

+

corresponding boundary conditions. The new line

'''1 2 right'''

'''1 2 right'''

-

say as that the boxes 1 and 2 are connected by the right side (beginning from the box 1)

+

say that the boxes 1 and 2 are connected by the right side (beginning from

+

box 1).

-

= Gfsview : a graphical tool =

+

= Gfsview: a graphical tool =

-

GfsView is a tool written specifically to visualize Gerris simulation files. We have seen the Gerris word '''GfsOutputSimulation''' before, we modify then our script adding the line

+

GfsView is a tool written specifically to visualize Gerris simulation files.

+

We have seen the Gerris keyword '''GfsOutputSimulation''' before, we modify

+

then our script adding the line

-

GfsOutputSimulation { start = end } file.gts

+

[[GfsOutputSimulation]] { start = end } file.gfs

-

which says ''write the whole simulation on file file.gts at final time''.

+

which says ''write the whole simulation in file file.gfs at the final

+

time''.

Now we can run Gfsview

Now we can run Gfsview

-

Gfsview2D file.gts

+

gfsview2D file.gfs

-

and clicking on “Linear”, “Vectors” in the tool-bar and changing the vector length by editing the properties of the “Vectors” object (select the object then choose “Edit→Properties”) you should be able to get something looking like

+

and clicking on “Linear”, “Vectors” in the tool-bar and changing the vector

+

length by editing the properties of the “Vectors” object (select the object

+

then choose “Edit→Properties”) you should be able to get something looking

+

like

-

[[File:figure.jpg]]

+

[[Image:figure.jpg]]

-

You can also pan by dragging the right mouse button, zoom by dragging the middle button and rotate by dragging the left button. If you like a given representation of results and you want to reuse it you can save the Gfsview file ("Save" in toolbar) in gvf format, like ''vectors.gvf''.

+

You can also pan by dragging the right mouse button, zoom by dragging the

+

middle button and rotate by dragging the left button.

-

We can pipe the results at every time we want directly on Gfsview writing now the file.gts at every time

+

You can get the value of an object by selecting the object on the left

+

panel; then press the Ctrl key and click on the position where you want to

+

get the object value, while continuing to hold the Ctrl key.

-

GfsOutputSimulation { time = 1} file.gts

+

If you like a given representation of results and you want to reuse it you

+

can save the Gfsview file ("Save" in toolbar) in gfv format, like

+

''vectors.gfv''. Now you can start Gfsview directly with the saved parameters

+

gfsview2D file.gfs vectors.gfv

+

+

We can pipe the results at every time we want directly in Gfsview, for

+

example

+

+

GfsOutputSimulation { step = 1 } stdout

and running

and running

-

Gerris2D tutorial5.gts | Gfsview -s vectors.gfv

+

gerris2D tutorial5.gfs | gfsview2D -s vectors.gfv

-

but stationary flows are stationary.

+

but stationary flows are stationary...

= Adding objects =

= Adding objects =

-

We will add a solid object in our channel, a cylinder. Gerris uses implicit functions to define solids, the Gerris word is '''GfsSolid''' and the syntax

+

We will add a solid object in our channel, a cylinder. Gerris uses implicit

+

functions to define solids, the Gerris keyword is '''[[GfsSolid]]''' and the

+

syntax

-

GfsSolid ( ''implicit function'' )

+

[[GfsSolid]] ( ''implicit function'' )

-

by the way a circle of radius 0.125 at (0,0) is

+

for example, a circle of radius 0.125 at (0,0) is

-

GfsSolid (x*x + y*y - 0.125*0.125)

+

[[GfsSolid|Solid]] (x*x + y*y - 0.125*0.125)

-

We also can refine the solid using the Gerris word '''RefineSolid''' like

+

We can also refine the solid using the Gerris keyword '''RefineSolid''',

-

'''RefineSolid 6'''

+

like

-

We note that Gerris can deal with arbitrarily complex solid boundaries (in '''gts''' format) embedded in the quad/octree mesh but creating polygonal surfaces is not an easy job and is explained in other tutorial. We use in this case the same Gerris word, ''GfsSolid mycomplexsurface.gts''.

+

'''[[GfsRefineSolid|RefineSolid]] 6'''

+

We note that Gerris can deal with arbitrarily complex solid boundaries (in

+

'''gts''' format) embedded in the quad/octree mesh but creating polygonal

+

surfaces is not an easy job and is explained in other tutorials. We use in

+

this case the same Gerris word, ''GfsSolid mycomplexsurface.gts''.

Now for our cylinder the script is

Now for our cylinder the script is

-

2 1 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

2 1 GfsSimulation GfsBox GfsGEdge {} {

-

'''GfsSolid (x*x + y*y - 0.125*0.125)'''

+

Refine 5

-

'''RefineSolid 6'''

+

Solid (x*x + y*y - 0.125*0.125)

-

GfsTime {end = 5}

+

RefineSolid 6

-

SourceViscosity 1.

+

Time { end = 5 }

-

GfsOutputLocation { step = 1 } data positionXYZ

+

SourceViscosity 1.

-

GfsOutputLocation { step = 1 } data0.45 positionX0.45YZ

+

OutputLocation { step = 1 } data positionXYZ

-

GfsOutputLocation { step = 1 } data1.45 positionX1.45YZ

+

OutputLocation { step = 1 } data0.45 positionX0.45YZ

-

GfsOutputSimulation { time = 1} file.gts

+

OutputLocation { step = 1 } data1.45 positionX1.45YZ

-

}

+

OutputSimulation { start = 1.0 } file.gfs

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet P 1

+

left = Boundary {

-

}

+

BcDirichlet P 1

-

top = Boundary {

+

}

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

GfsBox {

+

}

-

right = Boundary {

+

}

-

BcDirichlet P 0

+

GfsBox {

-

}

+

right = Boundary {

-

top = Boundary {

+

BcDirichlet P 0

-

BcDirichlet U 0

+

}

-

BcDirichlet V 0

+

top = Boundary {

-

}

+

BcDirichlet U 0

-

bottom = Boundary {

+

BcDirichlet V 0

-

BcDirichlet U 0

+

}

-

BcDirichlet V 0

+

bottom = Boundary {

-

}

+

BcDirichlet U 0

-

1 2 right

+

BcDirichlet V 0

+

}

+

}

+

1 2 right

+

</source>

-

Saving the Gerris script on '''tutorial6.gfs''' and running

+

Saving the Gerris script in '''tutorial6.gfs''' and running

-

Gerris2D tutorial6.gfs

+

gerris2D tutorial6.gfs

-

Gfsview -s vectors.gvf file.gts

+

gfsview -s vectors.gfv file.gfs

-

we can see the Benard-Von Karman wakes.

+

we can (not) see the Benard-Von Karman wake.

-

[[File:wake.jpg]]

+

[[Image:wake.jpg]]

humm, let's go to a textbook...

humm, let's go to a textbook...

Line 494:

Line 595:

== Wake behind a cylinder ==

== Wake behind a cylinder ==

-

ah the Reynolds number have to be bigger than 50 and we need a long channel to allow the wake develops...

+

ah the Reynolds number has to be bigger than 50 and we need a long channel

+

to allow the wake develops...

-

The Reynolds number is compute from the box of size 1 but for the specific case of the wakes behind of cylinder the typical length is the cylinder diameter. So Red = Re/4 because the cylinder diameter is L/4.

+

The Reynolds number is computed from the box of size 1 but for the specific

+

case of the wake behind a cylinder the typical length is the cylinder

+

diameter. So Red = Re/4 because the cylinder diameter is L/4.

-

We add also 2 other boxes (we know how) and we set the Reynolds number to 100

+

We add also 2 other boxes (we know how) and we set the Reynolds number to

-

the Reynolds number to 400. (which is 100. using the cylinder diameter), '''SourceViscosity 1./400.'''

+

100

-

the final time to 10 '''GfsTime {end = 10}'''

+

# '''SourceViscosity 1./400.'''

-

the final file results file10.gts at time 10 '''GfsOutputSimulation { start = end } file10.gts'''

+

# the final time to 10 '''Time { end = 10 }'''

+

# the final file results file10.gfs at time 10 '''OutputSimulation { start = end } file10.gfs'''

The Gerris script is

The Gerris script is

-

4 3 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

4 3 GfsSimulation GfsBox GfsGEdge {} {

-

GfsSolid (x*x + y*y - 0.125*0.125)

+

Refine 5

-

GfsTime {end = 10}

+

Solid (x*x + y*y - 0.125*0.125)

-

SourceViscosity 1./400.

+

Time {end = 10}

-

GfsOutputLocation { step = 1 } data positionXYZ

+

SourceViscosity 1./400.

-

GfsOutputLocation { step = 1 } data0.45 positionX0.45YZ

+

OutputLocation { step = 1 } data positionXYZ

-

GfsOutputLocation { step = 1 } data1.45 positionX1.45YZ

+

OutputLocation { step = 1 } data0.45 positionX0.45YZ

-

GfsOutputSimulation { start = end } file10.gts

+

OutputLocation { step = 1 } data1.45 positionX1.45YZ

-

}

+

OutputSimulation { start = end } file10.gts

-

GfsBox {

+

}

-

left = Boundary {

+

GfsBox {

-

BcDirichlet U 1

+

left = Boundary {

-

}

+

BcDirichlet U 1

-

top = Boundary {

+

}

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

}

+

}

-

GfsBox {

+

}

-

top = Boundary {

+

GfsBox {

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

}

+

}

-

GfsBox {

+

}

-

top = Boundary {

+

GfsBox {

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

}

+

}

-

GfsBox {

+

}

-

right = BoundaryOutflow

+

GfsBox {

-

top = Boundary {

+

right = BoundaryOutflow

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

}

+

}

-

1 2 right

+

}

-

2 3 right

+

1 2 right

-

3 4 right

+

2 3 right

+

3 4 right

+

</source>

-

We found the following results

+

We find the following results

-

[[File:cmprefine5.jpg]]

+

[[Image:cmprefine5.jpg]]

-

and the wake..? hum we will try a more discretized mesh, we set now

+

and were is the wake..? hum we will try a finer mesh, we now set

'''Refine 6'''

'''Refine 6'''

Line 573:

Line 680:

and now the famous wake appears!!!

and now the famous wake appears!!!

-

[[File:cmprefine6.jpg]]

+

[[Image:cmprefine6.jpg]]

-

conclusion : don't forget discretization!! It could be interesting to have a dynamical adaptive meshing.

+

conclusion: don't forget the discretization!! It could be interesting to

+

have dynamical adaptive meshing.

= Adaptive meshing =

= Adaptive meshing =

-

We are going to use dynamic adaptive mesh refinement, a very interesting characteristic of Gerris where the quad-tree structure of the discretization is used to adaptively follow the small structures of the flow, thus concentrating the computational effort on the area where it is most needed.

+

We are going to use dynamic adaptive mesh refinement, a very interesting

+

characteristic of Gerris where the quadtree structure of the discretization

+

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 GfsAdapt which inherits (yet) GfsEvent. Various criteria can be used to determine where refinement is needed. In practice, each criteria 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.

+

This is done using [[GfsAdapt]] which inherits (again) from [[GfsEvent]].

+

Various criteria can be used to determine where refinement is needed. In

+

practice, each criteria 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.

-

GfsAdapt is the base class for all the objects used to adapt the resolution dynamically, the parameters are

+

[[GfsAdapt]] is the base class for all the objects used to adapt the resolution

+

dynamically, the parameters are

-

minlevel

+

; minlevel: The minimum number of refinement levels (default is 0).

-

The minimum number of refinement levels (default is 0).

+

; maxlevel: The maximum number of refinement levels (default is infinity).

-

maxlevel

+

; mincells: The minimum number of cells in the simulation (default is 0).

-

The maximum number of refinement levels (default is infinity).

+

; maxcells: The maximum number of cells in the simulation. If this number is reached, the algorithm optimizes the distribution of the cells so that the maximum cost over all the cells is minimized (default is infinity).

-

mincells

+

; cmax: The maximum cell cost allowed. If the number of cells is smaller than the maximum allowed and the cost of a cell is larger than this value, the cell will be refined.

-

The minimum number of cells in the simulation (default is 0).

+

;weight: When combining several criteria, the algorithm will weight the cost of each by this value in order to compute the total cost (default is 1).

-

maxcells

+

;cfactor: Cells will be coarsened only if their cost is smaller than cmax/cfactor (default is 4).

-

The maximum number of cells in the simulation. If this number is reached, the algorithm optimizes the distribution of the cells so that the maximum cost over all the cells is minimized (default is infinity).

+

-

cmax

+

-

The maximum cell cost allowed. If the number of cells is smaller than the maximum allowed and the cost of a cell is larger than this value, the cell will be refined.

+

-

weight

+

-

When combining several criteria, the algorithm will weight the cost of each by this value in order to compute the total cost (default is 1).

+

-

cfactor

+

-

Cells will be coarsened only if their cost is smaller than cmax/cfactor (default is 4).

+

-

We will use '''GfsAdaptVorticity''' defined as the norm of the local vorticity vector multiplied by the cell size and divided by the maximum of the velocity norm over the whole domain. The syntax is

+

We will use '''[[GfsAdaptVorticity]]''' defined as the norm of the local

+

vorticity vector multiplied by the cell size and divided by the maximum of

# '''GfsAdaptGradient''' — Adapting cells depending on the local gradient of a variable

+

# '''[[GfsAdaptGradient]]''' — Adapting cells depending on the local gradient of a variable

-

# '''GfsAdaptFunction''' — Adapting cells depending on the value of a function

+

# '''[[GfsAdaptFunction]]''' — Adapting cells depending on the value of a function

-

and you can combine all together...

+

and you can combine them all together...

= Passive tracer and Adaptive meshing =

= Passive tracer and Adaptive meshing =

-

We continue to explore the adaptive meshing by the introduction of another basic concept, the passive tracer. Experimentalists use passive tracer (like ink) to visualize the fluid flows. Gerris can do that using '''GfsVariableTracer''' which advected a scalar quantity with the flow velocity, the syntax is

+

We continue to explore the adaptive meshing by the introduction of another

where we have take off the solid surface and the writing positions. Now we can save the file and pipe the stdout on GfsView to follow the dynamic of the entry jet

+

where we have taken off the solid surface and the writing positions. Now we

+

can save the file and pipe the stdout in GfsView to follow the dynamic of

+

the entry jet

-

gerris2D tutorial7.gfs | gfsview2D

+

gerris2D tutorial7.gfs | gfsview2D

-

We show the velocity field and the passive tracer for two different physical times(t=1 and t=4).

+

We show the velocity field and the passive tracer for two different physical

+

times (t=1 and t=4).

-

[[File:tuto8-T.jpg]] [[File:tuto8-T-4.jpg]]

+

[[Image:tuto8-T.jpg]] [[Image:tuto8-T-4.jpg]]

The following figure shows the mesh at different times

The following figure shows the mesh at different times

-

[[File:tuto8-G.jpg]] [[File:tuto8-G-4.jpg]]

+

[[Image:tuto8-G.jpg]] [[Image:tuto8-G-4.jpg]]

-

We add diffusion to the tracers using the Gerris word '''SourceDiffusion''' like

+

We add diffusion to the tracers using the Gerris word '''[[GfsSourceDiffusion|SourceDiffusion]]'''

+

like so

-

SourceDiffusion T 0.001

+

[[GfsSourceDiffusion|SourceDiffusion]] T 0.001

and the solution for t=4 is now

and the solution for t=4 is now

-

[[File:tuto8-Tdiff-4.jpg]]

+

[[Image:tuto8-Tdiff-4.jpg]]

-

we note that tracer can represent, for example, temperature or concentration.

+

we note that tracers can represent, for example, temperature or

+

concentration.

-

= (Less) passive tracer : VOF technique =

+

= (Less) passive tracer: VOF technique =

-

We know that experimentalists use bubbles to analyze fluid flows (PIV). Bubbles can be a passive tracer but ... can be a field of study. Moreover every frontier separating two different fluid have potential interest in academic and industry.

+

We know that experimentalists use bubbles to analyze fluid flows (PIV).

+

Bubbles can be a passive tracer but... can also be a field of study. Moreover

+

every frontier separating different fluids have potential interest in

+

academic and industry.

-

Gerris uses a VOF (Volume Of Fluid) technique to follow interfaces, the VOF is a numerical technique for tracking and locating interfaces, in particular fluid-fluid ones.

+

Gerris uses a VOF (Volume Of Fluid) technique to follow interfaces, the VOF

+

is a numerical technique for tracking and locating interfaces, in particular

+

fluid-fluid ones.

-

Gerris first define the marker of the interface using '''GfsVariableTracerVOF''' which defines a volume-fraction field advected using the geometrical Volume-Of-Fluid technique, the syntax is

+

Gerris first defines the marker of the interface using

+

'''[[GfsVariableTracerVOF]]''' which defines a volume-fraction field advected

+

using the geometrical Volume-Of-Fluid technique, the syntax is

-

'''VariableTracerVOF''' tracerVOF

+

'''[[GfsVariableTracerVOF]]''' tracerVOF

-

The tracer will be advected and we need to define the ''geometrical'' position of the boundary. To define the frontier Gerris uses the word '''GfsInitFraction''' with the following syntax

+

The tracer will be advected and we need to define the ''geometrical''

+

position of the boundary. To define the frontier Gerris uses the word

+

'''[[GfsInitFraction]]''' with the following syntax

-

'''GfsInitFraction''' tracerVOF (''implicit surface'')

+

'''[[GfsInitFraction]]''' tracerVOF (''implicit surface'')

-

We add now a ''bubble'' of radius 0.125 L (recall that L is the size of the unit box)

+

We now add a ''bubble'' of radius 0.125 L (recall that L is the size of the

+

unit box)

-

VariableTracerVOF T1

+

<source gfs>

-

GfsInitFraction T1 ((x)*(x) + y*y - 0.125*0.125)

+

VariableTracerVOF T1

+

InitFraction T1 ((x)*(x) + y*y - 0.125*0.125)

+

</source>

and now our script is

and now our script is

+

<source gfs>

+

4 3 GfsSimulation GfsBox GfsGEdge {} {

+

Refine 5

+

Time { end = 20 }

+

VariableTracer T

+

VariableTracerVOF T1

+

InitFraction T1 ((x)*(x) + y*y - 0.125*0.125)

+

SourceViscosity 1./400

+

AdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T1

+

AdaptGradient { istep = 1 } {maxlevel = 6 cmax = 1e-2} T

+

OutputTime { step = 1 } stderr

+

OutputSimulation { step = 1 } stdout

+

}

+

GfsBox {

+

top = Boundary {

+

BcDirichlet U 0

+

BcDirichlet V 0

+

}

+

bottom = Boundary {

+

BcDirichlet U 0

+

BcDirichlet V 0

+

}

+

left = Boundary {

+

BcDirichlet U ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

BcDirichlet T ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

}

+

}

+

GfsBox {}

+

GfsBox {}

+

GfsBox {

+

right = BoundaryOutflow

+

}

+

1 2 right

+

2 3 right

+

3 4 right

+

</source>

-

4 3 GfsSimulation GfsBox GfsGEdge {} {

+

where we added mesh refinement in the line GfsAdaptGradient { istep = 1 } {

-

Refine 5

+

maxlevel = 7 cmax = 1e-2 } T1, the following figures show the two tracers T

-

Time { end = 20 }

+

and T1 for physical times t=1 and t=4.

-

VariableTracer T

+

-

'''VariableTracerVOF T1'''

+

-

'''InitFraction T1 ((x)*(x) + y*y - 0.125*0.125)'''

+

-

SourceViscosity 1./400

+

-

'''GfsAdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T1'''

+

-

GfsAdaptGradient { istep = 1 } {maxlevel = 6 cmax = 1e-2} T

+

-

OutputTime { step = 1 } stderr

+

-

OutputSimulation { step = 1 } stdout

+

-

}

+

-

GfsBox {

+

-

top = Boundary {

+

-

BcDirichlet U 0

+

-

BcDirichlet V 0

+

-

}

+

-

bottom = Boundary {

+

-

BcDirichlet U 0

+

-

BcDirichlet V 0

+

-

}

+

-

left = Boundary {

+

-

BcDirichlet U ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

-

BcDirichlet T ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

-

}

+

-

}

+

-

GfsBox {

+

-

}

+

-

GfsBox {

+

-

}

+

-

GfsBox {

+

-

right = BoundaryOutflow

+

-

}

+

-

1 2 right

+

-

2 3 right

+

-

3 4 right

+

-

+

-

where we added mesh refinement in the line GfsAdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T1, the following figures show the two tracers T and T1 for physical times t=1 and t=4.

+

-

[[File:tuto9-T.jpg]] [[File:tuto9-T-4.jpg]]

+

[[Image:tuto9-T.jpg]] [[Image:tuto9-T-4.jpg]]

== Adding surface tension ==

== Adding surface tension ==

-

Gerris can model the ''physical'' characteristics of the frontier (signaled by the tracer T1 in the last script), Gerris uses two reserved words

+

Gerris can model the ''physical'' characteristics of the frontier (signaled

+

by the tracer T1 in the last script), Gerris uses two reserved words

-

'''GfsSourceTension''' which adds a surface-tension term to the momentum equations, associated with an interface defined by its volume fraction and curvature.

+

* '''[[GfsSourceTension]]''' which adds a surface-tension term to the momentum equations, associated with an interface defined by its volume fraction and curvature.

-

'''VariableCurvature''' which contains the mean curvature (double the mean curvature in 3D) of an interface

+

* '''[[GfsVariableCurvature]]''' which contains the mean curvature (double the mean curvature in 3D) of an interface

which says ''rely the variable of curvature K to the tracer T1 and add a surface-tension term with constant tension equal to 0.01''

+

which says ''define the curvature K of the interface defined by tracer T1 and add a surface-tension term with constant tension equal to 0.1''

The script is

The script is

-

4 3 GfsSimulation GfsBox GfsGEdge {} {

+

<source gfs>

-

Refine 5

+

4 3 GfsSimulation GfsBox GfsGEdge {} {

-

Time { end = 20 }

+

Refine 5

-

VariableTracer T

+

Time { end = 20 }

-

VariableTracerVOF T1

+

VariableTracer T

-

InitFraction T1 ((x)*(x) + y*y - 0.125*0.125)

+

VariableTracerVOF T1

-

'''GfsVariableCurvature K T1'''

+

InitFraction T1 ((x)*(x) + y*y - 0.125*0.125)

-

'''GfsSourceTension T1 0.01 K'''

+

VariableCurvature K T1

-

SourceViscosity 1./400

+

SourceTension T1 0.1 K

-

GfsAdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T1

+

SourceViscosity 1./400

-

GfsAdaptGradient { istep = 1 } {maxlevel = 6 cmax = 1e-2} T

+

AdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T1

-

OutputTime { step = 1 } stderr

+

AdaptGradient { istep = 1 } {maxlevel = 6 cmax = 1e-2} T

-

OutputSimulation { step = 1 } stdout

+

OutputTime { step = 1 } stderr

-

}

+

OutputSimulation { step = 1 } stdout

-

GfsBox {

+

}

-

top = Boundary {

+

GfsBox {

-

BcDirichlet U 0

+

top = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

bottom = Boundary {

+

}

-

BcDirichlet U 0

+

bottom = Boundary {

-

BcDirichlet V 0

+

BcDirichlet U 0

-

}

+

BcDirichlet V 0

-

left = Boundary {

+

}

-

BcDirichlet U ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

left = Boundary {

-

BcDirichlet T ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

BcDirichlet U ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

-

}

+

BcDirichlet T ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

-

}

+

}

-

GfsBox {

+

}

-

}

+

GfsBox {}

-

GfsBox {

+

GfsBox {}

-

}

+

GfsBox {

-

GfsBox {

+

right = BoundaryOutflow

right = BoundaryOutflow

-

}

+

}

-

1 2 right

+

1 2 right

-

2 3 right

+

2 3 right

-

3 4 right

+

3 4 right

+

</source>

The figures show the jet ''pushing'' the bubble for times t=1, 4, 6, 8.

The figures show the jet ''pushing'' the bubble for times t=1, 4, 6, 8.

-

[[File:tuto10-T.jpg]] [[File:tuto10-T-4.jpg]]

+

[[Image:tuto10-T.jpg]] [[Image:tuto10-T-4.jpg]]

-

[[File:tuto10-T-6.jpg]] [[File:tuto10-T-8.jpg]]

+

[[Image:tuto10-T-6.jpg]] [[Image:tuto10-T-8.jpg]]

== Breaking bubbles ==

== Breaking bubbles ==

-

What will happens if we lower the surface tension? Set now

+

What happens if we lower the surface tension? Set now

'''GfsSourceTension''' T1 0.01 K

'''GfsSourceTension''' T1 0.01 K

+

The figures show the jet ''pushing'' the bubble which now ... breaks!! (for

+

times t=1, 4, 6, 8).

-

The figures show the jet ''pushing'' the bubble which now ... breaks!! (for times t=1, 4, 6, 8).

+

[[Image:tuto11-T.jpg]] [[Image:tuto11-T4.jpg]]

-

[[File:tuto11-T.jpg]] [[File:tuto11-T4.jpg]]

+

[[Image:tuto11-T6.jpg]] [[Image:tuto11-T8.jpg]]

-

+

-

[[File:tuto11-T6.jpg]] [[File:tuto11-T8.jpg]]

+

and the grid and a little (big) zoom for time t=8

and the grid and a little (big) zoom for time t=8

-

[[File:tuto11-T8Grid.jpg]] [[File:tuto11-T8zoom.jpg]]

+

[[Image:tuto11-T8Grid.jpg]] [[Image:tuto11-T8zoom.jpg]]

-

[[File:t.mpg]]

+

It is interesting to note that in the grid figure above Gerris uses 3232

-

+

mesh points (or squares). Without adaptive mesh refinement we must set 4

-

[[File:level.mpeg]]

+

boxes of 64x64 or more of 128x128 because the frontier needs a 7 level

-

+

refinement so 3232 or 16384 or 65538, you have the choice.

-

+

-

It is interesting to note that in the grid figure above Gerris uses 3232 mesh points (or squares). Without adaptive mesh refinement we must set 4 boxes of 64x64 or more of 128x128 because the frontier needs a 7 level refinement so

+

-

3232 or 16384 or 65538

+

-

you have the choice.

+

= Gerris in parallel =

= Gerris in parallel =

-

One of the human's dreams is to run a program in parallel, Gerris allows do it quite easily, for instance if you want run our last script in four processors we have to modify only the boundary conditions using the Gerris word '''pid''' like

+

One of man's dreams is to run a program in parallel. Gerris allows to do

+

this quite easily, for instance if you want run our last script on four

+

processors we have to modify only the boundary conditions using the Gerris

+

keyword '''pid''' like

-

GfsBox { '''pid = 0'''

+

<source gfs>

-

top = Boundary {

+

4 3 GfsSimulation GfsBox GfsGEdge {} {

-

BcDirichlet U 0

+

Refine 5

-

BcDirichlet V 0

+

Time { end = 20 }

-

}

+

VariableTracer T

-

bottom = Boundary {

+

VariableTracerVOF T1

-

BcDirichlet U 0

+

InitFraction T1 ((x)*(x) + y*y - 0.125*0.125)

-

BcDirichlet V 0

+

VariableCurvature K T1

-

}

+

SourceTension T1 0.01 K

-

left = Boundary {

+

SourceViscosity 1./400

-

BcDirichlet U ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

AdaptGradient { istep = 1 } { maxlevel = 7 cmax = 1e-2 } T1

-

BcDirichlet T ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

AdaptGradient { istep = 1 } {maxlevel = 6 cmax = 1e-2} T

-

}

+

OutputTime { step = 1 } stderr

+

OutputSimulation { step = 1 } stdout

+

}

+

GfsBox {

+

pid = 0

+

top = Boundary {

+

BcDirichlet U 0

+

BcDirichlet V 0

}

}

-

GfsBox { '''pid = 1'''

+

bottom = Boundary {

+

BcDirichlet U 0

+

BcDirichlet V 0

}

}

-

GfsBox { '''pid = 2'''

+

left = Boundary {

+

BcDirichlet U ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

+

BcDirichlet T ( (y > -0.05 && y < 0.05 ) ? 1 : 0 )

}

}

-

GfsBox { '''pid = 3'''

+

}

-

right = BoundaryOutflow

+

GfsBox { pid = 1 }

-

}

+

GfsBox { pid = 2 }

+

GfsBox {

+

pid = 3

+

right = BoundaryOutflow

+

}

+

1 2 right

+

2 3 right

+

3 4 right

+

</source>

and run the script with

and run the script with

Line 966:

Line 1,127:

mpirun -np 4 gerris2D tutorial2.gfs

mpirun -np 4 gerris2D tutorial2.gfs

-

What we do is an example of manually partitioning the domain. In more complex cases, Gerris can also automatically partition the domain for a given number of processors, variable resolution, complex boundaries.

+

What we do is an example of manually partitioning the domain. In more

+

complex cases, Gerris can also automatically partition the domain for a

Very very simple tutorial

This is a step by step tutorial to Gerris.

Gerris is a Partial Differential Equations Solver (PDES) for the
time-dependent incompressible variable-density Euler, Stokes or
Navier-Stokes equations (and some variants). Gerris is also a programming
language and we begin now with some basic concepts.

Gerris as a language

When we learn a language we begin with words, then syntax, and then
semantic.

The Gerris language is composed by words that reflect the internal structure
of the code. The Gerris code is written in C with inheritance.

The Gerris language is an inheritance language where the root of each word
is a component of its parent.

Sample code : intermezzo

We need to define the computational time and the data we want to output.

The Gerris word GfsTime defines the physical and the computational
time (number of time steps performed). By default both the physical time
and the time step number are zero when the program starts. It is possible
to set different values using for example

where i is the time step number and t is the physical time. The end
identifier specifies that the simulation should stop when the physical time
reaches the given value. It is also possible to stop the simulation
when a specified number of time steps is reached, using the iend identifier.
If both end and iend are specified, the simulation stops when either of
these are reached. By default, both end and iend values are infinite.

Gerris comes with a number of objects allowing to output specific data of
the simulation. For that we need take a look at GfsOutput. A
generic object which defines a given family (parent and childrens).

The parent of GfsOutput is GfsEvent which is used to
control any action which needs to be performed at a given time during a
simulation. The keywords for GfsEvent are

start

Physical starting time (default is zero). The "end" keyword can be used to indicate the end of the simulation.

istart

Time step starting time (default is zero).

step

Repeat every step physical time units (default is infinity).

istep

Repeat every istep time steps (default is infinity).

end

Stop at or before this physical time (default is infinity).

iend

Stop at or before this number of time steps (default is infinity).

The children of GfsOutput are .. many ... (a rabbit family). Here are
a few

which says, we write into a file file.gfs every 0.3 of physical time
starting from 0.6. The data format gfs is a Gerris format and we will
talk about it later. Note that you can save data in other formats if you
want.

which says do every unit time the following: write in file data
the numerical values of the dynamical variables at positions given by the
input file positionXYZ. The input file is an ascii file with three
columns of coordinates (x y z)

Sample code: viscosity

We forgot the viscosity!!! we take now take a look at the Gerris
documentation

By default, the density is unity and the molecular viscosity is zero (i.e. there is no explicit viscous term in the momentum equation). In practice, it does not mean that there is no viscosity at all however, because any discretization scheme always has some numerical viscosity. However, keep in mind that the only relevant parameter for the (constant density) Navier-Stokes equations is the Reynolds number. If you do not include any explicit viscous term the (theoretical) Reynolds number is always infinite.

So our script is wrong, good syntax but bad semantic!!! That tels us that we
have to think about the physical problem first!!!

Sample code: adding a box

Now we add a box to the right of our first box (the domain is now 2x1), 2 in
x coordinates [(0.5:1.5)]. We generate also a new file positionX1.45YZ to
study the profile at the end of the two boxes. We modify the Gerris file as
follows

which says write the whole simulation in file file.gfs at the final
time.

Now we can run Gfsview

gfsview2D file.gfs

and clicking on “Linear”, “Vectors” in the tool-bar and changing the vector
length by editing the properties of the “Vectors” object (select the object
then choose “Edit→Properties”) you should be able to get something looking
like

You can also pan by dragging the right mouse button, zoom by dragging the
middle button and rotate by dragging the left button.

You can get the value of an object by selecting the object on the left
panel; then press the Ctrl key and click on the position where you want to
get the object value, while continuing to hold the Ctrl key.

If you like a given representation of results and you want to reuse it you
can save the Gfsview file ("Save" in toolbar) in gfv format, like
vectors.gfv. Now you can start Gfsview directly with the saved parameters

gfsview2D file.gfs vectors.gfv

We can pipe the results at every time we want directly in Gfsview, for
example

GfsOutputSimulation { step = 1 } stdout

and running

gerris2D tutorial5.gfs | gfsview2D -s vectors.gfv

but stationary flows are stationary...

Adding objects

We will add a solid object in our channel, a cylinder. Gerris uses implicit
functions to define solids, the Gerris keyword is GfsSolid and the
syntax

We note that Gerris can deal with arbitrarily complex solid boundaries (in
gts format) embedded in the quad/octree mesh but creating polygonal
surfaces is not an easy job and is explained in other tutorials. We use in
this case the same Gerris word, GfsSolid mycomplexsurface.gts.

Wake behind a cylinder

ah the Reynolds number has to be bigger than 50 and we need a long channel
to allow the wake develops...

The Reynolds number is computed from the box of size 1 but for the specific
case of the wake behind a cylinder the typical length is the cylinder
diameter. So Red = Re/4 because the cylinder diameter is L/4.

We add also 2 other boxes (we know how) and we set the Reynolds number to
100

SourceViscosity 1./400.

the final time to 10 Time { end = 10 }

the final file results file10.gfs at time 10 OutputSimulation { start = end } file10.gfs

conclusion: don't forget the discretization!! It could be interesting to
have dynamical adaptive meshing.

Adaptive meshing

We are going to use dynamic adaptive mesh refinement, a very interesting
characteristic of Gerris where the quadtree structure of the discretization
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 GfsAdapt which inherits (again) from GfsEvent.
Various criteria can be used to determine where refinement is needed. In
practice, each criteria 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.

GfsAdapt is the base class for all the objects used to adapt the resolution
dynamically, the parameters are

minlevel

The minimum number of refinement levels (default is 0).

maxlevel

The maximum number of refinement levels (default is infinity).

mincells

The minimum number of cells in the simulation (default is 0).

maxcells

The maximum number of cells in the simulation. If this number is reached, the algorithm optimizes the distribution of the cells so that the maximum cost over all the cells is minimized (default is infinity).

cmax

The maximum cell cost allowed. If the number of cells is smaller than the maximum allowed and the cost of a cell is larger than this value, the cell will be refined.

weight

When combining several criteria, the algorithm will weight the cost of each by this value in order to compute the total cost (default is 1).

cfactor

Cells will be coarsened only if their cost is smaller than cmax/cfactor (default is 4).

We will use GfsAdaptVorticity defined as the norm of the local
vorticity vector multiplied by the cell size and divided by the maximum of
the velocity norm over the whole domain. The syntax is

Passive tracer and Adaptive meshing

We continue to explore the adaptive meshing by the introduction of another
basic concept, the passive tracer. Experimentalists use passive tracer (like
ink) to visualize the fluid flows. Gerris can do that using
GfsVariableTracer which advects a scalar quantity with the flow
velocity, the syntax is

we note that tracers can represent, for example, temperature or
concentration.

(Less) passive tracer: VOF technique

We know that experimentalists use bubbles to analyze fluid flows (PIV).
Bubbles can be a passive tracer but... can also be a field of study. Moreover
every frontier separating different fluids have potential interest in
academic and industry.

Gerris uses a VOF (Volume Of Fluid) technique to follow interfaces, the VOF
is a numerical technique for tracking and locating interfaces, in particular
fluid-fluid ones.

Gerris first defines the marker of the interface using
GfsVariableTracerVOF which defines a volume-fraction field advected
using the geometrical Volume-Of-Fluid technique, the syntax is

Breaking bubbles

The figures show the jet pushing the bubble which now ... breaks!! (for
times t=1, 4, 6, 8).

and the grid and a little (big) zoom for time t=8

It is interesting to note that in the grid figure above Gerris uses 3232
mesh points (or squares). Without adaptive mesh refinement we must set 4
boxes of 64x64 or more of 128x128 because the frontier needs a 7 level
refinement so 3232 or 16384 or 65538, you have the choice.

Gerris in parallel

One of man's dreams is to run a program in parallel. Gerris allows to do
this quite easily, for instance if you want run our last script on four
processors we have to modify only the boundary conditions using the Gerris
keyword pid like

What we do is an example of manually partitioning the domain. In more
complex cases, Gerris can also automatically partition the domain for a
given number of processors, variable resolution, complex boundaries.