Challenge

Week 11 - Simulation of Flow through a pipe in OpenFoam

SIMULATION OF FLOW THROUGH A PIPE IN OPENFOAM

Objectives:

  • To write a program in Matlab/Octave that can generate the computational mesh automatically for any wedge angle and grading schemes.
  • To validate the numerical solution with the Hagen-Poiseuille's equation.

Hagen-Poiseuille flow:

Hagen-Poiseuille flow (or simply Poiseuille flow) represents the flow through a circular pipe which is applicable to a variety of applications ranging from macroscopic pipes in industries to the flow of blood in the veins.

Hagen-Poiseuille's equation is a physical law that gives the pressure drop in an incompressible and laminar flow of a Newtonian fluid flowing through a long cylindrical pipe of constant cross-section.

  1. Average velocity `V_(avg) = (Re * mu)/(rho*D)`
  2. Maximum velocity `V_(max) = 2 * V_(avg)`
  3. Pressure drop `Deltap = (8*mu*L_(fdr)*V_(avg))/(r^2)`
  4. Kinematic pressure drop `Deltap_k = (Deltap)/rho`
  5. Wall shear stress `tau = (f/4)*((rho*V_(avg)^2)/2)`

where,

Re `->` Reynold's number `(rho*V_(avg)*D)/mu`

`mu` `->` Dynamic viscosity (`(N s)/m^2`)

`rho` `->` Density (`(kg)/m^3`)

D `->` Diameter of the pipe (m)

`L_(fdr)` `->` Length of the fully-developed region (m)

f `->` Darcy's friction factor (`64/(Re)`)

Hydrodynamic entry length:

It refers to the distance traveled by the flow after entering the pipe before it becomes fully developed.

Awareness of entry length is necessary for the effective placement of the instrumentation such as flow meters. Hydrodynamic entry length for a laminar flow is given as:

`L_e` = 0.05 * Re * D

`L_(fdr) = L - L_e`

Geometry:

A circular pipe of diameter 0.02 m and length 3 m is considered for this challenge.

Geometry, loadings, boundary conditions, and materials are symmetric with respect to the x-axis. Therefore to decrease the computational effort and by taking advantage of the axis-symmetrical model, a reduced wedge model with a suitable wedge angle (<`5^o`) can be considered instead of a complete circular pipe for the simulation.

Preliminary data:

Diameter D = 0.02 m

Radius r = D/2 = 0.01 m

Total length L = 3 m

Reynold's number Re = 2100 (for laminar flow through a circular pipe)

Hydraulic entry length `L_e` = 0.05 * 2100 * 0.02 = 2.1 m

Length of the fully developed region `L_(fdr)` = L - `L_e` = 3 - 2.1 = 0.9 m

Wedge angle `theta` = `4^@`

Density `rho` = 998 kg/`m^3` (for water @ `20^@ C`)

Dynamic viscosity `mu` = 1e-03 `N s`/`m^2` (for water @ `20^@ C`)

Kinematic viscosity `nu` = `mu`/`rho` = 1e-06 `m^2`/s (for water @ `20^@ C`)

Matlab code - To generate blockMeshDict file:

clear all
close all
clc

%Reynolds number
Re=2100;
%Diameter of the pipe
D=0.02;
%Total length of the pipe
L=3;
%Hydraullic entry length
L_e=0.05*Re*D;
%Length of the fully developed region
L_f=L-L_e;
%Radius of the pipe
r=D/2;
%Wedge angle
theta=4;
%Dynamic viscosity of water at 20degC
mu=1e-03;
%Density of water at 20degC
rho=998;

%Hagen-Poiseuille equation
%Average velocity
v_avg=(Re*mu)/(rho*D);
%Maximum velocity
v_max=2*(v_avg);
%Pressure drop
del_p=(8*mu*L_f*v_avg)/(r^2);
%Kinematic pressure drop
del_p_k=del_p/rho;
%Friction factor
f=64/Re;
%Wall shear stress
tau=(f/4)*((rho*(v_avg)^2)/2);

%To create blockMeshDict file
%Header section
header1='/*--------------------------------*- C++ -*----------------------------------*\';
header2='  =========                 |';
header3='  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox';
header4='   \\    /   O peration     | Website:  https://openfoam.org';
header5='    \\  /    A nd           | Version:  8';
header6='     \\/     M anipulation  |';
header7='\*---------------------------------------------------------------------------*/';

