ESyS-Particle  2.3.4
LatticeMaster.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 // --- Project includes ---
14 #include "Parallel/GetRef_cmd.h"
16 
17 // --- STL includes ---
18 #include <map>
19 #include <set>
20 
21 using namespace esys::lsm;
22 
28 template <class TmplParticle>
29 void CLatticeMaster::readGeometry(const std::string &fileName)
30 {
31  console.Debug()
32  << "begin CLatticeMaster::readGeometry: fileName="
33  << fileName << "\n";
34 
35  // setup geometry reader and get geometry info from header file
36  GeometryReader geoReader(fileName);
37  GeometryInfo geoInfo = geoReader.getGeometryInfo();
38 
39  // check if geometry info has been set previously
40  if(m_bbx_has_been_set){
41  // check if old & new geometry are compatible
42  if(!m_geo_info.isCompatible(geoInfo)){
43  std::cerr << "Geometry info read from file is incompatible with previously set geometry (bounding box, circular boundaries) - Model may not run properly!" << std::endl;
44  }
45  // set only the geometry version, the other geometry info remains unchanged
46  m_geo_info.setLsmGeoVersion(geoInfo.getLsmGeoVersion());
47  } else {
48  m_geo_info=geoInfo; // set full geometry meta-info
49 
50  // set model spatial domain -> sets geometry info & initializes neighbor table in workers
51  if(m_geo_info.hasAnyPeriodicDimensions()){
52  setSpatialDomain(m_geo_info.getBBoxCorners()[0],m_geo_info.getBBoxCorners()[1],m_geo_info.getPeriodicDimensions());
53  } else {
54  setSpatialDomain(m_geo_info.getBBoxCorners()[0],m_geo_info.getBBoxCorners()[1]);
55  }
56  m_bbx_has_been_set=true; // flag that spatial domain has been set
57  }
58 
59  // read particles
60  GeometryReader::ParticleIterator &particleIt = geoReader.getParticleIterator();
61  console.XDebug()<< "Number of particles: " << particleIt.getNumRemaining() << "\n";
62  if (geoReader.getParticleType() != "Simple") {
63  throw
64  std::runtime_error(
65  (std::string("Unknown particle type ") + geoReader.getParticleType()).c_str()
66  );
67  }
68 
69  addParticles<GeometryReader::ParticleIterator,TmplParticle>(particleIt);
70 
71  // read connections
73  geoReader.getConnectionIterator();
74  console.XDebug()<< "Number of connections: " << connectionIt.getNumRemaining() << "\n";
75 
76  addConnections(connectionIt);
77  console.Debug()<<"end CLatticeMaster::readGeometry\n";
78 }
79 
80 template <typename TmplVisitor>
81 void CLatticeMaster::visitMeshFaceReferences(const string &meshName)
82 {
83  throw std::runtime_error("CLatticeMaster::visitMeshFaceReferences: Not implemented.");
84 }
85 
86 template <typename TmplVisitor>
87 void CLatticeMaster::visitMesh2dNodeReferences(const string &meshName, TmplVisitor &visitor)
88 {
89  console.XDebug()<<"CLatticeMaster::visitMesh2dNodeReferences( " << meshName << ")\n";
90  GetNodeRefCommand cmd(getGlobalRankAndComm(),meshName);
91  // broadcast command
92  cmd.broadcast();
93 
94  // receive data (multimap)
95  std::multimap<int,int> ref_mmap;
96  m_tml_global_comm.gather(ref_mmap);
97  // collate into set
98  std::set<int> ref_set; //== this is the set of node ids ==
99  for(std::multimap<int,int>::iterator iter=ref_mmap.begin();
100  iter!=ref_mmap.end();
101  iter++){
102  ref_set.insert(iter->second);
103  }
104  for (std::set<int>::const_iterator it = ref_set.begin(); it != ref_set.end(); it++)
105  {
106  visitor.visitNodeRef(*it);
107  }
108  console.XDebug()<<"end CLatticeMaster::visitMesh2dNodeReferences()\n";
109 }
110 
111 template <typename TmplVisitor>
112 void CLatticeMaster::visitMesh2dEdgeStress(const string &meshName, TmplVisitor &visitor)
113 {
114  console.XDebug()<<"CLatticeMaster::visitMesh2dEdgeStress( " << meshName << ")\n";
115  std::multimap<int,pair<int,Vec3> > temp_mm;
116  std::map<int,Vec3> data; //=== map of id, value ===
117 
118  BroadcastCommand cmd(getGlobalRankAndComm(), CMD_GETMESH2DSTRESS);
119  cmd.append(meshName.c_str());
120  cmd.broadcastCommand();
121  cmd.broadcastBuffer();
122 
123  // get data from slaves
124  m_tml_global_comm.gather(temp_mm);
125 
126  // add data together
127  for(std::multimap<int,pair<int,Vec3> >::iterator iter=temp_mm.begin();
128  iter!=temp_mm.end();
129  iter++){
130  if(data.find((iter->second).first)==data.end()){ // id not in data -> insert
131  data.insert(iter->second);
132  } else { // id is in data -> add
133  data[(iter->second).first]+=(iter->second).second;
134  }
135  }
136 
137  for (std::map<int,Vec3>::const_iterator it = data.begin(); it != data.end(); it++)
138  {
139  visitor.visitRefStressPair(it->first, it->second);
140  }
141 
142  cmd.wait("visitMesh2dEdgeStress");
143  console.XDebug()<<"end CLatticeMaster::visitMesh2dEdgeStress()\n";
144 }
145 
146 template <typename TmplVisitor>
148  const string &meshName,
149  TmplVisitor &visitor
150 )
151 {
152  console.XDebug()<<"CLatticeMaster::visitTriMeshFaceForce( " << meshName << ")\n";
153  std::multimap<int,pair<int,Vec3> > temp_mm;
154  std::map<int,Vec3> data; //=== map of id, value ===
155 
156  BroadcastCommand cmd(getGlobalRankAndComm(), CMD_GETTRIMESHFORCE);
157  cmd.append(meshName.c_str());
158  cmd.broadcastCommand();
159  cmd.broadcastBuffer();
160 
161  // get data from slaves
162  m_tml_global_comm.gather(temp_mm);
163 
164  // add data together
165  for(std::multimap<int,pair<int,Vec3> >::iterator iter=temp_mm.begin();
166  iter!=temp_mm.end();
167  iter++){
168  if(data.find((iter->second).first)==data.end()){ // id not in data -> insert
169  data.insert(iter->second);
170  } else { // id is in data -> add
171  data[(iter->second).first]+=(iter->second).second;
172  }
173  }
174 
175  for (std::map<int,Vec3>::const_iterator it = data.begin(); it != data.end(); it++)
176  {
177  visitor.visitRefForcePair(it->first, it->second);
178  }
179 
180  cmd.wait("visitTriMeshFaceStress");
181  console.XDebug()<<"end CLatticeMaster::visitTriMeshFaceForce()\n";
182 }
183 
184 template <typename TmplVisitor, typename TmplParticle>
186  const IdVector &particleIdVector,
187  TmplVisitor &visitor
188 )
189 {
190  console.Debug() << "CLatticeMaster::visitParticlesOfType: enter\n";
191  typedef std::multimap<int,TmplParticle> ParticleMMap;
192  ParticleMMap particleMMap;
193 
194  console.Debug()
195  << "CLatticeMaster::visitParticlesOfType: broadcasting command\n";
196  BroadcastCommand cmd(getGlobalRankAndComm(), CMD_GETIDPARTICLEDATA);
197  cmd.broadcastCommand();
198 
199  console.Debug()
200  << "CLatticeMaster::visitParticlesOfType: broadcasting particle id's\n";
201  m_tml_global_comm.broadcast_cont(particleIdVector);
202 
203  console.Debug()
204  << "CLatticeMaster::visitParticlesOfType:"
205  << " gathering particle data from workers\n";
206  m_tml_global_comm.gather_packed(particleMMap);
207  console.Debug()
208  << "CLatticeMaster::visitParticlesOfType:"
209  << " gathered " << particleMMap.size() << " particles\n";
210 
211  console.Debug()
212  << "CLatticeMaster::visitParticlesOfType:"
213  << " visiting particle data\n";
214  for(
215  typename ParticleMMap::iterator iter=particleMMap.begin();
216  iter != particleMMap.end();
217  iter++
218  )
219  {
220  iter->second.visit(visitor);
221  }
222 
223  cmd.wait("visitParticles");
224  console.Debug() << "CLatticeMaster::visitParticlesOfType: exit\n";
225 }
226 
227 template <typename TmplVisitor>
229  const IdVector &particleIdVector,
230  TmplVisitor &visitor
231 )
232 {
233  console.Debug() << "CLatticeMaster::visitParticles: enter\n";
234 
235  if (m_particle_type == "Basic")
236  {
237  visitParticlesOfType<TmplVisitor,CParticle>(particleIdVector, visitor);
238  }
239  else if (m_particle_type == "Rot")
240  {
241  visitParticlesOfType<TmplVisitor,CRotParticle>(particleIdVector, visitor);
242  }
243  else if (m_particle_type == "RotVi")
244  {
245  visitParticlesOfType<TmplVisitor,CRotParticleVi>(particleIdVector, visitor);
246  }
247  else if (m_particle_type == "RotTherm")
248  {
249  visitParticlesOfType<TmplVisitor,CRotThermParticle>(particleIdVector, visitor);
250  }
251  else
252  {
253  throw
254  std::runtime_error(
255  std::string("Unknown particle type: ") + m_particle_type
256  );
257  }
258  console.Debug() << "CLatticeMaster::visitParticles: exit\n";
259 }
260 
261 template <class TmplIterator, class TmplParticle>
262 void CLatticeMaster::addParticles(TmplIterator &particleIt)
263 {
264  CMPIBarrier barrier(m_global_comm);
265  CMPILCmdBuffer cmd_buffer(m_global_comm,m_global_rank);
266 
267  // cast storage pointer to correct type
268  vector<TmplParticle> particleVector;
269  console.XDebug()
270  << "CLatticeMaster::addParticles:"
271  << " Reserving vector memory for particles.\n";
272 
273  // Determine the directions for calculating the minimum and maximum extents of particles.
274  // Indexes for valid directions x, y, z are 0, 1, 2. If a dimension is irrelevant for the
275  // purpose of finding particle extents (because it is periodic or does not factor into
276  // a 2D calculation), its index is 3. The indexes are sorted ascending to minimize the
277  // number of tests needed to process each particle in particlesMinMax(...).
278  esys::lsm::IntVector periodicity(3);
279  if (m_geo_info.hasAnyPeriodicDimensions())
280  periodicity = m_geo_info.getPeriodicDimensions();
281  for (int i=0; i<3; i++)
282  m_particle_dimensions[i] = periodicity[i]==0 ? i : 3;
283  if (m_geo_info.is2d())
284  m_particle_dimensions[2]=3;
285  int periodicTotal = periodicity[0] + periodicity[1] + periodicity[2];
286  if (periodicTotal==1 || periodicTotal==2)
287  std::sort(m_particle_dimensions.begin(), m_particle_dimensions.end());
288 
289  const int numBroadcastParticles = 50000;
290  particleVector.reserve(numBroadcastParticles);
291  console.XDebug()
292  << "CLatticeMaster::addParticles:"
293  << " Beginning add-particle loop..." << "\n";
294  for (int i = 0; particleIt.hasNext(); i++) {
295  const TmplParticle particle(particleIt.next());
296 
297  // Update the minimum and maximum extents of the particles as each is read in.
298  particlesMinMax(particle);
299 
300  particleVector.push_back(particle);
301  if (((i+1) % 5000) == 0) {
302  console.XDebug()
303  << "CLatticeMaster::addParticles:"
304  << "Adding particle with id "
305  << particleVector.rbegin()->getID() << "\n";
306  }
307 
308  if (((i+1) % numBroadcastParticles) == 0)
309  {
310  console.XDebug() << "CLatticeMaster::addParticles:"
311  << " Broadcasting receive cmd...." << "\n";
312  cmd_buffer.broadcast(CMD_RECEIVEPARTICLES);
313  console.XDebug()
314  << "CLatticeMaster::addParticles: Broadcasting particles...." << "\n";
315  m_tml_global_comm.broadcast_cont_packed(particleVector);
316  barrier.wait("CLatticeMaster::addParticles: Post particle broadcast.");
317  barrier.wait("CLatticeMaster::addParticles: Post Command.");
318  particleVector.clear();
319  particleVector.reserve(numBroadcastParticles);
320  }
321  }
322  console.XDebug()
323  << "CLatticeMaster::addParticles: Done add-particle loop..." << "\n";
324  console.XDebug()
325  << "CLatticeMaster::addParticles: Broadcasting final particle-receive cmd"
326  << "\n";
327  cmd_buffer.broadcast(CMD_RECEIVEPARTICLES);
328  console.XDebug() << "CLatticeMaster::addParticles:"
329  << " Broadcasting final set of particles...\n";
330  m_tml_global_comm.broadcast_cont_packed(particleVector);
331  barrier.wait("Post final particle broadcast.");
332  barrier.wait("Post final particle-broadcast command.");
333  // -- build ntable
334  console.XDebug()
335  << "CLatticeMaster::addParticles: "
336  << "Building ntable (searchNeighbours)...\n";
337  searchNeighbors(true);
338  console.XDebug()
339  << "CLatticeMaster::addParticles: exit\n";
340 
341 }
342 
343 template <class TmplIterator>
344 void CLatticeMaster::addConnections(TmplIterator &connectionIt)
345 {
346  console.XDebug()
347  << "CLatticeMaster::addConnections: enter\n";
348 
349  CMPIBarrier barrier(m_global_comm);
350  CMPILCmdBuffer cmd_buffer(m_global_comm,m_global_rank);
351 
352  const int numBroadcastConnections = 100000;
353  vector<int> connectionBuffer;
354  connectionBuffer.reserve(numBroadcastConnections);
355  int i = 0;
356  for (; connectionIt.hasNext(); i++)
357  {
358  typename TmplIterator::value_type data = connectionIt.next();
359  connectionBuffer.push_back(data.getTag());
360  connectionBuffer.push_back(data.getP1Id());
361  connectionBuffer.push_back(data.getP2Id());
362  if ((i+1) % 50000 == 0)
363  {
364  console.XDebug() << "Adding connection number " << i << "\n";
365  }
366  if ((i+1) % numBroadcastConnections == 0)
367  {
368  console.XDebug() << "CLatticeMaster::addConnections:"
369  << " Broadcasting receive cmd...." << "\n";
370  cmd_buffer.broadcast(CMD_RECEIVECONNECTIONS);
371  console.XDebug()
372  << "CLatticeMaster::addConnections: Broadcasting connections...." << "\n";
373  m_tml_global_comm.broadcast_cont_packed(connectionBuffer);
374  barrier.wait("CLatticeMaster::addConnections: Post connection broadcast.");
375  barrier.wait("CLatticeMaster::addConnections: Post Command.");
376  connectionBuffer.clear();
377  connectionBuffer.reserve(numBroadcastConnections);
378  }
379  //m_temp_conn[data.getTag()].push_back(data.getP1Id());
380  //m_temp_conn[data.getTag()].push_back(data.getP2Id());
381  }
382  console.XDebug()
383  << "CLatticeMaster::addConnections: Done add-connection loop..." << "\n";
384  console.XDebug()
385  << "CLatticeMaster::addConnections: Broadcasting final connection-receive cmd"
386  << "\n";
387  cmd_buffer.broadcast(CMD_RECEIVECONNECTIONS);
388  console.XDebug() << "CLatticeMaster::addConnections:"
389  << " Broadcasting final set of connections...\n";
390  m_tml_global_comm.broadcast_cont_packed(connectionBuffer);
391  barrier.wait("Post final connection broadcast.");
392  barrier.wait("Post final connection-broadcast command.");
393 
394  console.XDebug()<< "Added " << i << " connections..." << "\n";
395  // -- build ntable
396  searchNeighbors(true);
397  console.XDebug()
398  << "CLatticeMaster::addConnections: exit\n";
399 }
400 
401 template<typename TmplParticle>
402 void CLatticeMaster::particlesMinMax(const TmplParticle &particle)
403 {
404  Vec3 position = particle.getPos();
405  double radius = particle.getRad();
406 
407  for (int j=0, k=m_particle_dimensions[j]; j<3 && k<3; k=m_particle_dimensions[++j]) {
408  if (m_init_min_pt[k]!=m_init_min_pt[k] || position[k]-radius<m_init_min_pt[k])
409  m_init_min_pt[k] = position[k]-radius;
410  if (m_init_max_pt[k]!=m_init_max_pt[k] || position[k]+radius>m_init_max_pt[k])
411  m_init_max_pt[k] = position[k]+radius;
412  }
413 }
BroadcastCommand::broadcastCommand
void broadcastCommand()
Definition: BroadCast_cmd.cpp:28
CMD_RECEIVECONNECTIONS
const int CMD_RECEIVECONNECTIONS
Definition: sublattice_cmd.h:85
BroadcastCommand
base class for broadcast commands
Definition: BroadCast_cmd.h:25
esys::lsm::IntVector
std::vector< int > IntVector
Definition: LatticeMaster.h:116
CMPILCmdBuffer::broadcast
void broadcast(int)
Definition: mpicmdbuf.cpp:38
CLatticeMaster::addParticles
void addParticles(TmplIterator &it)
Definition: LatticeMaster.hpp:262
Console::Debug
Console & Debug()
set verbose level of next message to "dbg"
CMD_GETMESH2DSTRESS
const int CMD_GETMESH2DSTRESS
Definition: sublattice_cmd.h:121
esys::lsm::IStreamIterator::getNumRemaining
int getNumRemaining() const
Definition: IterativeReader.hpp:51
CLatticeMaster::visitMeshFaceReferences
void visitMeshFaceReferences(const string &meshName)
Definition: LatticeMaster.hpp:81
CLatticeMaster::visitTriMeshFaceForce
void visitTriMeshFaceForce(const string &meshName, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:147
GetRef_cmd.h
CMPIBarrier
A convenience class encapsulating an MPI barrier. Includes timing of the wait and a debug message ( v...
Definition: mpibarrier.h:31
CMD_RECEIVEPARTICLES
const int CMD_RECEIVEPARTICLES
Definition: sublattice_cmd.h:41
CLatticeMaster::visitParticles
void visitParticles(const IdVector &particleIdVector, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:228
esys::lsm::GeometryReader::getGeometryInfo
const GeometryInfo & getGeometryInfo() const
Definition: GeometryReader.cpp:266
Console::XDebug
Console & XDebug()
set verbose level of next message to "xdg"
esys::lsm::GeometryInfo::setLsmGeoVersion
void setLsmGeoVersion(float version)
Definition: GeometryInfo.cpp:320
esys::lsm::GeometryReader::getParticleIterator
ParticleIterator & getParticleIterator()
Definition: GeometryReader.cpp:281
esys::lsm::GeometryInfo::getLsmGeoVersion
float getLsmGeoVersion() const
Definition: GeometryInfo.cpp:328
esys::lsm::GeometryInfo
Definition: GeometryInfo.h:34
CMPILCmdBuffer
Class for sending commands from the LatticeMaster to the SubLatticeControler.
Definition: mpicmdbuf.h:30
esys::lsm::GeometryReader
Definition: GeometryReader.h:159
esys::lsm::GeometryReader::getParticleType
const std::string & getParticleType()
Definition: GeometryReader.cpp:276
CLatticeMaster::visitMesh2dNodeReferences
void visitMesh2dNodeReferences(const string &meshName, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:87
GetNodeRefCommand
command for getting mesh node reference list
Definition: GetRef_cmd.h:28
BroadcastCommand::broadcast
void broadcast()
Definition: BroadCast_cmd.cpp:43
CMD_GETTRIMESHFORCE
const int CMD_GETTRIMESHFORCE
Definition: sublattice_cmd.h:122
CMD_GETIDPARTICLEDATA
const int CMD_GETIDPARTICLEDATA
Definition: sublattice_cmd.h:66
Vec3
Definition: vec3.h:47
esys::lsm::bpu::iter
boost::python::object iter(const boost::python::object &pyOb)
Definition: Util.h:25
CLatticeMaster::visitMesh2dEdgeStress
void visitMesh2dEdgeStress(const string &meshName, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:112
BroadcastCommand::append
void append(const TmplData &basicTypeData)
Definition: BroadCast_cmd.hpp:27
CLatticeMaster::IdVector
std::vector< int > IdVector
Definition: LatticeMaster.h:588
BroadcastCommand::wait
void wait(const std::string &barrierName)
Definition: BroadCast_cmd.cpp:38
CLatticeMaster::particlesMinMax
void particlesMinMax(const TmplParticle &particle)
Definition: LatticeMaster.hpp:402
BroadcastCommand::broadcastBuffer
void broadcastBuffer()
Definition: BroadCast_cmd.cpp:33
CLatticeMaster::readGeometry
void readGeometry(const std::string &fileName)
Definition: LatticeMaster.hpp:29
CLatticeMaster::addConnections
void addConnections(TmplIterator &it)
Definition: LatticeMaster.hpp:344
esys::lsm::IStreamIterator
Definition: IterativeReader.h:29
GeometryReader.h
esys::lsm::GeometryReader::getConnectionIterator
ConnectionIterator & getConnectionIterator()
Definition: GeometryReader.cpp:286
CLatticeMaster::visitParticlesOfType
void visitParticlesOfType(const IdVector &particleIdVector, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:185
esys::lsm::ParticleIterator
Definition: GeometryReader.h:41
console
Console console
Definition: console.cpp:25
CMPIBarrier::wait
void wait(const char *)
Definition: mpibarrier.cpp:32
esys::lsm
Lattice Solid Model namespace.
Definition: CheckPointable.cpp:19