ESyS-Particle  2.3.4
trimesh_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 #include "Foundation/console.h"
14 
15 template<class ParticleType,class IType>
17 
25 template<class ParticleType,class IType>
27  : TriMesh_PIS<ParticleType>(mesh_p,ppa_p),m_comm(ppa_p->getComm())
28 {
29  console.XDebug() << "TriMesh_PIS_EB constructor\n";
30  m_param=param;
31  this->m_update_timestamp = 0;
32 }
33 
34 template <class ParticleType,class IType>
36 {
37 }
38 
48 template <class ParticleType,class IType>
49 bool TriMesh_PIS_EB<ParticleType,IType>::isIn(const std::vector<int>& v)
50 {
51  bool res=false;
52 
53  if(v.size()<3){
54  res=false;
55  } else {
56  switch (v[2]){
57  case 0: res=m_tri_int_set.find(make_pair(v[0],v[1]))!=m_tri_int_set.end(); break;
58  default: console.Error() << "wrong value in argument of TriMesh_PIS::isIn !!\n"; break;
59  }
60  }
61 
62  return res;
63 }
64 
68 template<class ParticleType,class IType>
70 {
71  console.XDebug() << "TriMesh_PIS_EB calculating " << m_triangle_interactions.size() << " triangle forces\n";
72 
73  // calculate forces for triangle interactions
74  for(typename list<typename IType::TriIntType>::iterator tri_iter=m_triangle_interactions.begin();
75  tri_iter!=m_triangle_interactions.end();
76  tri_iter++){
77  tri_iter->calcForces();
78  }
79 }
80 
83 template<class ParticleType,class IType>
85 {
86  console.XDebug() << "TriMesh_PIS_EB::update on node " << m_comm.rank() << "\n";
87  bool res=false;
88 
89  typename list<typename IType::TriIntType>::iterator iter=m_triangle_interactions.begin();
90  while(iter!=m_triangle_interactions.end()){
91  if(iter->broken()){
92  res=true;
93  typename list<typename IType::TriIntType>::iterator er_iter=iter;
94  iter++;
95  // remove ids from map
96  m_tri_int_set.erase(make_pair(er_iter->getTid(),er_iter->getPid()));
97  // remove interaction
98  m_triangle_interactions.erase(er_iter);
99  } else {
100  iter++;
101  }
102  }
103 
104  console.XDebug() << "end TriMesh_PIS_EB::update on node " << m_comm.rank() << "\n";
105  return res;
106 }
107 
114 template<class ParticleType,class IType>
116 {
117  console.XDebug() << "TriMesh_PIS_EB::exchange_boundary(" << dim << "," << dir << ") at node " << m_comm.rank() << "\n";
118 
119  std::set<int> bdry_ids;
120  std::vector<typename IType::TriIntType> recv_tri_buffer;
121  std::vector<typename IType::TriIntType> send_tri_buffer;
122 
123  // --- setup data to send ---
124  // get boundary
125  bdry_ids = this->m_ppa->getBoundarySlabIds(dim,dir);
126  // for all interactions
127  for(typename list<typename IType::TriIntType>::iterator iter=m_triangle_interactions.begin();
128  iter!=m_triangle_interactions.end();
129  iter++){
130  int pid=iter->getPid();
131  if(bdry_ids.find(pid)!=bdry_ids.end()) { // if particle in interaction is in bdry -> put in buffer
132  send_tri_buffer.push_back(*iter);
133  }
134  }
135  // ---- shift ----
136  m_comm.shift_cont_packed(send_tri_buffer,recv_tri_buffer,dim,dir,m_exchg_tag);
137  // insert received data
138  for(typename std::vector<typename IType::TriIntType>::iterator iter=recv_tri_buffer.begin();
139  iter!=recv_tri_buffer.end();
140  iter++){
141  tryInsert(*iter);
142  }
143 
144  console.XDebug() << "end TriMesh_PIS_EB::exchange_boundary\n";
145 }
146 
149 template<class ParticleType,class IType>
151 {
152  console.XDebug() << "TriMesh_PIS_EB::exchange\n";
153  for(int i=0;i<3;i++){
154  if(m_comm.get_dim(i)>1){
155  // -- up --
156  exchange_boundary(i,1);
157  // -- down --
158  exchange_boundary(i,-1);
159  }
160  }
161  console.XDebug() << "end TriMesh_PIS_EB::exchange\n";
162 }
163 
169 template<class ParticleType,class IType>
171 {
172  console.XDebug() << "TriMesh_PIS_EB::rebuild on node " << m_comm.rank() << "\n";
174  (ParallelParticleArray<ParticleType>*)(this->m_ppa); // should be a dynamic_cast
175  // for all triangle interactions
176  typename list<typename IType::TriIntType>::iterator ti_iter=m_triangle_interactions.begin();
177  while(ti_iter!=m_triangle_interactions.end()){
178  int pid=ti_iter->getPid();
179  ParticleType *part_p=t_ppa->getParticlePtrByIndex(pid);
180  if(part_p!=NULL) { // particle is available in m_ppa -> setup pointer in interaction
181  ti_iter->setPP(part_p);
182  Triangle *tri_p = this->m_mesh->getTriangleById(ti_iter->getTid());
183  ti_iter->setTP(tri_p);
184  ti_iter++;
185  } else { // particle is not available in m_ppa -> remove interaction
186  const typename list<typename IType::TriIntType>::iterator er_iter=ti_iter;
187  ti_iter++;
188  m_tri_int_set.erase(make_pair(er_iter->getTid(),pid));
189  m_triangle_interactions.erase(er_iter);
190  }
191  }
192 
193  console.XDebug() << "end TriMesh_PIS_EB::rebuild on node " << m_comm.rank() << "\n";
194 }
195 
207 template<class ParticleType,class IType>
208 void TriMesh_PIS_EB<ParticleType,IType>::tryInsert(const std::vector<int>& pids)
209 {
211  (ParallelParticleArray<ParticleType>*)(this->m_ppa); // should be dynamic_cast
212 
213  if(pids.size()<3){
214  bool is_in=isIn(pids); // interaction already in
215  ParticleType *part_p=t_ppa->getParticlePtrByIndex(pids[1]);
216  if((!is_in) && (part_p!=NULL)){
217  switch (pids[2]){
218  case 0: {
219  Triangle *tri_p = this->m_mesh->getTriangleById(pids[0]);
220  if (tri_p!=NULL){
221  m_triangle_interactions.push_back(
222  typename IType::TriIntType(
223  part_p,
224  tri_p,
225  m_param,
226  this->m_ppa->isInInner(part_p->getPos())
227  )
228  );
229  m_tri_int_set.insert(make_pair(pids[0],pids[1]));
230  }
231  } break;
232  default : {
233  console.Error()
234  << "Error: pids[2]= " << pids[2]
235  << "\n"; // Can't happen !!
236  }
237  }
238  }
239  }
240 }
241 
244 template<class ParticleType,class IType>
245 void TriMesh_PIS_EB<ParticleType,IType>::tryInsert(const typename IType::TriIntType& In)
246 {
248  (ParallelParticleArray<ParticleType>*)(this->m_ppa);
249  // check if interaction is already in
250  bool is_in=(m_tri_int_set.find(make_pair(In.getTid(),In.getPid()))!=m_tri_int_set.end());
251  ParticleType *part_p=t_ppa->getParticlePtrByIndex(In.getPid());
252  if((!is_in) && (part_p!=NULL)){
253  m_triangle_interactions.push_back(In);
254  m_tri_int_set.insert(make_pair(In.getTid(),In.getPid()));
255  }
256 }
257 
260 template<class ParticleType,class IType>
262 {
263  console.XDebug() << "TriMesh_PIS_EB::buildFromPPATagged(" << tag << "," << mask << ")\n";
264  set<int> id_set;
265 
266 
267  // for all triangles
268  for (
269  TriMesh::triangle_iterator tri_iter = this->m_mesh->triangles_begin();
270  tri_iter != this->m_mesh->triangles_end();
271  tri_iter++
272  ){
273  // get particles near triangle
275  ((ParallelParticleArray<ParticleType>*)this->m_ppa)->getParticlesNearTriangle(*tri_iter);
276  console.XDebug() << "triangle " << tri_iter->getID() << " nr. of particles : " << plh->size() << "\n";
277  // for all particles found
278  for(typename ParallelParticleArray<ParticleType>::ParticleListIterator p_iter=plh->begin();
279  p_iter!=plh->end();
280  p_iter++){
281  // if valid interaction
282  console.XDebug() << "interaction : " << tri_iter->getID() << " " << (*p_iter)->getID() << "\n";
283  if(id_set.find((*p_iter)->getID())==id_set.end()){
284  pair<bool,double> dist=tri_iter->dist((*p_iter)->getPos());
285  console.XDebug() << "is valid: " << dist.first << " dist : " << dist.second << "\n";
286  if(dist.first){
287  int ptag=(*p_iter)->getTag();
288  // if tag is correct, add interaction
289  if((ptag & mask)==(tag & mask)){
290  console.XDebug() << "Insert !!\n";
291  bool in_flag = this->m_ppa->isInInner((*p_iter)->getPos());
292  m_triangle_interactions.push_back(typename IType::TriIntType((*p_iter),&(*tri_iter),m_param,in_flag));
293  m_tri_int_set.insert(make_pair(tri_iter->getID(),(*p_iter)->getID()));
294  id_set.insert((*p_iter)->getID());
295  }
296  }
297  }
298  }
299  }
300  console.XDebug() << "end TriMesh_PIS_EB::buildFromPPATagged()";
301 }
302 
305 template<class ParticleType,class IType>
307 {
308  console.XDebug() << "TriMesh_PIS_EB::buildFromPPAByGap(" << gmax << ")\n";
309  set<int> id_set;
310 
311  // for all triangles
312  for (
313  TriMesh::triangle_iterator tri_iter = this->m_mesh->triangles_begin();
314  tri_iter != this->m_mesh->triangles_end();
315  tri_iter++
316  ){
317  // get particles near triangle
319  ((ParallelParticleArray<ParticleType>*)this->m_ppa)->getParticlesNearTriangle(*tri_iter);
320  console.XDebug() << "triangle " << tri_iter->getID() << " nr. of particles : " << plh->size() << "\n";
321  // for all particles found
322  for(typename ParallelParticleArray<ParticleType>::ParticleListIterator p_iter=plh->begin();
323  p_iter!=plh->end();
324  p_iter++){
325  // if valid interaction
326  console.XDebug() << "interaction : " << tri_iter->getID() << " " << (*p_iter)->getID() << "\n";
327  if(id_set.find((*p_iter)->getID())==id_set.end()){
328  pair<bool,double> dist=tri_iter->dist((*p_iter)->getPos());
329  console.XDebug() << "is valid: " << dist.first << " dist : " << dist.second << "\n";
330  if(dist.first){
331  // check gap
332  double gap=fabs(dist.second-(*p_iter)->getRad());
333  console.XDebug() << "radius: " << (*p_iter)->getRad() << " gap : " << gap << "\n";
334  // if small enough, add
335  if(gap<gmax){
336  console.XDebug() << "Insert !!\n";
337  bool in_flag = this->m_ppa->isInInner((*p_iter)->getPos());
338  m_triangle_interactions.push_back(typename IType::TriIntType((*p_iter),&(*tri_iter),m_param,in_flag));
339  m_tri_int_set.insert(make_pair(tri_iter->getID(),(*p_iter)->getID()));
340  id_set.insert((*p_iter)->getID());
341  }
342  }
343  }
344  }
345  }
346  console.XDebug() << "end TriMesh_PIS_EB::buildFromPPAByGap()";
347 }
348 
354 template<class ParticleType,class IType>
356 {
357  const std::string delim = "\n";
358  typedef typename IType::TriIntType::CheckPointable CheckPointable;
359 
360  // stage 1: count how many interactions with "inner" particles we have
361  int icount=0;
362  for(typename list<typename IType::TriIntType>::iterator it=m_triangle_interactions.begin();
363  it!=m_triangle_interactions.end();
364  it++){
365  if(it->isInner()) icount++;
366  }
367 
368  // stage 2: write data
369  oStream << IType::getType() << delim;
370  oStream << icount << delim;
371  for(typename list<typename IType::TriIntType>::iterator it=m_triangle_interactions.begin();
372  it!=m_triangle_interactions.end();
373  it++){
374  if(it->isInner()) CheckPointable(*it).saveCheckPointData(oStream);
375  oStream << delim;
376  }
377 }
TriMesh_PIS
Abstract base class for parallel storage of interactions between a triangle mesh and particles.
Definition: trimesh_pis.h:29
Triangle
Class representing a Triangle.
Definition: Triangle.h:48
TriMesh_PIS_EB::TriMesh_PIS_EB
TriMesh_PIS_EB(TriMesh *, ParallelParticleArray< ParticleType > *, typename IType::ParameterType)
Definition: trimesh_pis_eb.hpp:26
Console::Error
Console & Error()
set verbose level of next message to "err"
TriMesh_PIS_EB::rebuild
virtual void rebuild()
Definition: trimesh_pis_eb.hpp:170
TriMesh_PIS_EB::m_param
IType::ParameterType m_param
Definition: trimesh_pis_eb.h:36
console.h
ParallelParticleArray::getParticlePtrByIndex
T * getParticlePtrByIndex(int)
Definition: pp_array.hpp:220
TriMesh_PIS_EB
Class for parallel storage of interactions between a triangle mesh and particles which does require e...
Definition: trimesh_pis_eb.h:30
TriMesh_PIS_EB::buildFromPPAByGap
void buildFromPPAByGap(double)
Definition: trimesh_pis_eb.hpp:306
TriMesh_PIS_EB::exchange_boundary
void exchange_boundary(int, int)
Definition: trimesh_pis_eb.hpp:115
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
TriMesh_PIS::m_update_timestamp
int m_update_timestamp
Definition: trimesh_pis.h:31
TriMesh_PIS_EB::exchange
virtual void exchange()
Definition: trimesh_pis_eb.hpp:150
TriMesh_PIS_EB::setTimeStepSize
virtual void setTimeStepSize(double dt)
Definition: trimesh_pis_eb.hpp:35
T_Handle
Template class for a handle/ref. counted pointer.
Definition: handle.h:27
TriMesh::triangle_iterator
vector< Triangle >::iterator triangle_iterator
Definition: TriMesh.h:64
esys::lsm::bpu::iter
boost::python::object iter(const boost::python::object &pyOb)
Definition: Util.h:25
TriMesh_PIS_EB::isIn
virtual bool isIn(const vector< int > &)
Definition: trimesh_pis_eb.hpp:49
TriMesh_PIS_EB::saveSnapShotData
virtual void saveSnapShotData(std::ostream &)
Definition: trimesh_pis_eb.hpp:355
TriMesh_PIS_EB::update
virtual bool update()
Definition: trimesh_pis_eb.hpp:84
TriMesh_PIS_EB::tryInsert
virtual void tryInsert(const typename IType::TriIntType &)
Definition: trimesh_pis_eb.hpp:245
console
Console console
Definition: console.cpp:25
TriMesh
class for a triangle mesh
Definition: TriMesh.h:51
TriMesh_PIS_EB::calcForces
virtual void calcForces()
Definition: trimesh_pis_eb.hpp:69
TriMesh_PIS_EB::buildFromPPATagged
void buildFromPPATagged(int, int)
Definition: trimesh_pis_eb.hpp:261