Skip to content

Tutorial: incompressible‐‐pimpleHFDIBFoam‐‐fallingParticleDistribution

techMathGroup edited this page Aug 22, 2024 · 26 revisions

Case description

This tutorial represents a situation where a number of non-spherical particles of different sizes is sedimenting in a rectangular domain.

Note that in order for the tutorial to be fast to evaluate even on personal computers, it is constructed as two-dimensional. However, the DEM part of the code is suitable only for three-dimensional simulations and the particles properties were adjusted in such a way that the tutorial gives plausible results.

Geometry and boundary conditions

Incompresible_BlockFigure_2

The test domain is a hexahedron of dimensions (120mm x 0.1mm x 60mm) which has the Y-direction empty, that is, not active for the solution. The geometry is generated directly using the blockMesh OpenFOAM application and is displayed in the figure above, including its dimensions and boundary. As stated above, the front and back in the Y-directions are defined as type empty, the active boundaries treated as type wall are highlighted in green and preascribed with zeroGradient boundary condition for pressure and noSlip for fluid velocity. At the remaining type patch boundary, we fix the value of pressure, i.e., fixedValue set to uniform 0 is used, and prescribe a zeroGradient boundary condition for fluid velocity.

Details on the test geometry, mesh, and types of boundaries, see

"tutorialDirectory"/system/blockMeshDict

For details regarding boundary and initial conditions for the solved-for variables, see the files in the directory

"tutorialDirectory"/0.org/

CFD-DEM related case settings

The DEM solver is configured via the HFDIBDEMDict found at path

"tutorialDirectory"/constant/HFDIBDEMDict

The file used in this tutorial is:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                |                                                 |
| \      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \    /   O peration     | Version:  8                                     |
|   \  /    A nd           | Web:      www.OpenFOAM.org                      |
|    \/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "constant";
    object      HFDIBDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
bodyNames ( "icoSphere" );

interpolationSchemes
{
    U      cellPointFace;
    method line;
}

surfaceThreshold    1e-4;
stepDEM             0.02;
geometricD          (1 -1 1);
recordSimulation    true;
recordFirstTimeStep false;
nSolidsInDomain      1000;

outputSetup
{
    basic       true;
    iB          false;
    DEM         false;
    addModel    true;
    parallelDEM false;
}

DEM
{
    
    materials
    {
        particle
        {
            Y       1e7;
            nu      0.3;
            mu      0.75;
            adhN    0;
            eps     0.25;
        }

        wall
        {
            Y       1e7;
            nu      0.2;
            mu      0.75;
            adhN    0;
            eps     0.25;
        }
    }
    LcCoeff 4.0;

    collisionPatches
    {
		wall0
		{
			material wall;
			nVec (-1.0 0.0 0.0);
			planePoint (0.0 0.00 0.0);
		}
		wall1
		{
			material wall;
			nVec (1.0 0.0 0.0);
			planePoint (0.12 0.0 0.0);
		}
		wall2
		{
			material wall;
			nVec (0.0 0.0 1.0);
			planePoint (0.00 0.0 0.03);
		}

		wall3
		{
			material wall;
			nVec (0.0 0.0 -1.0);
			planePoint (0.0 0.0 -0.03);
		}
    }
}

virtualMesh
{
    level 2;
    charCellSize 0.0012;
}

icoSphere
{
    fullyCoupledBody;
    updateTorque true;
    startSynced false;
    rho         rho [1 -3 0 0 0 0 0] 10000;
    material particle;
    U
    {
        BC  noSlip;
    }
    bodyGeom convex;
    sdBasedLambda false;
    interfaceSpan 1.0;
    refineBuffers 1;
    timesToSetStatic 80;
    bodyAddition
    {
        addModel distribution;
        distributionCoeffs
        {
            stlBaseSize     0.005;
            addMode         fieldBased;
            fieldBasedCoeffs
            {
                fieldName   lambda;
                fieldValue	0.05;
            }
    
            addDomain      boundBox;
            boundBoxCoeffs
            {
                minBound (0 -0.001 -0.03);
                maxBound (0.04 0.001 0.03);
            }
    
            scalingMode    noScaling;
            noScalingCoeffs{};
            rotationMode   noRotation;
            noRotationCoeffs{};
        }
    }
}

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

Going from top of the file, in the list bodyNames() the particle names that shall be active in the simulation are defined; if the particle is based on STL surface mesh, an STL file with a matching name has to be present in the directory constant/triSurface/. Here, we work with a particle named "icoSphere", which is linked to the file:

"tutorialDirectory"/constant/triSurface/icoSphere.stl

