ESyS-Particle  2.3.4
mesh2d_pis_eb.hpp
Go to the documentation of this file.
1 // //
3 // Copyright (c) 2003-2017 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.apache.org/licenses/LICENSE-2.0 //
10 // //
12 
13 template<class ParticleType,class IType>
15 template<class ParticleType,class IType>
17 
25 template<class ParticleType,class IType>
27  :Mesh2D_PIS<ParticleType>(mesh_p,ppa_p),m_comm(ppa_p->getComm())
28 {
29  console.XDebug() << "Mesh2D_PIS_EB constructor\n";
30  m_param=param;
31  this->m_update_timestamp=0;
32 }
33 
43 template<class ParticleType,class IType>
44 bool Mesh2D_PIS_EB<ParticleType,IType>::isIn(const std::vector<int>& v)
45 {
46  bool res=false;
47 
48  if(v.size()<3){
49  res=false;
50  } else {
51  switch (v[2]){
52  case 1: res=m_edge_int_set.find(make_pair(v[0],v[1]))!=m_edge_int_set.end(); break;
53  case 2: res=m_edge_int_set.find(make_pair(v[0],v[1]))!=m_corner_int_set.end(); break;
54  default: console.Error() << "wrong value in argument of Mesh2D_PIS::isIn !!\n"; break;
55  }
56  }
57 
58  return res;
59 }
60 
64 template<class ParticleType,class IType>
66 {
67  console.XDebug() << "Mesh2D_PIS_EB calculating " << m_edge_interactions.size() << " edge forces and"
68  << m_corner_interactions.size() << " corner forces\n";
69 
70  // calculate forces for edge interactions
71  for(typename list<typename IType::TriIntType>::iterator ed_iter=m_edge_interactions.begin();
72  ed_iter!=m_edge_interactions.end();
73  ed_iter++){
74  ed_iter->calcForces();
75  }
76  // calculate forces for corner interactions
77  for(typename list<typename IType::CornerIntType>::iterator c_iter=m_corner_interactions.begin();
78  c_iter!=m_corner_interactions.end();
79  c_iter++){
80  c_iter->calcForces();
81  }
82 }
83 
86 template<class ParticleType,class IType>
88 {
89  console.XDebug() << "Mesh2D_PIS_EB::update on node " << m_comm.rank() << "\n";
90  bool res=false;
91 
92  // edge interactions
93  typename list<typename IType::TriIntType>::iterator iter=m_edge_interactions.begin();
94  while(iter!=m_edge_interactions.end()){
95  if(iter->broken()){
96  res=true;
97  typename list<typename IType::TriIntType>::iterator er_iter=iter;
98  iter++;
99  // remove ids from map
100  m_edge_int_set.erase(make_pair(er_iter->getTid(),er_iter->getPid()));
101  // remove interaction
102  m_edge_interactions.erase(er_iter);
103  } else {
104  iter++;
105  }
106  }
107  // corner interactions
108  typename list<typename IType::CornerIntType>::iterator c_iter=m_corner_interactions.begin();
109  while(c_iter!=m_corner_interactions.end()){
110  if(c_iter->broken()){
111  res=true;
112  typename list<typename IType::CornerIntType>::iterator cr_iter=c_iter;
113  c_iter++;
114  // remove ids from map
115  m_corner_int_set.erase(make_pair(cr_iter->getCid(),cr_iter->getPid()));
116  // remove interaction
117  m_corner_interactions.erase(cr_iter);
118  } else {
119  c_iter++;
120  }
121  }
122  console.XDebug() << "end Mesh2D_PIS_EB::update on node " << m_comm.rank() << "\n";
123  return res;
124 }
125 
126 
129 template<class ParticleType,class IType>
131 {
132  console.XDebug() << "TriMesh_PIS_EB::exchange\n";
133  for(int i=0;i<3;i++){
134  if(m_comm.get_dim(i)>1){
135  // -- up --
136  exchange_boundary(i,1);
137  // -- down --
138  exchange_boundary(i,-1);
139  }
140  }
141  console.XDebug() << "end TriMesh_PIS_EB::exchange\n";
142 }
143 
150 template<class ParticleType,class IType>
152 {
153  console.XDebug() << "Mesh2D_PIS_EB::exchange_boundary(" << dim << "," << dir << ") at node " << m_comm.rank() << "\n";
154 
155  std::set<int> bdry_ids;
156  std::vector<typename IType::TriIntType> recv_tri_buffer;
157  std::vector<typename IType::TriIntType> send_tri_buffer;
158  std::vector<typename IType::CornerIntType> recv_corner_buffer;
159  std::vector<typename IType::CornerIntType> send_corner_buffer;
160 
161  // --- setup data to send ---
162  // get boundary
163  bdry_ids = this->m_ppa->getBoundarySlabIds(dim,dir);
164  // --- edges ---
165  // for all interactions
166  for(typename std::list<typename IType::TriIntType>::iterator iter=m_edge_interactions.begin();
167  iter!=m_edge_interactions.end();
168  iter++){
169  int pid=iter->getPid();
170  if(bdry_ids.find(pid)!=bdry_ids.end()) { // if particle in interaction is in bdry -> put in buffer
171  send_tri_buffer.push_back(*iter);
172  }
173  }
174  // shift
175  m_comm.shift_cont_packed(send_tri_buffer,recv_tri_buffer,dim,dir,m_edge_exchg_tag);
176  // insert received data
177  for(typename std::vector<typename IType::TriIntType>::iterator iter=recv_tri_buffer.begin();
178  iter!=recv_tri_buffer.end();
179  iter++){
180  tryInsert(*iter);
181  }
182  // --- corners ---
183  // for all interactions
184  for(typename std::list<typename IType::CornerIntType>::iterator iter=m_corner_interactions.begin();
185  iter!=m_corner_interactions.end();
186  iter++){
187  int pid=iter->getPid();
188  if(bdry_ids.find(pid)!=bdry_ids.end()) { // if particle in interaction is in bdry -> put in buffer
189  send_corner_buffer.push_back(*iter);
190  }
191  }
192  // shift
193  m_comm.shift_cont_packed(send_corner_buffer,recv_corner_buffer,dim,dir,m_corner_exchg_tag);
194  // insert received data
195  for(typename std::vector<typename IType::CornerIntType>::iterator iter=recv_corner_buffer.begin();
196  iter!=recv_corner_buffer.end();
197  iter++){
198  tryInsert(*iter);
199  }
200 
201  console.XDebug() << "end Mesh2D_PIS_EB::exchange_boundary\n";
202 }
203 
204 template<class ParticleType,class IType>
206 {
207 }
208 
214 template<class ParticleType,class IType>
216 {
217  console.XDebug() << "Mesh2D_PIS_EB::rebuild on node " << m_comm.rank() << "\n";
219  (ParallelParticleArray<ParticleType>*)(this->m_ppa); // should be a dynamic_cast
220  // for all edge interactions
221  typename std::list<typename IType::TriIntType>::iterator ti_iter=m_edge_interactions.begin();
222  while(ti_iter!=m_edge_interactions.end()){
223  int pid=ti_iter->getPid();
224  ParticleType *part_p=t_ppa->getParticlePtrByIndex(pid);
225  if(part_p!=NULL) { // particle is available in m_ppa -> setup pointer in interaction
226  ti_iter->setPP(part_p);
227  Edge2D *ed_p = this->m_mesh->getEdgeById(ti_iter->getTid());
228  ti_iter->setTP(ed_p);
229  ti_iter++;
230  } else { // particle is not available in m_ppa -> remove interaction
231  const typename list<typename IType::TriIntType>::iterator er_iter=ti_iter;
232  ti_iter++;
233  m_edge_int_set.erase(make_pair(er_iter->getTid(),pid));
234  m_edge_interactions.erase(er_iter);
235  }
236  }
237  // and now for the corners
238  typename list<typename IType::CornerIntType>::iterator ci_iter=m_corner_interactions.begin();
239  while(ci_iter!=m_corner_interactions.end()){
240  int pid=ci_iter->getPid();
241  ParticleType *part_p=t_ppa->getParticlePtrByIndex(pid);
242  if(part_p!=NULL) { // particle is available in m_ppa -> setup pointer in interaction
243  ci_iter->setPP(part_p);
244  Corner2D *co_p = this->m_mesh->getCornerById(ci_iter->getCid());
245  ci_iter->setCP(co_p);
246  ci_iter++;
247  } else { // particle is not available in m_ppa -> remove interaction
248  const typename list<typename IType::CornerIntType>::iterator cr_iter=ci_iter;
249  ci_iter++;
250  m_corner_int_set.erase(make_pair(cr_iter->getCid(),pid));
251  m_corner_interactions.erase(cr_iter);
252  }
253  }
254 
255  console.XDebug() << "end Mesh2D_PIS_EB::rebuild on node " << m_comm.rank() << "\n";
256 }
257 
260 template<class ParticleType,class IType>
261 void Mesh2D_PIS_EB<ParticleType,IType>::tryInsert(const typename IType::TriIntType& In)
262 {
263  console.XDebug() << "Mesh2D_PIS_EB::tryInsert(const typename IType::TriIntType& In)\n";
265  (ParallelParticleArray<ParticleType>*)(this->m_ppa);
266  // check if interaction is already in
267  bool is_in=(m_edge_int_set.find(make_pair(In.getTid(),In.getPid()))!=m_edge_int_set.end());
268  ParticleType *part_p=t_ppa->getParticlePtrByIndex(In.getPid());
269  if((!is_in) && (part_p!=NULL)){
270  m_edge_interactions.push_back(In);
271  m_edge_int_set.insert(make_pair(In.getTid(),In.getPid()));
272  }
273 }
274 
277 template<class ParticleType,class IType>
278 void Mesh2D_PIS_EB<ParticleType,IType>::tryInsert(const typename IType::CornerIntType& In)
279 {
280  console.XDebug() << "Mesh2D_PIS_EB::tryInsert(const typename IType::CornerIntType& In)\n";
282  (ParallelParticleArray<ParticleType>*)(this->m_ppa);
283  // check if interaction is already in
284  bool is_in=(m_corner_int_set.find(make_pair(In.getCid(),In.getPid()))!=m_corner_int_set.end());
285  ParticleType *part_p=t_ppa->getParticlePtrByIndex(In.getPid());
286  if((!is_in) && (part_p!=NULL)){
287  m_corner_interactions.push_back(In);
288  m_corner_int_set.insert(make_pair(In.getCid(),In.getPid()));
289  }
290 }
291 
303 template<class ParticleType,class IType>
304 void Mesh2D_PIS_EB<ParticleType,IType>::tryInsert(const vector<int>& pids)
305 {
306  console.XDebug() << "Mesh2D_PIS_EB::(const vector<int>& pids)\n";
308  (ParallelParticleArray<ParticleType>*)(this->m_ppa); // should be dynamic_cast
309 
310  if(pids.size()<3){
311  bool is_in=isIn(pids); // interaction already in
312  ParticleType *part_p=t_ppa->getParticlePtrByIndex(pids[1]);
313  if((!is_in) && (part_p!=NULL)){
314  switch (pids[2]){
315  case 1: { // edge
316  Edge2D *edge_p = this->m_mesh->getEdgeById(pids[0]);
317  if(edge_p!=NULL){
318  m_edge_interactions.push_back(
319  typename IType::TriIntType(
320  part_p,
321  edge_p,
322  m_param,
323  this->m_ppa->isInInner(part_p->getPos())
324  )
325  );
326  m_edge_int_set.insert(make_pair(pids[0],pids[1]));
327  } else {
328  console.Error() << "ERROR: Wrong edge id " << pids[0] << " in Mesh2D_PIS_EB::tryInsert\n";
329  }
330  } break;
331  case 2: {
332  Corner2D *corner_p = this->m_mesh->getCornerById(pids[0]);
333  if(corner_p!=NULL){
334  m_corner_interactions.push_back(
335  typename IType::CornerIntType(
336  part_p,
337  corner_p,
338  m_param,
339  this->m_ppa->isInInner(part_p->getPos())
340  )
341  );
342  m_corner_int_set.insert(make_pair(pids[0],pids[1]));
343  } else {
344  console.Error() << "ERROR: Wrong corner id " << pids[0] << " in Mesh2D_PIS_EB::tryInsert\n";
345  }
346  } break;
347  default : console.Error() << "Error: pids[2]= " << pids[2] << "\n"; // Can't happen !!
348  }
349  }
350  }
351 }
352 
353 
356 template<class ParticleType,class IType>
358 {
359  console.XDebug() << "Mesh2D_PIS_EB::buildFromPPATagged(" << tag << "," << mask << ")\n";
360  set<int> id_set;
361 
362  // for all edges
363  for(
364  Mesh2D::edge_iterator ed_iter = this->m_mesh->edges_begin();
365  ed_iter != this->m_mesh->edges_end();
366  ed_iter++){
367  // get particles near edge
369  ((ParallelParticleArray<ParticleType>*)this->m_ppa)->getParticlesNearEdge(&(*ed_iter));
370  console.Debug() << "edge " << ed_iter->getID() << " nr. of particles : " << plh->size() << "\n";
371  // for all particles found
372  for(
374  p_iter!=plh->end();
375  p_iter++){
376  // if valid interaction
377  console.Debug() << "interaction : " << ed_iter->getID() << " " << (*p_iter)->getID() << "\n";
378  if(id_set.find((*p_iter)->getID())==id_set.end()){
379  pair<bool,double> dist=ed_iter->dist((*p_iter)->getPos());
380  console.Debug() << "is valid: " << dist.first << " dist : " << dist.second << "\n";
381  if(dist.first){
382  int ptag=(*p_iter)->getTag();
383  // if tag is correct, add interaction
384  if((ptag & mask)==(tag & mask)){
385  console.Debug() << "Inserting " << (*p_iter)->getID() << " !!\n";
386  bool in_flag = this->m_ppa->isInInner((*p_iter)->getPos());
387  m_edge_interactions.push_back(typename IType::TriIntType((*p_iter),&(*ed_iter),m_param,in_flag));
388  m_edge_int_set.insert(make_pair(ed_iter->getID(),(*p_iter)->getID()));
389  id_set.insert((*p_iter)->getID());
390  }
391  }
392  }
393  }
394 
395  }
396  console.XDebug() << "end Mesh2D_PIS_EB::buildFromPPATagged()";
397 }
398 
404 template<class ParticleType,class IType>
406 {
407  console.XDebug() << "Mesh2D_PIS_EB::buildFromPPAByGap(" << gmax << ")\n";
408  set<int> id_set;
409 
410  // for all edges
411  for(
412  Mesh2D::edge_iterator ed_iter = this->m_mesh->edges_begin();
413  ed_iter != this->m_mesh->edges_end();
414  ed_iter++
415  ){
416  // get particles near edge
418  ((ParallelParticleArray<ParticleType>*)this->m_ppa)->getParticlesNearEdge(&(*ed_iter));
419  console.Debug() << "edge " << ed_iter->getID() << " nr. of particles : " << plh->size() << "\n";
420  // for all particles found
421  for(
423  p_iter!=plh->end();
424  p_iter++){
425  // if valid interaction
426  console.Debug() << "interaction : " << ed_iter->getID() << " " << (*p_iter)->getID() << "\n";
427  if(id_set.find((*p_iter)->getID())==id_set.end()){
428  pair<bool,double> dist=ed_iter->dist((*p_iter)->getPos());
429  console.Debug() << "is valid: " << dist.first << " dist : " << dist.second << "\n";
430  if(dist.first){
431  // check ga
432  double gap=fabs(dist.second-(*p_iter)->getRad());
433  console.Debug() << "radius: " << (*p_iter)->getRad() << " gap : " << gap << "\n";
434  // if small enough, add
435  if(gap<gmax){
436  console.Debug() << "Inserting " << (*p_iter)->getID() << " !!\n";
437  bool in_flag = this->m_ppa->isInInner((*p_iter)->getPos());
438  m_edge_interactions.push_back(typename IType::TriIntType((*p_iter),&(*ed_iter),m_param,in_flag));
439  m_edge_int_set.insert(make_pair(ed_iter->getID(),(*p_iter)->getID()));
440  id_set.insert((*p_iter)->getID());
441  }
442  }
443  }
444  }
445  }
446 }
447 
448 template <class ParticleType,class IType>
450 {
451  return
453  m_edge_interactions.begin(),
454  m_edge_interactions.end(),
455  this->m_ppa
456  );
457 }
458 
459 template <class ParticleType,class IType>
461 {
462  const std::string delim = "\n";
463  typedef typename IType::TriIntType::CheckPointable CheckPointable;
464 
465  InteractionIterator it = getInnerInteractionIterator();
466  ost << IType::getType() << delim;
467  ost << it.getNumRemaining();
468  while (it.hasNext()){
469  ost << delim;
470  CheckPointable(it.next()).saveSnapShotData(ost);
471  }
472 }
473 
474 template <class ParticleType,class IType>
476 {
477  const std::string delim = "\n";
478  typedef typename IType::TriIntType::CheckPointable CheckPointable;
479 
480  InteractionIterator it = getInnerInteractionIterator();
481  ost << IType::getType() << delim;
482  ost << it.getNumRemaining();
483  while (it.hasNext()){
484  ost << delim;
485  CheckPointable(it.next()).saveCheckPointData(ost);
486  }
487 }
488 
489 template <class ParticleType,class IType>
491 {
492  console.Critical() << "Mesh2D_PIS_EB<ParticleType,IType>::loadCheckPointData NOT IMPLEMENTED\n";
493 }
494 
495 // --- Iterator members ---
496 
497 template <class ParticleType,class IType>
499  : m_numRemaining(0),
500  m_it(end),
501  m_end(end),
502  m_ppa(ppa)
503 {
504  m_numRemaining = 0;
505  for (Iterator it = begin; it != end; it++) {
506  if (isInner(it)) {
507  m_numRemaining++;
508  }
509  }
510  m_it = begin;
511  m_end = end;
512 }
513 
514 
515 template <class ParticleType,class IType>
517 {
518  return (m_numRemaining > 0);
519 }
520 
521 template <class ParticleType,class IType>
523 {
524  while (!isInner(m_it)) {
525  m_it++;
526  }
527  Interaction &i = *m_it;
528  m_it++;
529  m_numRemaining--;
530  return i;
531 }
532 
533 template <class ParticleType,class IType>
535 {
536  return m_numRemaining;
537 }
538 
539 template <class ParticleType,class IType>
541 {
542  return m_ppa->isInInner(it->getPos());
543 }
Mesh2D_PIS_EB::InteractionIterator::Interaction
IType::TriIntType Interaction
Definition: mesh2d_pis_eb.h:48
Mesh2D_PIS_EB::calcForces
virtual void calcForces()
Definition: mesh2d_pis_eb.hpp:65
Mesh2D_PIS_EB::Mesh2D_PIS_EB
Mesh2D_PIS_EB(Mesh2D *, ParallelParticleArray< ParticleType > *, typename IType::ParameterType)
Definition: mesh2d_pis_eb.hpp:26
Mesh2D_PIS_EB::saveCheckPointData
virtual void saveCheckPointData(std::ostream &)
Definition: mesh2d_pis_eb.hpp:475
Mesh2D_PIS_EB::isIn
virtual bool isIn(const vector< int > &)
Definition: mesh2d_pis_eb.hpp:44
Mesh2D_PIS_EB::exchange
virtual void exchange()
Definition: mesh2d_pis_eb.hpp:130
Mesh2D_PIS_EB::InteractionIterator
Definition: mesh2d_pis_eb.h:46
Console::Debug
Console & Debug()
set verbose level of next message to "dbg"
Console::Error
Console & Error()
set verbose level of next message to "err"
ParallelParticleArray::getParticlePtrByIndex
T * getParticlePtrByIndex(int)
Definition: pp_array.hpp:220
Mesh2D_PIS_EB::InteractionIterator::InteractionIterator
InteractionIterator(Iterator begin, Iterator end, AParallelParticleArray *ppa)
Definition: mesh2d_pis_eb.hpp:498
Mesh2D
Definition: Mesh2D.h:47
AParallelParticleArray::isInInner
virtual bool isInInner(const Vec3 &)=0
Mesh2D_PIS_EB::m_param
IType::ParameterType m_param
Definition: mesh2d_pis_eb.h:34
Mesh2D_PIS_EB::saveSnapShotData
virtual void saveSnapShotData(std::ostream &)
Definition: mesh2d_pis_eb.hpp:460
Mesh2D_PIS_EB::InteractionIterator::m_it
Iterator m_it
Definition: mesh2d_pis_eb.h:64
Mesh2D_PIS_EB::InteractionIterator::Iterator
list< Interaction >::iterator Iterator
Definition: mesh2d_pis_eb.h:49
ParallelParticleArray::ParticleListIterator
NeighborTable< T >::particlelist::iterator ParticleListIterator
Definition: pp_array.h:80
ParallelParticleArray
parrallel particle storage array with neighborsearch and variable exchange
Definition: pp_array.h:75
Console::XDebug
Console & XDebug()
set verbose level of next message to "xdg"
NULL
#define NULL
Definition: t_list.h:17
Console::Critical
Console & Critical()
set verbose level of next message to "crt"
Definition: console.cpp:141
Mesh2D_PIS_EB::InteractionIterator::m_end
Iterator m_end
Definition: mesh2d_pis_eb.h:65
AParallelParticleArray
abstract base class for parallel particle storage array
Definition: pp_array.h:42
Mesh2D_PIS_EB::InteractionIterator::isInner
bool isInner(const Iterator &it)
Definition: mesh2d_pis_eb.hpp:540
Mesh2D_PIS_EB::InteractionIterator::hasNext
bool hasNext()
Definition: mesh2d_pis_eb.hpp:516
Mesh2D_PIS_EB::loadCheckPointData
virtual void loadCheckPointData(std::istream &)
Definition: mesh2d_pis_eb.hpp:490
Mesh2D_PIS_EB::tryInsert
virtual void tryInsert(const typename IType::TriIntType &)
Definition: mesh2d_pis_eb.hpp:261
T_Handle
Template class for a handle/ref. counted pointer.
Definition: handle.h:27
Mesh2D_PIS_EB::update
virtual bool update()
Definition: mesh2d_pis_eb.hpp:87
Mesh2D_PIS_EB
Class for parallel storage of interactions between a 2D mesh and particles which does require exchang...
Definition: mesh2d_pis_eb.h:27
esys::lsm::bpu::iter
boost::python::object iter(const boost::python::object &pyOb)
Definition: Util.h:25
Mesh2D_PIS_EB::InteractionIterator::getNumRemaining
int getNumRemaining()
Definition: mesh2d_pis_eb.hpp:534
Mesh2D_PIS_EB::setTimeStepSize
virtual void setTimeStepSize(double dt)
Definition: mesh2d_pis_eb.hpp:205
Mesh2D_PIS_EB::buildFromPPATagged
void buildFromPPATagged(int, int)
Definition: mesh2d_pis_eb.hpp:357
Mesh2D_PIS_EB::getInnerInteractionIterator
InteractionIterator getInnerInteractionIterator()
Definition: mesh2d_pis_eb.hpp:449
Mesh2D_PIS_EB::exchange_boundary
void exchange_boundary(int, int)
Definition: mesh2d_pis_eb.hpp:151
Mesh2D::edge_iterator
vector< Edge2D >::iterator edge_iterator
Definition: Mesh2D.h:57
Mesh2D_PIS_EB::InteractionIterator::m_numRemaining
int m_numRemaining
Definition: mesh2d_pis_eb.h:63
Mesh2D_PIS::m_update_timestamp
int m_update_timestamp
Definition: mesh2d_pis.h:39
Edge2D
class for edge in 2D "mesh"
Definition: Edge2D.h:39
Mesh2D_PIS_EB::InteractionIterator::next
Interaction & next()
Definition: mesh2d_pis_eb.hpp:522
AParallelInteractionStorage::m_ppa
AParallelParticleArray * m_ppa
Definition: pi_storage.h:47
Corner2D
Class representing the corner in a 2D "mesh".
Definition: Corner2D.h:35
console
Console console
Definition: console.cpp:25
Mesh2D_PIS_EB::rebuild
virtual void rebuild()
Definition: mesh2d_pis_eb.hpp:215
Mesh2D_PIS_EB::buildFromPPAByGap
void buildFromPPAByGap(double)
Definition: mesh2d_pis_eb.hpp:405
Mesh2D_PIS
Abstract base class for parallel storage of interactions between a 2D mesh and particles.
Definition: mesh2d_pis.h:37