f1=fopen('blockMeshDict','w');
fprintf(f1, '%s\n',header1);
fprintf(f1, '%s\n',header2);
fprintf(f1, '%s\n',header3);
fprintf(f1, '%s\n',header4);
fprintf(f1, '%s\n',header5);
fprintf(f1, '%s\n',header6);
fprintf(f1, '%s\n',header7);

fprintf(f1, 'FoamFile\n{\n');
fprintf(f1, '\t %s \t 2.0;\n','version');
fprintf(f1, '\t %s \t ascii;\n','format');
fprintf(f1, '\t %s \t\t dictionary;\n','class');
fprintf(f1, '\t %s \t blockMeshDict;\n','object');
fprintf(f1, '}\n');

header8='// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //';
fprintf(f1, '%s\n\n',header8);
fprintf(f1, 'convertToMeters 1;\n\n');

%Vertices section
fprintf(f1, 'vertices\n');
fprintf(f1, '(\n');
fprintf(f1, '\t (%d %d %d)\n',0,0,0);
fprintf(f1, '\t (%d %d %d)\n',0,r*cosd(theta/2),r*sind(theta/2));
fprintf(f1, '\t (%d %d %d)\n',0,r*cosd(theta/2),-r*sind(theta/2));
fprintf(f1, '\t (%d %d %d)\n',L,0,0);
fprintf(f1, '\t (%d %d %d)\n',L,r*cosd(theta/2),r*sind(theta/2));
fprintf(f1, '\t (%d %d %d)\n',L,r*cosd(theta/2),-r*sind(theta/2));
fprintf(f1, ');\n\n');

%Blocks section
fprintf(f1, 'blocks\n');
fprintf(f1, '(\n');
fprintf(f1, '\t hex (0 3 5 2 0 3 4 1) (%d %d %d)',500,25,1);
fprintf(f1, ' simpleGrading (1 0.2 1)\n\n');
fprintf(f1, ');\n\n');

%Edges section
fprintf(f1, 'edges\n');
fprintf(f1, '(\n');
fprintf(f1, '\t arc %d %d (%d %d %d)\n',1,2,0,r,0);
fprintf(f1, '\t arc %d %d (%d %d %d)\n',4,5,L,r,0);
fprintf(f1, ');\n\n');

%Boundary section
fprintf(f1, 'boundary\n');
fprintf(f1, '(\n');
%Inlet
fprintf(f1, '\t inlet \n');
fprintf(f1, '\t {\n');
fprintf(f1, '\t\t type patch;\n');
fprintf(f1, '\t\t faces \n');
fprintf(f1, '\t\t (\n');
fprintf(f1, '\t\t\t (0 1 2 0)\n');
fprintf(f1, '\t\t );\n');
fprintf(f1, '\t }\n');
%Outlet
fprintf(f1, '\t outlet \n');
fprintf(f1, '\t {\n');
fprintf(f1, '\t\t type patch;\n');
fprintf(f1, '\t\t faces \n');
fprintf(f1, '\t\t (\n');
fprintf(f1, '\t\t\t (3 5 4 3)\n');
fprintf(f1, '\t\t );\n');
fprintf(f1, '\t }\n');
%Top
fprintf(f1, '\t top \n');
fprintf(f1, '\t {\n');
fprintf(f1, '\t\t type wall;\n');
fprintf(f1, '\t\t faces \n');
fprintf(f1, '\t\t (\n');
fprintf(f1, '\t\t\t (1 4 5 2)\n');
fprintf(f1, '\t\t );\n');
fprintf(f1, '\t }\n');
%Front
fprintf(f1, '\t front \n');
fprintf(f1, '\t {\n');
fprintf(f1, '\t\t type wedge;\n');
fprintf(f1, '\t\t faces \n');
fprintf(f1, '\t\t (\n');
fprintf(f1, '\t\t\t (0 3 4 1)\n');
fprintf(f1, '\t\t );\n');
fprintf(f1, '\t }\n');
%Back
fprintf(f1, '\t back \n');
fprintf(f1, '\t {\n');
fprintf(f1, '\t\t type wedge;\n');
fprintf(f1, '\t\t faces \n');
fprintf(f1, '\t\t (\n');
fprintf(f1, '\t\t\t (0 2 5 3)\n');
fprintf(f1, '\t\t );\n');
fprintf(f1, '\t }\n');
%Axis
fprintf(f1, '\t axis \n');
fprintf(f1, '\t {\n');
fprintf(f1, '\t\t type empty;\n');
fprintf(f1, '\t\t faces \n');
fprintf(f1, '\t\t (\n');
fprintf(f1, '\t\t\t (0 3 3 0)\n');
fprintf(f1, '\t\t );\n');
fprintf(f1, '\t }\n');
fprintf(f1, ');\n\n');

