void prepareLattice(LBconverter<T> const* converter, BlockStructure2D<T,DESCRIPTOR>& lattice, Dynamics<T, DESCRIPTOR>& bulkDynamics, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& bc ){ const int nx = lattice.getNx(); const int ny = lattice.getNy(); const T omega = converter->getOmega(); // link lattice with dynamics for collision step lattice.defineDynamics(0,nx-1, 0,ny-1, &bulkDynamics); // left boundary bc.addVelocityBoundary0N( 0, 0, 1,ny-2, omega); // right boundary bc.addVelocityBoundary0P(nx-1,nx-1, 1,ny-2, omega); // bottom boundary bc.addVelocityBoundary1N( 1,nx-2, 0, 0, omega); // top boundary bc.addVelocityBoundary1P( 1,nx-2,ny-1,ny-1, omega); // corners bc.addExternalVelocityCornerNN( 0, 0, omega); bc.addExternalVelocityCornerNP( 0,ny-1, omega); bc.addExternalVelocityCornerPN(nx-1, 0, omega); bc.addExternalVelocityCornerPP(nx-1,ny-1, omega); }
void plotStatistics(BlockStructure2D<T, DESCRIPTOR>& latticeTwo, BlockStructure2D<T, DESCRIPTOR>& latticeOne, int iT) { cout << "Writing Gif\n"; ImageWriter<T> imageCreator("leeloo.map"); imageCreator.writeScaledGif(createFileName("p", iT, 6), latticeOne.getDataAnalysis().getPressure()); }
void getResults(BlockStructure2D<T,DESCRIPTOR>& lattice, LBconverter<T> const* converter, int iT, Timer<double>* timer, const T logT, const T imSave, const T vtkSave, const T maxT, std::string filenameGif, std::string filenameVtk, const bool timerPrintSum, const int timerPrintMode, const int timerTimeSteps) { const int imSize = 600; /// Get statistics if (iT%converter->numTimeSteps(logT)==0) { lattice.getStatistics().print(iT, converter->physTime(iT)); } if (iT%timerTimeSteps==0) { timer->print(iT,timerPrintMode); } /// Writes the Gif files if (iT%converter->numTimeSteps(imSave)==0 && iT>0) { DataAnalysisBase2D<T,DESCRIPTOR> const& analysis = lattice.getDataAnalysis(); ImageWriter<T> imageWriter("leeloo"); imageWriter.writeScaledGif(createFileName(filenameGif, iT, 6), analysis.getVelocityNorm(), imSize, imSize ); } /// Writes the VTK files if (iT%converter->numTimeSteps(vtkSave)==0 && iT>0) { DataAnalysisBase2D<T,DESCRIPTOR> const& analysis = lattice.getDataAnalysis(); T dx = converter->getLatticeL(); T dt = converter->physTime(); VtkImageOutput2D<T> vtkOut(createFileName(filenameVtk, iT, 6), dx); vtkOut.writeData<double>(analysis.getVorticity(), "vorticity", (T)1/dt); vtkOut.writeData<2,double>(analysis.getVelocity(), "velocity", dx/dt); } if (iT == converter->numTimeSteps(maxT)-1 ){ timer->stop(); if (timerPrintSum==true) timer->printSummary(); } }
void setBoundaryValues(LBconverter<T> const* converter, BlockStructure2D<T,DESCRIPTOR>& lattice, int iT){ if(iT==0){ const int nx = lattice.getNx(); const int ny = lattice.getNy(); // set initial values: v = [0,0] for (int iX=0; iX<nx; ++iX) { for (int iY=0; iY<ny; ++iY) { T vel[] = { T(), T()}; lattice.get(iX,iY).defineRhoU((T)1, vel); lattice.get(iX,iY).iniEquilibrium((T)1, vel); } } // set non-zero velocity for upper boundary cells for (int iX=1; iX<nx-1; ++iX) { T u = converter->getLatticeU(); T vel[] = { u, T() }; lattice.get(iX,ny-1).defineRhoU((T)1, vel); lattice.get(iX,ny-1).iniEquilibrium((T)1, vel); } // Make the lattice ready for simulation lattice.initialize(); } }
void plotStatistics(int iT, BlockStructure2D<T, DESCRIPTOR>& lattice, LBunits<T>& converter, T middleU) { T dx = converter.getDeltaX(); T dt = converter.getDeltaT(); cout << "Iteration " << setw(5) << iT; cout << "; t=" << setprecision(3) << setw(6) << iT*converter.getDeltaT(); cout << "; E=" << setprecision(10) << setw(15) << lattice.getStatistics().getAverageEnergy()*dx*dx/dt/dt; cout << "; rho=" << setprecision(8) << setw(11) << lattice.getStatistics().getAverageRho(); cout << "; uMax= " << setprecision(8) << setw(11) << middleU*dx/dt; cout << endl; }
void produceGif(int iT, BlockStructure2D<T, DESCRIPTOR>& lattice) { const int imSize = 400; DataAnalysisBase2D<T,DESCRIPTOR> const& analysis = lattice.getDataAnalysis(); ImageWriter<T> imageWriter("leeloo"); imageWriter.writeScaledGif(createFileName("p", iT, 6), analysis.getPressure(), imSize, imSize); imageWriter.writeScaledGif(createFileName("u", iT, 6), analysis.getVelocityNorm(), imSize, imSize); }
void getResults(BlockStructure2D<T,DESCRIPTOR>& lattice, LBconverter<T>& converter, int iT) { const T lx = 2.; const T ly = 1.; const int saveIter = 2000; const int statIter = 200; const int imSize = 400; if (iT%statIter==0) { T middleU[2]; lattice.get(converter.numNodes(lx)/2, converter.numNodes(ly)/2).computeU(middleU); OstreamManager cout(std::cout,"plotStatistics"); T dx = converter.getDeltaX(); T dt = converter.getDeltaT(); cout << "iteration=" << setw(5) << iT; cout << "; t=" << setprecision(3) << setw(6) << iT*converter.getDeltaT(); cout << "; E=" << setprecision(10) << setw(15) << lattice.getStatistics().getAverageEnergy()*dx*dx/dt/dt; cout << "; rho=" << setprecision(8) << setw(11) << lattice.getStatistics().getAverageRho(); cout << "; uMax= " << setprecision(8) << setw(11) << middleU[0]*dx/dt; cout << endl; } if (iT%saveIter==0) { DataAnalysisBase2D<T,DESCRIPTOR> const& analysis = lattice.getDataAnalysis(); ImageWriter<T> imageWriter("leeloo"); imageWriter.writeScaledGif(createFileName("p", iT, 6), analysis.getPressure(), imSize, imSize); imageWriter.writeScaledGif(createFileName("u", iT, 6), analysis.getVelocityNorm(), imSize, imSize); ofstream *ofile = 0; if (singleton::mpi().isMainProcessor()) { ofile = new ofstream((singleton::directories().getLogOutDir()+"centerVel.dat").c_str()); } for (int iY=0; iY<lattice.getNy(); ++iY) { T dx = converter.getDeltaX(); T dt = converter.getDeltaT(); T analytical = poiseuilleVelocity(iY, converter); T numerical[2]; lattice.get(lattice.getNx()/2, iY).computeU(numerical); if (singleton::mpi().isMainProcessor()) { *ofile << iY*dx << " " << analytical*dx/dt << " " << numerical[0]*dx/dt << "\n"; } } delete ofile; } }
void setBoundaryValues(LBconverter<T> const&converter, BlockStructure2D<T,DESCRIPTOR>& lattice, int iT){ int nx = lattice.getNx(); int ny = lattice.getNy(); if(iT==0){ for (int iX=0; iX<nx; ++iX) { for (int iY=0; iY<ny; ++iY) { T force[2] = { poiseuilleForce(converter), T() }; lattice.get(iX,iY).defineExternalField ( DESCRIPTOR<T>::ExternalField::forceBeginsAt, DESCRIPTOR<T>::ExternalField::sizeOfForce, force ); } } /// Make the lattice ready for simulation lattice.initialize(); } }
void iniGeometry( BlockStructure2D<T, DESCRIPTOR>& lattice, LBunits<T> const& converter, Dynamics<T, DESCRIPTOR>& bulkDynamics, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition, BoundaryType boundaryType ) { int nx = converter.getNx(); int ny = converter.getNy(); T omega = converter.getOmega(); lattice.defineDynamics(0,nx-1, 0,ny-1, &bulkDynamics); boundaryCondition.addVelocityBoundary1P(1,nx-2,ny-1,ny-1, omega); boundaryCondition.addVelocityBoundary1N(1,nx-2, 0, 0, omega); if (boundaryType==velocity) { boundaryCondition.addVelocityBoundary0N(0,0, 1, ny-2, omega); boundaryCondition.addVelocityBoundary0P(nx-1,nx-1, 1, ny-2, omega); } else { boundaryCondition.addPressureBoundary0N(0,0, 1, ny-2, omega); boundaryCondition.addPressureBoundary0P(nx-1,nx-1, 1, ny-2, omega); } boundaryCondition.addExternalVelocityCornerNN(0,0, omega); boundaryCondition.addExternalVelocityCornerNP(0,ny-1, omega); boundaryCondition.addExternalVelocityCornerPN(nx-1,0, omega); boundaryCondition.addExternalVelocityCornerPP(nx-1,ny-1, omega); for (int iX=0; iX<nx; ++iX) { for (int iY=0; iY<ny; ++iY) { T u[2] = {poiseuilleVelocity(iY, converter),0.}; T rho = (T)1 + poiseuillePressure(iX, converter) * DESCRIPTOR<T>::invCs2; lattice.get(iX,iY).defineRhoU(rho, u); lattice.get(iX,iY).iniEquilibrium(rho, u); } } lattice.initialize(); }
void prepareLattice(LBconverter<T> const& converter, BlockStructure2D<T, DESCRIPTOR>& lattice, Dynamics<T, DESCRIPTOR>& bulkDynamics, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition ) { int nx = lattice.getNx(); int ny = lattice.getNy(); T omega = converter.getOmega(); /// define lattice Dynamics lattice.defineDynamics(0,nx-1, 0,ny-1, &bulkDynamics); /// sets boundary boundaryCondition.addVelocityBoundary1P(1,nx-2,ny-1,ny-1, omega); boundaryCondition.addVelocityBoundary1N(1,nx-2, 0, 0, omega); /// set Velocity boundaryCondition.addExternalVelocityCornerNN(0,0, omega); boundaryCondition.addExternalVelocityCornerNP(0,ny-1, omega); boundaryCondition.addExternalVelocityCornerPN(nx-1,0, omega); boundaryCondition.addExternalVelocityCornerPP(nx-1,ny-1, omega); }
void writeProfile ( string fName, BlockStructure2D<T, DESCRIPTOR>& lattice, LBunits<T>& converter ) { ofstream *ofile = 0; if (singleton::mpi().isMainProcessor()) { ofile = new ofstream((singleton::directories().getLogOutDir()+fName).c_str()); } for (int iY=0; iY<converter.getNy(); ++iY) { T dx = converter.getDeltaX(); T dt = converter.getDeltaT(); T analytical = poiseuilleVelocity(iY, converter); T numerical[2]; lattice.get(converter.getNx()/2, iY).computeU(numerical); if (singleton::mpi().isMainProcessor()) { *ofile << iY*dx << " " << analytical*dx/dt << " " << numerical[0]*dx/dt << "\n"; } } delete ofile; }
void iniGeometry( BlockStructure2D<T, DESCRIPTOR>& latticeOne, BlockStructure2D<T, DESCRIPTOR>& latticeTwo, Dynamics<T, DESCRIPTOR>& bulkDynamics1, Dynamics<T, DESCRIPTOR>& bulkDynamics2, Dynamics<T, DESCRIPTOR>& bounceBackRho0, Dynamics<T, DESCRIPTOR>& bounceBackRho1, T force ) { // The setup is: periodicity along horizontal direction, bounce-back on top // and bottom. The upper half is initially filled with fluid 1 + random noise, // and the lower half with fluid 2. Only fluid 1 experiences a forces, // directed downwards. T noise = 1.e-2; int nx = latticeOne.getNx(); int ny = latticeOne.getNy(); latticeOne.defineDynamics(0,nx-1, 0,ny-1, &bulkDynamics1); latticeTwo.defineDynamics(0,nx-1, 0,ny-1, &bulkDynamics2); latticeOne.defineDynamics(0,nx-1, 0,0, &bounceBackRho0); latticeTwo.defineDynamics(0,nx-1, 0,0, &bounceBackRho1); latticeOne.defineDynamics(0,nx-1, ny-1,ny-1, &bounceBackRho1); latticeTwo.defineDynamics(0,nx-1, ny-1,ny-1, &bounceBackRho0); for (int iX=0; iX<nx; ++iX) { for (int iY=0; iY<ny; ++iY) { T f[2] = {0.,-force}; T zeroVelocity[2] = {0.,0.}; T noForce[2] = {0.,0.}; T rho1 = (T)1; T rho2 = (T)1; if (iY>ny/2) { rho2 = 0.; rho1 += (double)random()/(double)RAND_MAX * noise; rho1 += force*DESCRIPTOR<T>::invCs2* ((T)ny - (T)iY - (T)ny/(T)2); } else { rho1 = 0.; } Cell<T,DESCRIPTOR>& cell1 = latticeOne.get(iX,iY); cell1.defineRhoU(rho1, zeroVelocity); cell1.iniEquilibrium(rho1, zeroVelocity); cell1.defineExternalField ( DESCRIPTOR<T>::ExternalField::forceBeginsAt, DESCRIPTOR<T>::ExternalField::sizeOfForce, f ); Cell<T,DESCRIPTOR>& cell2 = latticeTwo.get(iX,iY); cell2.defineRhoU(rho2, zeroVelocity); cell2.iniEquilibrium(rho2, zeroVelocity); cell2.defineExternalField ( DESCRIPTOR<T>::ExternalField::forceBeginsAt, DESCRIPTOR<T>::ExternalField::sizeOfForce, noForce ); } } latticeOne.initialize(); latticeTwo.initialize(); }