ESyS-Particle  2.2.2
LatticeMaster.hpp
Go to the documentation of this file.
1 // //
3 // Copyright (c) 2003-2013 by The University of Queensland //
4 // Earth Systems Science Computational Centre (ESSCC) //
5 // http://www.uq.edu.au/esscc //
6 // //
7 // Primary Business: Brisbane, Queensland, Australia //
8 // Licensed under the Open Software License version 3.0 //
9 // http://www.opensource.org/licenses/osl-3.0.php //
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  const int numBroadcastParticles = 50000;
274  particleVector.reserve(numBroadcastParticles);
275  console.XDebug()
276  << "CLatticeMaster::addParticles:"
277  << " Beginning add-particle loop..." << "\n";
278  for (int i = 0; particleIt.hasNext(); i++) {
279  const TmplParticle particle(particleIt.next());
280 
281  particleVector.push_back(particle);
282  if (((i+1) % 5000) == 0) {
283  console.XDebug()
284  << "CLatticeMaster::addParticles:"
285  << "Adding particle with id "
286  << particleVector.rbegin()->getID() << "\n";
287  }
288 
289  if (((i+1) % numBroadcastParticles) == 0)
290  {
291  console.XDebug() << "CLatticeMaster::addParticles:"
292  << " Broadcasting receive cmd...." << "\n";
293  cmd_buffer.broadcast(CMD_RECEIVEPARTICLES);
294  console.XDebug()
295  << "CLatticeMaster::addParticles: Broadcasting particles...." << "\n";
296  m_tml_global_comm.broadcast_cont_packed(particleVector);
297  barrier.wait("CLatticeMaster::addParticles: Post particle broadcast.");
298  barrier.wait("CLatticeMaster::addParticles: Post Command.");
299  particleVector.clear();
300  particleVector.reserve(numBroadcastParticles);
301  }
302  }
303  console.XDebug()
304  << "CLatticeMaster::addParticles: Done add-particle loop..." << "\n";
305  console.XDebug()
306  << "CLatticeMaster::addParticles: Broadcasting final particle-receive cmd"
307  << "\n";
308  cmd_buffer.broadcast(CMD_RECEIVEPARTICLES);
309  console.XDebug() << "CLatticeMaster::addParticles:"
310  << " Broadcasting final set of particles...\n";
311  m_tml_global_comm.broadcast_cont_packed(particleVector);
312  barrier.wait("Post final particle broadcast.");
313  barrier.wait("Post final particle-broadcast command.");
314  // -- build ntable
315  console.XDebug()
316  << "CLatticeMaster::addParticles: "
317  << "Building ntable (searchNeighbours)...\n";
318  searchNeighbors(true);
319  console.XDebug()
320  << "CLatticeMaster::addParticles: exit\n";
321 
322 }
323 
324 template <class TmplIterator>
325 void CLatticeMaster::addConnections(TmplIterator &connectionIt)
326 {
327  console.XDebug()
328  << "CLatticeMaster::addConnections: enter\n";
329 
330  CMPIBarrier barrier(m_global_comm);
331  CMPILCmdBuffer cmd_buffer(m_global_comm,m_global_rank);
332 
333  const int numBroadcastConnections = 100000;
334  vector<int> connectionBuffer;
335  connectionBuffer.reserve(numBroadcastConnections);
336  int i = 0;
337  for (; connectionIt.hasNext(); i++)
338  {
339  typename TmplIterator::value_type data = connectionIt.next();
340  connectionBuffer.push_back(data.getTag());
341  connectionBuffer.push_back(data.getP1Id());
342  connectionBuffer.push_back(data.getP2Id());
343  if ((i+1) % 50000 == 0)
344  {
345  console.XDebug() << "Adding connection number " << i << "\n";
346  }
347  if ((i+1) % numBroadcastConnections == 0)
348  {
349  console.XDebug() << "CLatticeMaster::addConnections:"
350  << " Broadcasting receive cmd...." << "\n";
351  cmd_buffer.broadcast(CMD_RECEIVECONNECTIONS);
352  console.XDebug()
353  << "CLatticeMaster::addConnections: Broadcasting connections...." << "\n";
354  m_tml_global_comm.broadcast_cont_packed(connectionBuffer);
355  barrier.wait("CLatticeMaster::addConnections: Post connection broadcast.");
356  barrier.wait("CLatticeMaster::addConnections: Post Command.");
357  connectionBuffer.clear();
358  connectionBuffer.reserve(numBroadcastConnections);
359  }
360  //m_temp_conn[data.getTag()].push_back(data.getP1Id());
361  //m_temp_conn[data.getTag()].push_back(data.getP2Id());
362  }
363  console.XDebug()
364  << "CLatticeMaster::addConnections: Done add-connection loop..." << "\n";
365  console.XDebug()
366  << "CLatticeMaster::addConnections: Broadcasting final connection-receive cmd"
367  << "\n";
368  cmd_buffer.broadcast(CMD_RECEIVECONNECTIONS);
369  console.XDebug() << "CLatticeMaster::addConnections:"
370  << " Broadcasting final set of connections...\n";
371  m_tml_global_comm.broadcast_cont_packed(connectionBuffer);
372  barrier.wait("Post final connection broadcast.");
373  barrier.wait("Post final connection-broadcast command.");
374 
375  console.XDebug()<< "Added " << i << " connections..." << "\n";
376  // -- build ntable
377  searchNeighbors(true);
378  console.XDebug()
379  << "CLatticeMaster::addConnections: exit\n";
380 }
Class for sending commands from the LatticeMaster to the SubLatticeControler.
Definition: mpicmdbuf.h:29
A convenience class encapsulating an MPI barrier. Includes timing of the wait and a debug message ( v...
Definition: mpibarrier.h:30
void visitMeshFaceReferences(const string &meshName)
Definition: LatticeMaster.hpp:81
ParticleIterator & getParticleIterator()
Definition: GeometryReader.cpp:281
void wait(const char *)
Definition: mpibarrier.cpp:32
int getNumRemaining() const
Definition: IterativeReader.hpp:51
command for getting mesh node reference list
Definition: GetRef_cmd.h:27
void addConnections(TmplIterator &it)
Definition: LatticeMaster.hpp:325
void visitParticles(const IdVector &particleIdVector, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:228
boost::python::object iter(const boost::python::object &pyOb)
Definition: Util.h:25
base class for broadcast commands
Definition: BroadCast_cmd.h:24
Definition: GeometryReader.h:158
Definition: GeometryInfo.h:33
std::vector< int > IdVector
Definition: LatticeMaster.h:546
void visitParticlesOfType(const IdVector &particleIdVector, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:185
void setLsmGeoVersion(float version)
Definition: GeometryInfo.cpp:320
Definition: IterativeReader.h:28
void visitTriMeshFaceForce(const string &meshName, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:147
const int CMD_RECEIVECONNECTIONS
Definition: sublattice_cmd.h:85
const int CMD_GETIDPARTICLEDATA
Definition: sublattice_cmd.h:66
Definition: GeometryReader.h:40
void addParticles(TmplIterator &it)
Definition: LatticeMaster.hpp:262
const int CMD_RECEIVEPARTICLES
Definition: sublattice_cmd.h:41
void readGeometry(const std::string &fileName)
Definition: LatticeMaster.hpp:29
void append(const TmplData &basicTypeData)
Definition: BroadCast_cmd.hpp:27
BasicCon & XDebug(bool h=true)
set verbose level of next message to &quot;xdg&quot;
Definition: console.cpp:316
float getLsmGeoVersion() const
Definition: GeometryInfo.cpp:328
const std::string & getParticleType()
Definition: GeometryReader.cpp:276
BasicCon & Debug(bool h=true)
set verbose level of next message to &quot;dbg&quot;
Definition: console.cpp:305
Con console
ConnectionIterator & getConnectionIterator()
Definition: GeometryReader.cpp:286
void wait(const std::string &barrierName)
Definition: BroadCast_cmd.cpp:38
void broadcast()
Definition: BroadCast_cmd.cpp:43
const int CMD_GETTRIMESHFORCE
Definition: sublattice_cmd.h:111
void broadcast(int)
Definition: mpicmdbuf.cpp:38
void visitMesh2dEdgeStress(const string &meshName, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:112
const int CMD_GETMESH2DSTRESS
Definition: sublattice_cmd.h:110
void visitMesh2dNodeReferences(const string &meshName, TmplVisitor &visitor)
Definition: LatticeMaster.hpp:87
void broadcastBuffer()
Definition: BroadCast_cmd.cpp:33
void broadcastCommand()
Definition: BroadCast_cmd.cpp:28
const GeometryInfo & getGeometryInfo() const
Definition: GeometryReader.cpp:266