ACU-T: 6108 AcuSolve - EDEM Bidirectional Coupling with User-Defined Drag Model
Prerequisites
This tutorial covers the setup process for running a bidirectional AcuSolve EDEM coupled simulation using a custom user-defined drag model. An overview of the UDF code and the compilation process is provided in the beginning of the tutorial, followed by the simulation setup and post-processing. It is assumed that you have prior experience using HyperMesh CFD and EDEM, the basics of which are covered in the tutorials: ACU-T: 1000 UI Introduction, and ACU-T: 6100 Particle Separation in a Windshifter using Altair EDEM .
Problem Description
The objective of the simulation is to calculate the terminal velocity of the solid particle as it falls through the water column. The particle’s initial location is 4.8 mm from the bottom of the water column. Under Stokes flow, the particle initially accelerates due to gravity and the fluid drag force is negligible. As the particle moves through the fluid, the frictional drag increases and the acceleration reduces to zero over time and thereafter the particle travels with a constant velocity, known as the terminal velocity.
Important Simulation Parameters | |
---|---|
Water density (kg/m3) | 1000 |
Water viscosity (Pa s) | 0.001 |
Particle density (kg/m3) | 1500 |
Particle diameter (m) | 0.0001 |
AcuSolve User-Defined Function (UDF) Overview
UDF Format
Header Files
- acusim.h: This header file includes the main data types
used by AcuSolve and the standard C header files
such as stdio.h, string.h and
math.h. Common data types used by AcuSolve:
a. Integer Type integer b. Real Type floating point c. String Type string d. Void Type void - udf.h: This header file contains all of the macros and declarations needed for accessing the data in the UDF.
Function Prototype
Once the header files are declared, you need to prototype the user function using the UDF_PROTOTYPE() macro and the name of the user function as the argument. For example, UDF_PROTOTYPE(usrStokesDrag).
This user function name should be the same as the one specified in the model setup. Otherwise, it can lead to run time errors. Although the user function names can be anything that is supported by C, it is good practice to use function names that start with usr to distinguish the user functions from other solver parameters.
Function Definition
Return Type
All C functions should have a return type. Since the drag force values should be sent back to AcuSolve through outVec, the return value does not have any significance and the return type should be set to Void.
Function Arguments
- udfHd
- Pointer which contains the necessary information for accessing various data. All supporting routines require this argument.
- outVec
- Resulting vector of the user function. On input this array contains all zeros. This vector is used to send the force information back to AcuSolve.
- nItems
- This is the first dimension of outVec, which specifies the number of items that needs to be filled. For all drag model user functions, the value is 1 since you are calculating the drag force on 1 particle in each call.
- vecDim
- This is the second dimension of outVec which specifies the vector dimension of the particular data. This value depends on the type of data that is sent back.
- Drag user function
- Minimum three values (x, y ,z components) are required. Optionally a fourth value can also be sent back to AcuSolve (drag coefficient).
- Lift user function
- Three values (x, y, z components).
- Torque user function
- Three values (x, y, z components).
Function Code
Variables:
Variables are used to store certain types of data. This data can be a single value or an array of values. In C language, all variables need to be declared before they can be used in the program. Although the declaration can be done anywhere inside the program, declaring all the required variables upfront makes the code more organized and easily understandable. The syntax for declaring a variable in C is Datatype variable_name ;
Example
Real volume ;
where Real is the data type and volume is the name of the variable.
In many UDFs, including the current example, you may need to access some data from AcuSolve which has already been calculated and stored by the solver at a particular memory address. For this, you need to declare pointer variables which point to the memory address of the requested data. For instance, if you need to access the local fluid velocity, you need to declare a pointer variable that stores the memory address of the location where AcuSolve has already stored the value.
Example
Real* xVel ;
Accessing data from AcuSolve:
The routine to be used for accessing particle and fluid data from AcuSolve is udfGetEDEMData(udfHd, dataName). This returns an array of data and length of the array depends on the type of data that is requested.
For example,
To access the particle’s volume, first you need to declare a pointer variable and then use the following data routine.
Real* vol ;
- Calculate drag force values:
- Send force data to AcuSolve:
Full Code Snippet
#include "acusim.h"
#include "udf.h"
/*===========================================================================
*
* Prototype the function
*
*===========================================================================
*/
UDF_PROTOTYPE( usrStokesDrag ) ;
/*===========================================================================
*
* "stokesDrag": calculate EDEM particle drag force based on the Stokes law
*
* Arguments:
* udfHd - opaque handle for accessing information
* outVec - output vector
* nItems - number of items in outVec (=1 in this case)
* vecDim - vector dimension of outVec (=3 in this case)
*
* Input file parameters:
* user_values = { }
* user_strings = { "" }
*
*===========================================================================
*/
Void usrStokesDrag( UdfHd udfHd,
Real* outVec,
Integer nItems,
Integer vecDim )
{
Real beta ;
Real vol ;
Real visc ;
Real diam ;
Real* scalar ;
Real* flowVel ;
Real* particleVel ;
Real slipVel[3] ;
Real poros ;
/*---------------------------------------------------------------------------
* Get particle and flow data at current particle location
*---------------------------------------------------------------------------
*/
scalar = udfGetEDEMData( udfHd, UDF_EDEM_PARTICLE_VOLUME) ;
vol = scalar[0] ;
scalar = udfGetEDEMData( udfHd, UDF_EDEM_FLOW_VISCOSITY ) ;
visc = scalar[0] ;
scalar = udfGetEDEMData( udfHd, UDF_EDEM_FLOW_POROSITY ) ;
poros = scalar[0] ;
flowVel = udfGetEDEMData( udfHd, UDF_EDEM_FLOW_VELOCITY ) ;
particleVel = udfGetEDEMData( udfHd, UDF_EDEM_PARTICLE_VELOCITY) ;
if ( vol <= 0 ) {
udfSetError( udfHd, "Error: EDEM particle volume"
" should bigger than zero" ) ;
}
/*---------------------------------------------------------------------------
* Calculate drag
*---------------------------------------------------------------------------
*/
slipVel[0] = flowVel[0] - particleVel[0] ;
slipVel[1] = flowVel[1] - particleVel[1] ;
slipVel[2] = flowVel[2] - particleVel[2] ;
diam = pow((6*vol/PI),0.333333333333);
beta = 3*PI*visc*poros*diam ;
/*---------------------------------------------------------------------------
* Push the drag force to AcuSolve
*---------------------------------------------------------------------------
*/
outVec[0] = beta * slipVel[0] ;
outVec[1] = beta * slipVel[1] ;
outVec[2] = beta * slipVel[2] ;
} /* end of usrStokesDrag() */
For more information about the UDF routines available refer to the AcuSolve User-Defined Functions Manual.
Compiling the UDF
For the solver to access the user-defined functions, the functions must be compiled and linked into a shared library. These libraries should be placed in the problem directory along with the solver input files.
Windows
From the Start menu, expand Altair <solver version> and launch the AcuSolve Cmd Prompt.
In the terminal, cd to the directory where the model files and the UDF script file are located. Then execute the following command to compile the UDF:
acuMakeDll -src usrStokesDrag.c
Linux
Open a command line prompt and cd to the directory where the model files and the UDF script are located. Then execute the following command:
acuMakeLib -src usrStokesDrag.c
Part 1 – AcuSolve Simulation
Start HyperMesh CFD and Open the HyperMesh Database
Validate the Geometry
The Validate tool scans through the entire model, performs checks on the surfaces and solids, and flags any defects in the geometry, such as free edges, closed shells, intersections, duplicates, and slivers.
Set Up Flow
Set the General Simulation Parameters
Assign Material Properties
Define Flow Boundary Conditions
Generate the Mesh
Define Nodal Outputs
Once the meshing is complete, you are automatically taken to the Solution ribbon.
Part 2 - EDEM Simulation
Start Altair EDEM from the Windows start menu by clicking .
Open the EDEM Input Deck
Review the EDEM Model Setup
The main area of focus for this tutorial is the user-defined drag model setup and compilation process for a bidirectional AcuSolve - EDEM coupling simulation. Therefore, for the sake of brevity, the EDEM database provided with the input files contains all of the required setup.
Summary of the EDEM Model
A spherical particle of diameter 0.0001 m is introduced in a water column at a point which is 0.0048 m from the bottom. Since the density of the particle is 1500 kg/m3, that is, heavier than water, the particle falls freely through the water column.
Define the Simulation Settings
Submit the Coupled Simulation
Analyze the Results
Summary
In this tutorial, you learned how to write a user-defined function in C programming language for implementing a custom drag model for bidirectional AcuSolve-EDEM coupling. The Stokes drag law was used to calculate the terminal velocity of a spherical particle falling through a water column. The simulation results showed that the Stokes drag law is quite accurate in predicting the drag force on a particle in low Reynolds number flows.