Problem description:
This tutorial simulates particle flows around a coil for a short time. The code can be found in CoilSelfTest.cpp. It treats particles placed in a feeder being driven forward by a rotating coil.
Headers
The following headers are included:
These are basically the headers used for the beginner tutorials, except for the additional Coil class.
Before the main function
CoilSelfTest, like many of the previous tutorials, inherits from the Mercury3D class.
[CST:headers]
Definition: CoilSelfTest.cpp:22
This adds on the hierarchical grid code for 3D problems.
Definition: Mercury3D.h:16
The different components of the class will be explained in turn in the following.
step 1: Define Walls
The particles are initially contained by a container made up of six walls, five of which are defined to be infinite. The wall in the positive Z-direction is different. Its normal is set (rightWall->set(...
) in the positive Z-direction (Vec3D(0, 0, 1)
), is set a distance zMax_
(which is returned by getZMax()
) from the origin, and contains a 'hole' (which is practically a horizontal tube, since the wall is 'infinite') around the X-axis of radius 1.0
in order to let the particles through.
w.setSpecies(speciesHandler.getObject(0));
wallHandler.copyAndAddObject(
w);
wallHandler.copyAndAddObject(
w);
wallHandler.copyAndAddObject(
w);
wallHandler.copyAndAddObject(
w);
wallHandler.copyAndAddObject(
w);
rightWall.
setSpecies(speciesHandler.getObject(0));
rightWall.
set(
Vec3D(0, 0, 1), getZMax(), 1.0);
wallHandler.copyAndAddObject(rightWall);
RowVector3d w
Definition: Matrix_resize_int.cpp:3
void setSpecies(const ParticleSpecies *species)
Defines the species of the current wall.
Definition: BaseWall.cc:148
Definition: InfiniteWallWithHole.h:17
void set(Vec3D normal, Mdouble position, Mdouble holeRadius)
Defines a standard wall, given an outward normal vector s. t. normal*x=position.
Definition: InfiniteWallWithHole.cc:51
A infinite wall fills the half-space {point: (position_-point)*normal_<=0}.
Definition: InfiniteWall.h:27
Definition: Kernel/Math/Vector.h:30
step 2: Coil
After that the Coil object is added. Its geometrical properties are subsequently set by using the Coil::set() method, specifying its starting position (the origin, i.e. Vec3D(0,0,0)
), its length (1.0
), its radius (1.0 - particleRadius
), its number of turns (2.0
), its rotation speed (-1.0
revelations per second) and its thickness (0.5 * particleRadius
).
NB: its direction or central axis is not specified, since these are the Z-direction and the Z-axis, respectively, by default.
coil.
set(
Vec3D(0, 0, 0), 1.0, 1.0 - particleRadius, 2.0, -1.0, 0.5 * particleRadius);
auto pCoil = wallHandler.copyAndAddObject(coil);
This class defines a coil in the z-direction from a (constant) starting point, a (constant) length L,...
Definition: Coil.h:20
void set(Vec3D Start, Mdouble length, Mdouble radius, Mdouble numberOfRevelations, Mdouble omega, Mdouble thickness)
Set all parameters of this Coil.
Definition: Coil.cc:81
step 3: Create Particles
The particle properties are set subsequently. The particleHandler is cleared just to be sure it is empty, then the particle to be copied into the container is created and the previously set species is assigned to it. The particle is assigned a zero velocity and the previously defined particle radius.
particleHandler.clear();
p0.setSpecies(speciesHandler.getObject(0));
p0.setVelocity(
Vec3D(0.0, 0.0, 0.0));
p0.setRadius(particleRadius);
Vector3f p0
Definition: MatrixBase_all.cpp:2
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:16
step 4: Place Particles
After specifying the particle properties, the container is filled with copies of the particle. In this example, particles are placed in a rectangular grid pattern, on evenly spaced positions. First, the number of particles that fit in each direction is computed. Then, a triple for-loop passes every possible particle position, and a particle is placed on the position if there's no part of the coil there.
const unsigned int Nx =
static_cast<unsigned int> (
std::floor((getXMax() - getXMin()) / (2.1 * particleRadius)));
const unsigned int Ny =
static_cast<unsigned int> (
std::floor((getYMax() - getYMin()) / (2.1 * particleRadius)));
const unsigned int Nz =
static_cast<unsigned int> (
std::floor((getZMax() - getZMin()) / (2.1 * particleRadius)));
for (
unsigned int i = 0;
i <
Nx;
i++)
{
for (
unsigned int j = 0;
j <
Ny;
j++)
{
for (
unsigned int k = 0;
k <
Nz;
k++)
{
p0.setPosition(
Vec3D(getXMin() + (getXMax() - getXMin()) * (0.5 +
i) /
Nx,
getYMin() + (getYMax() - getYMin()) * (0.5 +
j) /
Ny,
getZMin() + (getZMax() - getZMin()) * (0.5 +
k) /
Nz));
if (!pCoil->getDistanceAndNormal(
p0, distance,
normal))
{
particleHandler.copyAndAddObject(
p0);
}
else
{
logger(
DEBUG,
"particle at position % could not be inserted",
p0.getPosition());
}
}
}
}
int i
Definition: BiCGSTAB_step_by_step.cpp:9
double Mdouble
Definition: GeneralDefine.h:13
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
char char char int int * k
Definition: level2_impl.h:374
#define DEBUG
Definition: main.h:181
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 floor(const bfloat16 &a)
Definition: BFloat16.h:643
unsigned Nx
Number of elements in each direction (used by SimpleCubicMesh)
Definition: structured_cubic_point_source.cc:114
unsigned Ny
Definition: structured_cubic_point_source.cc:115
unsigned Nz
Number of elements in z-direction.
Definition: axisym_linear_elasticity/cylinder/cylinder.cc:62
void normal(const Vector< double > &x, Vector< double > &normal)
Definition: free_surface_rotation.cc:65
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2
Data members:
CoilSelfTest only has two (public) data members, namely a pointer to the coil:
Actions Before TimeStep:
The actionsBeforeTimeStep() method specifies all actions that need to be performed at the beginning of each time step, i.e. before the actual numerical solution at that time step is computed. In this case, it states that from 1 second into the simulation time and onward, the coil should turn with the given rotational speed.
void actionsBeforeTimeStep() override
{
if (getTime() > 1)
{
}
}
void move_time(Mdouble dt)
Rotate the Coil for a period dt, so that the offset_ changes with omega_*dt.
Definition: Coil.cc:193
Main Function
In the main program, a CoilSelfTest object is created, after which some of its basic properties are set like its number of dimensions (three), time step and saving parameters. Lastly, the problem is actually solved by calling its solve() method.
{
Mdouble restitutionCoefficient = 0.8;
problem.speciesHandler.copyAndAddObject(species);
}
#define UNUSED
Definition: GeneralDefine.h:18
int main(int argc, char *argv[])
Definition: T_protectiveWall.cpp:194
EIGEN_DEVICE_FUNC const GlobalUnaryPowReturnType< Derived, ScalarExponent > pow(const Eigen::ArrayBase< Derived > &x, const ScalarExponent &exponent)
Definition: GlobalFunctions.h:137
void setCollisionTimeAndRestitutionCoefficient(Mdouble tc, Mdouble eps, BaseParticle *p)
Sets k, disp such that it matches a given tc and eps for a collision of two copies of particle p.
Definition: LinearViscoelasticNormalSpecies.cc:191
void setDensity(Mdouble density)
Definition: ParticleSpecies.cc:88
Mdouble getDensity() const
Allows density_ to be accessed.
Definition: ParticleSpecies.cc:98
const Mdouble pi
Definition: ExtendedMath.h:23
unsigned int getSaveCountFromNumberOfSavesAndTimeMaxAndTimeStep(unsigned int numberOfSaves, Mdouble timeMax, Mdouble timeStep)
Returns the correct saveCount if the total number of saves, the final time and the time step is known...
Definition: FormulaHelpers.cc:75
Constructor for SteadyAxisymAdvectionDiffusion problem
Definition: steady_axisym_advection_diffusion.cc:213
Next, the particle species is defined. The particles in this problem will use a linear visco-elastic (normal) contact model. The dissipation and stiffness defining the contact model can be set in different ways. In this example the contact model properties are set by giving a collision time, coefficient of restitution and the particle mass.
Mdouble restitutionCoefficient = 0.8;
problem.speciesHandler.copyAndAddObject(species);
Reference:
Imole, O. I., Krijgsman, D., Weinhart, T., Magnanimo, V., Montes, B. E. C., Ramaioli, M., & Luding, S. (2016). Reprint of" Experiments and discrete element simulation of the dosing of cohesive powders in a simplified geometry". Powder technology, 293, 69-81.
(Return to Overview of advanced tutorials)