FRIEDRICH-ALEXANDER-UNIVERSITAT¨ ERLANGEN-NURNBERG¨ INSTITUT FUR¨ INFORMATIK (MATHEMATISCHE MASCHINEN UND DATENVERARBEITUNG)

Lehrstuhl f¨urInformatik 10 (Systemsimulation)

waLBerla: Visualization of Fluid Simulation Data with POV-Ray

Simon Bogner, Stefan Donath, Christian Feichtinger, Ulrich R¨ude

Technical Report 09-13 waLBerla: Visualization of Fluid Simulation Data with POV-Ray

Simon Bogner, Stefan Donath, Christian Feichtinger, Ulrich R¨ude

Lehrstuhl f¨urSystemsimulation Friedrich-Alexander University of Erlangen-Nuremberg 91058 Erlangen, Germany

[email protected] December 14, 2009

Contents

1 Introduction 3

2 Feature Outline 4

3 File Structure and Output Directory Structure5 3.1 Scene Composition...... 6 3.2 Resources and Visualization Types...... 6

4 pe Objects 9

5 DensFields 10 5.1 File Structure...... 10 5.2 Usage...... 10

6 CellFields 17 6.1 Usage and Output File Structure...... 17 6.2 Porous Medium Example...... 17

7 Free Surface Visualization 20 7.1 Free Surface Extraction...... 20 7.2 Usage and Examples...... 20

8 Conclusion 23 1 Introduction

The waLBerla framework is a versatile, parallel fluid solver based on the lattice Boltzmann method (LBM). The acronym waLBerla stands for widely applicable lattice Boltzmann solver from Erlangen. Besides simulation of simple fluid flow, it supports a variety of different applications involving multi-phase and free surface flows and particulate flows with fully resolved, moving particles [DGF+07, GFI+08]. To enable efficient analysis of the simulation outcome, waLBerla features different means of data visualization. Parallel generic modules [GDF+07b] enable plotting of computed values into XMGrace-compatible graphs and writing of arbitrary, cell-based data to file formats of the visualization tool kit (VTK) [VTK09] that can be viewed and further analyzed by VTK-based tools like ParaView [Par09]. Besides value-based validation, a realistic visualization of the flow and its characteristic quantities is important and of avail because human intuition is best proof for nature’s behavior. Consequently, waLBerla has been extented by a generic module for output files that are readable by POV-Ray, which is a well-known ray tracer tool [oVPL04]. Thus, the motion would become visible by rendering images of different time steps with the POV-Ray raytracer. Initially developed to only visualize particulate flows, this waLBerla module has been enhanced in order to be compatible with free surface flows, too, and be able to visualize scientific relevant data like densities, velocities and forces. This report gives a detailed insight into the technical realization of a flexible interface between waLBerla and POV-Ray, using the POV-Ray scene description language (SDL).

3 2 Feature Outline

WaLBerla can create special output data using the POV-Ray scene description language (SDL). SDL is a language used to define a 3-dimensional world consisting of various geometrical shapes, light sources, etc... The following list gives a rough summary of the output options currently provided by waLBerla.

DensField: A DensField is a 3-dimensional array of floating point values. As described in [GDF+07a], waLBerla holds the simulation data in Fields. WaLBerla can be instructed to write out the values of any field of type ScalarField or type VecField (DensField1 and VelField, in which waLBerla stores the macroscopic values of density and fluid velocity, are also possible) in an axis-aligned subregion as a DensField. Typical application: Visualization of the velocity or density profile of a flow.

CellField: CellFields can be used to visualize the waLBerla FlagField. A CellField is thus an axis-aligned subregion of the FlagField. Usually one is interested in cells of a certain flag state only. Typical application: Visualization of the geometry of a porous medium. FreeSurface: If a free surface flow is simulated, the behavior of the free surface may be visualized either by its surface normals, which can be shown as glyphs, or by a triangle mesh resembling the free surface. Typical application: Visualization of two-phase free surface flows, such as foams.

Obstacles: The various kinds of obstacles (i.e. particles, walls, etc.) supported by waLBerla (see [GDF+07b]) can be visualized. Typical application: Visualization of particle suspensions.

Ray tracing is a powerful way to create images from spatial information, but because of its computation- intensive nature it is far from being interactive. In spite of this limitation, one of the main design goals was to provide the user with as much flexibility as possible, i.e., to provide the output not only in a format adapted to POV-Ray, but also well-readable and modifiable for the user. The SDL files generated by waLBerla can be edited to adjust the output files to change the properties (point of view, light sources, colors and textures of objects, etc.) of the final images. The following section treats the activation of POV-Ray output via waLBerla parameter files. An overview of the most important output files and file dependencies is given. Also the incorporation of external resources, e.g. textures, to a visualization is explained. For the actual usage and visualization options of DensFields, CellFields, FreeSurfaces and Obstacles, respectively, own sections have been devoted. It is suggested to the reader to take a look on the next section carefully and then continue with a section of his interest.

