MercuryDPM  Trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
RandomClusterInsertionBoundary.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2020, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
27 
28 
29 
30 
31 
32 
37 {
38  logger(DEBUG, "RandomClusterInsertionBoundary::RandomClusterInsertionBoundary() finished");
39 }
40 
46 
47  logger(DEBUG, "RandomClusterInsertionBoundary::RandomClusterInsertionBoundary() finished");
48 }
49 
54 = default;
55 
61 {
62 #ifdef DEBUG_CONSTRUCTOR
63  std::cout << "BaseClusterInsertionBoundary::copy() const finished" << std::endl;
64 #endif
65  return new RandomClusterInsertionBoundary(*this);
66 }
67 
85 void RandomClusterInsertionBoundary::set(BaseParticle *particleToCopy, unsigned int maxFailed, Vec3D posMin, Vec3D posMax,
86  Vec3D velMin, Vec3D velMax, Mdouble radMin, Mdouble radMax,
87  Mdouble rMicroParticle)
88 {
89  setParticleToCopy(particleToCopy);
90  setRadiusRange(radMin, radMax);
91 
92  setMaxFailed(maxFailed);
93  setGeometry(posMin, posMax, velMin, velMax);
94 
95  setRadiusMicroParticle(rMicroParticle);
96 }
97 
98 void RandomClusterInsertionBoundary::set(BaseParticle &particleToCopy, unsigned int maxFailed, Vec3D posMin, Vec3D posMax,
99  Vec3D velMin, Vec3D velMax, Mdouble radMin, Mdouble radMax,
100  Mdouble rMicroParticle)
101 {
102  set(&particleToCopy, maxFailed, posMin, posMax, velMin, velMax, radMin, radMax, rMicroParticle);
103 }
104 
126 void RandomClusterInsertionBoundary::set(BaseParticle *particleToCopy, unsigned int maxFailed, Vec3D posMin, Vec3D posMax,
127  unsigned int nParticlesPerCluster, Vec3D velMin, Vec3D velMax,
128  Mdouble radMin, Mdouble radMax)
129 {
130  setParticleToCopy(particleToCopy);
131  setRadiusRange(radMin, radMax);
132 
133  setMaxFailed(maxFailed);
134  setGeometry(posMin, posMax, velMin, velMax);
135 
136  setNumberOfParticlesPerCluster(nParticlesPerCluster);
137 }
138 
139 void RandomClusterInsertionBoundary::set(BaseParticle &particleToCopy, unsigned int maxFailed, Vec3D posMin, Vec3D posMax,
140  unsigned int nParticlesPerCluster, Vec3D velMin, Vec3D velMax,
141  Mdouble radMin, Mdouble radMax)
142 {
143  set(&particleToCopy, maxFailed, posMin, posMax, nParticlesPerCluster, velMin, velMax, radMin, radMax);
144 }
145 
147 {
148  if (nParticlesPeCluster <= 0)
149  logger(ERROR, "The number of particles for a single cluster must be greater than zero. nParticlesPeCluster = %", nParticlesPeCluster);
150  else {
151  nParticles_ = nParticlesPeCluster;
153  }
154 }
155 
157 {
158  logger(VERBOSE, "In RandomClusterInsertionBoundary::checkBoundaryBeforeTimeStep\n");
159 
160  if (!isActivated_)
161  return;
162 
163  /* Each time step, the InsertionBoundary attempts to fill up a region with
164  * clusters.
165  *
166  * It first calls generateParticle() to get a randomised particle, subject
167  * to a specified distribution over sizes and species. (The basic class
168  * supports size dispersity only but PolydisperseInsertionBoundary will
169  * support species dispersity.)
170  * Then it repeatedly calls placeParticle(), which gives the cluster a
171  * random location (and possibly velocity) in a specified,
172  * geometry-dependent bound. Each time, it checks whether the new cluster
173  * would have an interaction with another cluster or a wall.
174  *
175  * If it manages to do that within maxFailed_ tries, then:
176  * * the new cluster is created and inserted,
177  * * the failure counter is reset, and
178  * the processes is repeated with a new generateParticle().
179  *
180  * Otherwise, the processes terminates for this time step.
181  * */
182 
183  // Keep count of how many successive times we have failed to place a new
184  // particle.
185  unsigned int failed = 0;
186  while (failed <= maxFailed_ && insertParticle(md->getNextTime())) // 'generating' loop
187  {
188  /* Generate random *intrinsic* properties for the new particle. */
189  logger(VERBOSE, "about to call generateParticle\n");
190 
191  auto p0 = generateParticle(md->random);
192  logger(VERBOSE, "generated a particle with intrinsics %", p0);
193 
194  while (true) // 'placing' loop
195  {
196  /* Generate extrinsic properties (position and velocity) for this
197  * new particle. */
198 
199  placeParticle(p0, md->random);
200 
201  logger(VERBOSE, "attempting to place particle at %, vel %", p0->getPosition(), p0->getVelocity());
202 
203 #ifdef MERCURY_USE_MPI
204  /* Communicate the new particle's properties by setHandler (note
205  * that this doesn't actually add the particle to the handler). */
206  if (NUMBER_OF_PROCESSORS > 1)
207  {
208  MPIParticle particle;
209  // //Every domain generates a particle (to get the species right etc)
210 
211  //Send particle data from root to other processors to sync the particle properties
212  if (PROCESSOR_ID == 0)
213  {
214  particle = copyDataFromParticleToMPIParticle(p0);
215  }
216 
218 
219  //Process the received data
220  if (PROCESSOR_ID != 0)
221  {
222  copyDataFromMPIParticleToParticle(&particle, p0, &(md->particleHandler));
223  }
224  }
225 #endif
226  p0->setHandler(&md->particleHandler);
227 
228  /* Check whether the particle has any interactions. */
229  if (md->checkParticleForInteraction(*p0))
230  {
231  BaseCluster cluster;
232  if(getRandomised())
233  cluster.random.randomise();
239  cluster.doCdatOutput(isCdatOutputOn_);
241  cluster.doAmatOutput(isAmatOutputOn_);
243  cluster.doVtkOutput(isVtkOutputOn_);
246  cluster.doEneOutput(isEneOutputOn_);
250  else
252  cluster.setRadiusCluster(p0->getRadius());
253  cluster.setPosition(p0->getPosition());
254  cluster.setVelocity(p0->getVelocity());
255  cluster.setParticleSpecies(
256  dynamic_cast<LinearPlasticViscoelasticFrictionSpecies*>(
257  md->speciesHandler.getObject(p0->getIndSpecies())));
258 #ifdef MERCURY_USE_MPI
259  cluster.setNumberOfDomains(md->getNumberOfDomains());
260  cluster.setDomain(md->getMin(), md->getMax());
262 #endif
263  cluster.solve();
264 
265  md->importParticlesAs( cluster.particleHandler, cluster.interactionHandler, p0->getSpecies() );
266 
267  failed = 0;
268 
269  // Number of cluster inserted
271  // Total number of particles inserted
273  // This is the total mass composed by every single particle (not cluster!) inserted
275  // This is the total volume composed by every single particle (not cluster!) inserted
277  logger(VERBOSE, "successfully placed a particle %, with position: % after % fails.", p0,
278  p0->getPosition(), failed);
279 
280  /* JMFT: The generateParticle() routine allocates memory, so we should
281  * free it here. (Don't worry, the particle will have been copied to the
282  * particleHandler by this point iff we want it.) */
283  delete p0;
284 
285  break; // out of the 'placing' loop
286  }
287  else
288  {
289  failed++;
290  logger(VERBOSE, "failed to place a cluster; have failed % times", failed);
291  }
292 
293  if (failed > maxFailed_)
294  {
295  logger(VERBOSE, "failed too many times; giving up");
296  break; // out of the 'placing' loop (and will leave the 'generating' loop too
297  }
298  }
299  logger(VERBOSE, "failed % times, so breaking out of InsertionBoundary loop for this timestep.", failed);
300  }
301  // logger(INFO, "volumeInserted_ = %", volumeInserted_);
302 }
303 
304 
307 {
308  if(getRandomised())
309  random.randomise();
310  Vec3D pos, vel;
311  pos.X = random.getRandomNumber(posMin_.X, posMax_.X);
312  pos.Y = random.getRandomNumber(posMin_.Y, posMax_.Y);
313  pos.Z = random.getRandomNumber(posMin_.Z, posMax_.Z);
314  vel.X = random.getRandomNumber(velMin_.X, velMax_.X);
315  vel.Y = random.getRandomNumber(velMin_.Y, velMax_.Y);
316  vel.Z = random.getRandomNumber(velMin_.Z, velMax_.Z);
317  p->setPosition(pos);
318  p->setVelocity(vel);
319 }
320 
326 {
327  return "RandomClusterInsertionBoundary";
328 }
Mdouble getVolume() const
void setCollisionTimeOverTimeStep(Mdouble cTOTS)
This sets the collisionTimeOverTimeStep number (which is the ratio between collision time and time st...
Definition: BaseCluster.cc:76
void solve()
The work horse of the code.
Definition: DPMBase.cc:3968
static MPIContainer & Instance()
fetch the instance to be used for communication
Definition: MpiContainer.h:130
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:72
Mdouble X
the vector components
Definition: Vector.h:65
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
unsigned int getSize() const
Gets the size of the particleHandler (including mpi and periodic particles)
Definition: BaseHandler.h:655
void setNumberOfInternalStructurePoints(int gL)
This sets the value of the number of particles used to compute the internal structure.
Definition: BaseCluster.cc:217
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
Definition: GeneralDefine.h:34
void doOverlOutput(bool iOOO)
This sets the bool variable that defines whether the cluster overlap output will be written or not...
Definition: BaseCluster.cc:292
RandomClusterInsertionBoundary * copy() const override
Creates a copy on the heap and returns a pointer.
void doIntStrucOutput(bool iISOO)
This sets the bool variable that defines whether the cluster internal structure output will be writte...
Definition: BaseCluster.cc:320
void doAmatOutput(bool iAOO)
This sets the bool variable that defines whether the cluster adjacency matrix output will be written ...
Definition: BaseCluster.cc:306
void doEneOutput(bool isEneOutputOn)
This sets the bool variable that defines whether the cluster ene output will be written or not...
Definition: BaseCluster.cc:376
Vec3D getMin() const
Definition: DPMBase.h:623
void setSizeDispersityParticle(Mdouble sDP)
This sets the value of particles' dispersity in size.
Definition: BaseCluster.cc:117
bool insertParticle(Mdouble time)
void setMaxFailed(unsigned int maxFailed)
Sets the number of times that the wall may fail to insert a particle.
void checkBoundaryBeforeTimeStep(DPMBase *md) override
inserts cluster, if no interactions are detected.
Mdouble getRandomNumber()
This is a random generating routine can be used for initial positions.
Definition: RNG.cc:143
bool getRandomised()
this returns a bool which indicates if the process is randomised (true) or not (false).
Mdouble getMass() const
unsigned int maxFailed_
Number of times that the wall may fail to insert a particle.
void doCdatOutput(bool iCOO)
This sets the bool variable that defines whether the cluster data output will be written or not...
Definition: BaseCluster.cc:278
void randomise()
sets the random variables such that they differ for each run
Definition: RNG.cc:98
void setParticleToCopy(BaseParticle *particleToCopy)
Sets the particle that will be inserted through the insertion boundary.
void copyDataFromMPIParticleToParticle(MPIParticle *bP, BaseParticle *p, ParticleHandler *particleHandler)
Copies data from an MPIParticle class to a BaseParticle and sets the particleHandler and species...
void setVelocity(Vec3D v)
This sets the value of velocity after creation.
Definition: BaseCluster.cc:264
void setDomain(const Vec3D &min, const Vec3D &max)
Sets the minimum coordinates of the problem domain.
Definition: DPMBase.cc:1059
This is a class that generates random numbers i.e. named the Random Number Generator (RNG)...
Definition: RNG.h:52
void placeParticle(BaseParticle *p, RNG &random) override
sets random position and velocity for the cluster.
void setRadiusMicroParticle(Mdouble rMP)
this sets the radius of the micro particle composing the cluster.
MPIParticle copyDataFromParticleToMPIParticle(BaseParticle *p)
Copies data from a SuperQuadricParticle to an MPIParticle class and returns this. ...
virtual bool checkParticleForInteraction(const BaseParticle &P)
Checks whether a particle P has any interaction with walls or other particles.
Definition: DPMBase.cc:4588
unsigned getNextGroupId()
Should be called each time you assign a groupId. Returns the value of nextGroupId_ and increases next...
Definition: BaseHandler.h:293
Mdouble volumeInserted_
Total volume of particles inserted.
void setVelocityDampingModulus(Mdouble vDM)
This sets the value of the velocity damping modulus.
Definition: BaseCluster.cc:200
void setRadiusRange(Mdouble radMin, Mdouble radMax)
Sets the range of cluster radius that may be generated.
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created...
Definition: DPMBase.h:1329
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:613
void doVtkOutput(bool iVOO)
This sets the bool variable that defines whether the cluster vtk output will be written or not...
Definition: BaseCluster.cc:334
Data class to send a particle over MPI.
Definition: MpiDataClass.h:81
void setNumberOfParticlesPerCluster(unsigned int nParticlesPeCluster)
sets the number of particles per cluster
void doFStatOutput(bool isfStatOutputOn)
This sets the bool variable that defines whether the cluster fStat output will be written or not...
Definition: BaseCluster.cc:362
#define PROCESSOR_ID
Definition: GeneralDefine.h:63
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddObject(const U &object)
Creates a copy of a Object and adds it to the BaseHandler.
Definition: BaseHandler.h:379
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1319
InteractionHandler interactionHandler
An object of the class InteractionHandler.
Definition: DPMBase.h:1359
~RandomClusterInsertionBoundary() override
Destructor: default destructor.
Vec3D getMax() const
Definition: DPMBase.h:629
#define NUMBER_OF_PROCESSORS
For the MPI communication routines this quantity is often required. defining this macro makes the cod...
Definition: GeneralDefine.h:62
Mdouble Y
Definition: Vector.h:65
RNG random
This is a random generator, often used for setting up the initial conditions etc...
Definition: DPMBase.h:1324
std::enable_if< std::is_scalar< T >::value, void >::type broadcast(T &t, int fromProcessor=0)
Broadcasts a scalar from the root to all other processors.
Definition: MpiContainer.h:429
void setGeometry(Vec3D posMin, Vec3D posMax, Vec3D velMin, Vec3D velMax)
Sets the geometry (position and velocity distribution) of the ClusterInsertionBoundary.
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
void setNumberOfParticles(int nP)
This sets the value of the number of particles in the cluster.
Definition: BaseCluster.cc:134
std::vector< unsigned > getNumberOfDomains()
returns the number of domains
Definition: DPMBase.cc:5025
std::string getName() const override
Returns the name of the object.
RandomClusterInsertionBoundary()
Constructor: inherits from BaseClusterInsertionBoundary constructor.
void setParticleSpecies(LinearPlasticViscoelasticFrictionSpecies *particleSpecies)
This sets the species of the particle.
Definition: BaseCluster.cc:250
virtual BaseParticle * generateParticle(RNG &random)
Virtual function that generates the intrinsic properties (species, radius) of one particle...
void importParticlesAs(ParticleHandler &particleHandler, InteractionHandler &interactionHandler, const ParticleSpecies *species)
Copies particles, interactions assigning species from a local simulation to a global one...
Definition: DPMBase.cc:4737
Mdouble getNextTime() const
Returns the current simulation time.
Definition: DPMBase.cc:805
void setEnergyRatioTolerance(Mdouble eRT)
This sets the value of the value of the energy ratio threshold under which the process can be conside...
Definition: BaseCluster.cc:234
void doRestartOutput(bool isRestartOutputOn)
This sets the bool variable that defines whether the cluster restart output will be written or not...
Definition: BaseCluster.cc:348
void setNumberOfDomains(std::vector< unsigned > direction)
Sets the number of domains in x-,y- and z-direction. Required for parallel computations.
Definition: DPMBase.cc:4958
unsigned int numberOfParticlesInserted_
Number of particles that are already inserted.
Definition: Vector.h:49
void setRadiusParticle(Mdouble rP)
This sets the value of particles' radius if there's no dispersity in size.
Definition: BaseCluster.cc:97
Mdouble Z
Definition: Vector.h:65
Mdouble massInserted_
Total mass of particles inserted.
void set(BaseParticle *particleToCopy, unsigned int maxFailed, Vec3D posMin, Vec3D posMax, Vec3D velMin, Vec3D velMax, Mdouble radMin, Mdouble radMax, Mdouble rMicroParticle)
Sets the properties of the ClusterInsertionBoundary.
void setPosition(Vec3D p)
This sets the value of position_, which is the position in which the cluster will be inserted...
Definition: BaseCluster.cc:60
void setClusterId(unsigned int iC)
This sets the value of the cluster ID.
Definition: BaseCluster.cc:183
void setRadiusCluster(Mdouble rCR)
This sets the desired value of the cluster radius (there is no getter of this value, but there is a getter of the actual mean cluster radius obtained, getMeanClusterRadius)
Definition: BaseCluster.cc:149
bool isActivated_
The InsertionBoundary is activated by default. If the InsertionBoundary is deactivated, then it introduces no particles (useful for trying to maintain a certain insertion rate).