lbm_reference
LBM.h
Go to the documentation of this file.
1 //! \file LBM.h
2 //! \date Jan 2, 2009
3 //! \author Florian Rathgeber
4 
5 #ifndef LBM_H_
6 #define LBM_H_
7 
8 #include <iostream>
9 #include <fstream>
10 #include <sstream>
11 #include <cmath>
12 #include <string>
13 #include <endian.h>
14 #include <sys/time.h>
15 
16 #include "D3Q19.h"
17 #include "../Vec.h"
18 #include "../Grid.h"
19 #include "../confparser/ConfParser.h"
20 #include "../confparser/ConfBlock.h"
21 
22 using namespace confparser;
23 
24 //! Common namespace for all LBM classes
25 
26 namespace lbm {
27 
28 template<typename T>
29 struct Sphere {
30 
31  Sphere( T _x, T _y, T _z, T _r, T _u_x, T _u_y, T _u_z ) :
32  x(_x), y(_y), z(_z), r(_r), u_x(_u_x), u_y(_u_y), u_z(_u_z) {}
33 
34  void move() {
35  x += u_x;
36  y += u_y;
37  z += u_z;
38  }
39 
40  T x;
41  T y;
42  T z;
43  T r;
44  T u_x;
45  T u_y;
46  T u_z;
47 };
48 
49 template<typename T>
51  PerformanceData() : scTime( 0. ), nTime( 0. ), vTime( 0. ), iTime( 0. ), oTime( 0. ), pTime( 0. ), cTime( 0. ), sTime( 0. ), mTime( 0. ) {}
52  std::string fileName;
62 };
63 
64 //! Enum describing possible states of a cell
65 
66 enum Flag {
67  UNDEFINED = 0,
68  FLUID = 1,
69  NOSLIP = 2,
70  VELOCITY = 3,
71  INFLOW = 4,
72  OUTFLOW = 5,
74 };
75 
76 //! Lattice Boltzmann Method fluid solver
77 
78 //! Uses the BGK collision model and Smagorinsky turbulence correction. The
79 //! coordinate system used is left-handed, i.e. screen coordinates
80 //!
81 //! The following boundary conditions are implemented:
82 //! - \em no-slip Bounce back condition (fixed wall)
83 //! - \em velocity Bounce back condition (moving wall)
84 //! - \em inflow Inflow velocity with density of 1.0
85 //! - \em outflow Enforces zero-gradient pressure at the boundary
86 //! - \em pressure Enforces atmospheric pressure at the boundary
87 //!
88 //! The constructor requires a configuration file in a ConfParser compatible
89 //! format to be given, which must specify the following hierarchy of blocks:
90 //! - \em domain Specifies the domain size
91 //! - \b sizeX \em int Number of cells in x-dimension
92 //! - \b sizeY \em int Number of cells in y-dimension
93 //! - \b sizeZ \em int Number of cells in z-dimension
94 //! - \em parameters Specifies the simulation parameters
95 //! - \b omega \em float Inverse lattice velocity
96 //! - \b cSmagorinsky \em float Smagorinsky turbulence constant
97 //! - \b maxSteps \em int Number of time steps to simulate
98 //! - \em vtk Specifies vtk output (optional, no output will be generated if
99 //! this block is not present)
100 //! - \b vtkFileName \em string Base name and path for the vtk file to write out
101 //! (relative to location of executable, will be
102 //! appended by current timestep and .vtk extension)
103 //! - \b vtkStep \em int Number of timesteps in between 2 vtk file outputs
104 //! - \em boundaries Specifies the boundary conditions, contains a subblock for
105 //! each side of the domain (\em bottom, \em top, \em back,
106 //! \em front, \em left, \em right) which in turn can contain
107 //! 1 or more of the following subblocks to specify the type of
108 //! boundary condition.
109 //! - \em noslip Bounce back condition (fixed wall)
110 //! - \em velocity Bounce back condition (moving wall)
111 //! - \b u_x \e float Velocity of moving wall in x-direction
112 //! - \b u_y \e float Velocity of moving wall in y-direction
113 //! - \b u_z \e float Velocity of moving wall in y-direction
114 //! - \em inflow Inflow velocity with density of 1.0
115 //! - \b u_x \e float Inflow velocity in x-direction
116 //! - \b u_y \e float Inflow velocity in y-direction
117 //! - \b u_z \e float Inflow velocity in z-direction
118 //! - \em outflow Enforces zero-gradient pressure at the boundary
119 //! - \em pressure Enforces atmospheric pressure at the boundary
120 //! .
121 //! Every boundary block needs to specify the coordinates of the rectangular
122 //! patch, where the fixed coordinate is implicitly set and needs not to be
123 //! specified (i.e. \e y for \e bottom and \e top, \e z for \e back and \e
124 //! front and \e x for \e left and \e right.
125 //! - \b xStart \e int Start cell in x-direction (not required for \e left and \e right)
126 //! - \b xEnd \e int End cell in x-direction (not required for \e left and \e right)
127 //! - \b yStart \e int Start cell in y-direction (not required for \e bottom and \e top)
128 //! - \b yEnd \e int End cell in y-direction (not required for \e bottom and \e top)
129 //! - \b zStart \e int Start cell in z-direction (not required for \e back and \e front)
130 //! - \b zEnd \e int End cell in z-direction (not required for \e back and \e front)
131 //! .
132 //! Boundary cells that are not specified are implicitly set to \e noslip. An
133 //! error is thrown if a boundary cell is specified twice. \e bottom and \e top
134 //! have priority over \e back and \e front which in turn have priority over
135 //! \e left and \e right, i.e. the edges of the rectangle are added to the
136 //! boundary regions according to these priorities given.
137 //!
138 //! Example configuration file:
139 //! \code
140 //! domain {
141 //! sizeX 62;
142 //! sizeY 62;
143 //! sizeZ 62;
144 //! }
145 //!
146 //! parameters {
147 //! omega 1.9;
148 //! cSmagorinsky 0.03;
149 //! maxSteps 1201;
150 //! }
151 //!
152 //! vtk {
153 //! vtkFileName vtk/outflow_60_60_60_1.9_0.03_1201_25;
154 //! vtkStep 25;
155 //! }
156 //!
157 //! boundaries {
158 //! top {
159 //! outflow {
160 //! xStart 1;
161 //! xEnd 60;
162 //! zStart 1;
163 //! zEnd 60;
164 //! }
165 //! }
166 //! bottom {
167 //! inflow {
168 //! xStart 26;
169 //! xEnd 35;
170 //! zStart 26;
171 //! zEnd 35;
172 //! u_x 0.0;
173 //! u_y 0.0;
174 //! u_z 0.1;
175 //! }
176 //! }
177 //! left {
178 //! inflow {
179 //! zStart 2;
180 //! zEnd 59;
181 //! yStart 2;
182 //! yEnd 59;
183 //! u_x 0.001;
184 //! u_y 0.0;
185 //! u_z 0.0;
186 //! }
187 //! }
188 //! right {
189 //! outflow {
190 //! zStart 2;
191 //! zEnd 59;
192 //! yStart 2;
193 //! yEnd 59;
194 //! }
195 //! }
196 //! back {
197 //! outflow {
198 //! xStart 1;
199 //! xEnd 60;
200 //! yStart 2;
201 //! yEnd 59;
202 //! }
203 //! }
204 //! front {
205 //! outflow {
206 //! xStart 1;
207 //! xEnd 60;
208 //! yStart 2;
209 //! yEnd 59;
210 //! }
211 //! }
212 //! }
213 //! \endcode
214 //! \note define the preprocessor symbol NSMAGO to disable turbulence correction
215 
216 template<typename T>
217 class LBM {
218 
219 public:
220 
221  // ============================ //
222  // Constructors and destructors //
223  // ============================ //
224 
225  //! Default constructor
226 
227  //! Does no initialization.
228 
229  LBM() : curStep_( 0 ) {}
230 
231  //! Constructor
232 
233  //! Initializes the geometry of the domain and the boundaries according to the
234  //! configuration file given.
235  //! \note There is no default constructor available!
236  //! \param[in] configFileName Path to configuration file
237 
238  LBM( const std::string configFileName );
239 
240  //! Constructor
241 
242  //! Initializes the geometry of the domain and the boundaries according to the
243  //! configuration block given.
244  //! \note There is no default constructor available!
245  //! \param[in] base Root configuration block
246 
247  LBM( ConfBlock& base );
248 
249  //! Destructor
250 
251  //! Deletes the grids of the distribution functions
252 
253  virtual ~LBM();
254 
255  //! Run the solver
256 
257  //! The output will be written to a series of VTK files (legacy format)
258 
259  void run();
260 
261  //! Perform a single LBM step
262 
263  //! The output will be written to a VTK file if appropriate (legacy format)
264 
265  double runStep();
266 
267  //! Get tri-linearly interpolated velocity at given position
268 
269  //! \param[in] x x-coordinate of position to get velocity
270  //! \param[in] y y-coordinate of position to get velocity
271  //! \param[in] z z-coordinate of position to get velocity
272 
273  inline Vec3<T> getVelocity( T x, T y, T z );
274 
275  //! Get tri-linearly interpolated velocity at given position
276 
277  //! \param[in] v 3-component vector (x,y,z) of position to get velocity
278 
279  inline Vec3<T> getVelocity( const Vec3<T>& v ) {
280  return getVelocity( v[0], v[1], v[2] );
281  }
282 
283  //! Setup the solver by processing configuration file
284 
285  //! Initializes the geometry of the domain and the boundaries according to the
286  //! configuration given.
287  //! \param[in] base Root block of parsed configuration file
288 
289  void setup( ConfBlock& base );
290 
291 protected:
292 
293  // ========================= //
294  // Internal helper functions //
295  // ========================= //
296 
297  //! Process a boundary block
298 
299  //! \param[in] block Boundary block to process (either \e bottom, \e top, \e
300  //! back, \e front, \e right, \e left)
301  //! \param[in] x Either fixed value for x-coordinate or -1 to read range
302  //! from configuration
303  //! \param[in] y Either fixed value for y-coordinate or -1 to read range
304  //! from configuration
305  //! \param[in] z Either fixed value for z-coordinate or -1 to read range
306  //! from configuration
307 
308  inline void setupBoundary( ConfBlock& block, int x, int y, int z );
309 
310  //! Get the time difference between two measurements
311 
312  //! \param[in] start Start time of measurement as return by \e gettimeofday
313  //! \param[in] end End time of measurement as return by \e gettimeofday
314  //! \returns Time difference \e end - \e start in seconds
315 
316  inline T getTime( timeval &start, timeval &end );
317 
318  //! Perform a collide-stream step without turbulence correction
319 
320  //! \param[in] x Cell coordinate for dimension x
321  //! \param[in] y Cell coordinate for dimension y
322  //! \param[in] z Cell coordinate for dimension z
323 
324  inline void collideStream( int x, int y, int z );
325 
326 #ifndef NSMAGO
327  //! Perform a collide-stream step with turbulence correction
328 
329  //! \param[in] x Cell coordinate for dimension x
330  //! \param[in] y Cell coordinate for dimension y
331  //! \param[in] z Cell coordinate for dimension z
332 
333  inline void collideStreamSmagorinsky( int x, int y, int z );
334 #endif
335 
336  //! Treat the no-slip boundary cells
337 
338  inline void treatNoslip();
339 
340  inline void treatStaircase();
341 
342  //! Treat the boundary cells with fixed velocity
343 
344  inline void treatVelocity();
345 
346  //! Treat the inflow boundary cells
347 
348  inline void treatInflow();
349 
350  //! Treat the outflow boundary cells
351 
352  inline void treatOutflow();
353 
354  //! Treat the outflow boundary cells with fixed athmospheric pressure
355 
356  inline void treatPressure();
357 
358  //! Treat the curved boundary cells
359 
360  inline void treatCurved();
361 
362  inline void moveSphere();
363 
364  //! Write out the VTK file for a given timestep
365 
366  //! \note Output is in binary VTK legacy file format
367 
368  void writeVtkFile();
369 
370  void writePerformanceSummary();
371 
372  std::string calcMLUP( T time, int cells );
373 
374  // ============ //
375  // Data members //
376  // ============ //
377 
378  //! Inverse lattice velocity
379 
381 
382 #ifndef NSMAGO
383  //! Lattice viscosity
384 
386 
387  //! Squared Smagorinsky turbulence constant
388 
390 #endif
391 
392  //! Number of collide-stream steps to perform
393 
395 
396  //! Current time step
397 
398  int curStep_;
399 
400  //! VTK files will be written out at multiples of this step size
401 
402  int vtkStep_;
403 
404  //! Path and base name of VTK files to write out. Will be appended by
405  //! \em .currentStep.vtk
406 
407  std::string vtkFileName_;
408 
409  //! Distribution function field (switched with grid1_ after each time step)
410 
412 
413  //! Distribution function field (switched with grid0_ after each time step)
414 
416 
417  //! Velocity field
418 
420 
421  //! Density field
422 
424 
425  //! Flag field
426 
428 
429  //! Vector holding all sphere obstacles
430 
431  std::vector< Sphere<T> > sphereObstacles_;
432 
433  //! List with coordinates of all noslip cells
434 
435  std::vector< Vec3<int> > noslipCells_;
436  std::vector< Vec3<int> > staircaseCells_;
437 
438  //! List with coordinates of all velocity cells
439 
440  std::vector< Vec3<int> > velocityCells_;
441 
442  //! List with velocities for all velocity cells
443 
444  std::vector< Vec3<T> > velocityVels_;
445 
446  //! List with coordinates of all inflow cells
447 
448  std::vector< Vec3<int> > inflowCells_;
449 
450  //! List with velocities for all inflow cells
451 
452  std::vector< Vec3<T> > inflowVels_;
453 
454  //! List with coordinates of all outflow cells
455 
456  std::vector< Vec3<int> > outflowCells_;
457 
458  //! List with outflow directions for all outflow cells
459 
460  std::vector< int > outflowDFs_;
461 
462  //! List with coordinates of all pressure cells
463 
464  std::vector< Vec3<int> > pressureCells_;
465 
466  //! List with outflow directions for all pressure cells
467 
468  std::vector< int > pressureDFs_;
469 
470  //! List with coordinates of all curved boundary cells
471 
472  std::vector< Vec3<int> > curvedCells_;
473 
474  //! List with fluid fractions for all lattice links of curved boundary cells
475 
476  std::vector< std::vector<T> > curvedDeltas_;
477 
479 
480 };
481 
482 //! Specialization of the the VTK file writer for template type double
483 //! \note This is necessary as the type needs to be written to the VTK file in
484 //! ASCII and there is no way to get an ASCII representation of the \e
485 //! type of a template paramter
486 
487 template<>
489 
490 //! Specialization of the the VTK file writer for template type float
491 //! \note This is necessary as the type needs to be written to the VTK file in
492 //! ASCII and there is no way to get an ASCII representation of the \e
493 //! type of a template paramter
494 
495 template<>
497 
498 } // namespace lbm
499 
500 #endif /* LBM_H_ */