MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
MercuryData.h
Go to the documentation of this file.
1 //Copyright (c) 2015, The MercuryDPM Developers Team. All rights reserved.
2 //For the list of developers, see <http://www.MercuryDPM.org/Team>.
3 //
4 //Redistribution and use in source and binary forms, with or without
5 //modification, are permitted provided that the following conditions are met:
6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above copyright
9 // notice, this list of conditions and the following disclaimer in the
10 // documentation and/or other materials provided with the distribution.
11 // * Neither the name MercuryDPM nor the
12 // names of its contributors may be used to endorse or promote products
13 // derived from this software without specific prior written permission.
14 //
15 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16 //ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 //WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 //DISCLAIMED. IN NO EVENT SHALL THE MERCURYDPM DEVELOPERS TEAM BE LIABLE FOR ANY
19 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 //ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 //(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 //SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #ifndef TOOLS_MERCURYDATA_H
27 #define TOOLS_MERCURYDATA_H
28 
29 #include <fstream>
30 #include <iostream>
31 #include <string>
32 #include <sstream>
33 #include <vector>
34 
40 template<std::size_t NDIMS>
42 {
43  public:
47  double position[NDIMS];
51  double velocity[NDIMS];
55  double rotation[NDIMS];
59  double angularV[NDIMS];
60 
64  double radius;
65 
69  std::size_t speciesID;
70 };
71 
79 template<>
80 struct MercuryParticle<2>
81 {
82  public:
86  double position[3];
90  double velocity[3];
94  double rotation[3];
98  double angularV[3];
99 
103  double radius;
104 
108  std::size_t speciesID;
109 
110 };
111 
115 template<std::size_t NDIMS>
116 std::istream& operator>>(std::istream& in, MercuryParticle<NDIMS>& part)
117 {
118  std::size_t i;
119  for (i = 0; i < NDIMS; i++)
120  in >> part.position[i];
121 
122  for (i = 0; i < NDIMS; i++)
123  in >> part.velocity[i];
124 
125  in >> part.radius;
126 
127  for (i = 0; i < NDIMS; i++)
128  in >> part.rotation[i];
129 
130  for (i = 0; i < NDIMS; i++)
131  in >> part.angularV[i];
132 
133  in >> part.speciesID;
134 
135  return in;
136 }
137 
138 template<>
139 std::istream& operator>><2>(std::istream& in, MercuryParticle<2>& part)
140 {
141  std::size_t i;
142  in >> part.position[0] >> part.position[2];
143  part.position[1] = 0;
144 
145  in >> part.velocity[0] >> part.velocity[2];
146  part.velocity[1] = 0;
147 
148  in >> part.radius;
149 
150  in >> part.rotation[1];
151  part.rotation[0] = part.rotation[2] = 0;
152 
153  in >> part.angularV[1];
154  part.angularV[0] = part.angularV[2] = 0;
155 
156  in >> part.speciesID;
157 
158  return in;
159 }
160 
161 
162 class MercuryDataFile;
163 
164 template<std::size_t NDIMS>
171 template<std::size_t NDIMS>
173 {
174  public:
179  double getTime() const
180  {
181  return time_;
182  }
183 
190  std::size_t getTimeStepID() const
191  {
192  return ID_;
193  }
194 
200  std::size_t getNumberOfParticles() const
201  {
202  return numParticles_;
203  }
204 
210  std::size_t size() const
211  {
212  return numParticles_;
213  }
214 
219  constexpr std::size_t getNumberOfDimensions() const
220  {
221  return NDIMS;
222  }
223 
227  typename std::vector< MercuryParticle<NDIMS> >::iterator begin()
228  {
229  return storage_.begin();
230  }
231 
235  typename std::vector< MercuryParticle<NDIMS> >::const_iterator begin() const
236  {
237  return storage_.begin();
238  }
239 
243  typename std::vector< MercuryParticle<NDIMS> >::iterator end()
244  {
245  return storage_.end();
246  }
247 
251  typename std::vector< MercuryParticle<NDIMS> >::const_iterator end() const
252  {
253  return storage_.end();
254  }
255 
260  {
261  return storage_[idx];
262  }
263 
267  const MercuryParticle<NDIMS>& operator[](std::size_t idx) const
268  {
269  return storage_[idx];
270  }
271 
272  private:
278  MercuryTimeStep(std::size_t id, MercuryDataFile *pData)
279  : time_(0), ID_(id), numParticles_(0), dataFile_(pData)
280  {
281  }
282 
287  : time_(0), ID_(0), numParticles_(0), dataFile_(nullptr)
288  {
289  }
290 
294  double time_;
298  std::size_t ID_;
302  std::size_t numParticles_;
306  double min_[NDIMS], max_[NDIMS];
312 
316  std::vector< MercuryParticle<NDIMS> > storage_;
317 
318  template<std::size_t NDIMS2>
319  friend std::istream& operator>>(std::istream&, MercuryTimeStep<NDIMS2>&);
320 
321  friend class MercuryTimeStepIterator<NDIMS>;
322 
323  friend class MercuryDataFile;
324 };
325 
332 template<std::size_t NDIMS>
333 std::istream& operator>>(std::istream& in, MercuryTimeStep<NDIMS>& step)
334 {
335  std::size_t i;
336  in >> step.numParticles_ >> step.time_;
337 
338  for (i = 0; i < NDIMS; i++)
339  in >> step.min_[i];
340 
341  for (i = 0; i < NDIMS; i++)
342  in >> step.max_[i];
343 
344  return in;
345 }
346 
356 template<std::size_t NDIMS>
358 {
359  public:
364  {
365  return (isEOFTimeStep_ != other.isEOFTimeStep_);
366  }
367 
372  {
373  return lastReadTimeStep_;
374  }
375 
380  {
381  return lastReadTimeStep_;
382  }
383 
389  void operator++();
390 
391  private:
396  : isEOFTimeStep_(true), dataFile_(nullptr)
397  {
398  }
399 
405  : lastReadTimeStep_(0,pData), isEOFTimeStep_(false), dataFile_(pData)
406  {
407  ++(*this);
408  lastReadTimeStep_.ID_ = 0;
409  }
410 
423 
424  friend class MercuryDataFile;
425 };
426 
427 
435 {
436  public:
442  MercuryDataFile(std::string name)
443  : file_(name)
444  { }
445 
453  operator bool() const
454  {
455  return file_.good();
456  }
457 
469  template<std::size_t NDIMS>
471  {
472  //Store the position, so we can jump back at the end of the function..
473  std::ios::pos_type currentPosition = file_.tellg();
474  //and jump to the start
475  file_.seekg(0);
476  //get the first line
477  std::string line;
478  std::getline(file_, line);
479  file_.seekg(currentPosition); //and pretend nothing has happened
480 
481  std::istringstream lineStream(line);
482 
483  //We'll try to find out if there were exactly enough arguments.
485  lineStream >> step;
486 
487  //Did we reach the end yet?
488  bool isValid = lineStream.good();
489  double dummy;
490  lineStream >> dummy;
491 
492  //now we should have reached it.
493  isValid = isValid && !lineStream.good();
494  return isValid;
495  }
496 
503  template<std::size_t NDIMS>
505  {
506  private:
508  : data_(pData)
509  { }
510 
512  public:
514  {
515  return data_->begin<NDIMS>();
516  }
518  {
519  return data_->end<NDIMS>();
520  }
521  friend class MercuryDataFile;
522  };
523 
524  template<std::size_t NDIMS>
526  {
527  return {this};
528  };
529 
539  template<std::size_t NDIMS>
541  {
542  file_.seekg(0);
543  return {this};
544  }
545 
549  template<std::size_t NDIMS>
551  {
552  return {};
553  }
554  private:
558  std::ifstream file_;
559 
560  template<std::size_t NDIMS>
561  friend class MercuryTimeStep;
562  template<std::size_t NDIMS>
564 };
565 
566 template<std::size_t NDIMS>
568 {
569  lastReadTimeStep_.ID_++;
570 
571  std::string line;
572  std::getline(dataFile_->file_, line);
573 
574  std::istringstream lineStream(line);
575 
576  lineStream >> lastReadTimeStep_;
577 
578  //I hope we didn't went beyond end of file...
579  if (lineStream.eof())
580  {
581 // logger(WARN, "The timestep header detected an EOF.. Usually this"
582 // " means that the format was not what it appeared to be."
583 // "\nproceed with caution!");
584  }
585  //Resize the backing storage container to make sure we can actually
586  //fit all the particles in there.
587  lastReadTimeStep_.storage_.resize(lastReadTimeStep_.numParticles_);
588  //Well, now that we're set up, read all the particles
589  for (MercuryParticle<NDIMS>& part : lastReadTimeStep_)
590  {
591  //line by line, because no data format can be trusted.
592  std::getline(dataFile_->file_, line);
593  lineStream.clear();
594  lineStream.str(line);
595 
596  lineStream >> part;
597  }
598 
599  if (dataFile_->file_.eof())
600  isEOFTimeStep_ = true;
601 }
602 
603 #endif
constexpr std::size_t getNumberOfDimensions() const
returns the number of dimensions used.
Definition: MercuryData.h:219
std::vector< MercuryParticle< NDIMS > >::iterator begin()
Iterator functions for range based for loops.
Definition: MercuryData.h:227
std::size_t speciesID
Definition: MercuryData.h:108
std::vector< MercuryParticle< NDIMS > > storage_
Definition: MercuryData.h:316
double velocity[NDIMS]
Definition: MercuryData.h:51
MercuryTimeStep(std::size_t id, MercuryDataFile *pData)
Constructor used by the MercuryTimeStepIterator, to flag a functional timestep.
Definition: MercuryData.h:278
std::size_t getTimeStepID() const
Gets the timestep ID Returns the timestep ID, which is a consecutively ascending number unique for th...
Definition: MercuryData.h:190
MercuryDataFile * dataFile_
Definition: MercuryData.h:311
bool operator!=(MercuryTimeStepIterator< NDIMS > other) const
Not-equals operator, as defined for ForwardIterators.
Definition: MercuryData.h:363
IteratorProxy< NDIMS > as()
Definition: MercuryData.h:525
friend std::istream & operator>>(std::istream &, MercuryTimeStep< NDIMS2 > &)
MercuryTimeStepIterator< NDIMS > end() const
Returns a forwarditerator one past the last timestep.
Definition: MercuryData.h:550
bool isMercuryDataFile()
Checks if this file is a valid Mercury 3D data file. This function jumps to the start of the file...
Definition: MercuryData.h:470
MercuryParticle< NDIMS > & operator[](std::size_t idx)
Random access function into the particles.
Definition: MercuryData.h:259
const MercuryTimeStep< NDIMS > & operator*() const
Const dereference operator, as defined for constant ForwardIterators.
Definition: MercuryData.h:379
double angularV[NDIMS]
Definition: MercuryData.h:59
std::ifstream file_
Definition: MercuryData.h:558
double position[NDIMS]
Definition: MercuryData.h:47
double min_[NDIMS]
Definition: MercuryData.h:306
MercuryTimeStepIterator< NDIMS > begin()
Returns a forwarditerator to the timesteps Returns a forwarditerator to the timesteps, invalidating any other valid iterators in the process (since this is a lazy loader and does not actually load the entire file in memory). End iterators do not get invalidated. This function makes no guarantee for the validity of the file-state.
Definition: MercuryData.h:540
std::vector< MercuryParticle< NDIMS > >::const_iterator end() const
Iterator functions for range based for loops.
Definition: MercuryData.h:251
std::istream & operator>>(std::istream &in, MercuryParticle< NDIMS > &part)
Read a single particle from a istream.
Definition: MercuryData.h:116
MercuryTimeStepIterator< NDIMS > end()
Definition: MercuryData.h:517
double rotation[NDIMS]
Definition: MercuryData.h:55
MercuryTimeStep< NDIMS > & operator*()
Dereference operator, as defined for ForwardIterators.
Definition: MercuryData.h:371
void operator++()
Pre-increment operator, as defined for ForwardIterators This method populates the timestep...
Definition: MercuryData.h:567
std::size_t size() const
Gets the number of particles recorded in this timestep.
Definition: MercuryData.h:210
MercuryTimeStepIterator< NDIMS > begin()
Definition: MercuryData.h:513
MercuryTimeStep()
EOF-Timestep constructor used by MercuryTimeStepIterator (and MercuryDataFile::isMercury3DDataFile())...
Definition: MercuryData.h:286
double max_[NDIMS]
Definition: MercuryData.h:306
MercuryTimeStep< NDIMS > lastReadTimeStep_
Definition: MercuryData.h:414
std::size_t numParticles_
Definition: MercuryData.h:302
MercuryDataFile * dataFile_
Definition: MercuryData.h:422
MercuryDataFile(std::string name)
Definition: MercuryData.h:442
std::size_t ID_
Definition: MercuryData.h:298
MercuryTimeStepIterator(MercuryDataFile *pData)
Definition: MercuryData.h:404
IteratorProxy(MercuryDataFile *pData)
Definition: MercuryData.h:507
std::vector< MercuryParticle< NDIMS > >::const_iterator begin() const
Iterator functions for range based for loops.
Definition: MercuryData.h:235
const MercuryParticle< NDIMS > & operator[](std::size_t idx) const
Random access function into the particles.
Definition: MercuryData.h:267
std::size_t getNumberOfParticles() const
Gets the number of particles recorded in this timestep.
Definition: MercuryData.h:200
double getTime() const
Gets the time associated with this timestep.
Definition: MercuryData.h:179
std::vector< MercuryParticle< NDIMS > >::iterator end()
Iterator functions for range based for loops.
Definition: MercuryData.h:243
std::size_t speciesID
Definition: MercuryData.h:69