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(); }
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); }
/// 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 velocityNeumannOutlet( MultiBlockLattice2D<T,DESCRIPTOR>& lattice, IncomprFlowParam<T> const& parameters, OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition ) { const plint nx = parameters.getNx(); const plint ny = parameters.getNy(); boundaryCondition.addVelocityBoundary0P ( Box2D(nx-1,nx-1, 0,ny-1), lattice, boundary::outflow ); }
/// A functional, used to instantiate bounce-back nodes at the locations of the cylinder void cylinderSetup( BlockLatticeBase2D<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, 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<T>(parameters) ); setBoundaryDensity ( lattice, outlet, ConstantDensity<T>(1.) ); initializeAtEquilibrium ( lattice, lattice.getBoundingBox(), PoiseuilleVelocityAndDensity<T>(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<T,DESCRIPTOR>); 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 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(); }
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) ); }
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(); }
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); }
int main(int argc, char *argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/"); //srand(global::mpi().getRank()); const double PI = 3.1415926535897932; plint nx = 1200; plint ny = 600; const int maxIter = 1600000; const int saveIter = 100; const int statIter = 10; double omega = 0.8; double rho1 = 1; double rho0 = 0; BlockLattice2D<T,DESCRIPTOR> myFluid (nx, ny, new BGKdynamics<T,DESCRIPTOR>(omega)); OnLatticeBoundaryCondition2D<T,DESCRIPTOR>* boundaryCondition = createLocalBoundaryCondition2D<T,DESCRIPTOR>(); boundaryCondition = createInterpBoundaryCondition2D<T,DESCRIPTOR>(); boundaryCondition->setVelocityConditionOnBlockBoundaries(myFluid); setBoundaryVelocity(myFluid, myFluid.getBoundingBox(), Array<T,2>(0.,0.) ); initializeAtEquilibrium(myFluid, myFluid.getBoundingBox(), 1., Array<T,2>(0.,0.), 0. ); //myFluid2.periodicity().toggle(0,true); std::cout<<"ok0"<<std::endl; //setBoundaryVelocity(myFluid, Box2D(1, nx, ny-1, ny-1), Array<T,2>(10.,0.) ); //initializeAtEquilibrium(myFluid, Box2D(1, nx, ny-1, ny-1), 1., Array<T,2>(10.,0.), 0. ); //std::cout<<"ok1"<<std::endl; myFluid.initialize(); //MultiParticleField2D<BulkParticleField2D<T,DESCRIPTOR> >* particles =0; BulkParticleChunk2D<T,DESCRIPTOR> myParticleChunk(nx, ny); BulkParticleField2D<T,DESCRIPTOR> myParticleField(nx, ny); BulkParticle2D<T,DESCRIPTOR> myParticle1(1, 1, Array<T,2>(300-100,300), 0, Array<T,2>(0.0, 0), 0.0, 20, 5); BulkParticle2D<T,DESCRIPTOR> myParticle2(2, 1, Array<T,2>(300+100*cos(2*PI/3),300+100*sin(2*PI/3)), 0, Array<T,2>(-0.0*cos(2*PI/3), -0.0*sin(2*PI/3)), 0, 20, 5); BulkParticle2D<T,DESCRIPTOR> myParticle3(3, 1, Array<T,2>(300+100*cos(PI/3), 300+100*sin(PI/3)), 0, Array<T,2>(-0.0*cos(PI/3), -0.0*sin(PI/3)), 0, 20, 5); BulkParticle2D<T,DESCRIPTOR> myParticle4(4, 1, Array<T,2>(300+100,300), 0, Array<T,2>(-0.0, 0), 0.0, 30, 5); BulkParticle2D<T,DESCRIPTOR> myParticle5(5, 1, Array<T,2>(300+100*cos(5*PI/3),300+100*sin(5*PI/3)), 0, Array<T,2>(-0.0*cos(5*PI/3), -0.0*sin(5*PI/3)),0, 20, 5); BulkParticle2D<T,DESCRIPTOR> myParticle6(6, 1, Array<T,2>(300+100*cos(4*PI/3),300+100*sin(4*PI/3)), 0, Array<T,2>(-0.0*cos(4*PI/3), -0.0*sin(4*PI/3)),0, 20, 5); BulkParticle2D<T,DESCRIPTOR> myParticle7(7, 1, Array<T,2>(900-100,300), 0, Array<T,2>(-0.0, 0), 0.0, 24.5, 5); BulkParticle2D<T,DESCRIPTOR> myParticle8(8, 1, Array<T,2>(900+100*cos(2*PI/3), 300+100*sin(2*PI/3)), 0, Array<T,2>(-0.0*cos(2*PI/3), -0.0*sin(2*PI/3)), 0, 24.5, 5); BulkParticle2D<T,DESCRIPTOR> myParticle9(9, 1, Array<T,2>(900+100*cos(PI/3), 300+100*sin(PI/3)), 0, Array<T,2>(-0.0*cos(PI/3), -0.0*sin(PI/3)), 0, 24.5, 5); BulkParticle2D<T,DESCRIPTOR> myParticle10(10,1,Array<T,2>(900+100,300), 0, Array<T,2>(-0.0, 0), 0.0, 24.5, 5); BulkParticle2D<T,DESCRIPTOR> myParticle11(11,1,Array<T,2>(900+100*cos(4*PI/3),300+100*sin(4*PI/3)), 0, Array<T,2>(-0.0*cos(4*PI/3), -0.0*sin(4*PI/3)),0, 24.5, 5); BulkParticle2D<T,DESCRIPTOR> myParticle12(12,1,Array<T,2>(900+100*cos(5*PI/3),300+100*sin(5*PI/3)), 0, Array<T,2>(-0.0*cos(5*PI/3), -0.0*sin(5*PI/3)),0, 24.5, 5); movingLumen2D<T,DESCRIPTOR> myLumen1(13, 450, 750, 200, 250, Array<T,2> (0.,-0.05)); movingLumen2D<T,DESCRIPTOR> myLumen2(14, 450, 750, 350, 400, Array<T,2> (0., 0.05)); //BulkParticle2D<T,DESCRIPTOR> myParticle7(7, 2, Array<T,2>(300,50), 0, // Array<T,2>(0,0.1),0, 30, 5); //BulkParticle2D(plint id_, plint tag_, Array<T,2> const& position_, T AngularPosition_, // Array<T,2> const& velocity_, T AngularVelocity_, T radius_, T density_); myParticleField.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle1); myParticleField.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle2); myParticleField.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle3); myParticleField.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle4); myParticleField.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle5); myParticleField.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle6); myParticleChunk.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle7); myParticleChunk.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle8); myParticleChunk.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle9); myParticleChunk.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle10); myParticleChunk.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle11); myParticleChunk.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle12); myParticleChunk.rigidize(); //myParticleField.addParticle(Box2D(0,nx-1, 0,ny-1), &myParticle7); for (plint iT=0; iT<maxIter; ++iT) { std::cout<<"=====================Identify particles boundary links==================\n\n"<<std::endl; for(plint i=0;i<myParticleChunk.particles.size(); i++){ Box2D myBox(myParticleChunk.particles[i]->getPosition()[0] - myParticleChunk.particles[i]->getRadius()*1.414, myParticleChunk.particles[i]->getPosition()[0] + myParticleChunk.particles[i]->getRadius()*1.414, myParticleChunk.particles[i]->getPosition()[1] - myParticleChunk.particles[i]->getRadius()*1.414, myParticleChunk.particles[i]->getPosition()[1] + myParticleChunk.particles[i]->getRadius()*1.414); myParticleChunk.particles[i]->computeBoundaryLinks(myBox); //myParticleChunk.particles[i]->computeBoundaries(myBox); Array<T,2> velocity = myParticleChunk.particles[i]->getVelocity(); Array<T,2> position = myParticleChunk.particles[i]->getPosition(); std::cout<<"Position="<<position[0]<<","<<position[1]<<std::endl; std::cout<<"Velocity="<<velocity[0]<<","<<velocity[1]<<std::endl; //system("PAUSE"); } for(plint i=0;i<myParticleField.particles.size(); i++){ Box2D myBox(myParticleField.particles[i]->getPosition()[0] - myParticleField.particles[i]->getRadius()*1.414, myParticleField.particles[i]->getPosition()[0] + myParticleField.particles[i]->getRadius()*1.414, myParticleField.particles[i]->getPosition()[1] - myParticleField.particles[i]->getRadius()*1.414, myParticleField.particles[i]->getPosition()[1] + myParticleField.particles[i]->getRadius()*1.414); myParticleField.particles[i]->computeBoundaryLinks(myBox); } myLumen1.computeBoundaryLinks(myFluid.getBoundingBox()); myLumen2.computeBoundaryLinks(myFluid.getBoundingBox()); std::cout<<"=============================Collide and stream==========================\n\n"<<std::endl; myFluid.collideAndStream(); std::cout<<"=============particle, movingObject, wall and fluid interaction=============\n\n"<<std::endl; for(plint i=0;i<myParticleField.particles.size(); i++){ myParticleField.particles[i]->particleToParticle(myParticleField); myParticleField.particles[i]->particleToChunk(myParticleChunk); } for(plint i=0;i<myParticleField.particles.size(); i++){ myParticleField.particles[i]->wallToParticle(myFluid); } for(plint i=0;i<myParticleField.particles.size(); i++){ myLumen1.objectToParticle(myParticleField.particles[i]); myLumen2.objectToParticle(myParticleField.particles[i]); } myParticleChunk.fixedChunkToFluid(myFluid,&myParticleField); //myParticleChunk.chunkToFluid(myFluid); myParticleField.particleToFluidCoupling(myFluid); myLumen1.objectToFluid(myFluid); myLumen2.objectToFluid(myFluid); std::cout<<"=============particle and movingObject advance=============================\n\n"<<std::endl; if(iT<=2000){ myLumen1.advance(); myLumen2.advance(); } if(iT==5000){ myLumen1.setVelocity(Array<T,2> (0., 0.07)); myLumen2.setVelocity(Array<T,2> (0.,-0.07)); } if(iT>=5000 && iT<=7000){ myLumen1.advance(); myLumen2.advance(); } myParticleChunk.advanceChunk(myFluid.getBoundingBox(), -1.); myParticleField.advanceParticles(myFluid.getBoundingBox(), -1.); //if(iT == 500)myParticleChunk.releaseParticle(2, &myParticleField); ImageWriter<T> imageWriter("leeloo.map"); if(iT%10 == 0){ //imageWriter.writeScaledGif(createFileName("fluid_", iT, 6), // *computeDensity(myFluid)); imageWriter.writeGif(createFileName("fluid_", iT, 6), //*computeVelocityNorm(myFluid), 0, 1); *computeVelocityComponent(myFluid,0), -0.1, 0.1); } } }