The global solver configurations are:

  • interpolationSchemes setting for the immersed boundary method
  • surfaceThreshold threshold for particle projection and interpolation schemes,
  • stepDEM integration step for DEM solver defined as fraction of the global CFD integration step. Consequently, the inverse value is the amount of DEM steps per one CFD iteration
  • geometricD solution directions, active directions: 1; inactive: -1
  • recordSimulation boolean option to separately record the position of particles at a given time
  • recordFirstTimeStep boolean option to record initial position of particles added to the domain
  • nSolidsInDomain maximum number of particles that can be active within the domain, if not present, 1000 is used

The control of the outputs set up through the outputSetup dictionary where the following outputs may be enabled

  • basic simulation time, and body velocities and locations per CFD step
  • iB detailed info regarding particle properties per DEM step
  • DEM detailed info regarding particle contact treatment
  • addModel detailed info regarding particle addition into the computational domain
  • parallelDEM detailed info regarding particle contact treatment from all subdomains for parallel computations

The DEM dictionary is used to set materials of solid phase and collision patches. The materials dictionary is split into sub-dictionaries where multiple materials might be defined using

  • Y - Young Modulus (material stiffness),
  • nu - Poisson ratio,
  • mu - static friction coefficient,
  • adhN- normal adhesion coefficient,
  • eps - coefficient of restitution (dissipation). Next the curvature coefficient LcCoeff represents the local curvature of the considered solids. collisionPatches dictionary is split into sub-dictionaries while each sub-dictionary contacns a definition of a collision boundary for DEM which may or may not correspond to a system boundary. In this specific case, each wall is defined as a dictionary consisting of
  • material enter the name of a material defined in materials dictionary,
  • nVec outer normal vector to the boundary, and
  • planePoint arbitrary point located in the collision boundary.

The virtualMesh dictionary is a setting of the contact treatment algorithm for the STL mesh-based solids. It is described by level - a decomposition level, similar to the corresponding snappyHexMesh setting, declaring how much the contact area will be refined; and by charCellSize, that is, the size of the characteristic computational cell for initial refinement of the contact area.

Finally, each particle listed in bodyNames() has to have its properties defined. This is done via a dictionary named according to the entry in bodyNames(), in this case, icoSphere{}. Within the dictionary, it is necessary to define: mode of particle motion, particle material and density, boundary condition to enforce on the fluid-solid interface, type of particle geometry, mode of particle addition into the domain, and additional settings for the solver numerics. Note that the combination of the particle listed bodyNames() and the corresponding dictionary acts as a template for generation and treatment of arbitrary number of particles based on the selected mode of addition.

In this tutorial, the particles motion is fully coupled with the fluid, and the particles have the density of 10000 kg/m3 and are of the particle material as defined in DEM.materials. The corresponding entries in the icoSphere template dictionary are:

  • fullyCoupledBody; if you wish to determine initial velocity you may enter fullyCoupledBody{velocit (0 1 0);}.
  • to enable particle rotation, define updateTorque and set it true
  • for particle to start synchronised with fluid velocity and rotation, set startSynced true in this case we assume zero initial velocity for particle
  • material particle
  • rho rho [1 -3 0 0 0 0 0] *value*;, where rho is the standard OpenFOAM dimensionedScalar variable.

The boundary condition at the fluid-solid interface is U{BC noSlip;}, which is the only value presently implemented.

From the point of geometry, the icoSphere particle is convex, which leads to the bodyGeom convex; entry. Also, there is an option to freeze the simulated particle at a place after a prolonged period of it not moving. This is done via timesToSetStatic 80, which means that the fullyCoupledBody will be converted to static after 80 CFD time steps of inactivity.

In this tutorial, a size distribution of particles of shape defined by /constant/triSurface/icoSphere.stl is generated at the begining of the simulation. The corresponding add model is addModel distribution and its settings are

bodyAddition
{
	addModel distribution;
    distributionCoeffs
    {
        stlBaseSize     0.005;          //stating referential size of the STL file
        addMode         fieldBased;     //selecting mode to condition particle addition
        fieldBasedCoeffs
        {
            fieldName   lambda;         //name of the indicator field
            fieldValue	0.05;           //target integral of the field over the addDomain
        }

        addDomain      boundBox;        //choosing to create new particles within the bounding box
        boundBoxCoeffs
        {
            minBound (0 -0.001 -0.03);  //( 0 -1 -30) mm
            maxBound (0.04 0.001 0.03); //(40  1  30) mm
        }

        scalingMode    noScaling;      //aded particles will not be additionally rescaled
        noScalingCoeffs{};
        rotationMode   noRotation;     //added particles will not be additionally rotated
        noRotationCoeffs{};
    }
}

This addModel in particular requires additional data in file

