12 #if __BYTE_ORDER == __LITTLE_ENDIAN
14 #define htobe32(x) bswap_32(x)
15 #define htobe64(x) bswap_64(x)
17 #define htobe32(x) (x)
18 #define htobe64(x) (x)
32 LBM<T>::LBM(
const std::string configFileName ) : curStep_( 0 ) {
36 ConfBlock base = p.parse( configFileName );
37 std::cout <<
"Parsed configuration file " << configFileName << std::endl;
39 }
catch ( std::exception& e ) {
40 std::cerr << e.what() << std::endl;
52 assert ( grid0_ != 0 && grid1_ != 0 );
63 int sizeX = grid0_->getSizeX() - 2;
64 int sizeY = grid0_->getSizeY() - 2;
65 int sizeZ = grid0_->getSizeZ() - 2;
67 int numCells = sizeX * sizeY * sizeZ;
70 std::cout <<
"Starting LBM without Smagorinsky turbulence correction" << std::endl;
72 std::cout <<
"Starting LBM with Smagorinsky turbulence correction"
77 for (
int step = 0; step < maxSteps_; ++step) {
81 std::cout <<
"LBM finished! Processed " << maxSteps_ <<
" timesteps in ";
82 std::cout << totTime <<
" secs!" << std::endl;
83 std::cout <<
"Average speed of " << (maxSteps_ * numCells) / (totTime
85 std::cout <<
" MLUP/s" << std::endl;
87 if ( prof_.fileName.length() ) writePerformanceSummary();
94 int sizeX = grid0_->getSizeX() - 2;
95 int sizeY = grid0_->getSizeY() - 2;
96 int sizeZ = grid0_->getSizeZ() - 2;
98 int numCells = sizeX * sizeY * sizeZ;
100 struct timeval start, end;
103 gettimeofday(&start, NULL);
106 for (
int z = 1; z <= sizeZ - 1; z++) {
107 for (
int y = 1; y <= sizeY - 1; y++) {
108 for (
int x = 1; x <= sizeX - 1; x++) {
112 collideStream( x, y, z );
116 collideStreamSmagorinsky( x, y, z );
124 gettimeofday(&end, NULL);
125 T scTime = getTime(start, end);
132 gettimeofday(&start, NULL);
133 T nTime = noslipCells_.size() ? getTime(end, start) : 0.;
140 gettimeofday(&end, NULL);
141 T vTime = velocityCells_.size() ? getTime(start, end) : 0.;
148 gettimeofday(&start, NULL);
149 T iTime = inflowCells_.size() ? getTime(end, start) : 0.;
156 gettimeofday(&end, NULL);
157 T oTime = outflowCells_.size() ? getTime(start, end) : 0.;
164 gettimeofday(&start, NULL);
165 T pTime = pressureCells_.size() ? getTime(end, start) : 0.;
172 gettimeofday(&end, NULL);
173 T cTime = curvedCells_.size() ? getTime(start, end) : 0.;
180 gettimeofday(&start, NULL);
181 T sTime = staircaseCells_.size() ? getTime(end, start) : 0.;
186 gettimeofday(&end, NULL);
194 T mTime = sphereObstacles_.size() ? getTime(start, end) : 0.;
195 stepTime = scTime + nTime + vTime + iTime + oTime + pTime + cTime + mTime;
197 if ( prof_.fileName.length() ) {
198 prof_.scTime += scTime;
199 prof_.nTime += nTime;
200 prof_.vTime += vTime;
201 prof_.iTime += iTime;
202 prof_.oTime += oTime;
203 prof_.pTime += pTime;
204 prof_.cTime += cTime;
205 prof_.sTime += sTime;
206 prof_.mTime += mTime;
209 std::cout << curStep_ <<
" / " << maxSteps_ <<
": " << scTime <<
" + ";
210 std::cout << nTime <<
" + " << vTime <<
" + " << iTime <<
" + " << oTime;
211 std::cout <<
" + " << pTime <<
" + " << cTime <<
" + " << sTime <<
" + " << mTime <<
" = ";
212 std::cout << stepTime <<
"s -> " << numCells / (stepTime * 1000000);
213 std::cout <<
" MLUP/s" << std::endl;
215 stepTime = getTime(start, end);
218 if ( vtkStep_ != 0 && curStep_ % vtkStep_ == 0 )
236 T u_x = (1. - xd) * (
237 (1. - yd) * ( u_(xf, yf, zf, 0) * (1. - zd) + u_(xf, yf, zc, 0) * zd )
238 + yd * ( u_(xf, yc, zf, 0) * (1. - zd) + u_(xf, yc, zc, 0) * zd )
240 (1. - yd) * ( u_(xc, yf, zf, 0) * (1. - zd) + u_(xc, yf, zc, 0) * zd )
241 + yd * ( u_(xc, yc, zf, 0) * (1. - zd) + u_(xc, yc, zc, 0) * zd )
243 T u_y = (1. - xd) * (
244 (1. - yd) * ( u_(xf, yf, zf, 1) * (1. - zd) + u_(xf, yf, zc, 1) * zd )
245 + yd * ( u_(xf, yc, zf, 1) * (1. - zd) + u_(xf, yc, zc, 1) * zd )
247 (1. - yd) * ( u_(xc, yf, zf, 1) * (1. - zd) + u_(xc, yf, zc, 1) * zd )
248 + yd * ( u_(xc, yc, zf, 1) * (1. - zd) + u_(xc, yc, zc, 1) * zd )
250 T u_z = (1. - xd) * (
251 (1. - yd) * ( u_(xf, yf, zf, 2) * (1. - zd) + u_(xf, yf, zc, 2) * zd )
252 + yd * ( u_(xf, yc, zf, 2) * (1. - zd) + u_(xf, yc, zc, 2) * zd )
254 (1. - yd) * ( u_(xc, yf, zf, 2) * (1. - zd) + u_(xc, yf, zc, 2) * zd )
255 + yd * ( u_(xc, yc, zf, 2) * (1. - zd) + u_(xc, yc, zc, 2) * zd )
257 return Vec3<T>( u_x, u_y, u_z );
270 std::cout <<
"Setting up LBM..." << std::endl;
272 ConfBlock* paramBlock = base.find(
"domain" );
273 if ( paramBlock == NULL ) {
274 throw "No domain size given.";
276 int sizeX = paramBlock->getParam<
int>(
"sizeX" );
277 int sizeY = paramBlock->getParam<
int>(
"sizeY" );
278 int sizeZ = paramBlock->getParam<
int>(
"sizeZ" );
279 std::cout <<
"Read domain specification:" << std::endl;
280 std::cout <<
"sizeX : " << sizeX << std::endl;
281 std::cout <<
"sizeY : " << sizeY << std::endl;
282 std::cout <<
"sizeZ : " << sizeZ << std::endl;
284 paramBlock = base.find(
"parameters" );
285 if ( paramBlock == NULL ) {
286 throw "No parameters given.";
288 omega_ = paramBlock->getParam<
T>(
"omega" );
290 T cSmagorinsky = paramBlock->getParam<
T>(
"cSmagorinsky" );
292 maxSteps_ = paramBlock->getParam<
int>(
"maxSteps" );
293 std::cout <<
"Read parameter specification:" << std::endl;
294 std::cout <<
"omega : " << omega_ << std::endl;
296 std::cout <<
"Smagorinsky constant : " << cSmagorinsky << std::endl;
298 std::cout <<
"Number of steps : " << maxSteps_ << std::endl;
302 nu_ = (2. / omega_ - 1.) * (1. / 6.);
304 cSmagoSqr_ = cSmagorinsky * cSmagorinsky;
307 paramBlock = base.find(
"vtk" );
308 if ( paramBlock != NULL ) {
309 vtkStep_ = paramBlock->getParam<
int>(
"vtkStep" );
310 vtkFileName_ = paramBlock->getParam<std::string>(
"vtkFileName" );
311 std::cout <<
"VTK output specification:" << std::endl;
312 std::cout <<
"VTK step modulo : " << vtkStep_ << std::endl;
313 std::cout <<
"VTK output file base name : " << vtkFileName_ << std::endl;
315 std::cout <<
"No vtk block given in configuration file, no output will be created." << std::endl;
319 paramBlock = base.find(
"profiling" );
320 if ( paramBlock != NULL ) {
321 prof_.fileName = paramBlock->getParam<std::string>(
"fileName" );
322 std::cout <<
"Performance summary file name : " << prof_.fileName << std::endl;
324 std::cout <<
"No profiling block given in configuration file, no performance summary will be created." << std::endl;
327 std::cout <<
"Set up the lattices..." << std::endl;
332 u_.
init( sizeX, sizeY, sizeZ, 0. );
333 rho_.init( sizeX, sizeY, sizeZ, 1. );
334 flag_.init( sizeX, sizeY, sizeZ,
UNDEFINED );
336 std::cout <<
"Set up the boundaries..." << std::endl;
339 paramBlock = base.find(
"boundaries" );
340 if ( paramBlock == NULL ) {
341 throw "No boundary description given.";
344 std::cout <<
"Bottom..." << std::endl;
347 ConfBlock* boundBlock = paramBlock->find(
"bottom" );
348 if ( boundBlock != NULL ) setupBoundary( *boundBlock, -1, 1, -1 );
350 for (
int z = 2; z < sizeZ - 2; ++z ) {
351 for (
int x = 1; x <= sizeX - 2; ++x ) {
353 flag_( x, 1, z ) =
NOSLIP;
354 noslipCells_.push_back(
Vec3<int>( x, 1, z ) );
359 std::cout <<
"Top..." << std::endl;
362 boundBlock = paramBlock->find(
"top" );
363 if ( boundBlock != NULL ) setupBoundary( *boundBlock, -1, sizeY - 2, -1 );
365 for (
int z = 2; z < sizeZ - 2; ++z ) {
366 for (
int x = 1; x <= sizeX - 2; ++x ) {
367 if ( flag_( x, sizeY - 2, z ) ==
UNDEFINED ) {
368 flag_( x, sizeY - 2, z ) =
NOSLIP;
369 noslipCells_.push_back(
Vec3<int>( x, sizeY - 2, z ) );
374 std::cout <<
"Left..." << std::endl;
377 boundBlock = paramBlock->find(
"left" );
378 if ( boundBlock != NULL ) setupBoundary( *boundBlock, 1, -1, -1 );
380 for (
int z = 2; z < sizeZ - 2; ++z ) {
381 for (
int y = 2; y < sizeY - 2; ++y ) {
383 flag_( 1, y, z ) =
NOSLIP;
384 noslipCells_.push_back(
Vec3<int>( 1, y, z ) );
389 std::cout <<
"Right..." << std::endl;
392 boundBlock = paramBlock->find(
"right" );
393 if ( boundBlock != NULL ) setupBoundary( *boundBlock, sizeX - 2, -1, -1 );
395 for (
int z = 2; z < sizeZ - 2; ++z ) {
396 for (
int y = 2; y < sizeY - 2; ++y ) {
397 if ( flag_( sizeX - 2, y, z ) ==
UNDEFINED ) {
398 flag_( sizeX - 2, y, z ) =
NOSLIP;
399 noslipCells_.push_back(
Vec3<int>( sizeX - 2, y, z ) );
404 std::cout <<
"Front..." << std::endl;
407 boundBlock = paramBlock->find(
"front" );
408 if ( boundBlock != NULL ) setupBoundary( *boundBlock, -1, -1, 1 );
410 for (
int y = 1; y <= sizeY - 2; ++y ) {
411 for (
int x = 1; x <= sizeX - 2; ++x ) {
413 flag_( x, y, 1 ) =
NOSLIP;
414 noslipCells_.push_back(
Vec3<int>( x, y, 1 ) );
419 std::cout <<
"Back..." << std::endl;
422 boundBlock = paramBlock->find(
"back" );
423 if ( boundBlock != NULL ) setupBoundary( *boundBlock, -1, -1, sizeZ - 2 );
425 for (
int y = 1; y <= sizeY - 2; ++y ) {
426 for (
int x = 1; x <= sizeX - 2; ++x ) {
427 if ( flag_( x, y, sizeZ - 2 ) ==
UNDEFINED ) {
428 flag_( x, y, sizeZ - 2 ) =
NOSLIP;
429 noslipCells_.push_back(
Vec3<int>( x, y, sizeZ - 2 ) );
435 paramBlock = base.find(
"obstacles" );
436 if ( paramBlock == NULL ) {
437 std::cout <<
"No obstacles defined" << std::endl;
440 std::cout <<
"Set up the obstacles..." << std::endl;
442 ConfBlock::childIterPair bit = paramBlock->findAll(
"cuboid_stationary" );
443 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
445 ConfBlock& b = it->second;
447 int xStart = b.getParam<
int>(
"xStart" );
448 int xEnd = b.getParam<
int>(
"xEnd" );
449 int yStart = b.getParam<
int>(
"yStart" );
450 int yEnd = b.getParam<
int>(
"yEnd" );
451 int zStart = b.getParam<
int>(
"zStart" );
452 int zEnd = b.getParam<
int>(
"zEnd" );
454 std::cout <<
"Stationary cuboid ranging from <" << xStart <<
",";
455 std::cout << yStart <<
"," << zStart <<
"> to <" << xEnd <<
"," << yEnd;
456 std::cout <<
"," << zEnd <<
">" << std::endl;
458 assert( xStart > 1 && xEnd < flag_.getSizeX() - 2 &&
459 yStart > 1 && yEnd < flag_.getSizeY() - 2 &&
460 zStart > 1 && zEnd < flag_.getSizeZ() - 2 );
461 for (
int z = zStart; z <= zEnd; ++z ) {
462 for (
int y = yStart; y <= yEnd; ++y ) {
463 for (
int x = xStart; x <= xEnd; ++x ) {
465 flag_( x, y, z ) =
NOSLIP;
468 if ( z == zStart || z == zEnd || y == yStart ||
469 y == yEnd || x == xStart || x == xEnd )
470 noslipCells_.push_back(
Vec3<int>( x, y, z ) );
476 bit = paramBlock->findAll(
"sphere_stationary" );
477 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
479 ConfBlock& bl = it->second;
481 T xCenter = bl.getParam<
T>(
"xCenter" );
482 T yCenter = bl.getParam<
T>(
"yCenter" );
483 T zCenter = bl.getParam<
T>(
"zCenter" );
484 T radius = bl.getParam<
T>(
"radius" );
486 std::cout <<
"Stationary sphere centered at <" << xCenter <<
",";
487 std::cout << yCenter <<
"," << zCenter <<
"> with radius " << radius;
488 std::cout << std::endl;
490 T r2 = radius * radius;
492 T zStart = floor( zCenter - radius ) + .5;
493 if ( zStart > sizeZ - .5)
continue;
494 if ( zStart < 1.5 ) zStart = 1.5;
495 T zEnd = floor( zCenter + radius ) + .5;
496 if ( zEnd < 1.5 )
continue;
497 if ( zEnd > sizeZ - .5) zEnd = sizeZ - .5;
498 T yStart = floor( yCenter - radius ) + .5;
499 if ( yStart > sizeY - .5)
continue;
500 if ( yStart < 1.5 ) yStart = 1.5;
501 T yEnd = floor( yCenter + radius ) + .5;
502 if ( yEnd < 1.5 )
continue;
503 if ( yEnd > sizeY - .5) yEnd = sizeY - .5;
504 T xStart = floor( xCenter - radius ) + .5;
505 if ( xStart > sizeX - .5)
continue;
506 if ( xStart < 1.5 ) xStart = 1.5;
507 T xEnd = floor( xCenter + radius ) + .5;
508 if ( xEnd < 1.5 )
continue;
509 if ( xEnd > sizeX - .5) xEnd = sizeX - .5;
512 for (
T z = zStart; z <= zEnd; z += 1 )
513 for (
T y = yStart; y <= yEnd; y += 1 )
514 for (
T x = xStart; x <= xEnd; x += 1 ) {
516 if ( (x - xCenter) * (x - xCenter)
517 + (y - yCenter) * (y - yCenter)
518 + (z - zCenter) * (z - zCenter) < r2 ) {
519 flag_( (
int) x, (
int) y, (
int) z ) =
NOSLIP;
525 for (
int z = zStart; z < zEnd; ++z )
526 for (
int y = yStart; y < yEnd; ++y )
527 for (
int x = xStart; x < xEnd; ++x ) {
528 if ( flag_( x, y, z ) ==
NOSLIP ) {
530 bool isBoundary =
false;
531 std::vector<T> delta(19, -1.);
532 for (
int f = 1; f <
Dim; ++f ) {
535 T xd = xCenter - (x + .5);
536 T yd = yCenter - (y + .5);
537 T zd = zCenter - (z + .5);
538 T b =
exn[f] * xd +
eyn[f] * yd +
ezn[f] * zd;
539 T c = xd * xd + yd * yd + zd * zd - r2;
541 delta[f] = 1.0 - ( b + sqrt( b * b - c ) ) /
le[f];
551 curvedCells_.push_back(
Vec3<int>( x, y, z ) );
552 curvedDeltas_.push_back( delta );
558 bit = paramBlock->findAll(
"sphere_moving" );
559 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
561 ConfBlock& bl = it->second;
563 T xCenter = bl.getParam<
T>(
"xCenter" );
564 T yCenter = bl.getParam<
T>(
"yCenter" );
565 T zCenter = bl.getParam<
T>(
"zCenter" );
566 T radius = bl.getParam<
T>(
"radius" );
567 T u_x = bl.getParam<
T>(
"u_x" );
568 T u_y = bl.getParam<
T>(
"u_y" );
569 T u_z = bl.getParam<
T>(
"u_z" );
571 std::cout <<
"Moving sphere centered at <" << xCenter <<
",";
572 std::cout << yCenter <<
"," << zCenter <<
"> with radius " << radius;
573 std::cout <<
" and u=<" << u_x <<
"," << u_y <<
"," << u_z <<
">";
574 std::cout << std::endl;
576 sphereObstacles_.push_back(
Sphere<T>( xCenter, yCenter, zCenter, radius, u_x, u_y, u_z ) );
579 bit = paramBlock->findAll(
"sphere_staircase" );
580 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
582 ConfBlock& bl = it->second;
584 T xCenter = bl.getParam<
T>(
"xCenter" );
585 T yCenter = bl.getParam<
T>(
"yCenter" );
586 T zCenter = bl.getParam<
T>(
"zCenter" );
587 T radius = bl.getParam<
T>(
"radius" );
588 std::cout <<
"Stationary sphere centered at <" << xCenter <<
",";
589 std::cout << yCenter <<
"," << zCenter <<
"> with radius " << radius;
590 std::cout << std::endl;
592 T r2 = radius * radius;
594 T zStart = floor( zCenter - radius ) + .5;
595 if ( zStart < 1.5 ) zStart = 1.5;
596 T zEnd = floor( zCenter + radius ) + .5;
597 if ( zEnd > sizeZ - .5) zEnd = sizeZ - .5;
598 T yStart = floor( yCenter - radius ) + .5;
599 if ( yStart < 1.5 ) yStart = 1.5;
600 T yEnd = floor( yCenter + radius ) + .5;
601 if ( yEnd > sizeY - .5) yEnd = sizeY - .5;
602 T xStart = floor( xCenter - radius ) + .5;
603 if ( xStart < 1.5 ) xStart = 1.5;
604 T xEnd = floor( xCenter + radius ) + .5;
605 if ( xEnd > sizeX - .5) xEnd = sizeX - .5;
608 for (
T z = zStart; z <= zEnd; z += 1 )
609 for (
T y = yStart; y <= yEnd; y += 1 )
610 for (
T x = xStart; x <= xEnd; x += 1 ) {
612 if ( (x - xCenter) * (x - xCenter)
613 + (y - yCenter) * (y - yCenter)
614 + (z - zCenter) * (z - zCenter) < r2 ) {
615 flag_( (
int) x, (
int) y, (
int) z ) =
NOSLIP;
622 for (
int z = zStart; z < zEnd; ++z )
623 for (
int y = yStart; y < yEnd; ++y )
624 for (
int x = xStart; x < xEnd; ++x ) {
625 if ( flag_( x, y, z ) ==
NOSLIP ) {
627 bool isBoundary =
false;
628 std::vector<T> delta(19, -1.);
629 for (
int f = 1; f <
Dim; ++f ) {
642 staircaseCells_.push_back(
Vec3<int>( x, y, z ) );
648 bit = paramBlock->findAll(
"inflow" );
649 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
651 ConfBlock& b = it->second;
653 int xStart = b.getParam<
int>(
"xStart" );
654 int xEnd = b.getParam<
int>(
"xEnd" );
655 int yStart = b.getParam<
int>(
"yStart" );
656 int yEnd = b.getParam<
int>(
"yEnd" );
657 int zStart = b.getParam<
int>(
"zStart" );
658 int zEnd = b.getParam<
int>(
"zEnd" );
659 T u_x = b.getParam<
T>(
"u_x" );
660 T u_y = b.getParam<
T>(
"u_y" );
661 T u_z = b.getParam<
T>(
"u_z" );
662 assert( xStart > 1 && xEnd < flag_.getSizeX() - 2 &&
663 yStart > 1 && yEnd < flag_.getSizeY() - 2 &&
664 zStart > 1 && zEnd < flag_.getSizeZ() - 2 );
665 for (
int z = zStart; z <= zEnd; ++z ) {
666 for (
int y = yStart; y <= yEnd; ++y ) {
667 for (
int x = xStart; x <= xEnd; ++x ) {
669 flag_( x, y, z ) =
NOSLIP;
670 inflowCells_.push_back(
Vec3<int>( x, y, z ) );
671 inflowVels_.push_back(
Vec3<T>( u_x, u_y, u_z ) );
678 std::cout <<
"Flag fluid cells..." << std::endl;
681 for (
int z = 2; z < sizeZ - 2; ++z )
682 for (
int y = 2; y < sizeY - 2; ++y )
683 for (
int x = 2; x < sizeX - 2; ++x )
686 std::cout <<
"Initialize distribution functions with equilibrium..." << std::endl;
689 for (
int z = 0; z < sizeZ; ++z )
690 for (
int y = 0; y < sizeY; ++y )
691 for (
int x = 0; x < sizeX; ++x )
692 for (
int i = 0; i <
Dim; ++i )
693 (*grid0_)( x, y, z, i ) =
w[i];
694 for (
int z = 0; z < sizeZ; ++z )
695 for (
int y = 0; y < sizeY; ++y )
696 for (
int x = 0; x < sizeX; ++x )
697 for (
int i = 0; i <
Dim; ++i )
698 (*grid1_)( x, y, z, i ) =
w[i];
700 }
catch ( std::exception& e ) {
701 std::cerr << e.what() << std::endl;
703 }
catch (
const char* e ) {
704 std::cerr << e << std::endl;
708 std::cout <<
"LBM setup finished!" << std::endl;
714 ConfBlock::childIterPair bit = block.findAll(
"noslip" );
716 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
718 ConfBlock& b = it->second;
720 int xStart = ( x == -1 ) ? b.getParam<
int>(
"xStart" ) : x;
721 int xEnd = ( x == -1 ) ? b.getParam<
int>(
"xEnd" ) : x;
722 int yStart = ( y == -1 ) ? b.getParam<
int>(
"yStart" ) : y;
723 int yEnd = ( y == -1 ) ? b.getParam<
int>(
"yEnd" ) : y;
724 int zStart = ( z == -1 ) ? b.getParam<
int>(
"zStart" ) : z;
725 int zEnd = ( z == -1 ) ? b.getParam<
int>(
"zEnd" ) : z;
726 assert( xStart > 0 && xEnd < flag_.getSizeX() - 1 &&
727 yStart > 0 && yEnd < flag_.getSizeY() - 1 &&
728 zStart > 0 && zEnd < flag_.getSizeZ() - 1 );
729 for ( z = zStart; z <= zEnd; ++z ) {
730 for ( y = yStart; y <= yEnd; ++y ) {
731 for ( x = xStart; x <= xEnd; ++x ) {
733 flag_( x, y, z ) =
NOSLIP;
734 noslipCells_.push_back(
Vec3<int>( x, y, z ) );
741 bit = block.findAll(
"velocity" );
743 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
745 ConfBlock& b = it->second;
747 int xStart = ( x == -1 ) ? b.getParam<
int>(
"xStart" ) : x;
748 int xEnd = ( x == -1 ) ? b.getParam<
int>(
"xEnd" ) : x;
749 int yStart = ( y == -1 ) ? b.getParam<
int>(
"yStart" ) : y;
750 int yEnd = ( y == -1 ) ? b.getParam<
int>(
"yEnd" ) : y;
751 int zStart = ( z == -1 ) ? b.getParam<
int>(
"zStart" ) : z;
752 int zEnd = ( z == -1 ) ? b.getParam<
int>(
"zEnd" ) : z;
753 T u_x = b.getParam<
T>(
"u_x" );
754 T u_y = b.getParam<
T>(
"u_y" );
755 T u_z = b.getParam<
T>(
"u_z" );
756 assert( xStart > 0 && xEnd < flag_.getSizeX() - 1 &&
757 yStart > 0 && yEnd < flag_.getSizeY() - 1 &&
758 zStart > 0 && zEnd < flag_.getSizeZ() - 1 );
759 for ( z = zStart; z <= zEnd; ++z ) {
760 for ( y = yStart; y <= yEnd; ++y ) {
761 for ( x = xStart; x <= xEnd; ++x ) {
764 velocityCells_.push_back(
Vec3<int>( x, y, z ) );
765 velocityVels_.push_back(
Vec3<T>( u_x, u_y, u_z ) );
772 bit = block.findAll(
"pressure" );
774 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
776 ConfBlock& b = it->second;
778 int xStart = ( x == -1 ) ? b.getParam<
int>(
"xStart" ) : x;
779 int xEnd = ( x == -1 ) ? b.getParam<
int>(
"xEnd" ) : x;
780 int yStart = ( y == -1 ) ? b.getParam<
int>(
"yStart" ) : y;
781 int yEnd = ( y == -1 ) ? b.getParam<
int>(
"yEnd" ) : y;
782 int zStart = ( z == -1 ) ? b.getParam<
int>(
"zStart" ) : z;
783 int zEnd = ( z == -1 ) ? b.getParam<
int>(
"zEnd" ) : z;
784 int xDir = ( x == -1 ) ? 0 : ( ( x > 1 ) ? -1 : 1 );
785 int yDir = ( y == -1 ) ? 0 : ( ( y > 1 ) ? -1 : 1 );
786 int zDir = ( z == -1 ) ? 0 : ( ( z > 1 ) ? -1 : 1 );
788 for (
int i = 0; i <
Dim; ++i ) {
789 if (
ex[i] == xDir &&
ey[i] == yDir &&
ez[i] == zDir ) {
795 assert( xStart > 0 && xEnd < flag_.getSizeX() - 1 &&
796 yStart > 0 && yEnd < flag_.getSizeY() - 1 &&
797 zStart > 0 && zEnd < flag_.getSizeZ() - 1 );
798 for ( z = zStart; z <= zEnd; ++z ) {
799 for ( y = yStart; y <= yEnd; ++y ) {
800 for ( x = xStart; x <= xEnd; ++x ) {
803 pressureCells_.push_back(
Vec3<int>( x, y, z ) );
804 pressureDFs_.push_back( f );
811 bit = block.findAll(
"inflow" );
813 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
815 ConfBlock& b = it->second;
817 int xStart = ( x == -1 ) ? b.getParam<
int>(
"xStart" ) : x;
818 int xEnd = ( x == -1 ) ? b.getParam<
int>(
"xEnd" ) : x;
819 int yStart = ( y == -1 ) ? b.getParam<
int>(
"yStart" ) : y;
820 int yEnd = ( y == -1 ) ? b.getParam<
int>(
"yEnd" ) : y;
821 int zStart = ( z == -1 ) ? b.getParam<
int>(
"zStart" ) : z;
822 int zEnd = ( z == -1 ) ? b.getParam<
int>(
"zEnd" ) : z;
823 T u_x = b.getParam<
T>(
"u_x" );
824 T u_y = b.getParam<
T>(
"u_y" );
825 T u_z = b.getParam<
T>(
"u_z" );
826 assert( xStart > 0 && xEnd < flag_.getSizeX() - 1 &&
827 yStart > 0 && yEnd < flag_.getSizeY() - 1 &&
828 zStart > 0 && zEnd < flag_.getSizeZ() - 1 );
829 for ( z = zStart; z <= zEnd; ++z ) {
830 for ( y = yStart; y <= yEnd; ++y ) {
831 for ( x = xStart; x <= xEnd; ++x ) {
833 flag_( x, y, z ) =
INFLOW;
834 inflowCells_.push_back(
Vec3<int>( x, y, z ) );
835 inflowVels_.push_back(
Vec3<T>( u_x, u_y, u_z ) );
842 bit = block.findAll(
"outflow" );
844 for ( ConfBlock::childIter it = bit.first; it != bit.second; ++it ) {
846 ConfBlock& b = it->second;
848 int xStart = ( x == -1 ) ? b.getParam<
int>(
"xStart" ) : x;
849 int xEnd = ( x == -1 ) ? b.getParam<
int>(
"xEnd" ) : x;
850 int yStart = ( y == -1 ) ? b.getParam<
int>(
"yStart" ) : y;
851 int yEnd = ( y == -1 ) ? b.getParam<
int>(
"yEnd" ) : y;
852 int zStart = ( z == -1 ) ? b.getParam<
int>(
"zStart" ) : z;
853 int zEnd = ( z == -1 ) ? b.getParam<
int>(
"zEnd" ) : z;
854 int xDir = ( x == -1 ) ? 0 : ( ( x > 1 ) ? -1 : 1 );
855 int yDir = ( y == -1 ) ? 0 : ( ( y > 1 ) ? -1 : 1 );
856 int zDir = ( z == -1 ) ? 0 : ( ( z > 1 ) ? -1 : 1 );
858 for (
int i = 0; i <
Dim; ++i ) {
859 if (
ex[i] == xDir &&
ey[i] == yDir &&
ez[i] == zDir ) {
865 assert( xStart > 0 && xEnd < flag_.getSizeX() - 1 &&
866 yStart > 0 && yEnd < flag_.getSizeY() - 1 &&
867 zStart > 0 && zEnd < flag_.getSizeZ() - 1 );
868 for ( z = zStart; z <= zEnd; ++z ) {
869 for ( y = yStart; y <= yEnd; ++y ) {
870 for ( x = xStart; x <= xEnd; ++x ) {
873 outflowCells_.push_back(
Vec3<int>( x, y, z ) );
874 outflowDFs_.push_back( f );
884 return (
T) ( end.tv_sec - start.tv_sec )
885 + (
T) ( end.tv_usec - start.tv_usec ) / 1000000.;
892 T rho = (*grid0_)( x, y, z, 0 );
897 for (
int f = 1; f <
Dim; ++f ) {
898 T fi = (*grid0_)( x, y, z, f );
905 assert ( rho > 0.8 && rho < 1.2 );
906 assert ( fabs(ux) < 2. );
907 assert ( fabs(uy) < 2. );
908 assert ( fabs(uz) < 2. );
909 rho_( x, y, z ) = rho;
910 u_( x, y, z, 0 ) = ux;
911 u_( x, y, z, 1 ) = uy;
912 u_( x, y, z, 2 ) = uz;
917 T fc = rho - 1.5 * ( ux * ux + uy * uy + uz * uz );
918 T omegai = 1 - omega_;
920 (*grid1_)( x, y, z, 0 ) = omegai * (*grid0_)( x, y, z, 0 )
921 + omega_ *
w[0] * fc;
923 for (
int f = 1; f <
Dim; ++f ) {
924 T eiu =
ex[f] * ux +
ey[f] * uy +
ez[f] * uz;
925 (*grid1_)( x +
ex[f], y +
ey[f], z +
ez[f], f )
926 = omegai * (*grid0_)( x, y, z, f )
927 + omega_ *
w[f] * ( fc + 3 * eiu + 4.5 * eiu * eiu);
936 T rho = (*grid0_)( x, y, z, 0 );
941 for (
int f = 1; f <
Dim; ++f ) {
942 T fi = (*grid0_)( x, y, z, f );
949 assert ( rho > 0.5 && rho < 1.5 );
950 assert ( fabs(ux) < 2. );
951 assert ( fabs(uy) < 2. );
952 assert ( fabs(uz) < 2. );
953 rho_( x, y, z ) = rho;
954 u_( x, y, z, 0 ) = ux;
955 u_( x, y, z, 1 ) = uy;
956 u_( x, y, z, 2 ) = uz;
961 T fc = rho - 1.5 * ( ux * ux + uy * uy + uz * uz );
965 feq[0] = (1./3.) * fc;
966 feq[1] = (1./18.) * ( fc + 3 * uy + 4.5 * uy * uy );
967 feq[2] = (1./18.) * ( fc + 3 * ux + 4.5 * ux * ux );
968 feq[3] = (1./18.) * ( fc - 3 * uy + 4.5 * uy * uy );
969 feq[4] = (1./18.) * ( fc - 3 * ux + 4.5 * ux * ux );
970 feq[5] = (1./18.) * ( fc + 3 * uz + 4.5 * uz * uz );
971 feq[6] = (1./18.) * ( fc - 3 * uz + 4.5 * uz * uz );
972 feq[7] = (1./36.) * ( fc + 3 * ( ux + uy ) + 4.5 * ( ux + uy ) * ( ux + uy ) );
973 feq[8] = (1./36.) * ( fc + 3 * ( ux - uy ) + 4.5 * ( ux - uy ) * ( ux - uy ) );
974 feq[9] = (1./36.) * ( fc - 3 * ( ux + uy ) + 4.5 * ( ux + uy ) * ( ux + uy ) );
975 feq[10] = (1./36.) * ( fc - 3 * ( ux - uy ) + 4.5 * ( ux - uy ) * ( ux - uy ) );
976 feq[11] = (1./36.) * ( fc + 3 * ( uy + uz ) + 4.5 * ( uy + uz ) * ( uy + uz ) );
977 feq[12] = (1./36.) * ( fc + 3 * ( ux + uz ) + 4.5 * ( ux + uz ) * ( ux + uz ) );
978 feq[13] = (1./36.) * ( fc - 3 * ( uy - uz ) + 4.5 * ( uy - uz ) * ( uy - uz ) );
979 feq[14] = (1./36.) * ( fc - 3 * ( ux - uz ) + 4.5 * ( ux - uz ) * ( ux - uz ) );
980 feq[15] = (1./36.) * ( fc + 3 * ( uy - uz ) + 4.5 * ( uy - uz ) * ( uy - uz ) );
981 feq[16] = (1./36.) * ( fc + 3 * ( ux - uz ) + 4.5 * ( ux - uz ) * ( ux - uz ) );
982 feq[17] = (1./36.) * ( fc - 3 * ( uy + uz ) + 4.5 * ( uy + uz ) * ( uy + uz ) );
983 feq[18] = (1./36.) * ( fc - 3 * ( ux + uz ) + 4.5 * ( ux + uz ) * ( ux + uz ) );
987 for (
int i = 0; i < 3; ++i ) {
989 for (
int f = 1; f < 19; ++f ) {
990 qadd +=
ep[i][f] * ( (*grid0_)( x, y, z, f ) - feq[f] );
995 for (
int i = 3; i < 6; ++i ) {
997 for (
int f = 7; f < 19; ++f ) {
998 qadd +=
ep[i][f] * ( (*grid0_)( x, y, z, f ) - feq[f] );
1005 T s = ( sqrt( nu_ * nu_ + 18. * cSmagoSqr_ * qo ) - nu_ ) / ( 6. * cSmagoSqr_);
1007 T omega = 1. / ( 3. * ( nu_ + cSmagoSqr_ * s ) + .5 );
1008 T omegai = 1. - omega;
1012 for (
int f = 0; f <
Dim; ++f ) {
1013 (*grid1_)( x +
ex[f], y +
ey[f], z +
ez[f], f )
1014 = omegai * (*grid0_)( x, y, z, f ) + omega * feq[f];
1019 template<
typename T>
1023 std::vector< Vec3<int> >::iterator iter;
1024 for( iter = noslipCells_.begin(); iter != noslipCells_.end(); iter++ ) {
1033 for (
int f = 1; f <
Dim; ++f ) {
1034 (*grid1_)( x -
ex[f], y -
ey[f], z -
ez[f],
finv[f] ) = (*grid1_)( x, y, z, f );
1039 template<
typename T>
1043 std::vector< Vec3<int> >::iterator iter;
1044 for( iter = staircaseCells_.begin(); iter != staircaseCells_.end(); iter++ ) {
1053 for (
int f = 1; f <
Dim; ++f ) {
1054 (*grid1_)( x -
ex[f], y -
ey[f], z -
ez[f],
finv[f] ) = (*grid1_)( x, y, z, f );
1059 template<
typename T>
1063 for(
int i = 0; i < (int) velocityCells_.size(); ++i ) {
1066 int x = velocityCells_[i][0];
1067 int y = velocityCells_[i][1];
1068 int z = velocityCells_[i][2];
1070 T ux = velocityVels_[i][0];
1071 T uy = velocityVels_[i][1];
1072 T uz = velocityVels_[i][2];
1074 T rho = 6 * rho_( x, y, z );
1076 u_( x, y, z, 0 ) = ux;
1077 u_( x, y, z, 1 ) = uy;
1078 u_( x, y, z, 2 ) = uz;
1083 for (
int f = 1; f <
Dim; ++f ) {
1085 (*grid1_)( x -
ex[f], y -
ey[f], z -
ez[f], op )
1086 = (*grid1_)( x, y, z, f )
1087 + rho *
w[f] * ( ex[op] * ux + ey[op] * uy + ez[op] * uz );
1092 template<
typename T>
1096 for(
int i = 0; i < (int) inflowCells_.size(); ++i ) {
1099 int x = inflowCells_[i][0];
1100 int y = inflowCells_[i][1];
1101 int z = inflowCells_[i][2];
1103 T ux = inflowVels_[i][0];
1104 T uy = inflowVels_[i][1];
1105 T uz = inflowVels_[i][2];
1107 u_( x, y, z, 0 ) = ux;
1108 u_( x, y, z, 1 ) = uy;
1109 u_( x, y, z, 2 ) = uz;
1113 T fc = 1. - 1.5 * ( ux * ux + uy * uy + uz * uz );
1114 (*grid1_)( x, y, z, 0 ) = (1./3.) * fc;
1115 (*grid1_)( x, y, z, 1 ) = (1./18.) * ( fc + 3 * uy + 4.5 * uy * uy );
1116 (*grid1_)( x, y, z, 2 ) = (1./18.) * ( fc + 3 * ux + 4.5 * ux * ux );
1117 (*grid1_)( x, y, z, 3 ) = (1./18.) * ( fc - 3 * uy + 4.5 * uy * uy );
1118 (*grid1_)( x, y, z, 4 ) = (1./18.) * ( fc - 3 * ux + 4.5 * ux * ux );
1119 (*grid1_)( x, y, z, 5 ) = (1./18.) * ( fc + 3 * uz + 4.5 * uz * uz );
1120 (*grid1_)( x, y, z, 6 ) = (1./18.) * ( fc - 3 * uz + 4.5 * uz * uz );
1121 (*grid1_)( x, y, z, 7 ) = (1./36.) * ( fc + 3 * ( ux + uy ) + 4.5 * ( ux + uy ) * ( ux + uy ) );
1122 (*grid1_)( x, y, z, 8 ) = (1./36.) * ( fc + 3 * ( ux - uy ) + 4.5 * ( ux - uy ) * ( ux - uy ) );
1123 (*grid1_)( x, y, z, 9 ) = (1./36.) * ( fc - 3 * ( ux + uy ) + 4.5 * ( ux + uy ) * ( ux + uy ) );
1124 (*grid1_)( x, y, z, 10 ) = (1./36.) * ( fc - 3 * ( ux - uy ) + 4.5 * ( ux - uy ) * ( ux - uy ) );
1125 (*grid1_)( x, y, z, 11 ) = (1./36.) * ( fc + 3 * ( uy + uz ) + 4.5 * ( uy + uz ) * ( uy + uz ) );
1126 (*grid1_)( x, y, z, 12 ) = (1./36.) * ( fc + 3 * ( ux + uz ) + 4.5 * ( ux + uz ) * ( ux + uz ) );
1127 (*grid1_)( x, y, z, 13 ) = (1./36.) * ( fc - 3 * ( uy - uz ) + 4.5 * ( uy - uz ) * ( uy - uz ) );
1128 (*grid1_)( x, y, z, 14 ) = (1./36.) * ( fc - 3 * ( ux - uz ) + 4.5 * ( ux - uz ) * ( ux - uz ) );
1129 (*grid1_)( x, y, z, 15 ) = (1./36.) * ( fc + 3 * ( uy - uz ) + 4.5 * ( uy - uz ) * ( uy - uz ) );
1130 (*grid1_)( x, y, z, 16 ) = (1./36.) * ( fc + 3 * ( ux - uz ) + 4.5 * ( ux - uz ) * ( ux - uz ) );
1131 (*grid1_)( x, y, z, 17 ) = (1./36.) * ( fc - 3 * ( uy + uz ) + 4.5 * ( uy + uz ) * ( uy + uz ) );
1132 (*grid1_)( x, y, z, 18 ) = (1./36.) * ( fc - 3 * ( ux + uz ) + 4.5 * ( ux + uz ) * ( ux + uz ) );
1136 template<
typename T>
1140 for(
int i = 0; i < (int) outflowCells_.size(); ++i ) {
1143 int x = outflowCells_[i][0];
1144 int y = outflowCells_[i][1];
1145 int z = outflowCells_[i][2];
1147 int d = outflowDFs_[i];
1151 for (
int f = 1; f <
Dim; ++f ) {
1152 (*grid1_)( x -
ex[d], y -
ey[d], z -
ez[d], f ) = (*grid1_)( x, y, z, f );
1157 template<
typename T>
1161 for( uint i = 0; i < pressureCells_.size(); ++i ) {
1164 int x = pressureCells_[i][0];
1165 int y = pressureCells_[i][1];
1166 int z = pressureCells_[i][2];
1168 int f = pressureDFs_[i];
1170 T ux = u_( x, y, z, 0 );
1171 T uy = u_( x, y, z, 1 );
1172 T uz = u_( x, y, z, 2 );
1176 T eiu =
ex[f] * ux +
ey[f] * uy +
ez[f] * uz;
1177 T fc =
w[f] * ( 2. - 3. * ( ux * ux + uy * uy + uz * uz ) + 9. * eiu * eiu );
1178 (*grid1_)( x, y, z, f ) = fc - (*grid1_)( x, y, z,
finv[f] );
1179 (*grid1_)( x, y, z,
finv[f] ) = fc - (*grid1_)( x, y, z, f );
1183 template<
typename T>
1187 for ( uint i = 0; i < curvedCells_.size(); ++i ) {
1188 int x = curvedCells_[i][0];
1189 int y = curvedCells_[i][1];
1190 int z = curvedCells_[i][2];
1192 for (
int f = 1; f <
Dim; ++f ) {
1193 T delta = curvedDeltas_[i][f];
1203 (*grid1_)( x +
ex[f], y +
ey[f], z +
ez[f], f ) = ( 1. / ( 1. + delta) ) * (
1204 delta * ( (*grid1_)( x + 2 * ex[f], y + 2 * ey[f], z + 2 * ez[f], f )
1205 + (*grid1_)( x, y, z,
finv[f] ) )
1206 + (1. - delta) * (*grid1_)( x + ex[f], y + ey[f], z + ez[f],
finv[f] ) );
1212 #define DIST(x,y,z) ((x) - xCenter) * ((x) - xCenter) + ((y) - yCenter) * ((y) - yCenter) + ((z) - zCenter) * ((z) - zCenter)
1213 template<
typename T>
1216 for ( uint i = 0; i < sphereObstacles_.size(); ++i ) {
1218 T xCenter = sphereObstacles_[i].x;
1219 T yCenter = sphereObstacles_[i].y;
1220 T zCenter = sphereObstacles_[i].z;
1221 T u_x = sphereObstacles_[i].u_x;
1222 T u_y = sphereObstacles_[i].u_y;
1223 T u_z = sphereObstacles_[i].u_z;
1224 T radius = sphereObstacles_[i].r;
1228 T r2 = radius * radius;
1230 T zStart = floor( zCenter - radius ) + .5;
1231 if ( zStart > flag_.getSizeZ() - .5)
continue;
1232 if ( zStart < 2.5 ) zStart = 2.5;
1233 T zEnd = floor( zCenter + radius ) + .5;
1234 if ( zEnd < 2.5 )
continue;
1235 if ( zEnd > flag_.getSizeZ() - 1.5) zEnd = flag_.getSizeZ() - 1.5;
1236 T yStart = floor( yCenter - radius ) + .5;
1237 if ( yStart > flag_.getSizeY() - 1.5)
continue;
1238 if ( yStart < 2.5 ) yStart = 2.5;
1239 T yEnd = floor( yCenter + radius ) + .5;
1240 if ( yEnd < 2.5 )
continue;
1241 if ( yEnd > flag_.getSizeY() - 1.5) yEnd = flag_.getSizeY() - 1.5;
1242 T xStart = floor( xCenter - radius ) + .5;
1243 if ( xStart > flag_.getSizeX() - 1.5)
continue;
1244 if ( xStart < 2.5 ) xStart = 2.5;
1245 T xEnd = floor( xCenter + radius ) + .5;
1246 if ( xEnd < 2.5 )
continue;
1247 if ( xEnd > flag_.getSizeX() - 1.5) xEnd = flag_.getSizeX() - 1.5;
1252 for (
int z = zStart; z < zEnd; ++z )
1253 for (
int y = yStart; y < yEnd; ++y )
1254 for (
int x = xStart; x < xEnd; ++x ) {
1258 if (
DIST(x + 0.5, y + 0.5, z + 0.5) > r2 )
continue;
1260 for (
int f = 1; f <
Dim; ++f ) {
1261 if (
DIST( x +
ex[f] + 0.5, y +
ey[f] + 0.5, z +
ez[f] + 0.5 ) > r2 ) {
1262 T xd = xCenter - (x + .5);
1263 T yd = yCenter - (y + .5);
1264 T zd = zCenter - (z + .5);
1265 T b =
exn[f] * xd +
eyn[f] * yd +
ezn[f] * zd;
1266 T c = xd * xd + yd * yd + zd * zd - r2;
1268 T deltai = ( b + sqrt( b * b - c ) ) /
le[f];
1269 T delta = 1.0 - deltai;
1270 T rho = 6 * rho_(x, y, z);
1287 (*grid1_)( x +
ex[f], y +
ey[f], z +
ez[f], f ) = ( 1. / ( 1. + delta) ) * (
1288 delta * ( (*grid1_)( x + 2 * ex[f], y + 2 * ey[f], z + 2 * ez[f], f )
1289 + (*grid1_)( x, y, z,
finv[f] ) )
1290 + (1. - delta) * (*grid1_)( x + ex[f], y + ey[f], z + ez[f],
finv[f] )
1291 +
w[f] * rho * ( u_x * ex[f] + u_y * ey[f] + u_z * ez[f]) );
1296 sphereObstacles_[i].move();
1300 template<
typename T>
1302 assert( prof_.fileName.length() );
1304 std::cout <<
"Writing performance summary file '" << prof_.fileName <<
".nosmago'" << std::endl;
1305 std::ofstream f( (prof_.fileName +
".nosmago").c_str(), std::ios::out );
1307 std::cout <<
"Writing performance summary file '" << prof_.fileName <<
".smago'" << std::endl;
1308 std::ofstream f( (prof_.fileName +
".smago").c_str(), std::ios::out );
1311 T boundTime = prof_.nTime + prof_.vTime + prof_.iTime + prof_.oTime + prof_.pTime + prof_.cTime + prof_.mTime;
1312 T totTime = boundTime + prof_.scTime;
1315 int sizeX = grid0_->getSizeX() - 2;
1316 int sizeY = grid0_->getSizeY() - 2;
1317 int sizeZ = grid0_->getSizeZ() - 2;
1319 int numCells = sizeX * sizeY * sizeZ;
1321 int nCells = noslipCells_.size();
1322 int vCells = velocityCells_.size();
1323 int iCells = inflowCells_.size();
1324 int oCells = outflowCells_.size();
1325 int pCells = pressureCells_.size();
1326 int cCells = curvedCells_.size();
1327 int sCells = staircaseCells_.size();
1328 int bCells = nCells + vCells + iCells + oCells + pCells + cCells + sCells;
1329 int fCells = numCells - bCells;
1332 f <<
"Domain size : " << sizeX <<
" x " << sizeY <<
" x " << sizeZ <<
"\n";
1334 f <<
"Number of timesteps : " << maxSteps_ <<
"\n";
1336 f <<
"Smagorinsky turbulence: no\n";
1338 f <<
"Smagorinsky turbulence: yes\n";
1348 f <<
"Cell type |" << std::setw(13) <<
"Total" << std::setw(13) <<
"Fluid" << std::setw(13) <<
"Boundary Tot" << std::setw(13) <<
"No-slip" << std::setw(13) <<
"Acceleration" << std::setw(13) <<
"Inflow" << std::setw(13) <<
"Outflow" << std::setw(13) <<
"Pressure" << std::setw(13) <<
"Curved" << std::setw(13) <<
"Staircase" << std::setw(13) <<
"Moving\n";
1349 f <<
"Number of cells |" << std::setw(13) << numCells << std::setw(13) << fCells << std::setw(13) << bCells << std::setw(13) << nCells << std::setw(13) << vCells << std::setw(13) << iCells << std::setw(13) << oCells << std::setw(13) << pCells << std::setw(13) << cCells << std::setw(13) << sCells <<
"\n";
1350 f <<
"Runtime [s] |" << std::setw(13) << totTime << std::setw(13) << prof_.scTime << std::setw(13) << boundTime << std::setw(13) << prof_.nTime << std::setw(13) << prof_.vTime << std::setw(13) << prof_.iTime << std::setw(13) << prof_.oTime << std::setw(13) << prof_.pTime << std::setw(13) << prof_.cTime << std::setw(13) << prof_.sTime << std::setw(13) << prof_.mTime <<
"\n";
1351 f <<
"Runtime share |" << std::setw(13) << 1 << std::setw(13) << prof_.scTime / totTime << std::setw(13) << boundTime / totTime << std::setw(13) << prof_.nTime / totTime << std::setw(13) << prof_.vTime / totTime << std::setw(13) << prof_.iTime / totTime << std::setw(13) << prof_.oTime / totTime << std::setw(13) << prof_.pTime / totTime << std::setw(13) << prof_.cTime / totTime << std::setw(13) << prof_.sTime / totTime << std::setw(13) << prof_.mTime / totTime <<
"\n";
1353 f <<
"MLUP/s |" << std::setw(13) << calcMLUP( totTime, numCells ) << std::setw(13) << calcMLUP( prof_.scTime, fCells ) << std::setw(13) << calcMLUP( boundTime, bCells ) << std::setw(13) << calcMLUP( prof_.nTime, nCells ) << std::setw(13) << calcMLUP( prof_.vTime, vCells ) << std::setw(13) << calcMLUP( prof_.iTime, iCells ) << std::setw(13) << calcMLUP( prof_.oTime, oCells ) << std::setw(13) << calcMLUP( prof_.pTime, pCells ) << std::setw(13) << calcMLUP( prof_.cTime, cCells ) << std::setw(13) << calcMLUP( prof_.sTime, sCells ) <<
"\n";
1356 template<
typename T>
1359 return std::string(
"n/a");
1361 std::stringstream o;
1362 o << cells * maxSteps_ / ( time * 1000000 );
1370 std::ostringstream oss;
1371 oss << vtkFileName_ <<
"." << curStep_ <<
".vtk";
1372 std::cout <<
"Writing file '" << oss.str() <<
"' for time step " << curStep_ << std::endl;
1373 std::ofstream vtkFile( oss.str().c_str(), std::ios::binary | std::ios::out );
1376 int sizeX = grid0_->getSizeX() - 2;
1377 int sizeY = grid0_->getSizeY() - 2;
1378 int sizeZ = grid0_->getSizeZ() - 2;
1381 vtkFile <<
"# vtk DataFile Version 2.0\n";
1382 vtkFile <<
"VTK output file for time step " << curStep_ <<
"\n\n";
1383 vtkFile <<
"BINARY\n\n";
1384 vtkFile <<
"DATASET STRUCTURED_POINTS\n";
1385 vtkFile <<
"DIMENSIONS " << sizeX <<
" " << sizeY <<
" " << sizeZ <<
"\n";
1386 vtkFile <<
"ORIGIN 0.0 0.0 0.0\n";
1387 vtkFile <<
"SPACING 1.0 1.0 1.0\n\n";
1388 vtkFile <<
"POINT_DATA " << sizeX * sizeY * sizeZ <<
"\n\n";
1391 vtkFile <<
"SCALARS flags int\n";
1392 vtkFile <<
"LOOKUP_TABLE default\n";
1393 for (
int z = 1; z <= sizeZ; ++z ) {
1394 for (
int y = 1; y <= sizeY; ++y ) {
1395 for (
int x = 1; x <= sizeX; ++x ) {
1397 uint32_t dump =
htobe32( *reinterpret_cast<uint32_t *>( &flag_( x, y, z ) ) );
1398 vtkFile.write( reinterpret_cast<char *>( &dump ),
sizeof(
int) );
1404 vtkFile <<
"SCALARS density double\n";
1405 vtkFile <<
"LOOKUP_TABLE default\n";
1406 for (
int z = 1; z <= sizeZ; ++z ) {
1407 for (
int y = 1; y <= sizeY; ++y ) {
1408 for (
int x = 1; x <= sizeX; ++x ) {
1410 uint64_t dump =
htobe64( *reinterpret_cast<uint64_t *>( &rho_( x, y, z ) ) );
1411 vtkFile.write( reinterpret_cast<char *>( &dump ),
sizeof(
double) );
1417 vtkFile <<
"VECTORS velocity double\n";
1418 for (
int z = 1; z <= sizeZ; ++z ) {
1419 for (
int y = 1; y <= sizeY; ++y ) {
1420 for (
int x = 1; x <= sizeX; ++x ) {
1422 uint64_t dump0 =
htobe64( *reinterpret_cast<uint64_t *>( &u_( x, y, z, 0 ) ) );
1423 uint64_t dump1 =
htobe64( *reinterpret_cast<uint64_t *>( &u_( x, y, z, 1 ) ) );
1424 uint64_t dump2 =
htobe64( *reinterpret_cast<uint64_t *>( &u_( x, y, z, 2 ) ) );
1425 vtkFile.write( reinterpret_cast<char *>( &dump0 ),
sizeof(
double) );
1426 vtkFile.write( reinterpret_cast<char *>( &dump1 ),
sizeof(
double) );
1427 vtkFile.write( reinterpret_cast<char *>( &dump2 ),
sizeof(
double) );
1438 std::ostringstream oss;
1439 oss << vtkFileName_ <<
"." << curStep_ <<
".vtk";
1440 std::cout <<
"Writing file '" << oss.str() <<
"' for time step " << curStep_ << std::endl;
1441 std::ofstream vtkFile( oss.str().c_str(), std::ios::binary | std::ios::out );
1444 int sizeX = grid0_->getSizeX() - 2;
1445 int sizeY = grid0_->getSizeY() - 2;
1446 int sizeZ = grid0_->getSizeZ() - 2;
1449 vtkFile <<
"# vtk DataFile Version 2.0\n";
1450 vtkFile <<
"VTK output file for time step " << curStep_ <<
"\n\n";
1451 vtkFile <<
"BINARY\n\n";
1452 vtkFile <<
"DATASET STRUCTURED_POINTS\n";
1453 vtkFile <<
"DIMENSIONS " << sizeX <<
" " << sizeY <<
" " << sizeZ <<
"\n";
1454 vtkFile <<
"ORIGIN 0.0 0.0 0.0\n";
1455 vtkFile <<
"SPACING 1.0 1.0 1.0\n\n";
1456 vtkFile <<
"POINT_DATA " << sizeX * sizeY * sizeZ <<
"\n\n";
1459 vtkFile <<
"SCALARS flags int\n";
1460 vtkFile <<
"LOOKUP_TABLE default\n";
1461 for (
int z = 1; z <= sizeZ; ++z ) {
1462 for (
int y = 1; y <= sizeY; ++y ) {
1463 for (
int x = 1; x <= sizeX; ++x ) {
1465 uint32_t dump =
htobe32( *reinterpret_cast<uint32_t *>( &flag_( x, y, z ) ) );
1466 vtkFile.write( reinterpret_cast<char *>( &dump ),
sizeof(
int) );
1472 vtkFile <<
"SCALARS density float\n";
1473 vtkFile <<
"LOOKUP_TABLE default\n";
1474 for (
int z = 1; z <= sizeZ; ++z ) {
1475 for (
int y = 1; y <= sizeY; ++y ) {
1476 for (
int x = 1; x <= sizeX; ++x ) {
1478 uint32_t dump =
htobe32( *reinterpret_cast<uint32_t *>( &rho_( x, y, z ) ) );
1479 vtkFile.write( reinterpret_cast<char *>( &dump ),
sizeof(
float) );
1485 vtkFile <<
"VECTORS velocity float\n";
1486 for (
int z = 1; z <= sizeZ; ++z ) {
1487 for (
int y = 1; y <= sizeY; ++y ) {
1488 for (
int x = 1; x <= sizeX; ++x ) {
1490 uint32_t dump0 =
htobe32( *reinterpret_cast<uint32_t *>( &u_( x, y, z, 0 ) ) );
1491 uint32_t dump1 =
htobe32( *reinterpret_cast<uint32_t *>( &u_( x, y, z, 1 ) ) );
1492 uint32_t dump2 =
htobe32( *reinterpret_cast<uint32_t *>( &u_( x, y, z, 2 ) ) );
1493 vtkFile.write( reinterpret_cast<char *>( &dump0 ),
sizeof(
float) );
1494 vtkFile.write( reinterpret_cast<char *>( &dump1 ),
sizeof(
float) );
1495 vtkFile.write( reinterpret_cast<char *>( &dump2 ),
sizeof(
float) );