GranOO  3.0
A robust and versatile workbench to build 3D dynamic simulations based on the Discrete Element Method
ContactDetection.hpp
Go to the documentation of this file.
1 // This file is part of GranOO, a workbench for DEM simulation.
2 //
3 // Author(s) : - Damien Andre IRCER/UNILIM, Limoges France
4 // <damien.andre@unilim.fr>
5 // - Jean-luc Charles Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
6 // <jean-luc.charles@ensam.eu>
7 // - Jeremie Girardot Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
8 // <jeremie.girardot@ensam.eu>
9 // - Cedric Hubert LAMIH/UPHF, Valenciennes France
10 // <cedric.hubert@uphf.fr>
11 // - Ivan Iordanoff Arts et Metiers ParisTech, CNRS, I2M, Bordeaux France
12 // <ivan.iordanoff@ensam.eu>
13 //
14 // Copyright (C) 2008-2019 D. Andre, JL. Charles, J. Girardot, C. Hubert, I. Iordanoff
15 //
16 // This program is free software: you can redistribute it and/or modify
17 // it under the terms of the GNU General Public License as published by
18 // the Free Software Foundation, either version 3 of the License, or
19 // (at your option) any later version.
20 //
21 // This program is distributed in the hope that it will be useful,
22 // but WITHOUT ANY WARRANTY; without even the implied warranty of
23 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 // GNU General Public License for more details.
25 //
26 // You should have received a copy of the GNU General Public License
27 // along with this program. If not, see <http://www.gnu.org/licenses/>.
28 
29 
30 #ifndef _libDEM_ContactDetection_hpp_
31 #define _libDEM_ContactDetection_hpp_
32 
33 #include "GranOO3/Core/Macro.hpp"
34 #include "GranOO3/Math/Stat.hpp"
40 #include "GranOO3/FEM/Surface.hpp"
41 
42 //
43 // Base class for detection method
44 //
45 
46 namespace GranOO3
47 {
48  namespace DEM
49  {
50 
51  template<class T>
52  class ContactDetection : public Collision::BroadPhase<DEM::DiscreteElement, T>,
53  public Core::NeedSetOf< DiscreteElement>
54  {
55  public:
56  static ContactDetection& get_ByUniqueId(const std::string& id);
57  static std::string class_ID() {return "DEM::ContactDetection_" + T::class_ID() + "_";}
58 
59  private:
60  static std::map<std::string, ContactDetection *> UniqueIdMap_;
61 
62  protected:
64  virtual ~ContactDetection();
65 
66  public:
67  virtual void parse_xml();
68  virtual void init() {};
69  void detect_contact(std::function<void(DEM::DiscreteElement&, T&)>&);
70 
72  const ContactLaw<T>& get_ContactLaw() const;
74  unsigned int get_Contactnumber() const;
75 
76  const std::vector<double>& get_InterpenetrationValues() const;
77 
78  void get_Contactinfo(unsigned int& number, double & ave, double & std, double & min, double & max) const;
79 
81 
82  double get_interactionCoeff() const;
83  void set_InteractionCoeff(double c) {interactionCoeff_ = c;};
84 
85  bool is_bonded(DiscreteElement& de1, T& de2);
86  void RecordContact(DiscreteElement& de1, T& de2);
87 
88  protected:
89  virtual void detect_contact() = 0;
90 
91  void Process(DiscreteElement& de1, T& de2, const Geom::Vector& normal, const double& penetration);
92 
93  private:
94  void RegisterWithUniqueId(const std::string& id);
97 
98  private:
100  unsigned int contactNumber_;
101  std::vector<double> interpenetrationValues_;
104  std::string recordContactIn_;
106  };
107 
108 
109  template<class T> std::map<std::string, ContactDetection<T> *>
110  ContactDetection<T>::UniqueIdMap_ = std::map<std::string, ContactDetection *>();
111 
112  template<class T>
114  : Core::NeedSetOf< DiscreteElement>(false),
115  law_(nullptr),
116  contactNumber_(0),
117  interpenetrationValues_(),
118  recordInterpenetrationValues_(false),
119  excludedBondedDiscreteElement_(false),
120  recordContactIn_(""),
121  interactionCoeff_(1.) {
122  }
123 
124  template<class T>
126  }
127 
128  template<class T> void
131 
133  parser.read_attribute(Attr::GRANOO_OPTIONAL, "RecordInterpenetrationValues",
134  recordInterpenetrationValues_);
135  parser.read_attribute(Attr::GRANOO_OPTIONAL, "ExcludedBondedDiscreteElement",
136  excludedBondedDiscreteElement_);
137 
138  // Register it, if the user want
139  std::string uniqueId = "";
140  parser.read_attribute(Attr::GRANOO_OPTIONAL, "UniqueId", uniqueId);
141  if (uniqueId != "")
142  RegisterWithUniqueId(uniqueId);
143 
144  parser.read_attribute(Attr::GRANOO_OPTIONAL, "RecordContactIn", recordContactIn_);
145  parser.read_attribute(Attr::GRANOO_OPTIONAL, "InteractionCoeff", interactionCoeff_);
146  XmlAssert(interactionCoeff_ > 0., "The interaction coeff must be positive");
147 
148  // Affect law pointer (hack between 1.0 and 2.0 collision detection management)
151  Collision::CallBack<DEM::DiscreteElement, T>* callBack = manager->get_callback();
152  law_ = dynamic_cast<ContactLaw<T> *>(callBack);
153  AssertMsg(law_ != 0, "Problem while reading ContactDetection, the given CallBack can't be casted to a ContactLaw");
154  }
155 
156  template<class T> void
158  contactNumber_ = 0;
159 
160  if (recordInterpenetrationValues_)
161  interpenetrationValues_.clear();
162 
163  if (recordContactIn_ != "")
164  get_RecordContactSet().clear();
165 
166  get_ContactLaw().pre_contact_detection();
167  detect_contact();
168  get_ContactLaw().post_contact_detection();
169  }
170 
171  template<> inline
173  return de1.is_bonded(de2);
174  }
175 
176  template<class T>
178  return false;
179  }
180 
181  template<> inline
183  get_RecordContactSet().add_item(de1);
184  get_RecordContactSet().add_item(de2);
185  }
186 
187  template<class T>
189  get_RecordContactSet().add_item(de1);
190  }
191 
192  template<class T>
193  void ContactDetection<T>::Process(DiscreteElement& de1, T& de2, const Geom::Vector& normal, const double& penetration) {
194 
195  if (excludedBondedDiscreteElement_)
196  if (is_bonded(de1, de2))
197  return;
198 
199  contactNumber_++;
200  get_ContactLaw().compute_reaction(de1, de2, normal, penetration);
201 
202  if (recordInterpenetrationValues_)
203  interpenetrationValues_.push_back(penetration);
204 
205  if (recordContactIn_ != "")
206  RecordContact(de1, de2);
207 
208 
209  }
210 
211  template<class T> unsigned int
213  return contactNumber_;
214  }
215 
216  template<class T> const std::vector<double>&
218  return interpenetrationValues_;
219  }
220 
221  template<class T> void
222  ContactDetection<T>::get_Contactinfo(unsigned int& number, double & ave, double & std, double & min, double & max) const {
223  InternAssert(recordInterpenetrationValues_ == true);
224  number = contactNumber_;
225  Math::Stat::All(interpenetrationValues_, ave, std, min, max);
226  }
227 
228  template<class T> void
230  InternAssert(UniqueIdMap_.count(id) == 0);
231  UniqueIdMap_[id] = this;
232  }
233 
234  template<class T> ContactDetection<T>&
235  ContactDetection<T>::get_ByUniqueId(const std::string& id) {
236  InternAssert(UniqueIdMap_.count(id) == 1);
237  return *UniqueIdMap_[id];
238  }
239 
240  template<class T> Core::SetOf<DiscreteElement >&
242  InternAssert(recordContactIn_ != "");
243  if (!Core::SetOf<DiscreteElement >::exist(recordContactIn_))
244  new Core::SetOf<DiscreteElement >(recordContactIn_);
245  return Core::SetOf<DiscreteElement >::get(recordContactIn_);
246  }
247 
248  template<class T> double
250  return interactionCoeff_;
251  }
252 
253  template<class T> ContactLaw<T>&
255  return *law_;
256  }
257 
258  template<class T> const ContactLaw<T>&
260  return *law_;
261  }
262 
263  template<class T> void
265  law_ = &law;
266  }
267 
268  }
269 }
270 
271 
272 #endif
#define InternAssert(condition)
Definition: Macro.hpp:81
#define AssertMsg(condition, message)
Definition: Macro.hpp:67
#define XmlAssert(condition, message)
Definition: XmlParser.hpp:52
Definition: Manager.hpp:118
Definition: Manager.hpp:58
Definition: NeedSetOf.hpp:51
virtual void parse_xml()
Definition: SetOf.hpp:236
static SetOf< type > & get()
Definition: XmlParser.hpp:122
static XmlParser & get()
void read_attribute(const Attribute::State, const std::string &, T &)
A class for managing contact with discrete elements (obsolete and not documented)
Definition: ContactDetection.hpp:54
bool is_bonded(DiscreteElement &de1, T &de2)
Definition: ContactDetection.hpp:177
static std::map< std::string, ContactDetection * > UniqueIdMap_
Definition: ContactDetection.hpp:60
void Process(DiscreteElement &de1, T &de2, const Geom::Vector &normal, const double &penetration)
Definition: ContactDetection.hpp:193
const std::vector< double > & get_InterpenetrationValues() const
Definition: ContactDetection.hpp:217
const ContactLaw< T > & get_ContactLaw() const
Definition: ContactDetection.hpp:259
void detect_contact(std::function< void(DEM::DiscreteElement &, T &)> &)
Definition: ContactDetection.hpp:157
ContactDetection()
Definition: ContactDetection.hpp:113
virtual void parse_xml()
Definition: ContactDetection.hpp:129
bool excludedBondedDiscreteElement_
Definition: ContactDetection.hpp:103
double get_interactionCoeff() const
Definition: ContactDetection.hpp:249
bool recordInterpenetrationValues_
Definition: ContactDetection.hpp:102
unsigned int get_Contactnumber() const
Definition: ContactDetection.hpp:212
void set_ContactLaw(ContactLaw< T > &law)
Definition: ContactDetection.hpp:264
virtual ~ContactDetection()
Definition: ContactDetection.hpp:125
static std::string class_ID()
Definition: ContactDetection.hpp:57
static ContactDetection & get_ByUniqueId(const std::string &id)
Definition: ContactDetection.hpp:235
void set_InteractionCoeff(double c)
Definition: ContactDetection.hpp:83
Core::SetOf< DiscreteElement > & get_RecordContactSet()
Definition: ContactDetection.hpp:241
unsigned int contactNumber_
Definition: ContactDetection.hpp:100
std::string recordContactIn_
Definition: ContactDetection.hpp:104
double interactionCoeff_
Definition: ContactDetection.hpp:105
virtual void detect_contact()=0
void get_Contactinfo(unsigned int &number, double &ave, double &std, double &min, double &max) const
Definition: ContactDetection.hpp:222
void RegisterWithUniqueId(const std::string &id)
Definition: ContactDetection.hpp:229
ContactDetection & operator=(const ContactDetection &)=delete
std::vector< double > interpenetrationValues_
Definition: ContactDetection.hpp:101
void RecordContact(DiscreteElement &de1, T &de2)
Definition: ContactDetection.hpp:188
virtual void init()
Definition: ContactDetection.hpp:68
ContactDetection(const ContactDetection &)=delete
ContactLaw< T > & get_ContactLaw()
Definition: ContactDetection.hpp:254
ContactLaw< T > * law_
Definition: ContactDetection.hpp:99
A class for managing contact with discrete elements (obsolete and not documented)
Definition: ContactLaw.hpp:70
the discrete element is just a spherical Element with additional dedicated features
Definition: DiscreteElement.hpp:47
bool is_bonded(const Element &el) const
ask if the current element is bonded to another one
Definition: Element.cpp:87
Definition: Vector.hpp:75
static void All(const T &, double &ave, double &std, double &min, double &max)
Definition: Stat.hpp:88
Definition: Common.hpp:198
T min(const T v0, const T v1)
Definition: Exprtk.hpp:1456
T max(const T v0, const T v1)
Definition: Exprtk.hpp:1463