"tutorialDirectory"/constant/distributionDict

which contains:

/*--------------------------------*- C++ -*----------------------------------*\
| =========                 |                                                |
| \      /  F ield         | OpenFOAM: The Open Source CFD Toolbox           |
|  \    /   O peration     | Version:  8                                     |
|   \  /    A nd           | Web:      www.OpenFOAM.org                      |
|    \/     M anipulation  |                                                 |
\*---------------------------------------------------------------------------*/
FoamFile
{
    version     2.0;
    format      ascii;
    class       dictionary;
    location    "constant";
    object      distributionDict;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 
convertToMeters 0.005;  //conversion of particleSize to meters

distribution 7          //7 fractions, percentage representation
(
    0
    10
    60
    15
    10
    5
    0
);

particleSize 7           //7 fractions, fraction sizes
(
    0.4
    0.8
    1.2
    1.6
    2
    3
    4
);

Each particle dict should also include refineBuffers 1;,sdBasedLambda false; the first is for adaptive mesh refinement which can be enabled in dynamicMeshDict, the second is an old option to be removed in next major update.

The case setting is then concluded by defining the gravity in

"tutorialDirectory"/constant/g

with value (9.81 0 0 ); Also, as this tutorial is for CFD-DEM simulation the gravity for fluid flow has to be defined using fvOptions, see

"tutorialDirectory"/system/fvOptions

Case settings not explicitly mentioned above are common for all the OpenFOAM cases based on the pimpleFOAM solver.

Running the case

The case is run using ./Allrun & or bash Allrun & script:

`#!/bin/sh
. $WM_PROJECT_DIR/bin/tools/RunFunctions

rm -rf 0

cp -r 0.org 0


runApplication blockMesh     # mesh generation, see system/blockMeshDict

application=`getApplication` # selects application (pimpleHFDIBFoam) from system/controlDict

runApplication $application  # run the simulation itself

paraFOAM -touch # to create .OpenFOAM file for visualisation in paraview

after the simulation ends, you may proceed to visualization and optional post-processing.

Results visualization

Several approaches might be used to visualize the results of the CFD-DEM simulation depending on the level of detail you wish to achieve.

Let's start with the minimalistic approach using only the paraview, enter the following command in the terminal opened in the tutorial directory

paraFOAM

the paraview window should appear with a loaded file, in this case: "fallingParticleDistribution.OpenFOAM." To set an accurate display, check the boxes marked within red borders and then click Apply. See the figure below PWOutput#1 0

The white rectangle should appear to adjust its position. Use options marked blue in the rectangle below or hold the left mouse button while moving with the mouse. Next, you must select the field you wish to display. For particle positions, select lambda; for the fluid velocity field, select U. The field is scaled according to the range available for a given time level. You may rescale it to fit your preferences. Follow the options marked red in the figure below. If you wish to display both fields simultaneously, you may use a transform filter. First, select the source you want to display this way. Next, click ctrl and space and write "transform." Select the filter and modify it according to the box marked in green in the figure below. Ensure both objects are visible, and select the fields you want to be displayed.
PWOutput#2 0

Alternatively, if you want to display both fields in one figure, you may apply the "threshold" filter to the lambda field with a value above 0.01, as depicted in the figure below and marked with green borders. Please ensure both objects are visible and the right field is selected. PWOutput#3 0

  • The more advanced approach enables the display of full particle geometries, for which the simulation is evaluated. However, it requires preprocessing using python3 scripts, which are also prepared in the directory. First, remove the initial time step by entering

rm -rf 0/

next run

python3 sync_time_levels.py

please check that the script loaded time levels in the correct order and proceed. Next, merge all individual particle STL meshes into one for each time level by running

python3 merge_STL_outputFiles.py

If everything proceeded correctly, the time levels present should be renamed to integer values starting with 0, and the new directory STLMerged/ should be present. Now, to display results, enter

paraFOAM

Repeat the first two steps of the minimalistic approach as described above for the initial setting. When you have the basic domain displayed prepared, you may right-click the loaded .OpenFOAM object below and click open. Select the "STLMerged/" directory and then click on STL_Results..stl and hit "OK", as indicated in figure below with yellow border. The STL files will be loaded with STLSolidLabeling field you may change this for solid color by following rectangles highlighted with pink in the figure below. PWOutput4 0

If you wish to improve your visualization further, highlight the area where the particles are added to the computational domain. This can be achieved by using the box filter: click ctrl and space and write "box." Select the filter and configure it according to HFDIBDEMDict. Follow the figure below for setting the box filter and possible display of the result.

PWOutput#5 0

This concludes this tutorial; if you have any questions, feel free to contact us by e-mail.