Ejemplo n.º 1
0
void cavitySetup( MultiBlockLattice3D<T,DESCRIPTOR>& lattice,
                  IncomprFlowParam<T> const& parameters,
                  OnLatticeBoundaryCondition3D<T,DESCRIPTOR>& boundaryCondition )
{
    const plint nx = parameters.getNx();
    const plint ny = parameters.getNy();
    const plint nz = parameters.getNz();
    Box3D topLid = Box3D(0, nx-1, ny-1, ny-1, 0, nz-1);
    Box3D bottomLid = Box3D(0, nx-1, 0, 0, 0, nz-1);
    Box3D everythingButTopLid = Box3D(0, nx-1, 0, ny-2, 0, nz-1);

    /*
    instantiateOuterNLDboundary(lattice, lattice.getBoundingBox());
    setOuterNLDboundaryDynamics(lattice, lattice.getBackgroundDynamics().clone(),
                                lattice.getBoundingBox(), boundary::dirichlet);
    setOuterNLDboundaryDynamics(lattice, lattice.getBackgroundDynamics().clone(), bottomLid, boundary::neumann);
    defineDynamics(lattice, bottomLid, lattice.getBackgroundDynamics().clone());
    */

    boundaryCondition.setVelocityConditionOnBlockBoundaries(lattice, lattice.getBoundingBox(), boundary::dirichlet);

    T u = sqrt((T)2)/(T)2 * parameters.getLatticeU();
    initializeAtEquilibrium(lattice, everythingButTopLid, (T) 1., Array<T,3>(0.,0.,0.) );
    initializeAtEquilibrium(lattice, topLid, (T) 1., Array<T,3>(u,0.,u) );
    setBoundaryVelocity(lattice, topLid, Array<T,3>(u,0.,u) );

    lattice.initialize();
}
Ejemplo n.º 2
0
void writeVTK(MultiBlockLattice2D<T,DESCRIPTOR>& lattice,
			  IncomprFlowParam<T> const& parameters, plint iter)
{
	T dx = parameters.getDeltaX();
	T dt = parameters.getDeltaT();
	VtkImageOutput2D<T> vtkOut(createFileName("vtk", iter, 6), dx);
	vtkOut.writeData<float>(*computeVelocityNorm(lattice), "velocityNorm", dx/dt);
	vtkOut.writeData<2,float>(*computeVelocity(lattice), "velocity", dx/dt);
}
Ejemplo n.º 3
0
void writeVTK(BlockLatticeT& lattice,
              IncomprFlowParam<T> const& parameters, plint iter)
{
    T dx = parameters.getDeltaX();
    T dt = parameters.getDeltaT();
    VtkImageOutput3D<T> vtkOut(createFileName("vtk", iter, 6), dx);
    vtkOut.writeData<float>(*computeVelocityNorm(lattice), "velocityNorm", dx/dt);
    vtkOut.writeData<3,float>(*computeVelocity(lattice), "velocity", dx/dt);
    vtkOut.writeData<3,float>(*computeVorticity(*computeVelocity(lattice)), "vorticity", 1./dt);
}
Ejemplo n.º 4
0
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 );
}
Ejemplo n.º 5
0
void copyUnknownOnOutlet( MultiBlockLattice2D<T,DESCRIPTOR>& lattice,
                          IncomprFlowParam<T> const& parameters,
                          OnLatticeBoundaryCondition2D<T,DESCRIPTOR>& boundaryCondition )
{
    const plint nx = parameters.getNx();
    const plint ny = parameters.getNy();

    // On the right boundary, we copy the unknown populations from previous locations
    integrateProcessingFunctional(new CopyUnknownPopulationsFunctional2D<T,DESCRIPTOR, 0, +1>,
                                  Box2D(nx-1,nx-1, 0,ny-1), lattice);
}
Ejemplo n.º 6
0
void defineCylinderGeometry( MultiBlockLattice2D<T,DESCRIPTOR>& lattice,
                             IncomprFlowParam<T> const& parameters )
{
    const plint nx = parameters.getNx();
    const plint ny = parameters.getNy();

    int cx     = nx/4;
    int cy     = ny/2+ny/10;
    int radius = cy/4;

    createCylinder(lattice, cx, cy, radius);
}
Ejemplo n.º 7
0
/// 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();
}
Ejemplo n.º 8
0
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();
}
Ejemplo n.º 9
0
/// Velocity on the parabolic Womersley profile
T womersleyVelocity(plint iY, T t, T A, T omega, T alpha, IncomprFlowParam<T> const& parameters)
{
    const complex<T> I(0.,1.);
    T y = (T)iY / parameters.getResolution();

    return ( A / (I * omega) * std::exp(I * omega * t) *
             ( (T)1. - std::cosh(std::sqrt((T)2.)*(y-(T).5)*(alpha+I*alpha)) /
               std::cosh(std::sqrt((T)2.)/(T)2. * (alpha+I*alpha)) ) ).real();
}
Ejemplo n.º 10
0
void writeGifs(BlockLatticeT& lattice,
               IncomprFlowParam<T> const& parameters, plint iter)
{
    const plint imSize = 600;
    const plint nx = parameters.getNx();
    const plint ny = parameters.getNy();
    const plint nz = parameters.getNz();
    const plint zComponent = 2;

    Box3D slice(0, nx-1, 0, ny-1, nz/2, nz/2);
    ImageWriter<T> imageWriter("leeloo");

    imageWriter.writeScaledGif( createFileName("uz", iter, 6),
                                *computeVelocityComponent (lattice, slice, zComponent),
                                imSize, imSize );
    imageWriter.writeScaledGif( createFileName("uNorm", iter, 6),
                                *computeVelocityNorm (lattice, slice),
                                imSize, imSize );
}
Ejemplo n.º 11
0
void cavitySetup( MultiBlockLattice3D<T,DESCRIPTOR>& lattice,
                  IncomprFlowParam<T> const& parameters,
                  OnLatticeBoundaryCondition3D<T,DESCRIPTOR>& boundaryCondition )
{
    const plint nx = parameters.getNx();
    const plint ny = parameters.getNy();
    const plint nz = parameters.getNz();
    Box3D topLid = Box3D(0, nx-1, ny-1, ny-1, 0, nz-1);
    Box3D everythingButTopLid = Box3D(0, nx-1, 0, ny-2, 0, nz-1);

    boundaryCondition.setVelocityConditionOnBlockBoundaries(lattice);

    T u = std::sqrt((T)2)/(T)2 * parameters.getLatticeU();
    initializeAtEquilibrium(lattice, everythingButTopLid, (T)1., Array<T,3>((T)0.,(T)0.,(T)0.) );
    initializeAtEquilibrium(lattice, topLid, (T)1., Array<T,3>(u,(T)0.,u) );
    setBoundaryVelocity(lattice, topLid, Array<T,3>(u,(T)0.,u) );

    lattice.initialize();
}
Ejemplo n.º 12
0
/// 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();
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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();
}
Ejemplo n.º 15
0
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) );
}
Ejemplo n.º 16
0
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)
                                      ) ) );
}
Ejemplo n.º 17
0
/// Linearly decreasing pressure profile
T poiseuillePressure(plint iX, IncomprFlowParam<T> const& parameters) {
	T Lx = parameters.getNx()-1;
	T Ly = parameters.getNy()-1;
	return 8.*parameters.getLatticeNu()*parameters.getLatticeU() / (Ly*Ly) * (Lx/(T)2-(T)iX);
}
Ejemplo n.º 18
0
/// Velocity on the parabolic Poiseuille profile
T poiseuilleVelocity(plint iY, IncomprFlowParam<T> const& parameters) {
	T y = (T)iY / parameters.getResolution();
	return 4.*parameters.getLatticeU() * (y-y*y);
}