1Name coincidence: There is also a waLBerla-internal scalar field called DensField!

4 3 File Structure and Output Directory Structure

In order to facilitate POV-Ray visualizations, the various output options have been integrated in the waLBerla parameter file. A povray block has to be specified by the user in order to activate and control the POV-Ray specific output. Listing1 exemplarily shows a typical povray block that would create an output directory named /simdata/povray. In the output directory waLBerla creates the directory structure shown in Fig.3.

Figure 1: Directory Structure

./dat contains the data to be rendered /0 objects/data written by process 1. /1 objects/data written by process 2. ... ./plane velocity planes (not subject of this report) /0 objects/data written by process 1. /1 objects/data written by process 2. ... ./png empty output directory for final images rendered by POV-Ray ./res include files for POV-Ray /resource1.inc user-declared include file 1 /resource2.inc user-declared include file 2 ... ./Globals.inc global declarations and scene composition for the POV-Ray visualization ./Cam0.pov Camera 0 ./Cam1.pov Camera 1 ... ./GenerateMPG.py a python script that calls FFmpeg to create animations from rendered images. ./GeneratePOV.py a python script that calls POV-Ray to render the final images.

Inside the povray block, the spacing keyword specifies how often data is written to the ./dat direc- tory in the output directory specified by filename. Since a simulation may run on multiple processes in parallel, each process will store its data in a subdirectory named by the process number. All objects (DensFields, obstacles, etc.) for the visualization are stored in these subdirectories, depending on which process the respective data is computed. For more details on waLBerla parallelization, please refer to [GDF+07b]. The data output files of different time steps for each object are numbered in subsequent order starting from zero - irrespective of the setting of the spacing variable. To eventually compose the written objects to a scene, waLBerla creates the file ./Globals.inc, which will be described in the next subsection. Inside the povray block, one ore more cameras have to be defined in the form of camera blocks. For each camera, individual light sources can be added to the scene. Each camera block leads to the creation of a file ./Cam.pov, where number is substituted by the number of the camera. The camera file automatically includes the scene file ./Globals.inc. For more information on cameras and light sources please refer to the POV-Ray documentation [oVPL04]. Additionally the user can instruct the inclusion of external POV-Ray resources to the file ./Globals.inc

