ESyS-Particle  2.3.2
RandomSpherePacker.hpp
Go to the documentation of this file.
1 
2 // //
3 // Copyright (c) 2003-2014 by The University of Queensland //
4 // Centre for Geoscience Computing //
5 // http://earth.uq.edu.au/centre-geoscience-computing //
6 // //
7 // Primary Business: Brisbane, Queensland, Australia //
8 // Licensed under the Open Software License version 3.0 //
9 // http://www.opensource.org/licenses/osl-3.0.php //
10 // //
12 
13 
14 #include "Foundation/console.h"
15 #include "Foundation/StringUtil.h"
17 #include "Geometry/SphereFitter.h"
19 
20 #include <algorithm>
21 #include <stdexcept>
22 #include <float.h>
23 
24 namespace esys
25 {
26  namespace lsm
27  {
28  template<typename TmplTraits>
30  Packer &packer,
31  int maxInsertionFailures,
32  const BoundingSphere &bSphere
33  ) :
34  m_pPacker(&packer),
35  m_fitterPtrVector(),
36  m_maxInsertionFailures(maxInsertionFailures),
37  m_lastFailCount(0),
38  m_successCount(0),
39  m_next(Fitter::getInvalidParticle()),
40  m_bSphere(bSphere)
41  {
42  if (m_next.isValid())
43  {
44  throw
45  std::runtime_error(
46  std::string("isValid method returns true for INVALID particle:")
47  +
49  );
50  }
52  }
53 
54  template<typename TmplTraits>
56  {
57  return m_maxInsertionFailures;
58  }
59 
60  template<typename TmplTraits>
63  {
64  return *m_pPacker;
65  }
66 
67  template<typename TmplTraits>
70  {
71  return *m_pPacker;
72  }
73 
74  template<typename TmplTraits>
75  const BoundingSphere &
77  {
78  return m_bSphere;
79  }
80 
81  template<typename TmplTraits>
82  void
84  {
85  FitterPtrVector fitters;
86  fitters.push_back(FitterPtr(new Move2SurfaceFitter(getPacker())));
87  if (getPacker().is2d())
88  {
89  fitters.push_back(FitterPtr(new TwoDSFitter(getPacker())));
90  fitters.push_back(FitterPtr(new TwoDSSphereFitter(getPacker(), getBSphere())));
91  }
92  else
93  {
94  fitters.push_back(FitterPtr(new ThreeDFitter(getPacker())));
95  fitters.push_back(FitterPtr(new ThreeDSSphereFitter(getPacker(), getBSphere())));
96  }
97  m_fitterPtrVector = fitters;
98  }
99 
100  template<typename TmplTraits>
103  {
104  return m_fitterPtrVector;
105  }
106 
107  template<typename TmplTraits>
110  {
111  return m_fitterPtrVector;
112  }
113 
114  template<typename TmplTraits>
116  {
117  return getPacker().getRandomPoint();
118  }
119 
120  template<typename TmplTraits>
123  const Vec3 &point
124  )
125  {
126  return getPacker().getCandidateParticle(point);
127  }
128 
129  template<typename TmplTraits>
132  const Particle& particle,
133  int numClosest
134  )
135  {
136  return getPacker().getClosestNeighbours(particle, numClosest);
137  }
138 
139  template<typename TmplTraits>
142  {
143  m_next = Fitter::getInvalidParticle();
144  if (m_lastFailCount < getMaxInsertionFailures())
145  {
146  int numFails = 0;
147  //int insertCount = 0;
148  FitterPtrVector fitters = getFitterPtrVector();
149  Particle particle = Fitter::getInvalidParticle();
150  Particle fitParticle = particle;
151  Plane plane=Plane(Vec3(-1.0, 0, 0), Vec3(DBL_MAX/2, DBL_MAX/2, DBL_MAX/2));
152  ParticleVector neighbours;
153  while ((!fitParticle.isValid()) && (numFails < getMaxInsertionFailures()))
154  {
155  particle = getCandidateParticle(getRandomPoint());
156  neighbours = getClosestNeighbours(particle, 4);
157 
158  for (
159  typename FitterPtrVector::iterator it = getFitterPtrVector().begin();
160  (
161  (it != getFitterPtrVector().end())
162  &&
163  (!fitParticle.isValid())
164  );
165  it++
166  )
167  {
168  fitParticle = (*it)->getFitParticle(particle, neighbours, plane);
169  }
170  numFails++;
171  }
172  m_lastFailCount = numFails;
173  m_successCount += ((fitParticle.isValid()) ? 1 : 0);
174  m_next = fitParticle;
175  }
176  return m_next;
177  }
178 
179  template<typename TmplTraits>
181  {
182  return (m_next.isValid() || generateNext().isValid());
183  }
184 
185  template<typename TmplTraits>
188  {
189  if (!(m_next.isValid()))
190  {
191  generateNext();
192  }
193  const Particle next = m_next;
194  m_next = Fitter::getInvalidParticle();
195  return next;
196  }
197 
198  template<typename TmplTraits>
200  {
201  console.Info()
202  << "BoundingSphere: minPt = " << getPacker().getBBox().getMinPt()
203  << ", maxPt = " << getPacker().getBBox().getMaxPt() << "\n"
204  << "BoundingSphere: sizes = " << getPacker().getBBox().getSizes() << "\n";
205 
206  for (
207  typename FitterPtrVector::iterator it = getFitterPtrVector().begin();
208  (it != getFitterPtrVector().end());
209  it++
210  ) {
211  console.Info() << (*(*it)).toString() << "\n";
212  }
213  console.Info() << "Total successful fits = " << m_successCount << "\n";
214  }
215 
216 
217 
218 
219 
220 
221 
222 
223 
224 
225 
226 
227 
228 
229 
230 
231 
232 
233 
234 
235 
236 
237 
238 
239 
240 
241 
242  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
244  ParticleGeneratorPtr particleGeneratorPtr,
245  ParticlePoolPtr particlePoolPtr,
246  NTablePtr nTablePtr,
247  const BoundingSphere &bSphere,
248  double tolerance,
249  double cubicPackRadius,
250  int maxInsertionFailures,
251  bool do2d
252  )
253  : Inherited(
254  particleGeneratorPtr,
255  particlePoolPtr,
256  nTablePtr,
257  do2d ? bSphere.get2dBBox() : bSphere.getBBox(),
258  BoolVector(3,false),
259  tolerance,
260  cubicPackRadius
261  ),
262  m_bSphere(bSphere),
263  m_maxInsertionFailures(maxInsertionFailures)
264  {
265  }
266 
267  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
269  {
270  }
271 
272  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
273  const BoundingSphere &
275  ) const
276  {
277  return m_bSphere;
278  }
279 
280  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
281  double
283  double minVal,
284  double maxVal
285  ) const
286  {
287  return minVal + (maxVal-minVal)*rng::s_zeroOneUniform();
288  }
289 
290  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
292  {
293  return
294  Vec3(
295  getRandom(this->getBBox().getMinPt().X(), this->getBBox().getMaxPt().X()),
296  getRandom(this->getBBox().getMinPt().Y(), this->getBBox().getMaxPt().Y()),
297  getRandom(this->getBBox().getMinPt().Z(), this->getBBox().getMaxPt().Z())
298  );
299  }
300 
301  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
304  const Particle& particle,
305  int numClosest
306  )
307  {
308  ParticleVector neighbourVector =
309  this->getNTable().getUniqueNeighbourVector(
310  particle.getPos(),
311  this->getParticleGenerator().getMaxFitRadius() + this->getTolerance()
312  );
313  std::sort(
314  neighbourVector.begin(),
315  neighbourVector.end(),
317  );
318 
319  if (static_cast<int>(neighbourVector.size()) > numClosest) {
320  neighbourVector.erase(
321  neighbourVector.begin() + numClosest,
322  neighbourVector.end()
323  );
324  }
325 
326  return neighbourVector;
327  }
328 
329  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
331  const Particle &particle
332  ) const
333  {
334  return
335  (
336  this->getParticleGenerator().isValidFitRadius(particle.getRad())
337  &&
338  particleFitsInBSphereWithNeighbours(particle)
339  );
340  }
341 
342  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
344  {
345  return m_maxInsertionFailures;
346  }
347 
348  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
350  {
353  *this,
354  getMaxInsertionFailures(),
355  getBSphere()
356  );
357  while (it.hasNext())
358  {
359  const Particle p = it.next();
360  this->createAndInsertParticle(p);
361  }
362  it.logInfo();
363  }
364 
365  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
366  bool
368  const Particle &particle
369  ) const
370  {
371  return
372  getBSphere().contains(
373  BoundingSphere(particle.getPos(), particle.getRadius()),
374  this->getTolerance()
375  );
376  }
377 
378  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
379  bool
381  const Particle &particle
382  ) const
383  {
384  return
385  (
386  particleFitsInBSphere(particle)
387  &&
388  this->particleFitsWithNeighbours(particle)
389  );
390  }
391 
392  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
394  {
395  GridIterator pointIt = GridIterator(this->getBBox(), this->getCubicPackingRadius());
396  while (pointIt.hasNext()) {
397  const Particle candidate =
398  this->getCandidateParticle(pointIt.next(), this->getCubicPackingRadius());
399  if (particleFitsInBSphereWithNeighbours(candidate)) {
400  this->createAndInsertParticle(candidate);
401  }
402  }
403  }
404 
405  template <typename TPartGen,template <typename TTPartGen> class TCubicPackWrap>
407  {
408  generateCubicPackingInSphere();
409  generateRandomFill();
410  }
411  }
412 }