MercuryDPM  Trunk
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
PolydisperseInsertionBoundary.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 #include "Particles/BaseParticle.h"
28 #include "Math/RNG.h"
29 //#include <cassert>
30 
35 /* Constructor */
37 {
38  logger(INFO, "In PolydisperseInsertionBoundary constructor");
39  /* std::vector does all the memory allocation for you.
40  * By default, these are vectors of zero length. */
41  logger(INFO, "About to leave PolydisperseInsertionBoundary copy constructor");
42 }
43 
44 /* Copy constructor */
46  : InsertionBoundary(other)
47 {
48  /* The new PolydisperseInsertionBoundary's generanda_ vector should point to
49  * its own copies of each of the generanda_, so we need to copy those
50  * across. */
51  for (int i = 0; i < generanda_.size(); i++)
52  generanda_[i] = other.generanda_[i]->copy();
53 
54  posMin_ = other.posMin_;
55  posMax_ = other.posMax_;
56  velMin_ = other.velMin_;
57  velMax_ = other.velMax_;
63 }
64 
65 /* Destructor */
67 {
68  // JMFT: Do we need to delete the elements of generanda_?
69  for (auto p : generanda_)
70 
71  delete p;
72 }
73 
75 {
76 #ifdef DEBUG_CONSTRUCTOR
77  logger(INFO, "PolydisperseInsertionBoundary::copy() const finished");
78 #endif
79  return new PolydisperseInsertionBoundary(*this);
80 }
81 
82 void PolydisperseInsertionBoundary::setGeometry(int maxFailed, Vec3D posMin, Vec3D posMax, Vec3D velMin, Vec3D velMax)
83 {
84  setMaxFailed(maxFailed);
85  posMin_ = posMin;
86  posMax_ = posMax;
87  velMin_ = velMin;
88  velMax_ = velMax;
89 }
90 
91 void PolydisperseInsertionBoundary::addGenerandum(BaseParticle* generandum, double probability, double sizeDispersity)
92 {
93  // Give the PolydisperseInsertionBoundary its own copy of the generandum.
94  generanda_.push_back(generandum->copy());
95  probabilitates_.push_back(probability);
96  sizeDispersities_.push_back(sizeDispersity);
97  numbersInserted_.push_back(0);
98  massesInserted_.push_back(0);
99  volumesInserted_.push_back(0);
100  logger(INFO, "PolydisperseInsertionBoundary: added a new generandum, now have %. New generandum has weighting %",
101  generanda_.size(), probability);
102 }
103 
104 
105 void PolydisperseInsertionBoundary::setGenerandum(unsigned int spec, BaseParticle* generandum, double probability,
106  double sizeDispersity)
107 {
108  if (spec < generanda_.size())
109  logger(INFO, "Setting the %-th species of a PolydisperseInsertionBoundary that so far has % species",
110  spec, generanda_.size());
111  else
112  logger(ERROR,
113  "Setting the %-th species of a PolydiserseInsertionBoundary with only % species is illegal. Use addGenerandum instead.",
114  spec, generanda_.size());
115 
116  if (probability == 0)
117  logger(WARN, "PolydisperseInsertionBoundary: Are you sure you want to set the probability to be 0?");
118 
119  generanda_[spec] = generandum->copy();
120  probabilitates_[spec] = probability;
121  sizeDispersities_[spec] = sizeDispersity;
122 
123  // Reset the counters for number, mass and volume
124  numbersInserted_[spec] = 0;
125  massesInserted_[spec] = 0;
126  volumesInserted_[spec] = 0;
127 }
128 
130 {
131  /* First choose what particle species to generate. */
132  Mdouble totalprob = 0;
133  for (auto p : probabilitates_)
134  totalprob += p;
135 
136  Mdouble check = random.getRandomNumber(0, totalprob);
137  unsigned int spec;
138  logger(VERBOSE, "PolydisperseInsertionBoundary: check = % out of %",
139  check, totalprob);
140  for (int i = 0; i < generanda_.size(); i++)
141  {
142  if (check >= probabilitates_[i])
143  check -= probabilitates_[i];
144  else
145  {
146  spec = i;
147  break;
148  }
149  }
150 
151  auto P = generanda_[spec]->copy();
152 
153  /* The 'reference' particle for this species has a radius, but we allow some
154  * sizeDispersity. */
155  double radius = P->getRadius()
156  * random.getRandomNumber(1 - sizeDispersities_[spec], 1 + sizeDispersities_[spec]);
157  P->setRadius(radius);
158 
159  /* JMFT: TODO: These do *not* give the correct values!
160  * They give the number &c. of each species that the
161  * PolydisperseInsertionBoundary has _attempted_ to place, not the number
162  * that have actually been placed successfully. */
163  numbersInserted_[spec]++;
164  massesInserted_[spec] += P->getMass();
165  // volumesInserted_[spec] += P->getVolume();
166 
167  return P;
168 }
169 
170 /* JMFT: TODO: We should think how to recycle this code from
171  * CubeInsertionBoundary more efficiently */
173 {
174  Vec3D pos, vel;
175  pos.X = random.getRandomNumber(posMin_.X, posMax_.X);
176  pos.Y = random.getRandomNumber(posMin_.Y, posMax_.Y);
177  pos.Z = random.getRandomNumber(posMin_.Z, posMax_.Z);
178  vel.X = random.getRandomNumber(velMin_.X, velMax_.X);
179  vel.Y = random.getRandomNumber(velMin_.Y, velMax_.Y);
180  vel.Z = random.getRandomNumber(velMin_.Z, velMax_.Z);
181  P->setPosition(pos);
182  P->setVelocity(vel);
183 }
184 
185 // JMFT: TODO
187 {
189  /*
190  for (int i = 0; i < generanda_.size(); i++)
191  {
192  BaseParticle* particleToCopy = new SphericalParticle;
193  // BaseParticle::write writes the extra word 'BaseParticle', which will be
194  // ignored by BaseParticle::read. To avoid an off-by-one error, we need to
195  // get rid of this extra word first...
196  std::string dummy;
197  is >> dummy;
198 
199  // Now read the particleToCopy.
200  particleToCopy->read(is);
201  generanda_[i] = particleToCopy->copy();
202  delete particleToCopy;
203  generanda_[i]->setSpecies(getHandler()->getDPMBase()->speciesHandler.getObject(
204  particleToCopy_->getIndSpecies()
205  ));
206  }
207  */
208 }
209 
210 // JMFT: TODO
211 void PolydisperseInsertionBoundary::write(std::ostream& os) const
212 {
213  logger(VERBOSE, "In PolydisperseInsertionBoundary::write");
215  os << " numberOfGeneranda " << generanda_.size() << " ";
216  for (int i = 0; i < generanda_.size(); i++)
217  {
218  generanda_[i]->write(os);
219  os << " weight " << probabilitates_[i] << " sizeDispersity " << sizeDispersities_[i];
220  }
221  os << " posMin " << posMin_ << " posMax " << posMax_
222  << " velMin " << velMin_ << " velMax " << velMax_
223  << " ";
224 }
225 
227 {
228  return "PolydisperseInsertionBoundary";
229 }
~PolydisperseInsertionBoundary() override
Destructor: default destructor.
Mdouble X
the vector components
Definition: Vector.h:65
void setVelocity(const Vec3D &velocity)
set the velocity of the BaseInteractable.
BaseParticle * generateParticle(RNG &random) override
Generates a particle from the possible species.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
double Mdouble
Definition: GeneralDefine.h:34
void placeParticle(BaseParticle *p, RNG &random) override
Places the particle in a random position with a random velocity.
void check(double real, double ideal, double error, std::string errorMessage)
Definition: Helpers.cc:898
const std::complex< Mdouble > i
Definition: ExtendedMath.h:50
void setMaxFailed(unsigned int maxFailed)
Sets the number of times that the wall may fail to insert a particle.
Mdouble getRandomNumber()
This is a random generating routine can be used for initial positions.
Definition: RNG.cc:143
virtual BaseParticle * copy() const =0
Particle copy method. It calls to copy constructor of this Particle, useful for polymorfism.
Boundary structure for boundaries used for insertion of particles.
PolydisperseInsertionBoundary()
Constructor; sets everything to 0.
void setGeometry(int maxFailed, Vec3D posMin, Vec3D posMax, Vec3D velMin, Vec3D velMax)
Set position and velocity of inserted particles.
void read(std::istream &is) override
reads boundary properties from istream
This is a class that generates random numbers i.e. named the Random Number Generator (RNG)...
Definition: RNG.h:52
Vec3D posMin_
As in CubeInsertionBoundary. JMFT: TODO: Later we should completely separate InsertionBoundary geomet...
PolydisperseInsertionBoundary * copy() const override
Creates a copy on the heap and returns a pointer.
void setGenerandum(unsigned int spec, BaseParticle *generandum, double probability, double sizeDispersity)
Change a particle to be copied.
Like an InsertionBoundary but generates particles of multiple types. Note that, as a child of Inserti...
void write(std::ostream &os) const override
Writes the boundary's id_ and maxFailed_.
std::vector< Mdouble > sizeDispersities_
The dispersity allowed in the particle size.
std::vector< Mdouble > probabilitates_
The probabilities of generating each type of particle. These probabilities are not normalised...
void addGenerandum(BaseParticle *generandum, double probability, double sizeDispersity)
Add a new prototype of particle to be copied.
Mdouble Y
Definition: Vector.h:65
void setPosition(const Vec3D &position)
Sets the position of this BaseInteractable.
std::vector< unsigned int > numbersInserted_
For keeping track of how much of each prototype we have inserted.
Definition: Vector.h:49
std::string getName() const override
Returns the name of the object.
Mdouble Z
Definition: Vector.h:65
std::vector< BaseParticle * > generanda_
Prototypes of the particles that can be generated.
void write(std::ostream &os) const override
writes boundary properties to ostream
void read(std::istream &is) override
Reads the boundary's id_ and maxFailed_.