int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); MultiBlockLattice2D<T, DESCRIPTOR> lattice ( nx, ny, new BGKdynamics<T,DESCRIPTOR>(omega) ); lattice.periodicity().toggleAll(true); // Set periodic boundaries. defineInitialDensityAtCenter(lattice); // First part: loop over time iterations. for (plint iT=0; iT<maxIter; ++iT) { lattice.collideAndStream(); } // Second part: Data analysis. Array<T,2> velocity; lattice.get(nx/2, ny/2).computeVelocity(velocity); pcout << "Velocity in the middle of the lattice: (" << velocity[0] << "," << velocity[1] << ")" << endl; pcout << "Velocity norm along a horizontal line: " << endl; Box2D line(0, 100, ny/2, ny/2); pcout << setprecision(3) << *computeVelocityNorm(*extractSubDomain(lattice, line)) << endl; plb_ofstream ofile("profile.dat"); ofile << setprecision(3) << *computeVelocityNorm(*extractSubDomain(lattice, line)) << endl; pcout << "Average density in the domain: " << computeAverageDensity(lattice) << endl; pcout << "Average energy in the domain: " << computeAverageEnergy(lattice) << endl; }
void halfCircleSetup ( MultiBlockLattice2D<T,DESCRIPTOR>& lattice, plint N, plint radius, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition ) { // The channel is pressure-driven, with a difference deltaRho // between inlet and outlet. T deltaRho = 1.e-2; T rhoIn = 1. + deltaRho/2.; T rhoOut = 1. - deltaRho/2.; Box2D inlet (0, N/2, N/2, N/2); Box2D outlet(N/2+1, N, N/2, N/2); boundaryCondition.addPressureBoundary1P(inlet, lattice); boundaryCondition.addPressureBoundary1P(outlet, lattice); // Specify the inlet and outlet density. setBoundaryDensity (lattice, inlet, rhoIn); setBoundaryDensity (lattice, outlet, rhoOut); // Create the initial condition. Array<T,2> zeroVelocity((T)0.,(T)0.); T constantDensity = (T)1; initializeAtEquilibrium ( lattice, lattice.getBoundingBox(), constantDensity, zeroVelocity ); defineDynamics(lattice, lattice.getBoundingBox(), new BounceBackNodes<T>(N, radius), new BounceBack<T,DESCRIPTOR>); lattice.initialize(); }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); IncomprFlowParam<T> parameters ( (T) 1e-2, // uMax (T) 10., // Re 30, // N 2., // lx 1. // ly ); plint nx = parameters.getNx(); plint ny = parameters.getNy(); writeLogFile(parameters, "Poiseuille flow"); MultiBlockLattice2D<T, DESCRIPTOR> lattice ( nx, ny, new BGKdynamics<T,DESCRIPTOR>(parameters.getOmega()) ); OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition = createLocalBoundaryCondition2D<T,DESCRIPTOR>(); createPoiseuilleBoundaries(lattice, parameters, *boundaryCondition); lattice.initialize(); // The following command opens a text-file, in which the velocity-profile // in the middle of the channel will be written and several successive // time steps. Note the use of plb_ofstream instead of the standard C++ // ofstream, which is required to guarantee a consistent behavior in MPI- // parallel programs. plb_ofstream successiveProfiles("velocityProfiles.dat"); // Main loop over time steps. for (plint iT=0; iT<10000; ++iT) { if (iT%1000==0) { pcout << "At iteration step " << iT << ", the density along the channel is " << endl; pcout << setprecision(7) << *computeDensity(lattice, Box2D(0, nx-1, ny/2, ny/2)) << endl << endl; Box2D profileSection(nx/2, nx/2, 0, ny-1); successiveProfiles << setprecision(4) // (2) Convert from lattice to physical units. << *multiply ( parameters.getDeltaX() / parameters.getDeltaT(), // (1) Compute velocity norm along the chosen section. *computeVelocityNorm (lattice, profileSection) ) << endl; } // Lattice Boltzmann iteration step. lattice.collideAndStream(); } delete boundaryCondition; }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); IncomprFlowParam<T> parameters( (T) 1e-2, // uMax (T) 100., // Re 64, // N 5., // lx 1. // ly ); const T logT = (T)0.01; const T imSave = (T)0.02; const T maxT = (T)1.1; writeLogFile(parameters, "Poiseuille flow"); MultiBlockLattice2D<T, DESCRIPTOR> lattice ( parameters.getNx(), parameters.getNy(), new BGKdynamics<T,DESCRIPTOR>(parameters.getOmega()) ); OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition = createLocalBoundaryCondition2D<T,DESCRIPTOR>(); cylinderSetup(lattice, parameters, *boundaryCondition); // Main loop over time iterations. for (plint iT=0; iT*parameters.getDeltaT()<maxT; ++iT) { // At this point, the state of the lattice corresponds to the // discrete time iT. However, the stored averages (getStoredAverageEnergy // and getStoredAverageEnergy) correspond to the previous time iT-1. if (iT%parameters.nStep(imSave)==0) { pcout << "Saving Gif ..." << endl; writeGifs(lattice, iT); } if (iT%parameters.nStep(logT)==0) { pcout << "step " << iT << "; t=" << iT*parameters.getDeltaT(); } // Lattice Boltzmann iteration step. lattice.collideAndStream(); // At this point, the state of the lattice corresponds to the // discrete time iT+1, and the stored averages are upgraded to time iT. if (iT%parameters.nStep(logT)==0) { pcout << "; av energy =" << setprecision(10) << getStoredAverageEnergy<T>(lattice) << "; av rho =" << getStoredAverageDensity<T>(lattice) << endl; } } delete boundaryCondition; }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); // Parameters of the simulation plint N = 400; // Use a 400x200 domain. plint maxT = 20001; plint imageIter = 1000; T omega = 1.; plint radius = N/3; // Inner radius of the half-circle. // Parameters for the creation of the multi-block. // d is the width of the block which is exempted from the full domain. plint d = (plint) (2.*std::sqrt((T)util::sqr(radius)-(T)util::sqr(N/4.))); plint x0 = (N-d)/2 + 1; // Begin of the exempted block. plint x1 = (N+d)/2 - 1; // End of the exempted block. // Create a block distribution with the three added blocks. plint envelopeWidth = 1; SparseBlockStructure2D sparseBlock(N+1, N/2+1); sparseBlock.addBlock(Box2D(0, x0, 0, N/2), sparseBlock.nextIncrementalId()); sparseBlock.addBlock(Box2D(x0+1, x1-1, 0, N/4+1), sparseBlock.nextIncrementalId()); sparseBlock.addBlock(Box2D(x1, N, 0, N/2), sparseBlock.nextIncrementalId()); // Instantiate the multi-block, based on the created block distribution and // on default parameters. MultiBlockLattice2D<T, DESCRIPTOR> lattice ( MultiBlockManagement2D ( sparseBlock, defaultMultiBlockPolicy2D().getThreadAttribution(), envelopeWidth ), defaultMultiBlockPolicy2D().getBlockCommunicator(), defaultMultiBlockPolicy2D().getCombinedStatistics(), defaultMultiBlockPolicy2D().getMultiCellAccess<T,DESCRIPTOR>(), new BGKdynamics<T,DESCRIPTOR>(omega) ); pcout << getMultiBlockInfo(lattice) << std::endl; OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition = createLocalBoundaryCondition2D<T,DESCRIPTOR>(); halfCircleSetup(lattice, N, radius, *boundaryCondition); // Main loop over time iterations. for (plint iT=0; iT<maxT; ++iT) { if (iT%imageIter==0) { pcout << "Saving Gif at time step " << iT << endl; writeGifs(lattice, iT); } lattice.collideAndStream(); } delete boundaryCondition; }
// Initialize the lattice at zero velocity and constant density, except // for a slight density excess on a square sub-domain. void defineInitialDensityAtCenter(MultiBlockLattice2D<T,DESCRIPTOR>& lattice) { // Initialize constant density everywhere. initializeAtEquilibrium ( lattice, lattice.getBoundingBox(), rho0, u0 ); // And slightly higher density in the central box. initializeAtEquilibrium ( lattice, lattice.getBoundingBox(), initializeRhoOnCircle ); lattice.initialize(); }
void createBoundariesFromVelocityField(MultiBlockLattice2D<T,DESCRIPTOR>& lattice, MultiTensorField2D<T,2>& velocity) { applyProcessingFunctional( new BoundaryFromVelocityFunctional2D<T,DESCRIPTOR>, lattice.getBoundingBox(), lattice, velocity ); }
/// A functional, used to instantiate bounce-back nodes at the locations of the cylinder void cylinderSetup( MultiBlockLattice2D<T,DESCRIPTOR>& lattice, IncomprFlowParam<T> const& parameters, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition ) { const plint nx = parameters.getNx(); const plint ny = parameters.getNy(); Box2D outlet(nx-1,nx-1, 1,ny-2); // Create Velocity boundary conditions everywhere boundaryCondition.setVelocityConditionOnBlockBoundaries ( lattice, Box2D(0, nx-1, 0, 0) ); boundaryCondition.setVelocityConditionOnBlockBoundaries ( lattice, Box2D(0, nx-1, ny-1, ny-1) ); boundaryCondition.setVelocityConditionOnBlockBoundaries ( lattice, Box2D(0,0, 1,ny-2) ); // .. except on right boundary, where we prefer a fixed-pressure condition. boundaryCondition.setPressureConditionOnBlockBoundaries ( lattice, outlet ); setBoundaryVelocity ( lattice, lattice.getBoundingBox(), PoiseuilleVelocity<T>(parameters) ); setBoundaryDensity ( lattice, outlet, ConstantDensity<T>(1.) ); initializeAtEquilibrium ( lattice, lattice.getBoundingBox(), PoiseuilleVelocityAndDensity<T,DESCRIPTOR>(parameters) ); plint cx = nx/4; plint cy = ny/2+2; plint r = cy/4; DotList2D cylinderShape; for (plint iX=0; iX<nx; ++iX) { for (plint iY=0; iY<ny; ++iY) { if ( (iX-cx)*(iX-cx) + (iY-cy)*(iY-cy) < r*r ) { cylinderShape.addDot(Dot2D(iX,iY)); } } } defineDynamics(lattice, cylinderShape, new BounceBack<T,DESCRIPTOR>); lattice.initialize(); }
/* void writeGif(MultiBlockLattice2D<PlbT,DESCRIPTOR>& lattice, plint iter) { ImageWriter<PlbT> imageWriter("leeloo"); imageWriter.writeScaledGif(createFileName("u", iter, 6), *computeVelocityNorm(lattice) ); } */ void writeVTK(MultiBlockLattice2D<PlbT,DESCRIPTOR>& lattice, IncomprFlowParam<PlbT> const& parameters, plint iter) { T dx = parameters.getDeltaX(); T dt = parameters.getDeltaT(); VtkImageOutput2D<T> vtkOut(createFileName("vtk", iter, 6), dx); vtkOut.writeData<T>(*realPart<PlbT,T>(*computeVelocityNorm(lattice),lattice.getBoundingBox()), "velocityNorm", dx/dt); //vtkOut.writeData<2,T>(*computeVelocity(lattice), "velocity", dx/dt); }
void cavitySetup( MultiBlockLattice2D<T,DESCRIPTOR>& lattice, IncomprFlowParam<T> const& parameters, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition ) { const plint nx = parameters.getNx(); const plint ny = parameters.getNy(); boundaryCondition.setVelocityConditionOnBlockBoundaries(lattice); setBoundaryVelocity(lattice, lattice.getBoundingBox(), Array<T,2>(0.,0.) ); initializeAtEquilibrium(lattice, lattice.getBoundingBox(), 1., Array<T,2>(0.,0.) ); T u = parameters.getLatticeU(); setBoundaryVelocity(lattice, Box2D(1, nx-2, ny-1, ny-1), Array<T,2>(u,0.) ); initializeAtEquilibrium(lattice, Box2D(1, nx-2, ny-1, ny-1), 1., Array<T,2>(u,0.) ); lattice.initialize(); }
/// A functional, used to instantiate bounce-back nodes at the locations of the cylinder void cylinderSetup( MultiBlockLattice2D<PlbT,DESCRIPTOR>& lattice, IncomprFlowParam<PlbT> const& parameters, OnLatticeBoundaryCondition2D<PlbT,DESCRIPTOR>& boundaryCondition ) { const plint nx = parameters.getNx(); const plint ny = parameters.getNy(); Box2D outlet(nx-1,nx-1, 1, ny-2); // Create Velocity boundary conditions everywhere boundaryCondition.setVelocityConditionOnBlockBoundaries ( lattice, Box2D(0, 0, 1, ny-2) ); boundaryCondition.setVelocityConditionOnBlockBoundaries ( lattice, Box2D(0, nx-1, 0, 0) ); boundaryCondition.setVelocityConditionOnBlockBoundaries ( lattice, Box2D(0, nx-1, ny-1, ny-1) ); // .. except on right boundary, where we prefer an outflow condition // (zero velocity-gradient). boundaryCondition.setVelocityConditionOnBlockBoundaries ( lattice, Box2D(nx-1, nx-1, 1, ny-2), boundary::outflow ); setBoundaryVelocity ( lattice, lattice.getBoundingBox(), PoiseuilleVelocity<PlbT>(parameters) ); setBoundaryDensity ( lattice, outlet, ConstantDensity<PlbT>(1.) ); initializeAtEquilibrium ( lattice, lattice.getBoundingBox(), PoiseuilleVelocityAndDensity<PlbT>(parameters) ); plint cx = nx/4; plint cy = ny/2+2; // cy is slightly offset to avoid full symmetry, // and to get a Von Karman Vortex street. plint radius = cy/4; defineDynamics(lattice, lattice.getBoundingBox(), new CylinderShapeDomain2D<T>(cx,cy,radius), new plb::BounceBack<PlbT,DESCRIPTOR>); lattice.initialize(); }
void channelSetup( MultiBlockLattice2D<T,NSDESCRIPTOR>& lattice, IncomprFlowParam<T> const& parameters, OnLatticeBoundaryCondition2D<T,NSDESCRIPTOR>& boundaryCondition, T alpha, T frequency, T amplitude) { const plint nx = parameters.getNx(); const plint ny = parameters.getNy(); Box2D bottom( 0,nx-1, 0, 0); Box2D top( 0,nx-1, ny-1, ny-1); boundaryCondition.addVelocityBoundary1N(bottom, lattice); boundaryCondition.addPressureBoundary1P(top, lattice); Array<T,2> u((T)0.,(T)0.); setBoundaryVelocity( lattice, lattice.getBoundingBox(), u ); initializeAtEquilibrium(lattice,lattice.getBoundingBox(),(T)1.0,u); Array<T,NSDESCRIPTOR<T>::d> force(womersleyForce((T)0, amplitude, frequency, parameters),0.); setExternalVector(lattice,lattice.getBoundingBox(),NSDESCRIPTOR<T>::ExternalField::forceBeginsAt,force); lattice.initialize(); }
int main(int argc, char *argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); // For the choice of the parameters G, rho0, and psi0, we refer to the book // Michael C. Sukop and Daniel T. Thorne (2006), // Lattice Boltzmann Modeling; an Introduction for Geoscientists and Engineers. // Springer-Verlag Berlin/Heidelberg. const T omega = 1.0; const int nx = 400; const int ny = 400; const T G = -120.0; const int maxIter = 100001; const int saveIter = 100; const int statIter = 100; const T rho0 = 200.0; const T deltaRho = 1.0; const T psi0 = 4.0; MultiBlockLattice2D<T, DESCRIPTOR> lattice ( nx,ny, new ExternalMomentBGKdynamics<T, DESCRIPTOR>(omega) ); lattice.periodicity().toggleAll(true); // Use a random initial condition, to activate the phase separation. applyProcessingFunctional(new RandomInitializer<T,DESCRIPTOR>(rho0,deltaRho), lattice.getBoundingBox(),lattice); // Add the data processor which implements the Shan/Chen interaction potential. plint processorLevel = 1; integrateProcessingFunctional ( new ShanChenSingleComponentProcessor2D<T,DESCRIPTOR> ( G, new interparticlePotential::PsiShanChen94<T>(psi0,rho0) ), lattice.getBoundingBox(), lattice, processorLevel ); lattice.initialize(); pcout << "Starting simulation" << endl; for (int iT=0; iT<maxIter; ++iT) { if (iT%statIter==0) { auto_ptr<MultiScalarField2D<T> > rho( computeDensity(lattice) ); pcout << iT << ": Average rho fluid one = " << computeAverage(*rho) << endl; pcout << "Minimum density: " << computeMin(*rho) << endl; pcout << "Maximum density: " << computeMax(*rho) << endl; } if (iT%saveIter == 0) { ImageWriter<T>("leeloo").writeScaledGif ( createFileName("rho", iT, 6), *computeDensity(lattice) ); } lattice.collideAndStream(); } }
void setupInletAndBulk( MultiBlockLattice2D<T,DESCRIPTOR>& lattice, IncomprFlowParam<T> const& parameters, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition ) { const plint ny = parameters.getNy(); // Create Velocity boundary conditions on inlet boundaryCondition.addVelocityBoundary0N(Box2D( 0, 0, 0,ny-1), lattice); setBoundaryVelocity ( lattice, Box2D( 0, 0, 0,ny-1), PoiseuilleVelocity<T>(parameters) ); initializeAtEquilibrium ( lattice, lattice.getBoundingBox(), PoiseuilleVelocityAndDensity<T,DESCRIPTOR>(parameters) ); }
T computeRMSerror ( MultiBlockLattice2D<T,NSDESCRIPTOR>& lattice, IncomprFlowParam<T> const& parameters, T alpha, plint iT, bool createImage=false) { MultiTensorField2D<T,2> analyticalVelocity(lattice); setToFunction( analyticalVelocity, analyticalVelocity.getBoundingBox(), WomersleyVelocity<T>(parameters,alpha,(T)iT) ); MultiTensorField2D<T,2> numericalVelocity(lattice); computeVelocity(lattice, numericalVelocity, lattice.getBoundingBox()); // Divide by lattice velocity to normalize the error return 1./parameters.getLatticeU() * // Compute RMS difference between analytical and numerical solution std::sqrt( computeAverage( *computeNormSqr ( *subtract(analyticalVelocity, numericalVelocity) ) ) ); }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); T Re; // Reynolds number. plint N; // Resolution. //getParametersFromCommandLine(argc, argv, Re, N); getParametersFromParamFile(Re, N); IncomprFlowParam<T> parameters( (T) 1e-2, // uMax (T) 100., // Re 128, // N 1., // lx 1. // ly ); const T logT = (T)0.1; const T imSave = (T)0.2; const T maxT = (T)10.1; writeLogFile(parameters, "2D cavity"); MultiBlockLattice2D<T, DESCRIPTOR> lattice ( parameters.getNx(), parameters.getNy(), new BGKdynamics<T,DESCRIPTOR>(parameters.getOmega()) ); OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* //boundaryCondition = createInterpBoundaryCondition2D<T,DESCRIPTOR>(); boundaryCondition = createLocalBoundaryCondition2D<T,DESCRIPTOR>(); cavitySetup(lattice, parameters, *boundaryCondition); // Main loop over time iterations. for (plint iT=0; iT*parameters.getDeltaT()<maxT; ++iT) { if ((iT+1)%parameters.nStep(logT)==0) { pcout << computeAverageDensity(lattice) << endl; pcout << computeAverageEnergy(lattice) << endl; } if (iT%parameters.nStep(logT)==0) { pcout << "step " << iT << "; lattice time=" << lattice.getTimeCounter().getTime() << "; t=" << iT*parameters.getDeltaT() << "; av energy=" << setprecision(10) << getStoredAverageEnergy<T>(lattice) << "; av rho=" << getStoredAverageDensity<T>(lattice) << endl; } if (iT%parameters.nStep(imSave)==0 && iT>0) { pcout << "Saving Gif ..." << endl; writeGifs(lattice, iT); pcout << endl; } // Lattice Boltzmann iteration step. lattice.collideAndStream(); } delete boundaryCondition; }
int main(int argc, char* argv[]) { /// === 1st Step: Initialization === olbInit(&argc, &argv); OstreamManager clout(std::cout,"main"); string fName("cavity2d.xml"); XMLreader config(fName); bool multiOutput=false; config["Output"]["MultiOutput"].read(multiOutput); clout.setMultiOutput(multiOutput); std::string olbdir, outputdir; config["Application"]["OlbDir"].read(olbdir); config["Output"]["OutputDir"].read(outputdir); singleton::directories().setOlbDir(olbdir); singleton::directories().setOutputDir(outputdir); // call creator functions using xml data LBconverter<T>* converter = createLBconverter<T>(config); int N = converter->numNodes(); Timer<T>* timer = createTimer<T>(config, *converter, N*N); /// === 3rd Step: Prepare Lattice === T logT; T imSave; T vtkSave; T maxT; int timerSkipType; bool timerPrintSum = true; int timerPrintMode = 0; int timerTimeSteps = 1; config["Application"]["PhysParam"]["MaxTime"].read(maxT); config["Output"]["Log"]["SaveTime"].read(logT); config["Output"]["VisualizationImages"]["SaveTime"].read(imSave); config["Output"]["VisualizationVTK"]["SaveTime"].read(vtkSave); config["Output"]["Timer"]["SkipType"].read(timerSkipType); config["Output"]["Timer"]["PrintSummary"].read(timerPrintSum); config["Output"]["Timer"]["PrintMode"].read(timerPrintMode); if (timerSkipType == 0) { timerTimeSteps=converter->numTimeSteps(config["Output"]["Timer"]["PhysTime"].get<T>()); } else { config["Output"]["Timer"]["TimeSteps"].read(timerTimeSteps); } writeLogFile(*converter, config["Output"]["Log"]["Filename"].get<std::string>()); std::string filenameGif = config["Output"]["VisualizationImages"]["Filename"].get<std::string>(); std::string filenameVtk = config["Output"]["VisualizationVTK"]["Filename"].get<std::string>(); #ifndef PARALLEL_MODE_MPI // sequential program execution BlockLattice2D<T, DESCRIPTOR> lattice(N, N); #else // parallel program execution MultiBlockLattice2D<T, DESCRIPTOR> lattice ( createRegularDataDistribution(N, N) ); #endif ConstRhoBGKdynamics<T, DESCRIPTOR> bulkDynamics ( converter->getOmega(), instances::getBulkMomenta<T,DESCRIPTOR>() ); OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition = createInterpBoundaryCondition2D(lattice); prepareLattice(converter, lattice, bulkDynamics, *boundaryCondition); /// === 4th Step: Main Loop with Timer === timer->start(); int iT=0; for (iT=0; converter->physTime(iT)<maxT; ++iT) { /// === 5th Step: Definition of Initial and Boundary Conditions === setBoundaryValues(converter, lattice, iT); /// === 6th Step: Collide and Stream Execution === lattice.collideAndStream(); /// === 7th Step: Computation and Output of the Results === getResults(lattice, converter, iT, timer, logT, imSave, vtkSave, maxT, filenameGif, filenameVtk, timerPrintSum, timerPrintMode, timerTimeSteps); } delete converter; delete timer; delete boundaryCondition; return 0; }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); IncomprFlowParam<T> parameters( (T) 1e-2, // uMax (T) 300., // Re 100, // N 5., // lx 1. // ly ); const T logT = (T)0.02; const T imSave = (T)0.1; const T vtkSave = (T)3.; const T maxT = (T)10.1; writeLogFile(parameters, "Poiseuille flow"); MultiBlockLattice2D<T, DESCRIPTOR> lattice ( parameters.getNx(), parameters.getNy(), new BGKdynamics<T,DESCRIPTOR>(parameters.getOmega()) ); lattice.periodicity().toggle(0, false); OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* //boundaryCondition = createInterpBoundaryCondition2D<T,DESCRIPTOR>(); boundaryCondition = createLocalBoundaryCondition2D<T,DESCRIPTOR>(); defineCylinderGeometry(lattice, parameters); setupInletAndBulk(lattice, parameters, *boundaryCondition); //copyUnknownOnOutlet(lattice, parameters, *boundaryCondition); velocityNeumannOutlet(lattice, parameters, *boundaryCondition); lattice.initialize(); // Main loop over time iterations. for (plint iT=0; iT*parameters.getDeltaT()<maxT; ++iT) { if ((iT+1)%parameters.nStep(logT)==0) { pcout << computeAverageDensity(lattice) << endl; pcout << computeAverageEnergy(lattice) << endl; } if (iT%parameters.nStep(logT)==0) { pcout << "step " << iT << "; lattice time=" << lattice.getTimeCounter().getTime() << "; t=" << iT*parameters.getDeltaT() << "; av energy=" << setprecision(10) << getStoredAverageEnergy<T>(lattice) << "; av rho=" << getStoredAverageDensity<T>(lattice) << endl; } if (iT%parameters.nStep(imSave)==0) { pcout << "Saving Gif ..." << endl; writeGifs(lattice, iT); } if (iT%parameters.nStep(vtkSave)==0 && iT>0) { pcout << "Saving VTK file ..." << endl; writeVTK(lattice, parameters, iT); } // Lattice Boltzmann iteration step. lattice.collideAndStream(); } delete boundaryCondition; }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); IncomprFlowParam<T> parameters( (T) 1e-2, // uMax (T) 100., // Re 1024, // N 1., // lx 1. // ly ); const T logT = (T)0.1; const T imSave = (T)0.2; const T vtkSave = (T)1.; const T maxT = (T)10.1; writeLogFile(parameters, "2D cavity"); MultiBlockLattice2D<T, DESCRIPTOR> lattice ( parameters.getNx(), parameters.getNy(), new BGKdynamics<T,DESCRIPTOR>(parameters.getOmega()) ); MultiBlockLattice2D<T, DESCRIPTOR> lattice2 ( parameters.getNx(), parameters.getNy(), new BGKdynamics<T,DESCRIPTOR>(parameters.getOmega()) ); OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition = createLocalBoundaryCondition2D<T,DESCRIPTOR>(); cavitySetup(lattice, parameters, *boundaryCondition); cavitySetup(lattice2, parameters, *boundaryCondition); T previousIterationTime = T(); MultiScalarField2D<T> rhoBar(lattice2); MultiTensorField2D<T,2> j(lattice2); std::vector<MultiBlock2D*> lattice2RhoBarJparam; lattice2RhoBarJparam.push_back(&lattice2); lattice2RhoBarJparam.push_back(&rhoBar); lattice2RhoBarJparam.push_back(&j); computeRhoBarJ(lattice2, rhoBar, j, lattice2.getBoundingBox()); integrateProcessingFunctional( new ExternalRhoJcollideAndStream2D<T,DESCRIPTOR>, lattice2.getBoundingBox(), lattice2RhoBarJparam, -1 ); // Main loop over time iterations. global::timer("iterations").start(); for (plint iT=0; iT<1000; ++iT) { // Lattice Boltzmann iteration step. lattice.collideAndStream(); lattice2.executeInternalProcessors(-1); lattice2.executeInternalProcessors(); computeRhoBarJ(lattice2, rhoBar, j, lattice2.getBoundingBox()); if (iT%100==0) { pcout << "Energy 1: " << computeAverageEnergy(lattice) << std::endl; pcout << "Energy 2: " << computeAverageEnergy(lattice2) << std::endl; pcout << global::timer("iterations").getTime()/(iT+1) << std::endl; //ImageWriter<T> imageWriter("leeloo"); //imageWriter.writeScaledGif(createFileName("diff", iT, 6), // //*computeVelocityNorm(lattice2) ); // *subtract(*computeVelocityNorm(lattice),*computeVelocityNorm(lattice2)) ); } } delete boundaryCondition; }
int main(int argc, char* argv[]) { /// === 1st Step: Initialization === olbInit(&argc, &argv); singleton::directories().setOutputDir("./tmp/"); OstreamManager clout(std::cout,"main"); const T uMax = 0.02; const T Re = 10.; const int N = 50; const T lx = 2.; const T ly = 1.; const int maxIter = 20000; LBconverter<T> converter( (int) 2, // dim 1./N, // latticeL_ uMax, // latticeU_ (T) 1./Re, // charNu_ (T) 1. // charL_ = 1, ); writeLogFile(converter, "poiseuille2d"); /// === 3rd Step: Prepare Lattice === #ifndef PARALLEL_MODE_MPI // sequential program execution BlockLattice2D<T, DESCRIPTOR> lattice(converter.numNodes(lx), converter.numNodes(ly) ); #else // parallel program execution MultiBlockLattice2D<T, DESCRIPTOR> lattice ( createRegularDataDistribution( converter.numNodes(lx), converter.numNodes(ly) ) ); #endif // choose between local and non-local boundary condition OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition = createInterpBoundaryCondition2D(lattice); // boundaryCondition = createLocalBoundaryCondition2D(lattice); ForcedBGKdynamics<T, DESCRIPTOR> bulkDynamics ( converter.getOmega(), instances::getBulkMomenta<T,DESCRIPTOR>() ); prepareLattice(converter, lattice, bulkDynamics, *boundaryCondition); /// === 4th Step: Main Loop with Timer === for (int iT=0; iT<maxIter; ++iT) { /// === 5th Step: Definition of Initial and Boundary Conditions === setBoundaryValues(converter, lattice, iT); /// === 6th Step: Collide and Stream Execution === lattice.collideAndStream(true); /// === 7th Step: Computation and Output of the Results === getResults(lattice, converter, iT); } delete boundaryCondition; }
int main(int argc, char* argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); PlbT Re(600.,600*1e-3); pcout << Re.real() <<" "<<Re.imaginary()<<endl; IncomprFlowParam<PlbT> parameters( (PlbT) 1e-2, // uMax (PlbT) Re, // Re 100, // N 6., // lx 1. // ly ); const T logT = (T)0.02; const T imSave = (T)0.06; const T vtkSave = (T)0.06; const T maxT = (T)20.1; pcout<<" " << parameters.getDeltaT().imaginary()<<endl; //writeLogFile(parameters, "Poiseuille flow"); MultiBlockLattice2D<PlbT, DESCRIPTOR> lattice ( parameters.getNx(), parameters.getNy(), new BGKdynamics<PlbT,DESCRIPTOR>(parameters.getOmega()) ); pcout << parameters.getOmega().real()<<" "<< parameters.getOmega().imaginary()<< endl; OnLatticeBoundaryCondition2D<PlbT,DESCRIPTOR>* boundaryCondition = createLocalBoundaryCondition2D<PlbT,DESCRIPTOR>(); cylinderSetup(lattice, parameters, *boundaryCondition); //Array<PlbT,2> velocity; // lattice.get(10, 10).computeVelocity(velocity); // pcout << "Velocity in the middle of the lattice: (" // << velocity[0].real()<<" "<<velocity[0].imaginary() << "," << velocity[1].real()<<" "<<velocity[1].imaginary() << ")" << endl; // Main loop over time iterations. for (plint iT=0; (T)iT*parameters.getDeltaT().real()<maxT; ++iT) { // At this point, the state of the lattice corresponds to the // discrete time iT. However, the stored averages (getStoredAverageEnergy // and getStoredAverageDensity) correspond to the previous time iT-1. if (iT%parameters.nStep(imSave)==0) { //pcout << "Saving Gif ..." << endl; //writeGif(lattice, iT); } //if (iT%parameters.nStep(vtkSave)==0 && iT>=0) { // pcout << "Saving VTK file ..." << endl; // writeVTK(lattice, parameters, iT); //} if (iT%parameters.nStep(vtkSave)==0 && iT>=0) { pcout << "Saving VTK file ..." << endl; writeVTK(lattice, parameters, iT); Array<PlbT,2> velocity; lattice.get(10, 10).computeVelocity(velocity); pcout << "Velocity in the middle of the lattice: (" << velocity[0].real()<<" "<<velocity[0].imaginary() << "," << velocity[1].real()<<" "<<velocity[1].imaginary() << ")" << endl; } if (iT%parameters.nStep(logT)==0) { pcout << "step " << iT << "; t=" << (T)iT*parameters.getDeltaT().real(); } // Lattice Boltzmann iteration step. lattice.collideAndStream(); // lattice.get(10, 10).computeVelocity(velocity); // pcout << "Velocity in the middle of the lattice: (" // << velocity[0].real()<<" "<<velocity[0].imaginary() << "," << velocity[1].real()<<" "<<velocity[1].imaginary() << ")" << endl; // At this point, the state of the lattice corresponds to the // discrete time iT+1, and the stored averages are upgraded to time iT. if (iT%parameters.nStep(logT)==0) { pcout << "; av energy =" << setprecision(10) << getStoredAverageEnergy<PlbT>(lattice) << "; av rho =" << getStoredAverageDensity<PlbT>(lattice) << endl; } } delete boundaryCondition; }
int main(int argc, char *argv[]) { plbInit(&argc, &argv); if (argc != 2) { pcout << "Error : Wrong parameters specified." << endl; pcout << "1 : N." << endl; exit(1); } const plint N = atoi(argv[1]); const T Re = 1.0; const T alpha = 1.0; // womersley number const plint Nref = 10; const T uMaxRef = 0.01; const T uMax = uMaxRef /(T)N * (T)Nref; // needed to avoid compressibility errors. const T lx = 100.0; const T ly = 1.0; pcout << "uMaxRef=" << uMaxRef << std::endl; pcout << "uMax=" << uMax << std::endl; global::directories().setOutputDir("./tmp/"); IncomprFlowParam<T> parameters(uMax, Re, N, lx, ly); // The frequency of the force (lattice units) T frequency = (T)4*alpha*alpha*parameters.getLatticeNu() / (T)(parameters.getResolution()*parameters.getResolution()); // The amplitude of the forcing term (lattice units) T amplitude = 8. * parameters.getLatticeNu() * parameters.getLatticeU() / ( (T)(parameters.getResolution()*parameters.getResolution()) ); // Period of the force (lattice units) plint tPeriod = (plint)((T)2*pi/frequency + 0.5); writeLogFile(parameters,"palabos.log"); plint nx = parameters.getNx(); plint ny = parameters.getNy(); T omega = parameters.getOmega(); MultiBlockLattice2D<T, NSDESCRIPTOR> lattice ( nx,ny,new DYNAMICS ); OnLatticeBoundaryCondition2D<T,NSDESCRIPTOR>* boundaryCondition = createLocalBoundaryCondition2D<T,NSDESCRIPTOR>(); lattice.periodicity().toggle(0,true); channelSetup( lattice, parameters, *boundaryCondition, alpha, frequency, amplitude); pcout << "Starting simulation" << endl; const plint maxIter = tPeriod * 100; //const plint tSave = tPeriod / 24; T error = T(); lattice.getTimeCounter().resetTime(1); pcout << "Omega = " << omega << ", it period = " << tPeriod << endl; util::ValueTracer<T> converge(uMax,N,1.0e-3); plint iT = 0; for (iT = 0; iT < maxIter; ++iT) { // Updating the force in the whole domain Array<T,NSDESCRIPTOR<T>::d> force(womersleyForce((T)iT, amplitude, frequency, parameters),0.); setExternalVector(lattice,lattice.getBoundingBox(), NSDESCRIPTOR<T>::ExternalField::forceBeginsAt,force); T errorTemp = computeRMSerror( lattice,parameters,alpha,iT); error += errorTemp; //if (iT % tSave == 0) { // pcout << "Writing Gif at time : " << iT << std::endl; // writeGif(lattice,iT); //} if (iT % tPeriod == 0) { // The error is averaged over one period error /= (T)(tPeriod); pcout << "For N = " << N << ", Error = " << error << endl; converge.takeValue(error,true); if (converge.hasConverged()) { cout << "Simulation converged!\n"; break; } error = T(); } lattice.collideAndStream(); } pcout << "For N = " << N << ", Error = " << computeRMSerror ( lattice,parameters,alpha,iT, true) << endl; }