5 Listing 1: Povray block example povray { spacing10; //writedataevery10.thtimestep filename /simdata/povray; // directory to create file −structure in

camera { p o s i t i o n L <−25,−25,75>; // position of the camera l o o k A t L <25 ,25 ,25 >; //controlsthelook−direction of the camera

p o i n t l i g h t { // automatically add a light source for this camera p o s i t i o n L <−25, −25, 75 >; // light position rgb <1 ,1 ,1 >; //lightcolor }

a r e a l i g h t { // another type of light source p o s i t i o n L <10, 1 , 40 >; l o w e r l e f t L <15, 0 , 0>; t o p r i g h t L <0, 0 , 15 >; s a m p l e x 1 ; s a m p l e y 1 ; f a d e distance 120; f a d e p o w e r 1 ; } }

// ’resource’ blocks can be used to include additional sdl files in povray r e s o u r c e { file ”textures.inc”; // povray standard textures } r e s o u r c e { file examples/povray/resources/Textures.dat; } // user defined textures }

by specifying an arbitrary number of resource blocks. Each resource block must have one file pa- rameter defined, which is either the file name of a user-created file or a standard include file provided by POV-Ray. In the latter case, the file name must be given in the form ’’’’. In the former case, the external file will automatically be copied into the output directory as ./res/resource.inc. Again, the files are tagged with a number . This is useful in order to add external resources (textures, color maps, etc.) to the scene. See also Sec. 3.2.

3.1 Scene Composition Figure2 exemplarily shows the dependencies of files for a project with two parallel processes and three cameras defined. As described above there will typically be multiple files for each object. Each waLBerla process creates one output file per written time step for every object residing on the respective process. These files are composed to a scene in the file ./Globals.inc. Since single objects may reside on different waLBerla processes, and therefore the output data may reside in different directories, multiple files may have to be included for one and the same object (see Fig.3). Even though there may be data written from different time steps, of course only files of the same time step are used to compose the scene: To include all files of a given time step, a control variable timestep is used. This variable may be set by the user to specify the time step to be rendered. By default, the internal POV-Ray variable frame_number is used to select the time step. See the chapter on animation in the POV-Ray documentation [oVPL04] for more information on the frame_number variable.

3.2 Resources and Visualization Types To control the looks of rendered objects, POV-Ray provides a wide range of options. According to the POV-Ray documentation [oVPL04], textures control how the surface of an object is rendered, while interiors can be used to describe the properties of the interior of an object. To specify the looks of an object over a waLBerla parameter file, waLBerla allows the definition of visualization types (PovVisType block) inside the povray block. Every visualization type needs to have its own unique identification number (id) defined. The id of the visualization type can then be assigned to an object, to determine how it is rendered by POV-Ray. Concrete examples of this will be given in the subsequent sections. Listing2 illustrates all keywords that are allowed inside a PovVisType block. The Parameters texture, interior and macro expect identifiers of textures, interiors and macros, respectively. For example,

6 Figure 2: File dependencies of POV-Ray output

Listing 2: Sample POV-Ray Visualization Type povray { ...

PovVisType { i d 1 ; texture DMFWood6; // surface texture of object interior MineralOilInt; // interior of an object macro DensityInterior; // macro applied to the object (advanced effects)

hollow; // render the interior of the object no shadow; // object casts no shadow

// the following block specifies photon rendering behavior of the object // needed only for objects that cause refraction effects such as free surfaces photons { collect; // photons become visible if they hit the object (not recommended for refracting objects ) target; // do photon rendering for this object reflection; // calculate reflection of photons refraction; // calculate refraction of photons }

// the following keywords make sense for moving obstacles only track; // track the path of the object force; // visualize the net force on the object }

... }

7 DMFWood6 actually is a texture that is declared in the ‘‘textures.inc’’ include file which ships with POV-ray. However, it is up to the user to provide well defined identifiers for the visualization type. There is no error checking done by waLBerla at this point. Thus it is possible to run the simulation in waLBerla and provide the missing POV-Ray declaration for resources afterwards. Moreover, it is possible to directly insert POV-Ray expressions here, for example

texture pigment { rgbt 0.9 // almost transparent surface texture } ;

Any expression that is allowed in a POV-Ray texture, interior or macro, respectively, is possible, as long as it does not contain any delimitor (i.e. semicolon). The most flexible way however is to declare all resources in external files and refer to them by their identifiers in visualization type definitions as stated before: Thus to modify or replace the resources in the final visualization, only the respective declarations need to be changed. The remaining keywords in the PovVisType block and the Photons sub-block are boolean type parameters. The particular option will be turned on if the keyword is present, and turned off otherwise. The track and force options only apply if the visualization type is assigned to a moving obstacle (see Sec.4). hollow and no_shadow turn on the respective POV-Ray options of the same name for the affected objects. The same holds for the options collect, target, reflection and refraction in the photons block. Note, that the latter are ignored by POV-Ray as long as photon mapping is not activated in POV-Ray’s global settings while . Photon mapping is only interesting when reflective or refractive objects are visualized, such as free surfaces (Sec.7). For more information, read the section on photon mapping in the POV-Ray documentation [oVPL04].

8 4 pe Objects

Moving or fixed obstacles that are handled by the pe engine are automatically included in waLBerla’s POV- Ray output. For the integration of the pe engine in waLBerla please refer to [GDF+07b]. For every written time step the obstacle geometry is written to the files ./dat//Obstacles.dat, de- pending on the number of the process an obstacle resides on. indicates the number of the time step. A standard texture is used for all pe objects, unless another visualization type is assigned to the object. This can be done by adding a povvistype statement to the defining block of the object in the parameter file. The definition of visualization types is described in Sec. 3.2. When applied to a moving obstacle, the special feature of tracking the path of its movement may be activated by the track keyword in the according povvistype block. Also, the net force on an obstacle may be visualized as a cone pointing away from the obstacle in the force direction. Force visualization is activated by the force keyword. A sample object definition is given in listing3.

Listing 3: Sample object block i n n e r { s p h e r e { i d 1 ; // User − specific ID of the sphere p o s i t i o n L <’domainX ’/2.0 , ’domainY ’/2.0 , ’domainZ ’/2.0 >; // Global position of the sphere r a d i u s L ’domainZ ’/8.0; // Radius of the sphere m a t e r i a l { material myMaterial; density 10; // density of the sphere’s material }

povvistype 1; // visualization type of sphere }

... }

WaLBerla also writes the exact position of every object to the POV-Ray files. The position and rotation of an object can be accessed by the identifier object_position and object_rotation, respectively, where is the id of the object. Both position and rotation are float-valued vectors of length 3. This can be used, for example, to make the camera focus the object like in the following: camera { l o c a t i o n <0 ,25 , −25 >; l o o k a t o b j e c t 1 p o s ; sky <0 ,1 ,0 >; }

See the POV-Ray documentation [oVPL04] for more information on the camera object.

9 5 DensFields

DensFields can be used to visualize waLBerla fields of type Real or more precisely any waLBerla field of type DensField, VelField, ScalarField and VecField. The term DensField originates from POV-Ray [oVPL04], where a density can be thought of as a function in 3-dimensional space that maps every point to a density value in between 0 and 1. This makes it possible to render every point on or inside an object differently depending on the density value at that point. A DensField is basically such a density pattern that was created from one of waLBerla’s data fields.

5.1 File Structure POV-Ray supports the definition of density patterns by providing a 3D bitmap read from a file. According to the POV-Ray documentation [oVPL04] every voxel in the df3 file format is an unsigned integer value of either 1, 2 or 4 bytes. These values are scaled into a float value in the range 0.0 to 1.0 by POV-Ray. If a DensField is defined in the parameter file, every process will create one df3 file for every local patch in every written time step, which is named ./dat//DensFieldPatch_. Here is the number of the process, is the number of the DensField, is the number of the patch and is the number of the written time step. The id is simply an integer number that is used by waLBerla to distinguish between various DensFields. In addition an SDL include file ./dat//DensField.inc is written for every process, which defines an access function densfunctionprocess(x,y,z) to the density values stored for the local patches. This function will return 0 if the argument (x, y, z) is not within the range of the patches of the process. If thereby densfield_interpolation is defined as a positive value, the values of every patch will be interpolated accordingly. However, POV-Ray will not interpolate the values at the borders of patches. This is because POV-Ray’s internal interpolation routines only work per df3 file. Even though the field values in the ghost layer is written out in the case that the border of a patch lies within the range of the DensField, such that the df3 files “overlap”, POV-Ray’s interpolation will still lead to wrong results in general. This is due to the fact that there is no guarantee, that the macroscopic values in the layer have been communicated or calculated, respectively, before the data is written. Whether communication has to be done between patches depends on the field type, making a generic solution rather expensive to implement. As an alternative, one could implement in POV-Ray’s SDL an interpolation routine, which then interpolates the values of different df3 files where needed, instead of using the internal interpolation routines. See the POV-Ray documentation [oVPL04] on interpolation of density patterns. To write the waLBerla field values to the df3 files, the following conversion formula is used. f(x, y, z) − f d(x, y, z) = b min · 28·pc (1) fmax − fmin Here, f(x, y, z) is the value of the waLBerla data field at position (x, y, z). If the field to be written is not of scalar type but a vector field, then f(x, y, z) is the euclidian norm of the vector at position (x, y, z). 8·p Floating point numbers in the interval [fmin, fmax] are mapped to the interval [0..2 ] of integers, with p 8·p being the number of bytes of the integer. Values below fmin or above fmax will be mapped to 0 or 2 , respectively. The above function can easily be inverted to reobtain the original field values up to roundoff errors as d(x, y, z) f˜(x, y, z) = · (f − f ) + f . (2) 28·p max min min

The constants fmin, fmax and p have to be specified by the user, as described in the following section.

5.2 Usage To create a DensField with waLBerla, a DensField block has to be added to the parameter file. DensField blocks have to be specified inside the povray block. A Densfield is always contained by an axis-aligned

10 box inside the domain. Listing4 shows a DensField, which extracts exactly the slice of cells with z = 25 of the domain. The field parameter specifies the data field to be written. A field identifier string is expected here, e.g., FIELD_DENS or FIELD_VELOCITY . The parameter range is used to specify the constants fmin, fmax from Eq.1 and Eq.2. precision controls the precision of the written values as described above and must be set to either 1, 2 or 4 [bytes]. Finally, the parameter povvistype can be used to assign a visualization type to the DensField. If povvistype is not specified, then waLBerla will automatically suggest a color-mapped interior for the visualization of the field. This interior will visualize voxels with a density value of 0 as transparent, a density value of 0.33 as blue and a density value of 1.0 as red. For other values POV-Ray will interpolate linearly between the colors. In listing4 a visualization type is used that equals the mentioned standard type with the color map replaced by the one from listing 5. By applying an almost transparent surface texture, the box shaped region of the DensField is outlined in the final visualization without hiding the interior. In this example the POV-Ray macro defined in the external file shown in listing5 controls the visualization of the DensField. Whenever a visualization type containing a macro is applied to a DensField, then the macro is assumed to accept a density function as its single parameter. This allows the specification of macros that visualize points inside the DensField according to the local density value, which is calculated from the function. Listing5 also shows the color map used to render the DensField. Listing4 assumes that this macro is defined in a file named Densities.dat. Listing 4: Densfield example

D e n s F i e l d { x L 0..’domainX’; // extents in x direction y L 0..’domainY’; // extents in y direction z L 25..25; //extentsinzdirection

f i e l d FIELD VELOCITY; // field identifier range 0.0..0.017; // range of values to be written precision 1; // precision of output values

povvistype 5; // visualization type }

PovVisType{ /∗ visualization type for velocity field ∗/ i d 5 ; texture pigment { r g b t 0 . 9 } ; // visualize extents of densfield (almost transparent) no shadow; //densfieldcastsnoshadows hollow; //rendertheinterior macro BlendedDensityInterior; // defined in external file }

r e s o u r c e { file Densities.dat; } // include BlendedDensityInterior

Listing 5: Density macro example

#declare BlendedColorMap = color m a p { [0.00 rgbt 0] [ 0 . 2 5 rgb <0 ,0 ,1 >] // b l u e [ 0 . 5 0 rgb <0 ,1 ,0 >] // g r e e n [ 0 . 7 5 rgb <1 ,1 ,0 >] // y e l l o w [ 1 . 0 0 rgb <1 ,0 ,0 >] // r e d }

#macro BlendedDensityInterior(dens) i n t e r i o r { media { e m i s s i o n 1 intervals 10 s a m p l e s 5 d e n s i t y { f u n c t i o n { dens(x,y,z) } c o l o r m a p { BlendedColorMap } } } } #end If a DensField is defined in the parameter file, waLBerla will automatically add it to the POV-Ray scene by including the corresponding output files in ./Globals.inc . Listing6 shows the correspond- ing SDL code resulting from the DensField defined in listing4. The #declare statement following the inclusion of the files DensField.inc of the DensField defines a density function densfield for the whole DensField by summing over the access functions for every process’ output data. In the case of the listing, only a single process was used. The box statement defines a containing box object for the DensField, and hands over the density pattern densfield0 to the macro from listing5. Finally, a function

11 FIELD_VELOCITY0(x,y,z) is declared, which maps every point in the DensField back to its original field value, according to Eq.2. The identifier of this function is the concatenation of the identifier string of the waLBerla field with the id of the DensField.

Listing 6: Densfield section in ./Globals.inc

///////////////////////////////////////////////////////////////////// // density fields.. /////////////////////////////////////////////////////////////////////

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ densfield 0 from <1,1 ,25> t o <50 ,50 ,25 > ∗ f i e l d i d : FIELD VELOCITY, range: 0..0.017 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/

#declare densfield0 interpolation=0; //per patch interpolation of field values #include concat(”dat/0/DensField0. inc”)

#declare densfield0 = density { f u n c t i o n { // global access function for density values densfunction0process0(x,y,z) } } box{ <0, 2 4 , 0>, <50, 2 5 , 50> t e x t u r e { pigment { r g b t 0 . 9 } } BlendedDensityInterior(densfield0) h o l l o w no shadow } #d e c l a r e FIELD VELOCITY0=f u n c t i o n { // this function returns the original field value at a given position // note: set densfunction0 interpolation value for a smooth function! 0 + (densfunction0process0(x,y,z)) ∗ 0 . 0 1 7 }

Note, that there are various ways to utilize density patterns in POV-Ray and therewith various ways to visualize DensFields. Since DensFields are always contained by axis-aligned boxes in the domain, the density pattern may be used to define a surface texture of a POV-Ray box object accordingly. Of course this way only voxels lying on the surface of the containing object can be visualized. Therefore, in order to show other voxels as well, one has to replace the box object with a “smaller” shaped object. One could also to slice through the containing box, by using a POV-Ray’s intersection or difference statement with the cutaway textures keyword. The latter means that the pigment of the original object is used for points on the intersection. See sections on textures and constructive solid geometry (CSG) in the POV-Ray documentation [oVPL04]. However, POV-Ray also supports volume rendering by defining the interior of objects, and this way is usually better suited for the visualization of volumetric data such as DensFields. This is why it was chosen for the sample listings above although a surface texture would have yielded similar results in this case. See the sections on media and interior in the POV-Ray documentation [oVPL04] and the example in the next paragraph. A different approach to render DensFields is to make use of POV-Ray’s isosurface objects. They can be used to plot all points with a certain density value as a surface, as described below in the second example. Isosurface objects are also described in the POV-Ray documentation [oVPL04].

Velocity Profile Example Listings4 and5 show how to define a DensField for the visualization of the fluid velocity. We now complete this example by visualizing a simulation of flow through a canal and around an obstacle. Inflow boundary conditions (uy = 0.01) at the front and back sides of the canal induce a flow along the y-axis. No-slip boundary conditions have been applied to the remaining sides of the domain as well as the obstacle surface in the center of the domain. Fig. 5.2 shows the final images rendered by POV-Ray. The obstacle in the center is a box and has a checkered surface texture. All but the right and the bottom walls of the canal have been removed in the POV-Ray scene. Because the colormap of the density field maps values close to zero to transparency, in the first image there is no color in the region around the obstacle, as the fluid is still at rest in that region. After a certain amount of time steps the velocity profile becomes steady, with two regions of maximal velocity to the left and right of the obstacle. These regions are given a red color by the colormap (see third picture in Fig. 5.2). Note: The BlendedDensityInterior from listing5 is copied to the output directory as

12 ./pov/resource0.inc by waLBerla (see Sec.3).

Isosurface Example We now extend the canal flow example from above to show how to make use of POV- Ray’s isosurface objects to visualize DensFields. Since the obstacle in the middle of the canal blocks the fluid flow, one can expect increased pressure around the front side of the obstacle. Listing7 is added to the povray block of the parameter file. The second density has increased precision and writes out waLBerla’s fluid density field values in a region around the front side of the obstacle. Note, that the containing box of the DensField is fully transparent and no interior has been defined to keep the containing object as well as the voxels themselves invisible. Listing8 shows the output generated by waLBerla for the second DensField in ./Globals.inc. The density function FIELD_DENS1(x, y, z) can now be used to define an isosurface through all points with an increased density. Listing9 shows a sample isosurface, that we appended to ./Globals.inc before we proceed to the ray tracing. The listing creates an isosurface through those points in the DensField that have a density value of ρ(x, y, z) = 1.006. The initial reference density of the simulation was ρ = 1.000. For the final images the parameter densfield1_interpolation was set to 2 in order to achieve a smoother surface. Note, that depending on the interpolation method used, the surface might appear to be slightly out of place. This is caused by the way POV-Ray interprets the voxel data, and can be corrected by adding a matching translate statement to the isosurface. With linear interpolation, for example, the isosurface has to be translated by the vector (0.5, 0.5, 0.5). Simulations running on multiple patches require additional user interaction when it comes to interpolation: Since the POV-Ray interpolation is restricted to single df3 file patterns, the resulting function will not be smooth at the borders of the patches. Fig. 5.2 shows the final visualizations of different time steps. The isosurface initially moves along with the wave front until it is blocked by the obstacle. After the flow becomes steady, the isosurface encapsulates the region in front of the object, where ρ(x, y, z) ≥ 1.006 holds.

Listing 7: Another DensField block

d e n s F i e l d { x L 10..’domainX’ −10; y L 10..’domainY’/2; z L 0..’domainZ’; f i e l d FIELD DENS ; range 0.98..1.02; precision 4; povvistype 6; }

PovVisType{ i d 6 ; texture pigment { r g b t 1 . 0 } ; no shadow ; h o l l o w ; }

Listing 8: The second DensField in ./Globals.inc

/∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗ ∗ densfield 1 from <10 ,10 ,1 > t o <40 ,25 ,50 > ∗ f i e l d i d : FIELD DENS, range: 0.98..1.02 ∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗∗/

#declare densfunction1 interpolation=0; //per patch interpolation of field values #include concat(”dat/0/DensField1. inc”)

#declare densfield1 = density { f u n c t i o n { // global access function for density values densfunction1process0(x,y,z) } } box{ <9, 0 , 9>, <40, 5 0 , 25> t e x t u r e { pigment { r g b t 1 . 0 } } h o l l o w no shadow } #declare FIELD DENS1=function { // this function returns the original field value at a given position // note: set densfunction1 interpolation value for a smooth function! 0.98 + (densfunction1process0(x,y,z)) ∗ 0 . 0 4 }

13 Figure 3: Velocity profile around an obstacle

14 Listing 9: Isosurface using a DensField as function i s o s u r f a c e { f u n c t i o n { FIELD DENS1(x,y, z) } // show isosurface through rho=1.006 threshold 1.006 m a x gradient 0.1 c o n t a i n e d b y { box { <11 ,1 ,11 > , <39 ,49 ,39 >}} open

t e x t u r e { pigment { r g b t < 0.9,0.0,0,0.1 > }} f i n i s h { phong 0.7 phong s i z e 20 } no shadow }

15 Figure 4: Increased density in front of obstacle visualized by isosurface

16 6 CellFields

This section explains the details of the CellField output option. A Cellfield visualizes cells of the lattice Boltzmann simulation depending on their state, or more precisely, their flag values. Thereby cells are represented by box objects of side length 1 in the visualization.

6.1 Usage and Output File Structure CellFields are specified inside of the povray block of a waLBerla parameter file. Here, each CellField must be defined in a CellField block, which consists of the following parameters: x, y and z specify an axis-aligned range for the CellField, such that only cells with coordinates within the specified region are visualized. WaLBerla will generate a box object for a cell in this region if the cell has a certain flag value. These flag values have to be given within the CellField block in the form of a flag block, which expects the following parameters: value is the integer value of the flag to be visualized and povvistype is the visualization type (Sec. 3.2) to be used for this flag. wireframe is allowed as an additional keyword. If given, then a wire frame is drawn along the edges of every according cell. Listing 10 shows a CellField block with two flag blocks. WaLBerla numbers all CellFields in the order of their definition to assure unique identifiers. The number of a CellField is called its id. If one or more CellFields are defined, waLBerla will output data to the files ./dat//CellField_.inc in every written time step. Here pid ranges over all process numbers, as each process creates its output separately, id is the number of the CellField and framenumber is the number of the written time step. According to the information of waLBerla’s FlagField, objects are placed at the respective cell positions. The actual declaration of these objects (shape, color, etc.) is written to ./Globals.inc in the CellField section.

Listing 10: Sample CellField ranging over the whole simulation domain

c e l l f i e l d { x L 0..’domainX’; y L 0..’domainY’; z L 0..’domainZ’;

f l a g { value 256; // solid wall povvistype 8; } f l a g { value 512; //moving wall povvistype 16; }

6.2 Porous Medium Example In this example a flow through a porous medium was simulated at a resolution of 941×941×45 cells. A top down view on the domain with porous medium is given in Fig. 6.2. Cells which are covered by the porous medium have a solid wall flag and block the fluid flow. They were visualized with a grey visualization type in this picture. At the domain boundary planes y = 0 and y = 941 an inflow and outflow, respectively, was created. The fluid velocity was visualized along the plane x = 480. Fig. 6.2 shows the velocity profile in that plane with the cellfield restricted to the half x ≥ 470. The color range from blue to red indicates a small or high fluid velocity, respectively. All pictures were taken after 1000 time steps.

17 Figure 5: Simulation of flow in a porous medium (Y-axis pointing to the left and up).

18 Figure 6: Velocity profile of flow through a porous medium (lower picture shows the velocity profile only)

19 7 Free Surface Visualization

In a free surface simulation, waLBerla stores additional information regarding the free surface in interface cells, which form a closed layer between liquid and gas phase. A detailed description of this concept can be found in [Poh07]. Most important in the following are the free surface fill levels, the free surface points and the free surface normals. The fill levels store the amount of cell volume filled with liquid for each cell. Cells with a fill level of 1 are liquid cells, and cells with a fill level of 0 are gas cells. From the fill level information a surface point lying on the free surface and its surface normal in that point can be approximated for every interface cell.

7.1 Free Surface Extraction WaLBerla currently supports the following methods of creating POV-Ray visualizations from the free surface data: The first method is to visualize the surface normals as glyphs starting from the calculated free surface points. This method thus directly shows what the free surface information calculated by the free surface algorithm. With the second method waLBerla creates a closed triangle mesh from the fill levels that resembles the free surface. To do this the marching cubes algorithm from [LC87] is used. The algorithm proceeds through the field of fill levels and approximates intersection points of an iso surface through a given threshold value in [0..1] with a cube of eight neighbored cells by linear interpolation. The intersection points can now be connected by a set of triangles lying within the cube. This is done in such a way that the triangles fuse together and form a closed surface. In order to add curvature information to the triangle mesh, surface normals are calculated and stored for every triangle vertex. This is done by applying the linear interpolation scheme along the edges of the marching cube on the surface normals calculated for the respective cells. The resulting surface approximation translates directly into a POV-Ray mesh2 object as described in the POV-Ray documentation [oVPL04]. According to waLBerla’s patch concept, which is introduced in [GDF+07b], the triangulation is done separately for every patch. The resulting triangle meshes from different patches are composed into one object during ray tracing. The triangulation process is implemented in the FSIsoSurface class, which reads the fill levels and the surface normals from the respective fields of a given patch. The free surface algorithm as described in [Poh07], however, only calculates surface normals for interface cells. Since during the triangulation the marching cubes scheme interpolates along edges that connect to other celltypes, too, the normal calculation, which is done in waLBerla’s FS NORMALS sweep had to be extended. Normals have to be constructed for all cells with a fill level above [below] the threshold value, if they have a neighbour with fill level below [above] the threshold value. Here a cell counts as neighbour only if it is connected to the original cell by an edge of the marching cube.

7.2 Usage and Examples To control the aspects of a free surface flow simulation there is a freesurface block in waLBerla’s param- eter files. The POV-Ray visualization of free surfaces is activated by simply adding a povvistype to the freesurface block. The smoothsurface parameter can be used to control which of the two output meth- ods presented above will be used. If the keyword is present, a triangle mesh is written, the surface normals otherwise. Every process will write its free surface output to the file ./dat//FS.dat, where pid is the number of the process and framenumber is the number of the written time step. The files are then composed to a POV-Ray union and added to the scene in the ./Globals.inc file. The following example suggests some materials suited for rendering free surface flows with POV-Ray.

Breaking Dam A standard test case in computational fluid dynamics is the breaking dam. This exam- ple shows how to visualize with POV-Ray such a flow simulated in waLBerla with the smoothSurface parameter set to 0.5. To give the simulated fluid a water like look, a fully transparent surface pigment in combination with a highly specular finish was chosen for the free surface (see listing 11). With this surface texture the free surface looks like a reflective transparent film. The POV-Ray manual [oVPL04]

20 describes finishes as well as the parameters stated in the following in detail. To make the liquid region that is enclosed by the free surface more distinctive from the outside region, an interior was assigned to the free surface mesh. The ior (Index of Refraction) of 1.33, which is similar to the refraction index of water, controls the directional change of light rays passing when entering or leaving the object. The dispersion parameter additionally influences the refraction of light according to the color of the hitting light rays. Also the interior medium was defined to be absorbing red and green light, which gives a blue - colored liquid.

Listing 11: POV-Ray material for the free surface

#declare FreeSurface = texture { pigment { r g b t <0, 0 , 0 , 1> } f i n i s h { ambient 0.05 diffuse 0.25 brilliance 6.0 phong 0 . 8 p h o n g s i z e 120 r e f l e c t i o n { 0 . 0 1 , 0 . 7 } } }

#declare WaterInt = interior { i o r 1 . 3 3 dispersion 1.05 media { a b s o r p t i o n <0.05,0.05,0 > } }

To create a effect, i.e. light being reflected and refracted by the free surface, photon mapping was used, which is controlled by the photons block in the SDL file or the parameter file respectively. For a highly reflective object such as a free surface, the collect option should always be turned off. Note, that photon rendering of objects is only done if it is activated in POV-Rays global settings (See [oVPL04]). Listing 12 shows the visualization type used for the free surface. It is important to declare the object as hollow. Otherwise POV-Ray skips the rendering of the interior of the object.

Listing 12: Visualization type for the free surface

PovVisType{ // water (free surface) i d 2 ; texture FreeSurface; interior WaterInt; h o l l o w ; photons { t a r g e t ; reflection ; refraction ; // c o l l e c t ; } }

21 Figure 7: Breaking dam.

22 8 Conclusion

In this paper we presented some possibilities to visualize CFD data from waLBerla with the POV-Ray ray tracer. The waLBerla framework supports a wide range of applications addressing different kinds of fluid dynamic problems. These include different kinds of obstacles and complex geometries, particle flows and moving objects, as well as free surface flows. All of the mentioned applications are integrated in a flexible manner such that they can be modularly combined with different debugging, analysis and visualization modules, consistently optimized for large-scale parallel simulations. Hence, also the proposed POV-Ray module is integrated in a generic way to support various visualization possibilities for all existing and future applications. While lacking the interactivity and flexibility of commonly used visualization toolkits, ray tracing can still yield very convincing results which becomes especially apparent when dealing with free surface flows. Here, two techniques have been implemented, one using glyphs, directly showing the computed data and designed for assisting debugging, and one for presentation purposes. There is also the possibility to visualize the macroscopic field values of a simulated flow directly, e.g., by using a color map to show the density or velocity of the flow. For moving objects, the pathways can be tracked and the acting forces can be visualized. The waLBerla interface as presented in this paper provides a priori control of most output features. However, the POV-Ray output generated by waLBerla has been structured in a flexible manner, that allows the modification of many visualization aspects of a simulation by modifying a single file even for parallel simulation setups.

23 References

[DGF+07] S. Donath, J. G¨otz,C. Feichtinger, K. Iglberger, S. Bergler, and U. R¨ude, On the Resource Requirements of the Hyper-Scale waLBerla Project, Tech. Report 07–13, Chair for System Simulation, Univ. of Erlangen, Sep 2007, http://www10.informatik.uni-erlangen.de/ Publications/TechnicalReports/TechRep07-13.pdf. [GDF+07a] J. G¨otz,S. Donath, Ch. Feichtinger, K. Iglberger, and U. R¨ude, Concepts of walberla prototype 0.0, Tech. Report 07–04, 2007. [GDF+07b] , Concepts of walberla prototype 0.1, Tech. Report 07–10, 2007.

[GFI+08] J. G¨otz,C. Feichtinger, K. Iglberger, S. Donath, and U. R¨ude, Large scale simulation of fluid structure interaction using lattice Boltzmann methods and the ‘physics engine’, Proceedings of CTAC 2008 (Geoffry N. Mercer and A. J. Roberts, eds.), ANZIAM J., vol. 50, 2008, pp. C166–C188. [LC87] William E. Lorensen and Harvey E. Cline, Marching cubes: A high resolution 3d surface construction algorithm, 21(4) (1987).

[oVPL04] Persistence of Vision Pty. Ltd., Persistence of vision (tm) raytracer, 2004, http://www. povray.org. [Par09] ParaView, Information on visualization tool ParaView, available at http://www.paraview. org/, August 2009. [Poh07] T. Pohl, High performance simulation of free surface flows using the lattice boltzmann method, Ph.D. thesis, University of Erlangen-Nuremberg, Lehrstuhl f¨urInformatik 10 (Systemsimu- lation), Institut f¨urInformatik, 2007.

[VTK09] VTK, Information on VTK, the Visualization Tool Kit, available at http://www.vtk.org/, August 2009.

24