EDEM2.4 Programming Guide
EDEM2.4 Programming Guide
4 Programming Guide
Revision 1
Contents
0BOverview ........................................................................................................................... 4
1BEDEM User Defined Library Development Process ...................................................... 4
12BEDEM Simulation Sequence ......................................................................................... 5
13BEDEM API Files ............................................................................................................. 6
1BContact Model User Defined Libraries .............................................................................. 8
14BContact Model API v2.2.0 .............................................................................................. 9
15BDeveloping a Contact Model User Defined Library ..................................................... 10
27BUsing the New Contact Model ................................................................................. 14
28BUsing the EDEM Analyst to Verify the Contact Model ............................................. 15
Particle Body Force User Defined Libraries ................................................................ 18
17BParticle Body Force API v2.1.0.................................................................................... 19
18BDeveloping a Particle Body Force User Defined Library ............................................. 20
34BUsing the New Particle Body Force ......................................................................... 23
Particle Factory User Defined Libraries .......................................................................... 24
14BParticle Factory API v2.0.0 .......................................................................................... 25
15BDeveloping a Particle Factory User Defined Library .................................................... 26
27BUsing the New Particle Factory................................................................................ 31
25Custom Properties ....................................................................................................... 32
90BUsing Custom Properties............................................................................................. 33
42BDeveloping a UDL that uses Custom Particle Properties ........................................ 33
43BCreate and Compile the Custom Particle Property .................................................. 33
4BUsing the New Custom Particle Property................................................................. 36
8BGlossary .......................................................................................................................... 37
9BAppendix A: Code Used in Examples ............................................................................. 39
45BCCohesionModel.h .................................................................................................. 39
46BCCohesionModel.cpp............................................................................................... 42
47BCForceExample.h .................................................................................................... 45
48BCForceExample.cpp ................................................................................................ 47
10BIndex ............................................................................................................................... 49
Overview
0B
This document describes the EDEM API, which you can use to code and implement
your own contact physics, external couplings and particle-generation factories in the
form of a User Defined Library (UDL) which operates as a plugin to EDEM. Read this
document along with the API reference help at \src\Api\Help\index.html
The figure below depicts a high-level sequence diagram showing the steps to write and
use a UDL contact model. The same steps apply for Particle Body Force and Particle
Factory UDLs.
The programmer typically adapts an existing contact model source file (available from
the DEM Solutions website) using a development environment or editor. Once compiled,
the new contact model is loaded into EDEM for use in simulations.
The figure below shows when UDL libraries are called during EDEMs simulation
sequence. Depending on where the UDL lies in the chain, each stage connects to the
relevant UDL (if applicable) before performing its main function (such as calculating
contacts).
1. Move geometry.
2. Generate new particles by calling
each registered particle factory in
turn (some of which may be UDLs).
3. Detect contacts.
4. Invoke the contact model chain for
each contact. Each contact model
in the chain is executed in order,
irrespective of whether it is a UDL
or built-in model. Note there are
two different contact model chains:
one for particle-to-particle contacts
and one for particle-to-geometry
contacts. Your UDL can be loaded
into one or both of these as
required.
5. Apply the Particle Body Force
chain to each particle in the
system. Particle Body Force
models in the chain are executed
in order, irrespective of whether it
is a UDL or built-in model.
6. Update particles based on the
forces applied to them in this
timestep.
7. Update bond information (if
applicable).
8. If there are more timesteps, repeat
from step 1 otherwise finish.
EDEM 2.4 includes a new v2.2.0 C++ API. Use this to get the normalOverlap calculated
from the physical radius of particles. This version supports multi-threading. You can also
continue to use any legacy API from previous versions of EDEM. Legacy versions of the
IPluginContactModel will continue to receive the normalOverlap calculated from the
contact radius of particle surfaces. For full details on the legacy API, refer to the EDEM
2.1.2 Programming Guide, available from the customer area of our website.
The tables below gives an overview of EDEMs API source file location and files. For full
details, refer to the API reference help at \src\Api\Help\index.html
Example source files (which you can use as the basis for writing your own UDLs) are
available from the customer area of our website.
API Directories
49B
Directory
Description
src/Api
src/Api/Help
src/Misc
src/LegacyApi
Header File
Description
ApiIds.h
ApiTypes.h
IApi.h
IApiManager_1_0.h
ICustomPropertyDataApi_1_0.h
ICustomPropertyManagerApi_1_0.h
IFieldApi_1_0.h
PluginConstants.h
Header File
Description
IPluginContactModel.h
IPluginContactModelV2_2_0.h
PluginContactModelCore.h
Header File
Description
IPluginParticleBodyForce.h
IPluginParticleBodyForceV2_1_0.h
PluginParticleBodyForceCore.h
Header File
Description
IPluginParticleFactory.h
IPluginParticleFactoryV2_0_0.h
PluginParticleFactoryCore.h
Description
CGenericFileReader.h
Helpers.h
Using the EDEM API, you can write and compile custom contact models as a UDL
written in C/C++. A Contact Model UDL consists of a shared library file and optionally a
file containing preferences.
Overview of Creating a New Contact Model
70B
9. Be sure the library and optional preferences file are in the contact
model folder (as specified with Tools > Options > File Locations).
10. Start EDEM then select the required contact model category from the
Interaction pulldown in the Physics section.
11. Click the + drop-down list then select your new contact model.
For a detailed example, refer to Developing a Contact Model User Defined Library on
page 10.
X
Description
Type
getDetailsForProperty
Setup
getNumberOfRequiredProperties
Setup
getPreferenceFileName
Setup
isThreadSafe
Setup
setup
Setup
usesCustomProperties
Setup
starting
Simulation
calculateForce
Simulation
stopping
Simulation
UH
1. Create a new folder then copy the following header files from
src\Api\ContactModels and src\Api\Core into your project folder.
IPluginContactModel.h
PluginContactModelCore.h
IPluginContactModelV2_2_0.h
PluginConstants.h
Helpers.h
H
2. Create a file cohesion_prefs.txt in your working directory. Edit the file to contain the
lines:
particle:particle 4e5
particle:mill 6e5
This indicates a particle-particle cohesion with an energy density of 4e5 J/m3 and a
particle-mill cohesion of 6e5 J/m3.
10
#if !defined(ccohesionmodel_h)
#define ccohesionmodel_h
#include <string>
#include <fstream>
#include "IPluginContactModelV2_2_0.h"
using namespace std;
class CCohesionModel : public NApiCm::IPluginContactModelV2_2_0
{
public:
/**
* Constructor, does nothing
*/
CCohesionModel();
/**
* Destructor, does nothing
*/
virtual ~CCohesionModel();
/**
* Sets prefFileName to the empty string as this plugin has no
* configuration
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual void getPreferenceFileName(char
prefFileName[NApi::FILE_PATH_MAX_LENGTH]);
/*******
* Insert the rest of the code here
*******/
/**
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual bool getDetailsForProperty(
unsigned int
propertyIndex,
NApi::EPluginPropertyCategory
category,
char
name[NApi::CUSTOM_PROP_MAX_NAME_LENGTH],
NApi::EPluginPropertyDataTypes& dataType,
unsigned int&
numberOfElements,
NApi::EPluginPropertyUnitTypes& unitType);
/**
* Name of the preferences file to load bond information from
*/
static const std::string PREFS_FILE;
11
private:
double m_energyDensity;
};
#endif
GETCMINTERFACEVERSION()
int INTERFACE_VERSION_MAJOR = 0x02;
int INTERFACE_VERSION_MINOR = 0x02;
int INTERFACE_VERSION_PATCH = 0x00;
// This contact model assumes that the Physical and the Contact radius
// are the same
// The unit vector from element 1 to the contact point
CSimple3DPoint contactPoint = CSimple3DPoint(contactPointX, contactPointY,
contactPointZ);
CSimple3DVector unitCPVect
= contactPoint - CSimple3DPoint(elem1PosX,
elem1PosY, elem1PosZ);
unitCPVect.normalise();
// Cohesion
// R^2 - (R - d)^2
double nCohesiveFactor
= m_energyDensity;
double nRadiusOfOverlapSquared = 2 * elem1PhysicalCurvature * normalOverlap;
12
= PI * nRadiusOfOverlapSquared;
= unitCPVect * nCohesiveFactor * nArea;
13
1. Start EDEM then open a simulation that will use the new contact model. You can
download an example simulation (cohesion_input.dem) from the customer area of
the DEM Solutions website.
2. Load your new contact model. Select Tools > Options > File Locations > Contact
Models then navigate to the location of your newly created dll.
3. Select Particle to Particle from the Interaction pulldown in the Physics section.
4. Click the + button then select the new cohesion contact model.
5. If your contact model includes code similar to Hertz-Mindlin (in other words, code to
calculate base contact forces), remove the built-in Hertz-Mindlin (no slip) contact
model from the list.
6. Select Particle to Geometry from the Interaction pulldown in the Physics section.
7. Click the + button then select the cohesion contact model.
8. If your contact model includes code similar to Hertz-Mindlin (in other words, code to
calculate base contact forces), remove the built-in Hertz-Mindlin (no slip) contact
model from the list.
9. Click the Geometry tab.
10. Be sure the periodic boundary is enabled in the Y axis.
11. Select File > Save.
The particles have already been created in this simulation and the model has been
simulated until a steady state was achieved.
1. Click on the Simulator button.
2. Click the Start progress button to start processing the simulation.
14
Run through the simulation to verify the changing behavior of the particles over time.
0s to 1s: Simulation behavior has not changed significantly from steady state:
2s to 3s: Particle clumping occurs as the particles are thrown from the mill lifters:
4s to 5s: The particle cohesion is high enough to prevent the particles from separating in
the mill; the particles act as a single mass:
15
Plot some contact graphs to see how the contact behavior changes with the increasing
cohesion.
1. Click the Analyst button on the toolbar then click the Create Graph button.
2. Select the Line Graph tab then set the element and x-axis details as follows:
3. Click the Y-Axis tab then select Number of Contacts as the Attribute to plot:
16
The graph shows that the number of particles in contact with the geometry decreases
over time; the particle flow has change from individual particles that impact on the
geometry to a single mass that rolls in the mill. This single mass has reduced impact on
the mill geometry when compared to the individual particles.
17
18
Description
Type
getDetailsForProperty
Setup
getPreferenceFileName
Setup
isThreadSafe
Setup
setup
Setup
usesCustomProperties
Setup
starting
Simulation
getNumberOfRequiredProperties
externalForce
stopping
Setup
Simulation
Simulation
19
This section describes how to create a Particle Body Force UDL that applies a particle
body force to particles in a box. This is analogous of the drag force on particles from an
upwards-moving vertical jet of air translating below the box of particles. The box is
100mm x 100 m x 100 mm and is centered at (0,0,0). The box is half full with 460
spherical particles of 5mm radius. The UDL:
NOTE: This example uses Microsoft Visual C++ 2008 Express Edition to compile the
contact models. See http://www.microsoft.com/express/download/.
HU
UH
#if !defined(cforceexample_h)
#define cforceexample_h
#include "IPluginParticleBodyForceV2_1_0.h"
#include <string>
#include <fstream>
class CForceExample : public NApiPbf::IPluginParticleBodyForceV2_1_0
{
public:
/**
* Name of the preferences file to load information
*/
static const std::string PREFS_FILE;
/**
* Constructor, does nothing
*/
CForceExample();
/**
* Destructor, does nothing
*/
virtual ~CForceExample();
/**
* Retrieves the name of the config file used by the plugin.
*
* Implementation from IPluginParticleBodyForceV2_1_0
*/
virtual void getPreferenceFileName(char
prefFileName[NApi::FILE_PATH_MAX_LENGTH]);
/**
* Multithread
*
* Implementation from IPluginParticleBodyForceV2_1_0
*/
virtual bool isThreadSafe();
/*******
* Complete the rest of the code here
*******/
private:
double m_forceZ;
double m_velocity;
};
#endif
21
GETEFINTERFACEVERSION()
int INTERFACE_VERSION_MAJOR = 0x02;
int INTERFACE_VERSION_MINOR = 0x01;
int INTERFACE_VERSION_PATCH = 0x00;
Refer to the code extract below (the complete file is shown in Appendix A: Code
Used in Examples on page 39) which shows the implementation of the physics part
in the ECalculateResult exernalForce method. The external force operates in
the direction of the vertical (z) axis, decreasing with respect to the height of the
particles. It translates in the x direction over time.
X
double height;
double startpoz1;
double startpoz2;
//Translate the force in the x-axis
height = 1.0 + (1000 * (posZ + 50e-3));
startpoz1 = -0.03 + ((time - 1.0) * m_velocity);
startpoz2 = 0.0 + ((time - 1.0) * m_velocity);
if(posX >= startpoz1 && posX <= startpoz2 && posY >= -0.015 && posY <=
0.015)
{
//Decreases the force with height
calculatedForceZ = (m_forceZ / height);
}
return eSuccess;
22
1. Start EDEM then open a simulation that will use the new particle body force. You can
download an example simulation from the DEM Solutions website.
2. Load your new particle body. Select Tools > Options > File Locations > Particle Body
Force then navigate to the location of your newly created dll.
3. Select Particle Body Force from the Interaction pulldown in the Physics section.
4. Click the + button then select your custom Particle Body Force UDL.
5. Select File > Save.
23
8. Be sure the library and optional preferences file are in the factories folder (as
specified with Tools > Options > File Locations).
9. Start EDEM then switch to the Factories tab. Click the Import button then
select the new factory from the Import Factory popup. Click OK.
24
Description
Type
getDetailsForProperty
Setup
getNumberOfRequiredProperties
Setup
getPreferenceFileName
Setup
setup
Setup
usesCustomProperties
Setup
starting
Simulation
createParticle
Simulation
stopping
Simulation
25
This section describes how to create a new Particle Factory that generates snooker balls
and takes a shot on a snooker table.
For MS Windows, this example uses Microsoft Visual C++ 2008 Express Edition to
compile the factory. See http://www.microsoft.com/express/download/. For Linux, this
example uses the standard GNU Compiler Collection (GCC).
HU
UH
Create a new folder then copy the following header files from src\Api\Factories
and src\Api\Core into your project folder.
IPluginParticleFactory.h
PluginParticleFactoryCore.h
IPluginParticleFactoryV2_0_0.h
PluginConstants.h
Helpers.h
H
#if !defined(csnooker_h)
#define csnooker_h
#include "IPluginParticleFactoryV2_0_0.h"
class CSnooker : public NApiFactory::IPluginParticleFactoryV2_0_0
{
public:
/**
* Constructor, does nothing
*/
CSnooker();
26
/**
* Destructor, does nothing
*/
virtual ~CSnooker();
// Implementation of method from IPluginParticleFactory_V2_0_0
virtual NApi::ECalculateResult createParticle(
double time,
bool&
particleCreated,
bool&
additionalParticleRequired,
char
type[NApi::API_BASIC_STRING_LENGTH],
double& scale,
double& posX,
double& posY,
double& posZ,
double& velX,
double& velY,
double& velZ,
double& angVelX,
double& angVelY,
double& angVelZ,
double orientation[9],
NApiCore::ICustomPropertyDataApi_1_0*
propData);
private:
/**
* Number of particles created so far
*/
unsigned int m_numberCreated;
};
#endif
27
28
29
30
1. Start EDEM then open a simulation that will use the new factory. You can use the
supplied Snooker_Factory.dem simulation in the examples folder.
2. Switch to the Factories tab.
3. Delete the in-built libSnooker factory then click the Import button.
4. Select your new Snooker library then click OK.
5. Select File > Save.
31
Custom Properties
25
With custom properties you can dynamically define custom attributes to use in your
simulation. Custom properties store additional attributes (for example, contact duration)
for further post-processing. Custom properties can be graphed and exported just like any
other attribute. When loaded, contact models, particle body forces, and coupled
applications can all use and share data about these new custom properties.
Custom Property Category
Contact
Geometry
Particle
Simulation
Example
Contact duration, highest force during contact
Cumulative impact force, wear
Residence time, temperature
Stickiness of a surface
A custom property is a named group of one or more numeric (double precision floating
point) values with an associated unit type. You can define any number of custom
properties. Each property has the following attributes:
Attribute
Name
State
Storage Type
Number of
Elements
Units
Values
Description
The unique name of the custom property.
When properties are first added, they are defined as tentative.
Tentative properties have not yet had space allocated for them.
When simulation starts, tentative properties are finalized and
space allocated for them.
The properties data type (currently always a C++ double).
Indicates the number of elements. Usually a property has one
element. A property with a position in 3D space would have three
elements (X, Y, and Z).
The unit type, for example length, temperature, charge, velocity
etc. If the property has no unit, this is set to None.
Indicates the propertys initial values. Double-click to change the
value (provided the custom property is either still tentative or is a
simulation property). For custom simulation properties, the Values
area also indicates the value for the current timestep.
Any UDL that uses a custom property with the same name and category will share the
propertys value(s) and have the ability to manipulate them, provided the two UDL
definitions (name, units, number of elements and data type) are identical. If two UDLs
have differing definitions then the first UDL only will load. The second UDL will not load
and an error is given.
32
Register each custom property you want to use. For each custom property
category (contact, particle etc.), use the methods
getNumberOfRequiredProperties() and getDetailsForProperty() to indicate the
name, number of elements and unit type of each property. When the UDL is
loaded, EDEM calls getNumberOfRequiredProperties() once for each category.
getDetailsForProperty() is called once for each property you are registering.
When EDEM starts processing, tentative properties are finalized and EDEM allocates
storage for each new property.
This section describes how to develop the custom particle property called Residence
Time. The property measures how long a particle has existed in a simulation.
NOTE: This example uses Microsoft Visual C++ 2008 Express Edition to compile the
contact models. See http://www.microsoft.com/express/download/.
HU
UH
33
propertyIndex,
category,
dataType,
numberOfElements,
unitType)
34
Define the externalForce() method to specify the custom particle property added to
particles each time step. To track the residence time, add the timestep to the current
residence time value:
// Cache pointers to the custom properties we wish to use
double* residenceTimeDelta =
particlePropData->getDelta(RESIDENCE_TIME_PROPERTY.c_str());
// update the residence time for this particle by adding the time step
// to the current value
*residenceTimeDelta += timestep;
return eSuccess;
35
1. Start EDEM then open a simulation that will use the new custom particle property.
You can download an example simulation from the DEM Solutions website.
2. Load your new particle body. Select Tools > Options > File Locations > Particle Body
Force then navigate to the location of your newly created dll.
3. Select Particle Body Force from the Interaction pulldown in the Physics section.
4. Click the + button then select ResidenceTime.dll.
5. To verify the custom particle property, select Tools > Particle. The Particle Properties
window is displayed:
6. Check Residence Time is listed as a tentative property. The custom property will
move to the finalized section when you start the simulation.
36
Glossary
8B
A
API: Application Programming Interface. An API is an interface defining how a program
requests services from libraries and/or operating systems. The API determines
the vocabulary and calling conventions to use the services. It usually includes
specifications for routines, data structures, object classes and protocols to
communicate between the requesting software and the library.
C
Class: A class is a programming language construct used to create objects. It describes
the state and behavior that the created objects all share. An object created by a
class is an instance of the class, and the class that created that instance can be
considered as the type of that object.
Constructor: a constructor is a special method which puts the object's members into a
valid state. It is a block of statements called when an object is created, either
when it is declared or dynamically constructed.
D
Data Field: A place where data is stored.
Data Type: A data type (or datatype) is a set of values and the operations on those
values.
Destructor: A destructor is a method which is automatically invoked when the object is
destroyed. Its main purpose is to clean up and to free the resources which were
acquired by the object along its life cycle and unlink it from other objects or
resources invalidating any references in the process.
F
Function: See Method.
H
Header File: A header file (or include file) is a file that a compiler automatically includes
when processing another source file. Typically, the inclusion of header files are
specified via compiler directives at the beginning (or head) of the other source
file.
L
Library: A library is a collection of classes used to develop software. Libraries contain
code and data that provide services to independent programs. This allows the
sharing and changing of code and data in a modular fashion. Some executables
37
M
Makefile: Make is a utility for automatically building executable programs and libraries
from source code. Files called makefiles specify how to derive the target program
from each of its dependencies.
Method: A method (or procedure, function, or subroutine) is a portion of code within a
larger program which performs a specific task and is relatively independent of the
remaining code.
Multithreaded: See Thread.
N
Namespace: A namespace is a context for identifiers. It groups related methods
together.
Namespace Member: A method that belongs to a particular namespace.
O
Object: An object is a data structure consisting of data fields and methods that can
manipulate those fields. Typically, when calling a method from some object, the
object itself should be passed as a parameter to the method.
S
Shared Library: See Library.
T
Thread: A thread results from a fork of a computer program into two or more
concurrently running tasks. Multiple threads can exist within the same process
and share resources such as memory, while different processes do not share
these resources.
U
User Defined Library (UDL): A computer program that interacts with a host application.
Also known as a plugin.
38
CCohesionModel.h
45B
The following code is used in Developing a Plugin Contact Model on page 10.
X
#if !defined(ccohesionmodel_h)
#define ccohesionmodel_h
#include <string>
#include <fstream>
#include "IPluginContactModelV2_2_0.h"
using namespace std;
/**
* This class provides an implementation of IPluginContactModelV2_2_0
* That adds performs hertz mindlin contact force calculation
*
* NOTE: This version of the hertz-mindlin code is provided only
* as an example of how to create a contact model plugin and is not
* updated on a regular basis.
*/
class CCohesionModel : public NApiCm::IPluginContactModelV2_2_0
{
public:
/**
* Constructor, does nothing
*/
CCohesionModel();
/**
* Destructor, does nothing
*/
virtual ~CCohesionModel();
/**
* Sets prefFileName to the empty string as this plugin has no
* configuration
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual void getPreferenceFileName(char prefFileName[NApi::FILE_PATH_MAX_LENGTH]);
/**
* Returns true to indicate plugin is thread safe
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual bool isThreadSafe();
/**
* Returns true to indicate the plugin uses custom properties
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual bool usesCustomProperties();
/**
* Does nothing
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual bool setup(NApiCore::IApiManager_1_0& apiManager,
const char prefFile[]);
39
/**
* Does nothing
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual void stopping(NApiCore::IApiManager_1_0& apiManager);
/**
*
*
* Implementation of method from IPluginContactModelV2_2_0
*/
virtual NApi::ECalculateResult calculateForce(
double
time,
double
timestep,
int
elem1Id,
const char
elem1Type[],
double
elem1Mass,
double
elem1ShearMod,
double
elem1Poisson,
double
elem1ContactCurvature,
double
elem1PhysicalCurvature,
double
elem1PosX,
double
elem1PosY,
double
elem1PosZ,
double
elem1ComX,
double
elem1ComY,
double
elem1ComZ,
double
elem1VelX,
double
elem1VelY,
double
elem1VelZ,
double
elem1AngVelX,
double
elem1AngVelY,
double
elem1AngVelZ,
double
elem1Charge,
double
elem1WorkFunction,
const double elem1Orientation[9],
NApiCore::ICustomPropertyDataApi_1_0*
elem1PropData,
bool
elem2IsSurf,
int
elem2Id,
const char
elem2Type[],
double
elem2Mass,
double
elem2Area,
double
elem2ShearMod,
double
elem2Poisson,
double
elem2ContactCurvature,
double
elem2PhysicalCurvature,
double
elem2PosX,
double
elem2PosY,
double
elem2PosZ,
double
elem2ComX,
double
elem2ComY,
double
elem2ComZ,
double
elem2VelX,
double
elem2VelY,
double
elem2VelZ,
double
elem2AngVelX,
double
elem2AngVelY,
double
elem2AngVelZ,
double
elem2Charge,
double
elem2WorkFunction,
const double elem2Orientation[9],
40
41
CCohesionModel.cpp
46B
The following code is used in Developing a Plugin Contact Model on page 10.
X
#include "CCohesionModel.h"
#include "Helpers.h"
using namespace NApi;
using namespace NApiCore;
using namespace NApiCm;
const string CCohesionModel::PREFS_FILE = "cohesion_prefs.txt";
CCohesionModel::CCohesionModel()
{
;
}
CCohesionModel::~CCohesionModel()
{
;
}
void CCohesionModel::getPreferenceFileName(char prefFileName[FILE_PATH_MAX_LENGTH])
{
// Copy in pref file name
strcpy(prefFileName, PREFS_FILE.c_str());
}
bool CCohesionModel::isThreadSafe()
{
// thread safe
return true;
}
bool CCohesionModel::usesCustomProperties()
{
// Does not use custom properties
return false;
}
bool CCohesionModel::setup(NApiCore::IApiManager_1_0& apiManager,
const char prefFile[])
{
//Read in the preference file
ifstream prefsFile(prefFile);
if(!prefsFile)
{
return false;
}
else
{
while (prefsFile)
{
prefsFile >> m_energyDensity;
}
}
return true;
}
bool CCohesionModel::starting(NApiCore::IApiManager_1_0& apiManager)
{
return true;
}
void CCohesionModel::stopping(NApiCore::IApiManager_1_0& apiManager)
{
;
42
43
calculatedUnsymNormalForceX,
calculatedUnsymNormalForceY,
calculatedUnsymNormalForceZ,
calculatedTangentialForceX,
calculatedTangentialForceY,
calculatedTangentialForceZ,
calculatedUnsymTangentialForceX,
calculatedUnsymTangentialForceY,
calculatedUnsymTangentialForceZ,
calculatedElem1AdditionalTorqueX,
calculatedElem1AdditionalTorqueY,
calculatedElem1AdditionalTorqueZ,
calculatedElem1UnsymAdditionalTorqueX,
calculatedElem1UnsymAdditionalTorqueY,
calculatedElem1UnsymAdditionalTorqueZ,
calculatedElem2AdditionalTorqueX,
calculatedElem2AdditionalTorqueY,
calculatedElem2AdditionalTorqueZ,
calculatedElem2UnsymAdditionalTorqueX,
calculatedElem2UnsymAdditionalTorqueY,
calculatedElem2UnsymAdditionalTorqueZ,
calculatedChargeMovedToElem1)
{
// This contact model assumes that the Physical and the Contact radius
// are the same
// The unit vector from element 1 to the contact point
CSimple3DPoint contactPoint = CSimple3DPoint(contactPointX, contactPointY,
contactPointZ);
CSimple3DVector unitCPVect
= contactPoint - CSimple3DPoint(elem1PosX, elem1PosY,
elem1PosZ);
unitCPVect.normalise();
// Cohesion
// R^2 - (R - d)^2
double nCohesiveFactor
double nRadiusOfOverlapSquared
double nArea
CSimple3DVector F_cohesive
=
=
=
=
m_energyDensity;
2 * elem1PhysicalCurvature * normalOverlap;
PI * nRadiusOfOverlapSquared;
unitCPVect * nCohesiveFactor * nArea;
calculatedNormalForceX = F_cohesive.dx();
calculatedNormalForceY = F_cohesive.dy();
calculatedNormalForceZ = F_cohesive.dz();
return eSuccess;
}
propertyIndex,
category,
char
name[NApi::CUSTOM_PROP_MAX_NAME_LENGTH],
NApi::EPluginPropertyDataTypes& dataType,
unsigned int&
numberOfElements,
NApi::EPluginPropertyUnitTypes& unitType)
{
return false;
}
44
CForceExample.h
47B
The following code is used in Developing a Plugin Particle Body Force on page 20.
X
#if !defined(cforceexample_h)
#define cforceexample_h
#include "IPluginParticleBodyForceV2_1_0.h"
#include <string>
#include <fstream>
class CForceExample : public NApiPbf::IPluginParticleBodyForceV2_1_0
{
public:
/**
* Name of the preferences file to load information
*/
static const std::string PREFS_FILE;
/**
* Constructor, does nothing
*/
CForceExample();
/**
* Destructor, does nothing
*/
virtual ~CForceExample();
/**
* Retrieves the name of the config file used by the plugin.
*
* Implementation from IPluginParticleBodyForceV2_1_0
*/
virtual void getPreferenceFileName(char
prefFileName[NApi::FILE_PATH_MAX_LENGTH]);
/**
* Multithread
*
* Implementation from IPluginParticleBodyForceV2_1_0
*/
virtual bool isThreadSafe();
/**
* If the plugin implementation wishes to register or receive custom
* property data then this method must return true.
*
* Implementation from IPluginParticleBodyForceV2_1_0
*/
virtual bool usesCustomProperties();
/**
* Initialises the plugin by giving it a chance to read any config
* files.
*
* Implementation from IPluginParticleBodyForceV2_1_0
*/
virtual bool setup(NApiCore::IApiManager_1_0& apiManager,
const char prefFile[]);
/**
* Called to indicate processing is about to begin.
*
* Implementation from IPluginParticleBodyForceV2_1_0
*/
virtual bool starting(NApiCore::IApiManager_1_0& apiManager);
/**
45
46
CForceExample.cpp
48B
The following code is used in Developing a Plugin Particle Body Force on page 20.
X
#include "CForceExample.h"
#include "Helpers.h"
using
using
using
using
namespace
namespace
namespace
namespace
NApiPbf;
NApi;
NApiCore;
std;
47
propertyIndex,
category,
dataType,
numberOfElements,
unitType)
48
Index
10B
API, 37
calculateForce, 9, 25
Class, 37
Cohesion Contact Model, 10, 14
Compiler, 13, 23, 31, 35
Constructor, 37
Custom Properties, 32, 33
Data Field, 37
Data Type, 37
Destructor, 37
externalForce, 19, 35
Force, 20, 23, 33, 36
Function, 37
getDetailsForProperty, 9, 19, 25
getNumberOfRequiredProperties, 9, 19,
25
getPreferenceFileName, 9, 19, 25
Header File, 37
Hertz-Mindlin, 14
49