MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SpeciesHandler.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2014, 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 
26 
27 #include "SpeciesHandler.h"
28 #include "DPMBase.h"
29 
36 
43 
50 
52 
57 {
58  logger(DEBUG, "SpeciesHandler::SpeciesHandler() finished");
59 }
60 
68 {
69  clear();
70  setDPMBase(other.getDPMBase());
72  for (BaseSpecies* mixSpec : other.mixedObjects_)
73  {
74  mixedObjects_.push_back(mixSpec->copy());
75  mixedObjects_.back()->setHandler(this);
76  }
77  logger(DEBUG, "SpeciesHandler::SpeciesHandler(const SpeciesHandler &other) finished");
78 }
79 
88 {
89  if (this != &rhs)
90  {
91  clear();
93  for (BaseSpecies* mixSpec : mixedObjects_)
94  {
95  delete mixSpec;
96  }
97  mixedObjects_.clear();
98  for (BaseSpecies* mixSpec : rhs.mixedObjects_)
99  {
100  mixedObjects_.push_back(mixSpec->copy());
101  mixedObjects_.back()->setHandler(this);
102  }
103  }
104 
105  logger(DEBUG, "SpeciesHandler SpeciesHandler::operator =(const SpeciesHandler& rhs)");
106  return *this;
107 }
112 {
113  clear(); //this deletes everything that comes from the BaseHandler.
114  /*for (BaseSpecies* o : mixedObjects_)
115  {
116  delete o;
117  }*/
118  for (BaseSpecies* mixSpec : mixedObjects_)
119  {
120  delete mixSpec;
121  }
122  mixedObjects_.clear();
123  logger(DEBUG, "SpeciesHandler::~SpeciesHandler() finished");
124 }
130 void SpeciesHandler::readObject(std::istream& is)
131 {
132  std::string type;
133  is >> type;
134  if (type == "LinearViscoelasticSpecies")
135  {
137  is >> species;
138  copyAndAddObject(species);
139  }
140  else if (type == "LinearPlasticViscoelasticSpecies")
141  {
143  is >> species;
144  copyAndAddObject(species);
145  }
146  else if (type == "LinearViscoelasticSlidingFrictionSpecies")
147  {
149  is >> species;
150  copyAndAddObject(species);
151  }
152  else if (type == "LinearPlasticViscoelasticSlidingFrictionSpecies")
153  {
155  is >> species;
156  copyAndAddObject(species);
157  }
158  else if (type == "LinearViscoelasticFrictionSpecies")
159  {
161  is >> species;
162  copyAndAddObject(species);
163  }
164  else if (type == "LinearPlasticViscoelasticFrictionSpecies")
165  {
167  is >> species;
168  copyAndAddObject(species);
169  }
170  else if (type == "LinearViscoelasticIrreversibleAdhesiveSpecies")
171  {
173  is >> species;
174  copyAndAddObject(species);
175  }
176  else if (type == "LinearPlasticViscoelasticIrreversibleAdhesiveSpecies")
177  {
179  is >> species;
180  copyAndAddObject(species);
181  }
182  else if (type == "LinearViscoelasticSlidingFrictionIrreversibleAdhesiveSpecies")
183  {
185  is >> species;
186  copyAndAddObject(species);
187  }
188  else if (type == "LinearPlasticViscoelasticSlidingFrictionIrreversibleAdhesiveSpecies")
189  {
191  is >> species;
192  copyAndAddObject(species);
193  }
194  else if (type == "LinearViscoelasticFrictionIrreversibleAdhesiveSpecies")
195  {
197  is >> species;
198  copyAndAddObject(species);
199  }
200  else if (type == "LinearPlasticViscoelasticFrictionIrreversibleAdhesiveSpecies")
201  {
203  is >> species;
204  copyAndAddObject(species);
205  }
206  else if (type == "LinearViscoelasticReversibleAdhesiveSpecies")
207  {
209  is >> species;
210  copyAndAddObject(species);
211  }
212  else if (type == "LinearPlasticViscoelasticReversibleAdhesiveSpecies")
213  {
215  is >> species;
216  copyAndAddObject(species);
217  }
218  else if (type == "LinearViscoelasticSlidingFrictionReversibleAdhesiveSpecies")
219  {
221  is >> species;
222  copyAndAddObject(species);
223  }
224  else if (type == "LinearPlasticViscoelasticSlidingFrictionReversibleAdhesiveSpecies")
225  {
227  is >> species;
228  copyAndAddObject(species);
229  }
230  else if (type == "LinearViscoelasticFrictionReversibleAdhesiveSpecies")
231  {
233  is >> species;
234  copyAndAddObject(species);
235  }
236  else if (type == "LinearPlasticViscoelasticFrictionReversibleAdhesiveSpecies")
237  {
239  is >> species;
240  copyAndAddObject(species);
241  }
242  else if (type == "LinearViscoelasticFrictionLiquidBridgeWilletSpecies")
243  {
245  is >> species;
246  copyAndAddObject(species);
247  }
248  else if (type == "k") //for backwards compatibility
249  {
251  }
252  else
253  {
254  std::stringstream line(std::stringstream::in | std::stringstream::out);
256  logger(ERROR, "Species type % not understood in restart file. %", type, line.str());
257  }
258 
259  //remove the default mixed species
260  for (unsigned int i = 0; i + 1 < getNumberOfObjects(); i++)
261  {
268  delete mixedObjects_.back();
269  mixedObjects_.pop_back();
270  }
271 
272  //Read the mixed species.
273  for (unsigned int i = 0; i+1 < getNumberOfObjects(); i++)
274  {
275  is >> type;
276  if (type == "LinearViscoelasticMixedSpecies")
277  {
279  is >> species;
280  mixedObjects_.push_back(species.copy());
281  }
282  else if (type == "LinearPlasticViscoelasticMixedSpecies")
283  {
285  is >> species;
286  mixedObjects_.push_back(species.copy());
287  }
288  else if (type == "LinearViscoelasticSlidingFrictionMixedSpecies")
289  {
291  is >> species;
292  mixedObjects_.push_back(species.copy());
293  }
294  else if (type == "LinearPlasticViscoelasticSlidingFrictionMixedSpecies")
295  {
297  is >> species;
298  mixedObjects_.push_back(species.copy());
299  }
300  else if (type == "LinearViscoelasticFrictionMixedSpecies")
301  {
303  is >> species;
304  mixedObjects_.push_back(species.copy());
305  }
306  else if (type == "LinearPlasticViscoelasticFrictionMixedSpecies")
307  {
309  is >> species;
310  mixedObjects_.push_back(species.copy());
311  }
312  else if (type == "LinearViscoelasticIrreversibleAdhesiveMixedSpecies")
313  {
315  is >> species;
316  mixedObjects_.push_back(species.copy());
317  }
318  else if (type == "LinearPlasticViscoelasticIrreversibleAdhesiveMixedSpecies")
319  {
321  is >> species;
322  mixedObjects_.push_back(species.copy());
323  }
324  else if (type == "LinearViscoelasticSlidingFrictionIrreversibleAdhesiveMixedSpecies")
325  {
327  is >> species;
328  mixedObjects_.push_back(species.copy());
329  }
330  else if (type == "LinearPlasticViscoelasticSlidingFrictionIrreversibleAdhesiveMixedSpecies")
331  {
333  is >> species;
334  mixedObjects_.push_back(species.copy());
335  }
336  else if (type == "LinearViscoelasticFrictionIrreversibleAdhesiveMixedSpecies")
337  {
339  is >> species;
340  mixedObjects_.push_back(species.copy());
341  }
342  else if (type == "LinearPlasticViscoelasticFrictionIrreversibleAdhesiveMixedSpecies")
343  {
345  is >> species;
346  mixedObjects_.push_back(species.copy());
347  }
348  else if (type == "LinearViscoelasticReversibleAdhesiveMixedSpecies")
349  {
351  is >> species;
352  mixedObjects_.push_back(species.copy());
353  }
354  else if (type == "LinearPlasticViscoelasticReversibleAdhesiveMixedSpecies")
355  {
357  is >> species;
358  mixedObjects_.push_back(species.copy());
359  }
360  else if (type == "LinearViscoelasticSlidingFrictionReversibleAdhesiveMixedSpecies")
361  {
363  is >> species;
364  mixedObjects_.push_back(species.copy());
365  }
366  else if (type == "LinearPlasticViscoelasticSlidingFrictionReversibleAdhesiveMixedSpecies")
367  {
369  is >> species;
370  mixedObjects_.push_back(species.copy());
371  }
372  else if (type == "LinearViscoelasticFrictionReversibleAdhesiveMixedSpecies")
373  {
375  is >> species;
376  mixedObjects_.push_back(species.copy());
377  }
378  else if (type == "LinearPlasticViscoelasticFrictionReversibleAdhesiveMixedSpecies")
379  {
381  is >> species;
382  }
383  else if (type == "LinearViscoelasticFrictionLiquidBridgeWilletMixedSpecies")
384  {
386  is >> species;
387  }
388  else if (type == "k") //for backwards compatibility
389  {
390  mixedObjects_.push_back(readOldObject(is));
391  }
392  else
393  {
394  logger(ERROR, "Species type: % not understood in restart file", type);
395  }
396  }
397 }
398 
408 {
409  //read in next line
410  std::stringstream line(std::stringstream::in | std::stringstream::out);
412 
413  //read each property
414  std::string property;
415  unsigned int particleDimension=0;
416  Mdouble density=0.0, stiffness=0.0, dissipation=0.0, slidingFrictionCoefficient=0.0, slidingFrictionCoefficientStatic=0.0, slidingStiffness=0.0, slidingDissipation=0.0;
417  line >> stiffness;
418  while (true)
419  {
420  line >> property;
421  if (property == "disp")
422  line >> dissipation;
423  else if (property == "rho")
424  line >> density;
425  else if (property == "kt")
426  line >> slidingStiffness;
427  else if (property == "dispt")
428  line >> slidingDissipation;
429  else if (property == "mu")
430  line >> slidingFrictionCoefficient;
431  else if (property == "mus")
432  line >> slidingFrictionCoefficientStatic;
433  else if (property == "dim_particle")
434  {
435  line >> particleDimension;
436  getDPMBase()->setParticleDimensions(particleDimension);
437  }
438  else if (property == "(mixed)")
439  {
440  density = 0;
441  }
442  else
443  {
444  logger(WARN, "Warning: % is not a species property", property);
445  break;
446  }
447  if (line.eof())
448  break;
449  }
450 
451  //create the correct species
452  if (slidingFrictionCoefficient == 0.0)
453  {
455  species->setDensity(density);
456  species->setStiffness(stiffness);
457  species->setDissipation(dissipation);
458  return species;
459  }
460  else
461  {
463  species->setDensity(density);
464  species->setStiffness(stiffness);
465  species->setDissipation(dissipation);
466  species->setSlidingStiffness(slidingStiffness);
467  species->setSlidingDissipation(slidingDissipation);
468  species->setSlidingFrictionCoefficient(slidingFrictionCoefficient);
469  if (slidingFrictionCoefficientStatic == 0.0)
470  slidingFrictionCoefficientStatic = slidingFrictionCoefficient;
471  species->setSlidingFrictionCoefficientStatic(slidingFrictionCoefficientStatic);
472  return species;
473  }
474 }
475 
485 unsigned int SpeciesHandler::getMixedId(const unsigned int id1, const unsigned int id2) const
486 {
487  unsigned int maxId = std::max(id1,id2);
488  return (maxId*(maxId-1))/2 + std::min(id1,id2);
489 }
490 
496 template<class U> typename U::MixedSpeciesType* SpeciesHandler::getMixedObject(const U* S, const U* T)
497 {
498  return dynamic_cast<typename U::MixedSpeciesType*>(getMixedObject(S->getIndex(),T->getIndex()));
499 }
500 
504 const std::vector<BaseSpecies*>& SpeciesHandler::getMixedObjects() const
505 {
506  return mixedObjects_;
507 }
508 
516 BaseSpecies* SpeciesHandler::getMixedObject(const unsigned int id1, const unsigned int id2)
517 {
518  if (id1 == id2)
519  {
520  return getObject(id1);
521  }
522  else
523  {
524  if (std::max(id1,id2) >= getNumberOfObjects())
525  {
526  logger(ERROR, "In: Object* SpeciesHandler::getMixedObject(const unsigned int id) const. No Object exist with index %, number of objects is %", std::max(id1, id2), getNumberOfObjects());
527  return nullptr;
528  }
529  else
530  {
531  return mixedObjects_[getMixedId(id1,id2)];
532  }
533  }
534 }
547 {
549  //logger(INFO, "Part / Mix: % / %", objects_.size(), mixedObjects_.size());
551  for (unsigned int id = 0; id + 1 < getNumberOfObjects(); ++id)
552  {
553  mixedObjects_.push_back(S->copyMixed());
554  mixedObjects_.back()->setIndex(id);
555  mixedObjects_.back()->setId(getNumberOfObjects()-1);
556  mixedObjects_.back()->mixAll(S,getObject(id));
557  }
558  S->setHandler(this);
562 }
563 
569 void SpeciesHandler::removeObject(unsigned const int id)
570 {
572  for (unsigned int id2 = 0; id2 < getNumberOfObjects(); ++id2)
573  {
574  mixedObjects_.erase(mixedObjects_.begin()+getMixedId(id, id2));
575  }
577 }
583 void SpeciesHandler::write(std::ostream& os) const
584 {
585  os << "Species " << getNumberOfObjects() << std::endl;
586  std::vector<BaseSpecies*>::const_iterator it2 = mixedObjects_.begin();
587  for (std::vector<ParticleSpecies*>::const_iterator it = begin(); it != end(); ++it)
588  {
589  os << (**it) << std::endl;
590  for (unsigned int id2 =0; id2 < (*it)->getIndex(); id2++)
591  {
592  os << (**it2) << std::endl;
593  it2++;
594  }
595  }
596  /*
597  This behaves like the code above but is actually readable
598  @weinhartt is there a reason?
599 
600  there is a reason. Curernt architecture does not allow this
601  \todo define new restart format. @dducks
602 
603  The code is written such that it writes PS0, then PS1 and MS01, then PS2 and
604  MS02, MS12, and so on (PS=ParticleSpecies, MS=MixedSpecies). We can change
605  the restart format, but we should write the read(os) function such that
606  it can also read the old format @weinhartt
607 
608  for (ParticleSpecies * spec : objects_) {
609  os << *spec << std::endl;
610  }
611  for (BaseSpecies * spec : mixedObjects_) {
612  os << *spec << std::endl;
613  }
614  */
615 }
619 std::string SpeciesHandler::getName() const
620 {
621  return "SpeciesHandler";
622 }
623 
628 {
629  for (unsigned int i = 0; i < getNumberOfObjects(); i++)
630  {
631  if (getObject(i)->getUseAngularDOFs())
632  return true;
633  for (unsigned int j = 0; j + 1 < i; j++)
634  {
635  if (getMixedObject(i, j)->getUseAngularDOFs())
636  return true;
637  }
638  }
639  return false;
640 }
641 
642 //instantiate templated functions
643 //template<class U> typename U::MixedSpeciesType* SpeciesHandler::getMixedObject(const U* S, const U* T)
644 
651 
658 
665 
Container to store all ParticleSpecies.
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.cc:106
BaseSpecies is the class from which all other species are derived.
Definition: BaseSpecies.h:44
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
unsigned int getMixedId(const unsigned int id1, const unsigned int id2) const
Gets the Id of the behaviour between two given species.
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
void computeAllMasses(unsigned int indSpecies)
Computes the mass for all BaseParticle of the given species in this ParticleHandler.
const std::vector< BaseSpecies * > & getMixedObjects() const
Returns a pointer to the vector of all mixed objects.
const std::vector< ParticleSpecies * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
double Mdouble
void setParticleDimensions(unsigned int particleDimensions)
Allows the dimension of the particle (f.e. for mass) to be changed. e.g. discs or spheres...
Definition: DPMBase.cc:474
SpeciesHandler()
Default constructor, it creates an empty SpeciesHandler.
Species< LinearViscoelasticNormalSpecies, SlidingFrictionSpecies > LinearViscoelasticSlidingFrictionSpecies
SpeciesHandler operator=(const SpeciesHandler &rhs)
Assignment operator that copies all species and the pointer to the DPMBase from the given SpeciesHand...
virtual void write(std::ostream &os) const
Write all the species and mixed species to an output stream.
const std::vector< ParticleSpecies * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
void setRotation(bool newRotFlag)
Allows to set the flag for enabling or disabling particle rotation in the simulations.
Definition: DPMBase.cc:210
~SpeciesHandler()
Destructor, it destructs the SpeciesHandler and all ParticleSpecies it contains.
virtual BaseSpecies * copyMixed() const =0
Creates a new MixedSpecies with the same force properties as the Species from which it is called...
U * copyAndAddObject(const U &O)
Creates a copy of a Object and adds it to the BaseHandler.
void getLineFromStringStream(std::istream &in, std::stringstream &out)
Reads a line from one stringstream into another, and prepares the latter for reading in...
Definition: Helpers.cc:389
virtual void addObject(ParticleSpecies *const S)
Adds a new ParticleSpecies to the SpeciesHandler.
void removeObject(unsigned const int id)
Remove the ParticleSpecies with given id.
virtual void removeObject(unsigned const int id)
Removes an Object from the BaseHandler.
Definition: BaseHandler.h:303
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created...
Definition: DPMBase.h:878
ParticleSpecies * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
void setDensity(Mdouble density)
Allows the density to be changed.
ParticleSpecies * readOldObject(std::istream &is)
Reads ParticleSpecies into the SpeciesHandler from old-style restart data.
void readObject(std::istream &is)
Reads Species data into the SpeciesHandler from restart file.
virtual void addObject(T *O)
Adds a new Object to the BaseHandler.
Definition: BaseHandler.h:284
std::vector< BaseSpecies * > mixedObjects_
The list of pointers to the mixed species.
Species< LinearViscoelasticNormalSpecies > LinearViscoelasticSpecies
unsigned int getNumberOfObjects() const
Gets the number of Object in this BaseHandler.
U::MixedSpeciesType * getMixedObject(const U *S, const U *T)
void setHandler(SpeciesHandler *handler)
Sets the pointer to the handler to which this species belongs.
Definition: BaseSpecies.cc:66
virtual BaseSpecies * copy() const =0
Creates a deep copy of the object from which it is called.
Contains contact force properties for contacts between particles with two different species...
Definition: MixedSpecies.h:40
virtual bool getUseAngularDOFs() const =0
Returns true if torques (i.e. angular degrees of freedom) have to be calculated.
Contains material and contact force properties.
Definition: Interaction.h:35
void copyContentsFromOtherHandler(const BaseHandler< ParticleSpecies > &BH)
Function that copies the contents (vector of pointers, maxObject_, nextId_, DPMBase_) from one handle...
DPMBase * getDPMBase()
Gets the problem that is solved using this handler.
Definition: BaseHandler.h:512
std::string getName() const
Returns the name of the handler, namely the string "SpeciesHandler".
bool useAngularDOFs()
Check if angular DOF have to be used.
void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...