This site contains the C++ source code and the documentation for routines
incorporating the anisotropic nonlinear transport diffusion for time dependent flow visualization.
The gzipped tar file contains the header file "timedepFlowVis.h",
the source file "timedepFlowVis.cpp", a Makefile, a
sample program, and this html file.
Note that this program computes only a sequence of pictures that have to be blended to be animated in a movie. Have a look at the corresponding reserach project site for details.
Download here:
timedepFlowVis.tar.gz (ca. 4MB)
(includes the source code and the vector field data)
FlowVisSourceCode.tar.gz (ca. 115KB)
(includes only the source code)
FlowVisVectorField.tar.gz (ca.3,9MB)
(includes only the vector field data)
Corresponding Research Project Site: PDE
Method in Flow Visualization
![]()
| Getting Started | |
| Available Constructors and the Function "timeStep" | |
| The Variables | |
| Study of Parameters | |
| File formats | |
| The C++ Source Code | |
| Documentation generated by doxygen |
After downloading the file timedepFlowVis.tar.gz you should unpack this file to some directory using the commands
gzip -d timedepflowVis.tar.gz
tar -xvf timedepflowVis.tar
This will extract all files you need. Next
you should compile the package using the given Makefile (command
"make").
The compile process will create a sample program which will visualize the
sample vector field data contained in the directory benard. Start the program
using the command "main".
The program will start and write a lot of messages about what it is doing onto the screen. The gray-level output images will be placed in the directory picture/ and the colored images will be saved in the directory colored_picture/. The directories have been created when unpacking the tar-file. You can use any image viewer, that can read PGM files, e.g. xv, to view the images.
The default vector field example is called "EXAMPLE_BENARD".
The C++ source code enclose two other examples: "EXAMPLE_WHIRLPOOL"
and "EXAMPLE_CIRCLE".
If you want to create another vector field example you have to modify the source
code. The examples are defined in the main program (confer "timedepflowvis.cpp"):
int main() {
#define EXAMPLE_BENARD
//#define EXAMPLE_CIRCLE
//#define EXAMPLE_WHIRLPOOL
TransportDiffusion
*diff;
//... omitted source code
#ifdef EXAMPLE_CIRCLE
diff = new TransportDiffusion(10,400,400,0.01,
"./picture/picture%03d.pgm","./color_picture/color_picture%03d.pgm",
1./1000.,1./100.,200.,0.4,200,1.e-6,
lowColor,highColor);
#endif
#ifdef EXAMPLE_WHIRLPOOL
//...omitted source code
diff= new
TransportDiffusion(vf,T,M_width,N_height,0.01,
"./picture/whirlpool_%03d.pgm","./color_picture/color_whirlpool_%03d.pgm",
1./1000., 1./10000.,
100.0, 0.5, 500, 1.e-6,lowColor,highColor);
#endif
#ifdef EXAMPLE_BENARD
diff = new
TransportDiffusion("./benard/benard_%d.dat",10, 0.1,
"./picture/029_benard_%03d.pgm",
"./color_picture/029_color_benard_%03d.pgm",
1./100., 1./100.,
1.0, 0.4, 500, 1.e-6,lowColor,highColor);
#endif
diff->timeStep(1,9);
delete
diff;
//... omitted source code
}
As seen below you only have to change the red lines. For example, if you like to have the circle vector field, you have to define "EXAMPLE_CIRCLE" and to undefine the other examples:
//#define EXAMPLE_BENARD
#define EXAMPLE_CIRCLE
//#define EXAMPLE_WHIRLPOOL
The file FlowVisSourceCode.tar.gz contains only the C++ source code and not the vector field data. That means that you have only the choice between EXAMPLE_CIRCLE and EXAMPLE_WHIRLPOOL.
The file timedepFlowVis.cpp implements three constructors and the function
"TimeStep" computing the nonlinear anisotropic transport diffusion to visualize a vector field given in an
(M_width x N_height) array.
As seen below, the main program creates an object (e.g. diff)
using one of the three different constructors.
Each example uses another constructor.
Available constructors are:
Transport_Diffusion(char* VFfileName, int T ,
D_TYPE tau,
char* outputFile, char* colorOutputFile,
D_TYPE lambda, D_TYPE lambda2,
D_TYPE beta, D_TYPE scaleF,
int MAXCOUNTER, D_TYPE eps
int* lowColor, int* highColor );
Transport_Diffusion(d3p* vf, int T, int M_width, int N_height,
D_TYPE tau,
char* outputFile, char* colorOutputFile,
D_TYPE lambda, D_TYPE lambda2,
D_TYPE beta, D_TYPE scaleF,
int MAXCOUNTER, D_TYPE eps
int* lowColor, int* highColor );
Transport_Diffusion(int T, int M_width, int N_height,
D_TYPE tau,
char* outputFile, char* colorOutputFile,
D_TYPE lambda, D_TYPE lambda2,
D_TYPE beta, D_TYPE scaleF,
int MAXCOUNTER, D_TYPE eps
int* lowColor, int* highColor );
The call of the function "timeStep" ( e. g.
diff->timeStep(1,50); ) will produce several images.
It solves some time steps of the PDE system. The first time step will be the one
with number "first", the last time step will be the one with number
"last".
Function returns 0 if it was executed successfully and some value different from 0
else.
int timeStep(int first, int last);
As seen in the previous section you can set many parameters for the transport diffusion process by using a constructor from above. The following table tells you the meaning of the parameters which have to been set. The values below the type definitions of a parameter give the default value that will be set by the constructor if this parameter is omitted.
| VFfileName | CHAR* | Name of vector field data file |
| vf | d3p* | d3 is an array of length 3. d3p is a pointer
to d3. These types are used to save vf, the vector field. The
"array" vf has the following shape: vf [t][k][i] . 0 <= t < T : vector field at time step t 0 <= k < M_width+N_height : pixel with number k (lexicographical ordered) i = 0 : X-value i = 1 : Y-value i = 2 : norm ( velocity ) |
| T | INT
10 |
Determines the number of the given vector fields. |
| M_width | INT
257 |
Determines the number of pixels along the x-coordinate axis. |
| N_height | INT
257 |
Determines the number of pixels along the y-coordinate axis. |
| tau | DOUBLE
0.1 |
Determines the length of one single time
step of the anisotropic transport diffusion. This parameter must be adapted to
the distance of the vector fields. E.g. for images of width 257 the value 0.0001 is recommended, if you use a test vector field. |
| outputFile | CHAR*
|
Names of the output file of the gray images.
The resulting filename will be created using sprintf(filename,
outputFile, number). The number of the time step will be included. The
default names of the images: ./picture/picture%03d.pgm |
| colorOutputFile | CHAR*
=> |
Name of the output file of the
colored
images. The resulting filename will be created using sprintf(filename,
outputFile, number). The default names of the images: ./color_picture/color_picture%03d.pgm |
| lambda | DOUBLE
1/10000 |
The shape of the diffusion coefficient
g(), controlling the Perona Malik diffusion perpendicular to the vector field
will be g(s2) = 1/(1 + s2 / lambda2).
If you want to modify the shape of the function g more than this parameter allows you to, or even if you want to modify the function controlling the linear diffusion along the vector field, you have to modify the code directly (see below). |
| lambda2 | DOUBLE
1/100 |
This variable is used to
calculate the one sided diffusion (perpendicular to the vector field). The Function galphap needs lambda2 to calculate the Perona Malik diffusion: galphap(s2) = 1/(1 + s2 / lambda22) |
| beta | DOUBLE
10.0 |
Balancing parameter (Transport vs. Diffusion), which also controls the diffusion parallel to the vector field. |
| scale_F | DOUBLE
=> |
ScaleF controls the maximum
value of the contrast enhancing right hand side f of the PDE system.
0.0 <= scaleF <= 1.0 |
| MAXCOUNTER | INT
500 |
Determines the maximum number of iteration steps of the CG solver. |
| eps | DOUBLE
1e-6 |
Determines the numerical accuracy of the CG solver. |
| first/last | INT | Determines the number of time steps the program will perform. Each time step of the anisotropic transport diffusion will have length tau. The program starts with the "first" and stop after the "last" vector field . |
| low/highColor | INT*
=> |
The Colors are used to color
(subsequently) the velocity of the vector field. They are coded in the RGB modus. The default colors are yellow for "high" velocity and blue for "low" velocity. |
As seen in the previous section you can set
many parameters for the transport diffusion process.
The following table
tells you what will happen, if you change the parameters.
|
PARAMETER |
> (increasing the parameter) | < (decreasing the parameter) |
|
Increasing lambda means intensifying the
diffusion perpendicular to the vector field, which also means that the
diffusion parallel : diffusion perpendicular (to the vector field) -ratio
changes. |
Decreasing lambda means extenuating the
diffusion perpendicular to the vector field, which also means that the
diffusion parallel : diffusion perpendicular (to the vector field) -ratio
changes. |
|
|
Increasing lambda2 is equivalent to decreasing the one sided diffusion (confer picture4). |
Decreasing lambda2 is equivalent to increasing the one sided diffusion (confer picture3). |
|
|
Increasing beta means intensifying the
diffusion parallel to the vector field, which also means that the
diffusion parallel : diffusion perpendicular (to the vector field) -ratio
changes. |
Decreasing beta means extenuating the diffusion
parallel to the vector field, which also means that the diffusion parallel
: diffusion perpendicular (to the vector field) -ratio changes. |
|
|
Increasing scaleF means enhancing the contast |
while decreasing scaleF means reducing the contrast of the picture. |
Some picture example (at time step 5) using
different parameters:
MAXCOUNTER = 500;
eps = 1.e-6;
tau = 0,1;
This section describes the format of files containing vector field data. For detailed information on the
PGM file format please refer to the man page on your system.
Vector field data must be given on a rectangular grid consisting of <width> X <height> cells. For each cell a 2 dimensional vector, i.e. 2 floating point numbers, must be given. In general the file format used for
vector field data is similar to the PGM file format. Any file consists of a header followed by data. The definition of the header is as follows:
|
A magic number for identifying the file type. The magic number is the two characters "V2" (Upper case V). | |
|
White space (blanks, tabs, carriage returns, linefeeds). | |
|
The width of the grid on which vector field data is given, formatted as ASCII integer. | |
|
White space. | |
|
The height of the grid on which the vector field is given, again formatted in ASCII integer. |
This header is followed immediately by <width> X <height> vectors, each 2 floating point numbers, formatted as ASCII decimals, starting at the top-left corner of the grid and proceeding in normal English reading order from left to right and from top to bottom. The following is a small example of a file of the above type:
V2
3 3
1.000 0.223 2.345 0.247 1.201 -0.750
5.600 -0.229 2.326 0.213 1.232 0.740
8.234 0.245 -2.345 0.289 1.223 -0.400
Please note that no comments are allowed in vector field data files.
There is an alternative file format which stores the vectors as plain bytes instead of ASCII floating point numbers. The differences are:
|
The magic number is "V5" instead of "V2". | |
|
Only one single character of white space (typically a new line) is allowed after the header. | |
|
The data section again contains a number of vectors, but this time stored as binary data, each floating point number 8 bytes long. This corresponds to the byte length of the internal data type D_TYPE of the program. If you want to use 4 byte floating point numbers, you have to modify the source code. See next section for details. | |
|
The files are in general smaller and faster to read.
|
Although a lot of functionality of can be controlled via constructors, some features must be modified directly in the source code:
|
Data types. The data type used by timedepflowVis is fixed through the definition of
D_TYPE. Per default the definition equals to the use of double as standard type. However, if your computer suffers from lack of memory you can switch to float and recompile the code. You will also have to modify the setting of
D_TYPE, if you want to read in vector field data in 4 bytes format. | |
Diffusion coefficient alphap. The
diffusion coefficient controls the diffusion along the vector field,
implemented in assembling_matrix (file timedepFlowVis.cpp). This value depend on the velocity (the length of the
vector field) . Per default alphap is defined as beta * |vf|2 *
tau/2, but you may change the diffusion coefficient and recompile the code. | |
Diffusion coefficient alphas. Diffusion perpendicular to the
vector field is controlled by the nonlinear Diffusion coefficient G, implemented in
G (file timedepFlowVis). The shape of the default coefficient is G(s) = 1/(1 +
s2 / lambda2), but you can implement some other function here. | |
|
Contrast enhancing function. The scalar contrast enhancing function
f is defined in timedepFlowVis.cpp. | |
Test vector
field. If you want to calculate your own test vector field, you have to
use the third constructor. Before recompiling the code, you have to
implement your test vector field in calculateVectorField. Do not forget to
calculate the norm of each vector at position "two". | |
DEFINE. If you want to calculate another PDE (e.g. only diffusion/transport), you have to "undefine" USE_TRANSPORT or USE_DIFFUSION. But be careful, you have to adapt the diffusion coefficients alphap and alphas! |
You can generally make the code faster if you set more platform specific compiler options
(cf. the man page of your compiler). The program becomes even faster if you restrict the number of iterations of the CG solver enormously. This will not be mathematically exact, but you will obtain nice results even with just a few CG iterations.