%Final section
fprintf(f1, 'mergePatchPairs\n');
fprintf(f1, '(\n');
fprintf(f1, ');\n');

header9='// ************************************************************************* //';
fprintf(f1, '%s\n',header9);
fclose(f1);

Mesh specifications:

  • Number of cells along the x-direction = 500
  • Number of cells along the y-direction = 25
  • Number of cells along the z-direction = 1

Simple grading factor:

  • Along x-direction = 1
  • Along y-direction = 0.2
  • Along z-direction = 1

blockMeshDict:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  8
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
	 version 	 2.0;
	 format 	 ascii;
	 class 		 dictionary;
	 object 	 blockMeshDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

convertToMeters 1;

vertices
(
	 (0 0 0)
	 (0 0.00999391 0.000348995)
	 (0 0.00999391 -0.000348995)
	 (3 0 0)
	 (3 0.00999391 0.000348995)
	 (3 0.00999391 -0.000348995)
);

blocks
(
	 hex (0 3 5 2 0 3 4 1) (500 25 1) simpleGrading (1 0.2 1)

);

edges
(
	 arc 1 2 (0 0.01 0)
	 arc 4 5 (3 0.01 0)
);

boundary
(
	 inlet 
	 {
		 type patch;
		 faces 
		 (
			 (0 1 2 0)
		 );
	 }
	 outlet 
	 {
		 type patch;
		 faces 
		 (
			 (3 5 4 3)
		 );
	 }
	 top 
	 {
		 type wall;
		 faces 
		 (
			 (1 4 5 2)
		 );
	 }
	 front 
	 {
		 type wedge;
		 faces 
		 (
			 (0 3 4 1)
		 );
	 }
	 back 
	 {
		 type wedge;
		 faces 
		 (
			 (0 2 5 3)
		 );
	 }
	 axis 
	 {
		 type empty;
		 faces 
		 (
			 (0 3 3 0)
		 );
	 }
);

mergePatchPairs
(
);
// ************************************************************************* //

Solver setup:

From the OpenFoam tutorials, the cavity case setup from the incompressible is chosen. The blockMeshDict file is replaced with the one generated by the matlab code.

The transportProperties file present in the "constant" folder is modified to set the kinematic viscosity of the desired fluid. For water at `20^@C`, the value of kinematic viscosity is 1e-6 `m^2`/s

transportProperties:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  8
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "constant";
    object      transportProperties;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

nu              [0 2 -1 0 0 0 0] 1e-06;


// ************************************************************************* //

fvSchemes:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  8
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "system";
    object      fvSchemes;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

ddtSchemes
{
    default         Euler;
}

gradSchemes
{
    default         Gauss linear;
    grad(p)         Gauss linear;
}

divSchemes
{
    default         none;
    div(phi,U)      Gauss linear;
}

laplacianSchemes
{
    default         Gauss linear orthogonal;
}

interpolationSchemes
{
    default         linear;
}

snGradSchemes
{
    default         orthogonal;
}


// ************************************************************************* //

fvSolution:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  8
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "system";
    object      fvSolution;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

solvers
{
    p
    {
        solver          PCG;
        preconditioner  DIC;
        tolerance       1e-06;
        relTol          0.05;
    }

    pFinal
    {
        $p;
        relTol          0;
    }

    U
    {
        solver          smoothSolver;
        smoother        symGaussSeidel;
        tolerance       1e-05;
        relTol          0;
    }
}

PISO
{
    nCorrectors     2;
    nNonOrthogonalCorrectors 0;
    pRefCell        0;
    pRefValue       0;
}


// ************************************************************************* //

Initial conditions:

The p and U files in the 0 folder are modified to set the desired initial conditions for pressure and velocity.

At inlet,

Velocity = `V_(avg)` = 0.105 m/s (Dirichlet)

Pressure = zeroGradient (Neumann)

At outlet,

Velocity = zeroGradient (Neumann)

Pressure = 0 `m^2`/`s^2` (Dirichlet)

p file:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  8
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volScalarField;
    object      p;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 2 -2 0 0 0 0];

internalField   uniform 0;

boundaryField
{
    inlet
    {
        type            zeroGradient;
    }

    outlet
    {
        type            fixedValue;
        value           uniform 0;
    }

    axis
    {
        type            empty;
    }

    top
    {
        type            zeroGradient;
    }

    front
    {
        type            wedge;
    }

    back
    {
        type            wedge;
    }
}
// ************************************************************************* //

U file:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  8
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       volVectorField;
    object      U;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

dimensions      [0 1 -1 0 0 0 0];

internalField   uniform (0.105 0 0);

boundaryField
{
    inlet
    {
        type            fixedValue;
        value           uniform (0.105 0 0);
    }

    outlet
    {
        type            zeroGradient;
    }

    axis
    {
        type            empty;
    }

    top
    {
        type            noSlip;
    }

    front
    {
        type            wedge;
    }

    back
    {
        type            wedge;
    }
}

// ************************************************************************* //

Time step:

L = 3 m

`V_(avg)` = 0.105 m/s

Required time t = 3/0.105 `approx` 29 s

let time step dt = 0.001

t/dt = 29000

for a write interval of 500, 29000/500 = 58

These values are modified in the controlDict file present in the "system" folder.

controlDict:

/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  8
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "system";
    object      controlDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

application     icoFoam;

startFrom       startTime;

startTime       0;

stopAt          endTime;

endTime         29;

deltaT          0.001;

writeControl    timeStep;

writeInterval   500;

purgeWrite      0;

writeFormat     ascii;

writePrecision  6;

writeCompression off;

timeFormat      general;

timePrecision   6;

runTimeModifiable true;


// ************************************************************************* //

blockMesh command is used to create the mesh for the given geometry. Once the mesh is created successfully, execute the icoFoam command in the terminal with the case setup file open in the run folder of OpenFOAM.

Results and discussions:

1. Velocity contours:

Entry region:

Fully developed region:

2. Velocity profiles:

Entry region:

Fully developed region:

From these two plots, it is obvious that the velocity profile becomes more parabolic in the fully developed region. Near the wall (0.01m), the velocity is almost zero due to the friction between the fluid and the wall. As the radial distance from the center decreases, the velocity increases parabolically.

3. Shear stress plots:

Entry region:

Fully developed region:

The shear stress is maximum at the wall and almost zero at the center. This is because there is more friction at the wall surface and the velocity gradient is more.

Validation:

For a fully developed region, the numerical and analytical solutions are compared graphically.

Analytical solution:

  1. Average velocity `V_(avg) = (Re * mu)/(rho*D)` = 0.105 m/s
  2. Maximum velocity `V_(max) = 2 * V_(avg)` = 0.21 m/s
  3. Pressure drop `Deltap = (8*mu*L_(fdr)*V_(avg))/(r^2)` = 1.89 Pa
  4. Kinematic pressure drop `Deltap_k = (Deltap)/rho` = 0.006102 `m^2`/`s^2`
  5. Wall shear stress `tau = (f/4)*((rho*V_(avg)^2)/2)` = 0.04 Pa

The velocity at any radial distance is given by,

`V(r) = V_(max)[1-(r/R)^2]`m/s

The shear stress is given by,

`tau=mu*((dV)/(dr))` `N/m^2`

The maximum values of velocity and shear stress are as follows:

Parameter Numerical value Analytical value % Difference
Velocity (m/s) 0.208205 0.21 0.85
Shear stress (`N/m^2`) 0.0322027 0.042 0.23

Velocity profile (fully developed region):

Shear stress plot (fully developed region):

Your portfolio, next

Ship work like this
in your own course.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.

Talk to a career counsellor

Free 20-minute call. We'll map the right course to where you want to work.

By submitting you agree to our Terms and Privacy Policy.