MercuryDPM  Beta
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
DPMBase.cc
Go to the documentation of this file.
1 //Copyright (c) 2013-2014, 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 
27 #include "DPMBase.h"
28 #include <iostream>
29 #include <iomanip>
30 #include <algorithm>
31 #include <cmath>
32 #include <fstream>
33 #include <cstdlib>
34 #include <limits>
35 #include <string>
36 #include <sstream>
37 #include <cstdio>
39 #include <cstring>
40 //This is only used to change the file permission of the xball script create, at some point this code may be moved from this file to a different file.
41 #include <sys/types.h>
42 #include <sys/stat.h>
45 
46 #include "Species/Species.h"
49 
50 //This is part of this class and just separates out the stuff to do with xballs.
51 #include "CMakeDefinitions.h"
52 #include "DPMBaseXBalls.icc"
53 #include "Logger.h"
54 #include "Particles/BaseParticle.h"
55 #include "Walls/BaseWall.h"
56 #include "Walls/InfiniteWall.h"
58 
63 void logWriteAndDie(std::string module, std::string message)
64 {
65  std::cerr << "A fatal error has occured"
66  << "\n Module :" << module
67  << "\n Message :" << message << std::endl;
68 
69  std::exit(-1);
70 }
75 std::ostream& operator<<(std::ostream& os, DPMBase &md)
76 {
77  md.write(os);
78  return os;
79 }
84  : FilesAndRunNumber(other)
85 {
86  constructor();
87 }
88 
93 {
96  gravity_ = other.gravity_;
97  xMin_ = other.xMin_;
98  xMax_ = other.xMax_;
99  yMin_ = other.yMin_;
100  yMax_ = other.yMax_;
101  zMin_ = other.zMin_;
102  zMax_ = other.zMax_;
103  time_ = other.time_;
104  timeStep_ = other.timeStep_;
105  ntimeSteps_ = other.ntimeSteps_;
106  timeMax_ = other.timeMax_;
107  restartVersion_ = other.restartVersion_; //to read new and old restart data
108  restarted_ = other.restarted_; //to see if it was restarted or not
109  append_ = other.append_;
110  rotation_ = other.rotation_;
111  xBallsColourMode_ = other.xBallsColourMode_; // sets the xballs argument cmode (see xballs.txt)
112  xBallsVectorScale_ = other.xBallsVectorScale_; // sets the xballs argument vscale (see xballs.txt)
113  xBallsScale_ = other.xBallsScale_; // sets the xballs argument scale (see xballs.txt)
114  xBallsAdditionalArguments_ = other.xBallsAdditionalArguments_; // std::string where additional xballs argument can be specified (see xballs.txt)
115 #ifdef CONTACT_LIST_HGRID
116  possibleContactList=other.possibleContactList;
117 #endif
118  random = other.random;
119 
124  wallHandler.setDPMBase(this);
125 
128  wallHandler = other.wallHandler;
131 }
136 {
137  constructor();
138 }
143 {
144 
145 }
150 void DPMBase::solve(int argc, char* argv[])
151 {
152  readArguments(argc, argv);
153  solve();
154 }
159 {
160  return time_;
161 }
165 unsigned int DPMBase::getNtimeSteps() const
166 {
167  return ntimeSteps_;
168 }
173 {
174  time_ = time;
175 }
180 {
181  if (newTMax >= 0)
182  {
183  timeMax_ = newTMax;
184  }
185  else
186  {
187  std::cerr << "Error in setTimeMax, newTMax=" << newTMax << std::endl;
188  exit(-1);
189  }
190 }
195 {
196  return timeMax_;
197 }
201 #ifdef CONTACT_LIST_HGRID
202 PossibleContactList& DPMBase::getPossibleContactList()
203 {
204  return possibleContactList;
205 }
206 #endif
207 
210 void DPMBase::setRotation(bool newRotFlag)
211 {
212  rotation_ = newRotFlag;
213 }
218 {
219  return rotation_;
220 }
225 {
226  return xMin_;
227 }
232 {
233  return xMax_;
234 }
239 {
240  return yMin_;
241 }
246 {
247  return yMax_;
248 }
253 {
254  return zMin_;
255 }
260 {
261  return zMax_;
262 }
267 {
268  if (newXMin <= getXMax())
269  {
270  xMin_ = newXMin;
271  }
272  else
273  {
274  std::cerr << "Warning in setXMin(" << newXMin << "): xMax=" << getXMax() << std::endl;
275  }
276 }
281 {
282  if (newYMin <= getYMax())
283  {
284  yMin_ = newYMin;
285  }
286  else
287  {
288  std::cerr << "Error in setYMin(" << newYMin << "): yMax=" << getYMax() << std::endl;
289  exit(-1);
290  }
291 }
296 {
297  if (newZMin <= getZMax())
298  {
299  zMin_ = newZMin;
300  }
301  else
302  {
303  std::cerr << "Warning in setZMin(" << newZMin << "): zMax=" << getZMax() << std::endl;
304  }
305 }
310 {
311  if (newXMax >= getXMin())
312  {
313  xMax_ = newXMax;
314  }
315  else
316  {
317  std::cerr << "Error in setXMax(" << newXMax << "): xMin=" << getXMin() << std::endl;
318  exit(-1);
319  }
320 }
325 {
326  if (newYMax >= getYMin())
327  {
328  yMax_ = newYMax;
329  }
330  else
331  {
332  std::cerr << "Warning in setYMax(" << newYMax << "): yMin=" << getYMin() << std::endl;
333  }
334 }
339 {
340  if (newZMax >= getZMin())
341  {
342  zMax_ = newZMax;
343  }
344  else
345  {
346  std::cerr << "Error in setZMax(" << newZMax << "): zMin=" << getZMin() << std::endl;
347  exit(-1);
348  }
349 }
354 {
355  if (timeStep >= 0.0)
356  {
357  timeStep_ = timeStep;
358  }
359  else
360  {
361  std::cerr << "Error in setTimeStep" << std::endl;
362  exit(-1);
363  }
364 }
369 {
370  return timeStep_;
371 }
376 {
377  xBallsColourMode_ = newCMode;
378 }
383 {
384  return xBallsColourMode_;
385 }
389 void DPMBase::setXBallsVectorScale(double newVScale)
390 {
391  xBallsVectorScale_ = newVScale;
392 }
397 {
398  return xBallsVectorScale_;
399 }
403 void DPMBase::setXBallsAdditionalArguments(std::string newXBArgs)
404 {
405  xBallsAdditionalArguments_ = newXBArgs.c_str();
406 }
411 {
413 }
418 {
419  xBallsScale_ = newScale;
420 }
425 {
426  return xBallsScale_;
427 }
431 void DPMBase::setGravity(Vec3D newGravity)
432 {
433  gravity_ = newGravity;
434 }
439 {
440  return gravity_;
441 }
445 void DPMBase::setDimension(unsigned int newDim)
446 {
447  setSystemDimensions(newDim);
448  setParticleDimensions(newDim);
449 }
453 void DPMBase::setSystemDimensions(unsigned int newDim)
454 {
455  if (newDim >= 1 && newDim <= 3)
456  systemDimensions_ = newDim;
457  else
458  {
459  std::cerr << "Error in setSystemDimensions" << std::endl;
460  exit(-1);
461  }
462 }
466 unsigned int DPMBase::getSystemDimensions() const
467 {
468  return systemDimensions_;
469 }
470 
474 void DPMBase::setParticleDimensions(unsigned int particleDimensions)
475 {
476  if (particleDimensions >= 1 && particleDimensions <= 3)
477  {
478  particleDimensions_ = particleDimensions;
480  }
481  else
482  {
483  std::cerr << "Error in setParticleDimensions" << std::endl;
484  exit(-1);
485  }
486 }
487 
492 unsigned int DPMBase::getParticleDimensions() const
493 {
494  return particleDimensions_;
495 }
496 
501 std::string DPMBase::getRestartVersion() const
502 {
503  return restartVersion_;
504 }
505 
510 void DPMBase::setRestartVersion(std::string newRV)
511 {
512  restartVersion_ = newRV;
513 }
514 
520 {
521  return restarted_;
522 }
523 
527 void DPMBase::setRestarted(bool newRestartedFlag)
528 {
529  restarted_ = newRestartedFlag;
530  //setAppend(new_);
531 }
532 
536 bool DPMBase::getAppend() const
537 {
538  return append_;
539 }
540 
544 void DPMBase::setAppend(bool newAppendFlag)
545 {
546  append_ = newAppendFlag;
547 }
548 
553 {
554  Mdouble elasticEnergy = 0.0;
555  for (std::vector<BaseInteraction*>::const_iterator it = interactionHandler.begin(); it != interactionHandler.end(); ++it)
556  elasticEnergy += (*it)->getElasticEnergy();
557  return elasticEnergy;
558 }
559 
564 {
565  Mdouble kineticEnergy = 0;
566  for (std::vector<BaseParticle*>::const_iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
567  {
568  if (!(*it)->isFixed())
569  {
570  kineticEnergy += .5 * (*it)->getMass() * (*it)->getVelocity().getLengthSquared();
571  }
572  }
573  return kineticEnergy;
574 
575 }
576 
580 double DPMBase::getInfo(const BaseParticle& P) const
581 {
582  return P.getSpecies()->getId(); // was getIndex()
583 }
584 
590 bool DPMBase::areInContact(const BaseParticle* pI, const BaseParticle* pJ) const
591 {
593 }
594 
599 {
600 }
601 
606 {
607 }
608 
613 {
614 }
615 
620 {
621 }
622 
627 {
628 }
629 
634 {
635 }
636 
641 {
642 }
643 
648 {
649  return true;
650 }
651 
656 {
657 }
658 
663 {
664 }
665 
670 {
671 }
672 
677 {
678 }
679 
684 {
685 }
686 
688 {
689  for (std::vector<BaseInteraction*>::const_iterator it = interactionHandler.begin(); it != interactionHandler.end(); ++it)
690  (*it)->gatherContactStatistics();
691 }
692 
696 void DPMBase::gatherContactStatistics(unsigned int index1 UNUSED, int index2 UNUSED, Vec3D Contact UNUSED, Mdouble delta UNUSED, Mdouble ctheta UNUSED, Mdouble fdotn UNUSED, Mdouble fdott UNUSED, Vec3D P1_P2_normal_ UNUSED, Vec3D P1_P2_tangential UNUSED)
697 {
698 }
699 
704 {
705 }
706 
711 {
712 }
713 
718 {
719 }
720 
725 {
726 }
727 
732 {
733 }
734 
739 {
740  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); (*it) != i; ++it)
741  {
742  computeInternalForces(i, *it);
743  }
744 }
745 
749 void DPMBase::setFixedParticles(unsigned int n)
750 {
751  for (unsigned int i = 0; i < std::min(particleHandler.getNumberOfObjects(), n); i++)
753 }
754 
758 void DPMBase::printTime() const
759 {
760  std::cout << "t=" << std::setprecision(3) << std::left << std::setw(6) << getTime()
761  << ", tmax=" << std::setprecision(3) << std::left << std::setw(6) << getTimeMax()
762  << std::endl;
763  std::cout.flush();
764 }
765 
770 {
771  return true;
772 }
773 
778 {
779  //These are the particle parameters like dissipation etc..
780  setRestarted(false);
781 
782  //This sets the maximum number of particles
787  wallHandler.setDPMBase(this);
789 
793 
794  // Set gravitational acceleration
795  gravity_ = Vec3D(0.0, -9.8, 0.0);
796 
797  //This is the parameter of the numerical part
798  time_ = 0.0;
799  timeStep_ = 0.0; // if dt is not user-specified, this is set in actionsBeforeTimeLoop()
800  ntimeSteps_ = 0;
801  setSaveCount(20);
802  timeMax_ = 1.0;
803 
804  //This sets the default xballs domain
805  xMin_ = 0.0;
806  xMax_ = 0.01;
807  yMin_ = 0.0;
808  yMax_ = 0.01;
809  zMin_ = 0.0;
810  zMax_ = 0.0;
811 
813 
814  setName("");
815 
816  //Default mode is energy with no scale of the vectors
817  xBallsColourMode_ = 0;
818  xBallsVectorScale_ = -1;
819  xBallsScale_ = -1;
821  setAppend(false);
822 
823  //The default random seed is 0
825 #ifdef DEBUG_OUTPUT
826  std::cerr << "MD problem constructor finished " << std::endl;
827 #endif
828 }
829 
834 {
835 }
836 
840 void DPMBase::writeEneHeader(std::ostream& os) const
841 {
842  //only write if we don't restart
843  if (getAppend())
844  return;
845 
847  long width = os.precision() + 6;
848  os << std::setw(width) << "t" << " " << std::setw(width)
849  << "ene_gra" << " " << std::setw(width)
850  << "ene_kin" << " " << std::setw(width)
851  << "ene_rot" << " " << std::setw(width)
852  << "ene_ela" << " " << std::setw(width)
853  << "X_COM" << " " << std::setw(width)
854  << "Y_COM" << " " << std::setw(width)
855  << "Z_COM" << std::endl;
856 }
857 
861 void DPMBase::writeFstatHeader(std::ostream& os) const
862  {
863  // line #1: time, volume fraction
864  // line #2: wall box: wx0, wy0, wz0, wx1, wy1, wz1
865  // line #3: radii-min-max & moments: rad_min, rad_max, r1, r2, r3, r4
866  os << "#"
867  << " " << getTime()
868  << " " << 0
869  << std::endl;
870  os << "#"
871  << " " << getXMin()
872  << " " << getYMin()
873  << " " << getZMin()
874  << " " << getXMax()
875  << " " << getYMax()
876  << " " << getZMax()
877  << std::endl;
878  os << "#"
879  << " ";
881  {
883  }
884  else
885  {
886  os << std::numeric_limits<double>::quiet_NaN();
887  }
888  os << " ";
890  {
892  }
893  else
894  {
895  os << std::numeric_limits<double>::quiet_NaN();
896  }
897  os << " " << 0
898  << " " << 0
899  << " " << 0
900  << " " << 0
901  << std::endl;
902  //B: write data
903  for (std::vector<BaseInteraction*>::const_iterator it = interactionHandler.begin(); it != interactionHandler.end(); ++it)
904  {
905  (*it)->writeToFStat(os);
906  }
907 }
908 
912 void DPMBase::writeEneTimestep(std::ostream& os) const
913 {
914  Mdouble ene_kin = 0, ene_elastic = 0, ene_rot = 0, ene_gra = 0, mass_sum = 0, x_masslength = 0, y_masslength = 0, z_masslength = 0;
915 
916  for (std::vector<BaseParticle*>::const_iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
917  if (!(*it)->isFixed())
918  {
919  ene_kin += .5 * (*it)->getMass() * (*it)->getVelocity().getLengthSquared();
920  ene_rot += .5 * (*it)->getInertia() * (*it)->getAngularVelocity().getLengthSquared();
921  ene_gra -= (*it)->getMass() * Vec3D::dot(getGravity(), (*it)->getPosition());
922  mass_sum += (*it)->getMass();
923  x_masslength += (*it)->getMass() * (*it)->getPosition().X;
924  y_masslength += (*it)->getMass() * (*it)->getPosition().Y;
925  z_masslength += (*it)->getMass() * (*it)->getPosition().Z;
926  } //end for loop over Particles
927 
928  ene_elastic = getElasticEnergy();
929 
931  long width = os.precision() + 6;
932  os << std::setw(width) << getTime()
933  << " " << std::setw(width) << ene_gra
934  << " " << std::setw(width) << ene_kin
935  << " " << std::setw(width) << ene_rot
936  << " " << std::setw(width) << ene_elastic
937  << " " << std::setw(width) << (mass_sum != 0.0 ? x_masslength / mass_sum : std::numeric_limits<double>::quiet_NaN())
938  << " " << std::setw(width) << (mass_sum != 0.0 ? y_masslength / mass_sum : std::numeric_limits<double>::quiet_NaN())
939  << " " << std::setw(width) << (mass_sum != 0.0 ? z_masslength / mass_sum : std::numeric_limits<double>::quiet_NaN()) << std::endl;
940 
941  //sliding = sticking = 0;
942 }
943 
947 void DPMBase::outputXBallsData(std::ostream& os) const
948  {
949  //Set the correct formation based of dimension if the formation is not specified by the user
950  unsigned int format;
951  switch (getSystemDimensions())
952  {
953  case 2:
954  format = 8;
955  break;
956  case 3:
957  format = 14;
958  break;
959  default:
960  std::cerr << "Unknown systemdimension" << std::endl;
961  exit(-1);
962  }
963 
964  // This outputs the location of walls and how many particles there are to file this is required by the xballs plotting
965  if (format != 14) // dim = 1 or 2
966  {
967  os << particleHandler.getNumberOfObjects() << " " << getTime() << " " << getXMin() << " " << getYMin() << " " << getXMax() << " " << getYMax() << " " << std::endl;
968  }
969  else
970  {
971  //dim==3
972  os << particleHandler.getNumberOfObjects() << " " << getTime() << " " << getXMin() << " " << getYMin() << " " << getZMin() << " " << getXMax() << " " << getYMax() << " " << getZMax() << " " << std::endl;
973  }
974  // This outputs the particle data
975  for (unsigned int i = 0; i < particleHandler.getNumberOfObjects(); i++)
976  {
977  outputXBallsDataParticle(i, format, os);
978  }
979 #ifdef DEBUG_OUTPUT
980  std::cerr << "Have output the properties of the problem to disk " << std::endl;
981 #endif
982 }
983 
989 bool DPMBase::readDataFile(const std::string fileName, unsigned int format)
990 {
991  std::string oldFileName = dataFile.getName();
992  //This opens the file the data will be recalled from
993  dataFile.setName(fileName);
994  dataFile.open(std::fstream::in);
995  if (!dataFile.getFstream().is_open() || dataFile.getFstream().bad())
996  {
997  std::cout << "Loading data file " << fileName << " failed" << std::endl;
998  return false;
999  }
1000 
1001  //dataFile.getFileType() is ignored
1002  FileType fileTypeData = dataFile.getFileType();
1004  readNextDataFile(format);
1005  dataFile.setFileType(fileTypeData);
1006 
1007  dataFile.close();
1008  dataFile.setName(oldFileName);
1009 
1010  //std::cout << "Loaded data file " << filename << " (t=" << getTime() << ")" << std::endl;
1011  return true;
1012 }
1013 
1018 bool DPMBase::readParAndIniFiles(const std::string fileName)
1019 {
1020  //Opens the par.ini file
1021  std::fstream file;
1022  file.open(fileName, std::fstream::in);
1023  if (!file.is_open() || file.bad())
1024  {
1025  //std::cout << "Loading par.ini file " << filename << " failed" << std::endl;
1026  return false;
1027  }
1028 
1029  Mdouble doubleValue;
1030  int integerValue;
1031 
1032  // inputfile par.ini
1033  // line 1 =============================================================
1034  // Example: 1 1 0
1035  // 1: integer (0|1) switches from non-periodic to periodic
1036  // integer (5|6) does 2D integration only (y-coordinates fixed)
1037  // and switches from non-periodic to periodic
1038  // integer (11) uses a quarter system with circular b.c.
1039  file >> integerValue;
1040  //~ std::cout << "11" << integerValue << std::endl;
1041  if (integerValue == 0)
1042  {
1043  InfiniteWall w0;
1044  w0.set(Vec3D(-1, 0, 0), Vec3D(getXMin(), 0, 0));
1046  w0.set(Vec3D( 1, 0, 0), Vec3D(getXMax(), 0, 0));
1048  w0.set(Vec3D(0, -1, 0), Vec3D(0, getYMin(), 0));
1050  w0.set(Vec3D(0, 1, 0), Vec3D(0, getYMax(), 0));
1052  w0.set(Vec3D(0, 0, -1), Vec3D(0, 0, getZMin()));
1054  w0.set(Vec3D(0, 0, 1), Vec3D(0, 0, getZMax()));
1056  }
1057  else if (integerValue == 1)
1058  {
1059  PeriodicBoundary b0;
1060  b0.set(Vec3D(1, 0, 0), getXMin(), getXMax());
1062  b0.set(Vec3D(0, 1, 0), getYMin(), getYMax());
1064  b0.set(Vec3D(0, 0, 1), getZMin(), getZMax());
1066  }
1067  else if (integerValue == 5)
1068  {
1069  InfiniteWall w0;
1070  w0.set(Vec3D(-1, 0, 0), Vec3D(-getXMin(), 0, 0));
1072  w0.set(Vec3D(1, 0, 0), Vec3D(getXMax(), 0, 0));
1074  w0.set(Vec3D(0, -1, 0), Vec3D(0, -getYMin(), 0));
1076  w0.set(Vec3D(0, 1, 0), Vec3D(0, getYMax(), 0));
1078 
1079  }
1080  else if (integerValue == 6)
1081  {
1082  PeriodicBoundary b0;
1083  b0.set(Vec3D(1, 0, 0), getXMin(), getXMax());
1085  b0.set(Vec3D(0, 1, 0), getYMin(), getYMax());
1087  b0.set(Vec3D(0, 0, 1), getZMin(), getZMax());
1089  }
1090  else
1091  {
1092  std::cerr << "Error in par.ini: line 1, value 1 is " << integerValue << std::endl;
1093  exit(-1);
1094  }
1095 
1096  // 2: integer (0|1) dont use | use the search pattern for linked cells
1097  file >> integerValue; //ignore
1098 
1099  // 3: real - gravity in z direction: positive points upwards
1100  file >> doubleValue;
1101  setGravity(Vec3D(0.0, 0.0, doubleValue));
1102 
1103  // line 2 =============================================================
1104  // Example: -10000 .5e-2
1105  // 1: time end of simulation - (negative resets start time to zero
1106  // and uses -time as end-time)
1107  file >> doubleValue;
1108  if (doubleValue < 0)
1109  setTime(0);
1110  setTimeMax(fabs(doubleValue));
1111 
1112  // 2: time-step of simulation
1113  file >> doubleValue;
1114  setTimeStep(doubleValue);
1115 
1116  // line 3 =============================================================
1117  // Example: 1e-1 100
1118  file >> doubleValue;
1119  if (doubleValue >= 0)
1120  {
1121  // 1: time-step for output on time-series protocoll file -> "ene"
1122  unsigned int savecount = static_cast<unsigned int>(round(doubleValue / getTimeStep()));
1123  setSaveCount(savecount);
1124 
1125  // 2: time-step for output on film (coordinate) file -> "c3d"
1126  // (fstat-output is coupled to c3d-output time-step)
1127  file >> doubleValue;
1128  savecount = static_cast<unsigned int>(round(doubleValue / getTimeStep()));
1129  dataFile.setSaveCount(savecount);
1130  fStatFile.setSaveCount(savecount);
1131  }
1132  else
1133  {
1134  // or: ---------------------------------------------------------------
1135  // 1: negative number is multiplied to the previous log-output-time
1136  // 2: requires initial log-output time
1137  // 3: negative number is multiplied to the previous film-output-time
1138  // 4: requires initial film-output time
1139  std::cerr << "Error in par.ini: line 3, value 1 is " << doubleValue << std::endl;
1140  exit(-1);
1141  }
1142 
1143  // line 4 =============================================================
1144  // Example: 2000 1e5 1e3 1e2
1145  // 1: particle density (mass=4/3*constants::pi*density*rad^3)
1146  file >> doubleValue;
1147 
1148  //clear species handler
1152 
1154  S->setDensity(doubleValue);
1155 
1156  // 2: linear spring constant
1157  file >> doubleValue;
1158  S->setStiffness(doubleValue);
1159 
1160  // 3: linear dashpot constant
1161  file >> doubleValue;
1162  S->setDissipation(doubleValue);
1163 
1164  // 4: background damping dashpot constant
1165  file >> doubleValue;
1166  if (doubleValue != 0.0)
1167  std::cerr << "Warning in par.ini: ignored background damping " << doubleValue << std::endl;
1168 
1169  // line 5 =============================================================
1170  // Example: 0 0
1171  // 1: growth rate: d(radius) = xgrow * dt
1172  file >> doubleValue;
1173  if (doubleValue != 0.0)
1174  std::cerr << "Warning in par.ini: ignored growth rate " << doubleValue << std::endl;
1175 
1176  // 2: target volume_fraction
1177  file >> doubleValue;
1178  if (doubleValue != 0.0)
1179  std::cerr << "Warning in par.ini: ignored target volume_fraction " << doubleValue << std::endl;
1180 
1181  file.close();
1182  //std::cout << "Loaded par.ini file " << filename << std::endl;
1183  return true;
1184 }
1185 
1192 {
1194  {
1195  while (true)// This true corresponds to the if s
1196  {
1198  //check if file exists and contains data
1199  int N;
1200  dataFile.getFstream() >> N;
1201  if (dataFile.getFstream().eof() || dataFile.getFstream().peek() == -1)
1202  {
1203  std::cout << "file " << dataFile.getName() << " not found" << std::endl;
1204  return false;
1205  }
1206  //check if tmin condition is satisfied
1207  Mdouble t;
1208  dataFile.getFstream() >> t;
1209  if (t > tMin)
1210  {
1211  //set_file_counter(get_file_counter()-1);
1212  return true;
1213  }
1214  if (verbose)
1215  std::cout << "Jumping file counter: " << dataFile.getCounter() << std::endl;
1216  }
1217  }
1218  return true;
1219 }
1220 
1224 bool DPMBase::readNextDataFile(unsigned int format)
1225 {
1226  dataFile.openNextFile(std::fstream::in);
1227  //fStatFile.openNextFile();
1228  //Set the correct formation based of dimension if the formation is not specified by the user
1229  if (format == 0)
1230  {
1231  switch (getSystemDimensions())
1232  {
1233  case 1:
1234  case 2:
1235  format = 8;
1236  break;
1237  case 3:
1238  format = 14;
1239  break;
1240  }
1241  //end case
1242 
1243  }
1244  //end if
1245 
1246  unsigned int N=0;
1247  Mdouble dummy;
1248  dataFile.getFstream() >> N;
1249 
1250  //read first parameter and check if we reached the end of the file
1251  if (N==0)
1252  return false;
1253 
1254  BaseParticle* P0 = new BaseParticle();
1256  while (particleHandler.getNumberOfObjects() < N)
1258  else
1259  while (particleHandler.getNumberOfObjects() > N)
1261  delete P0;
1262 
1263 #ifdef DEBUG_OUTPUT
1264  std::cout << "Number of particles read from file "<<N << std::endl;
1265 #endif
1266 
1267  //read all other data available for the time step
1268  switch (format)
1269  {
1270  //This is the format_ that Stefan's and Vitaley's code saves in - note the axis rotation_
1271  case 7:
1272  {
1273  dataFile.getFstream() >> dummy;
1274  setTime(dummy);
1275  dataFile.getFstream() >> dummy;
1276  setXMin(dummy);
1277  dataFile.getFstream() >> dummy;
1278  setYMin(dummy);
1279  dataFile.getFstream() >> dummy;
1280  setZMin(dummy);
1281  dataFile.getFstream() >> dummy;
1282  setXMax(dummy);
1283  dataFile.getFstream() >> dummy;
1284  setYMax(dummy);
1285  dataFile.getFstream() >> dummy;
1286  setZMax(dummy);
1287  //std::cout << " time " << t << std::endl;
1288  Mdouble radius;
1289  Vec3D position, velocity;
1290  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
1291  {
1292  dataFile.getFstream() >> position.X >> position.Z >> position.Y >> velocity.X >> velocity.Z >> velocity.Y >> radius >> dummy;
1293  (*it)->setPosition(position);
1294  (*it)->setVelocity(velocity);
1295  (*it)->setOrientation(Vec3D(0.0, 0.0, 0.0));
1296  (*it)->setAngularVelocity(Vec3D(0.0, 0.0, 0.0));
1297  (*it)->setRadius(radius);
1298  }
1299  //End the interator over all particles
1300  break;
1301  }
1302  //This is a 2D format_
1303  case 8:
1304  {
1305  dataFile.getFstream() >> time_ >> xMin_ >> yMin_ >> xMax_ >> yMax_;
1306  zMin_ = 0.0;
1307  zMax_ = 0.0;
1308  Mdouble radius;
1309  Vec3D position, velocity, angle, angularVelocity;
1310  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
1311  {
1312  dataFile.getFstream() >> position.X >> position.Y >> velocity.X >> velocity.Y >> radius >> angle.Z >> angularVelocity.Z >> dummy;
1313  (*it)->setPosition(position);
1314  (*it)->setVelocity(velocity);
1315  (*it)->setOrientation(-angle);
1316  (*it)->setAngularVelocity(-angularVelocity);
1317  (*it)->setRadius(radius);
1318  } //end for all particles
1319  break;
1320  }
1321  //This is a 3D format_
1322  case 14:
1323  {
1324  dataFile.getFstream() >> time_ >> xMin_ >> yMin_ >> zMin_ >> xMax_ >> yMax_ >> zMax_;
1325  Mdouble radius;
1326  Vec3D position, velocity, angle, angularVelocity;
1327  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
1328  {
1329  dataFile.getFstream() >> position >> velocity >> radius >> angle >> angularVelocity >> dummy;
1330  (*it)->setPosition(position);
1331  (*it)->setVelocity(velocity);
1332  (*it)->setOrientation(angle);
1333  (*it)->setAngularVelocity(angularVelocity);
1334  (*it)->setRadius(radius);
1335  } //end for all particles
1336  break;
1337  }
1338  //This is a 3D format_
1339  case 15:
1340  {
1341  dataFile.getFstream() >> time_ >> xMin_ >> yMin_ >> zMin_ >> xMax_ >> yMax_ >> zMax_;
1342  Mdouble radius;
1343  Vec3D position, velocity, angle, angularVelocity;
1344  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
1345  {
1346  dataFile.getFstream() >> position >> velocity >> radius >> angle >> angularVelocity >> dummy >> dummy;
1347  (*it)->setPosition(position);
1348  (*it)->setVelocity(velocity);
1349  (*it)->setOrientation(angle);
1350  (*it)->setAngularVelocity(angularVelocity);
1351  (*it)->setRadius(radius);
1352 
1353  } //end for all particles
1354  break;
1355  }
1356  } //end switch statement
1358 
1359  return true;
1360 }
1361 
1366 {
1368 }
1369 
1376 {
1377  if (restartFile.open(std::fstream::in))
1378  {
1380  restartFile.close();
1381  setRestarted(true);
1382  return (1);
1383  }
1384  else
1385  {
1386  std::cerr << restartFile.getName() << " could not be loaded" << std::endl;
1387  return (0);
1388  }
1389 }
1390 
1395 int DPMBase::readRestartFile(std::string fileName)
1396 {
1397  restartFile.setName(fileName);
1398  return readRestartFile();
1399 }
1400 
1406 {
1407  //this is because the rough bottom allows overlapping fixed particles
1408  if (P1->isFixed() && P2->isFixed())
1409  {
1410  return;
1411  }
1412 
1414  {
1415  return;
1416  }
1417 
1418  BaseParticle *PI, *PJ;
1419  if (P1->getId() > P2->getId())
1420  {
1421  PI = P2;
1422  PJ = P1;
1423  }
1424  else
1425  {
1426  PI = P1;
1427  PJ = P2;
1428  }
1429 
1430  //if statement above ensures that the PI has the lower id than PJ
1432  if (C != 0)
1433  {
1434  C->computeForce();
1435 
1436  PI->addForce(C->getForce());
1437  PJ->addForce(-C->getForce());
1438 
1439  if (getRotation())
1440  {
1441  PI->addTorque(C->getTorque() - Vec3D::cross(PI->getPosition() - C->getContactPoint(), C->getForce()));
1442  PJ->addTorque(-C->getTorque() + Vec3D::cross(PJ->getPosition() - C->getContactPoint(), C->getForce()));
1443  }
1444  }
1445 }
1446 
1452 {
1453  if (!CI->isFixed())
1454  {
1455  // Gravitational force
1456  CI->addForce(getGravity() * CI->getMass());
1457  // Still calls this in compute External Forces.
1459  }
1460 }
1461 
1466 {
1467  //No need to compute interactions between periodic particle images and walls
1468  if (pI->getPeriodicFromParticle() != nullptr)
1469  return;
1470 
1471  for (std::vector<BaseWall*>::iterator it = wallHandler.begin(); it != wallHandler.end(); ++it)
1472  {
1473  BaseInteraction* C = (*it)->getInteractionWith(pI, getTime(), &interactionHandler);
1474 
1475  if (C != nullptr)
1476  {
1477  C->computeForce();
1478 
1479  pI->addForce(C->getForce());
1480  (*it)->addForce(-C->getForce());
1481 
1482  if (getRotation()) // getRotation() returns a boolean.
1483  {
1484  pI->addTorque(C->getTorque() - Vec3D::cross(pI->getPosition() - C->getContactPoint(), C->getForce()));
1486  (*it)->addTorque(-C->getTorque() + Vec3D::cross((*it)->getPosition() - C->getContactPoint(), C->getForce()));
1487  }
1488  }
1489  }
1490 }
1491 
1496 {
1497  for_each(particleHandler.begin(), particleHandler.end(), [this] (BaseParticle* p)
1498  {
1499  p->integrateBeforeForceComputation(getTime(),getTimeStep());
1500  });
1501  for_each(wallHandler.begin(), wallHandler.end(), [this] (BaseWall* w)
1502  {
1503  w->integrateBeforeForceComputation(getTime(),getTimeStep());
1504  });
1505 }
1510 {
1511  for (std::vector<BaseBoundary*>::iterator B = boundaryHandler.begin(); B != boundaryHandler.end(); ++B)
1512  {
1513  for (std::vector<BaseParticle*>::iterator P = particleHandler.begin(); P != particleHandler.end(); ++P)
1514  {
1515  if ((*B)->checkBoundaryAfterParticleMoved(*P, particleHandler)) //Returns true if the particle is deleted
1516  --P;
1517  }
1518  }
1519 }
1520 
1525 {
1526  for_each(particleHandler.begin(), particleHandler.end(), [this] (BaseParticle* p)
1527  {
1528  p->integrateAfterForceComputation(getTime(),getTimeStep());
1529  });
1530  for_each(wallHandler.begin(), wallHandler.end(), [this] (BaseWall* w)
1531  {
1532  w->integrateAfterForceComputation(getTime(),getTimeStep());
1533  });
1534 }
1535 
1539 //void DPMBase::statisticsFromRestartData(const char *name)
1540 //{
1541 // ///todo{Check this whole function}
1542 // //This function loads all MD data
1543 // readRestartFile();
1544 //
1545 // //This creates the file statistics will be saved to
1546 // std::stringstream ss("");
1547 // ss << name << ".stat";
1548 // statFile.setName(ss.str());
1549 // statFile.setOpenMode(std::fstream::out);
1550 // statFile.open();
1551 //
1552 // // Sets up the initial conditions for the simulation
1553 // // setupInitialConditions();
1554 // // Setup the previous position arrays and mass of each particle.
1555 // computeParticleMasses();
1556 // // Other routines required to jump-start the simulation
1557 // actionsBeforeTimeLoop();
1558 // initialiseStatistics();
1559 // hGridActionsBeforeTimeLoop();
1560 // writeEneHeader(eneFile.getFstream());
1561 //
1562 // while (readDataFile(dataFile.getName().c_str()))
1563 // {
1564 // hGridActionsBeforeTimeLoop();
1565 // actionsBeforeTimeStep();
1566 // checkAndDuplicatePeriodicParticles();
1567 // hGridActionsBeforeTimeStep();
1572 // computeAllForces();
1573 // removeDuplicatePeriodicParticles();
1574 // actionsAfterTimeStep();
1575 // writeEneTimestep(eneFile.getFstream());
1576 // std::cout << std::setprecision(6) << getTime() << std::endl;
1577 // }
1578 //
1579 // dataFile.close();
1580 // statFile.close();
1581 //}
1582 
1587 {
1589  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
1590  {
1591  (*it)->setForce(Vec3D(0.0, 0.0, 0.0));
1592  (*it)->setTorque(Vec3D(0.0, 0.0, 0.0));
1593  }
1594  for (std::vector<BaseWall*>::iterator it = wallHandler.begin(); it != wallHandler.end(); ++it)
1595  {
1596  (*it)->setForce(Vec3D(0.0, 0.0, 0.0));
1597  (*it)->setTorque(Vec3D(0.0, 0.0, 0.0));
1598  } //end reset forces loop
1599 
1600 #ifdef DEBUG_OUTPUT
1601  std::cerr << "Have all forces set to zero " << std::endl;
1602 #endif
1603 
1605 
1606  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
1607  {
1608 
1610  computeInternalForces(*it);
1611  //end inner loop over contacts.
1612 
1613  computeExternalForces(*it);
1614 
1615  }
1616 
1617 #ifdef CONTACT_LIST_HGRID
1618  //possibleContactList.write(std::cout);
1619  PossibleContact* Curr=possibleContactList.getFirstPossibleContact();
1620  while(Curr)
1621  {
1622  computeInternalForces(Curr->getP1(),Curr->getP2());
1623  Curr=Curr->getNext();
1624  }
1625 #endif
1626  //end outer loop over contacts.
1627 
1628 }
1629 
1634 {
1635  broadPhase(i);
1636 }
1637 
1642 void DPMBase::write(std::ostream& os, bool writeAllParticles) const
1643 {
1644  os << "restart_version " << "1.0";
1646  os << "xMin " << getXMin()
1647  << " xMax " << getXMax()
1648  << " yMin " << getYMin()
1649  << " yMax " << getYMax()
1650  << " zMin " << getZMin()
1651  << " zMax " << getZMax() << std::endl
1652  << "timeStep " << getTimeStep()
1653  << " time " << getTime()
1654  << " ntimeSteps " << ntimeSteps_
1655  << " timeMax " << getTimeMax() << std::endl
1656  << "systemDimensions " << getSystemDimensions()
1657  << " particleDimensions " << getParticleDimensions()
1658  << " gravity " << getGravity() << std::endl;
1659  speciesHandler.write(os);
1660  os << "Walls " << wallHandler.getNumberOfObjects() << std::endl;
1661  for (std::vector<BaseWall*>::const_iterator it = wallHandler.begin(); it != wallHandler.end(); ++it)
1662  os << (**it) << std::endl;
1663  os << "Boundaries " << boundaryHandler.getNumberOfObjects() << std::endl;
1664  for (std::vector<BaseBoundary*>::const_iterator it = boundaryHandler.begin(); it != boundaryHandler.end(); ++it)
1665  os << (**it) << std::endl;
1666  if (writeAllParticles || particleHandler.getNumberOfObjects() < 4)
1667  {
1668  particleHandler.write(os);
1669  }
1670  else
1671  {
1672  os << "Particles " << particleHandler.getNumberOfObjects() << std::endl;
1673  for (unsigned int i = 0; i < 2; i++)
1674  os << *particleHandler.getObject(i) << std::endl;
1675  os << "..." << std::endl;
1676  }
1677  if (writeAllParticles || interactionHandler.getNumberOfObjects() < 4)
1678  {
1680  }
1681  else
1682  {
1683  os << "Interactions " << interactionHandler.getNumberOfObjects() << std::endl;
1684  for (unsigned int i = 0; i < 2; i++)
1685  os << *interactionHandler.getObject(i) << std::endl;
1686  os << "..." << std::endl;
1687  }
1690 }
1691 
1695 void DPMBase::read(std::istream& is)
1696 {
1697  std::string dummy;
1698  is >> dummy;
1699  if (strcmp(dummy.c_str(), "restart_version"))
1700  {
1701  //only very old files did not have a restart_version
1702  logger.log(Log::FATAL, "Error in DPMBase::read(is): this is not a valid restart file");
1703  }
1704  else
1705  {
1706  is >> restartVersion_;
1707  if (!restartVersion_.compare("1.0"))
1708  {
1710  is >> dummy >> xMin_
1711  >> dummy >> xMax_
1712  >> dummy >> yMin_
1713  >> dummy >> yMax_
1714  >> dummy >> zMin_
1715  >> dummy >> zMax_
1716  >> dummy >> timeStep_
1717  >> dummy >> time_
1718  >> dummy >> ntimeSteps_
1719  >> dummy >> timeMax_
1720  >> dummy >> systemDimensions_
1721  >> dummy >> particleDimensions_
1722  >> dummy >> gravity_;
1723  speciesHandler.read(is);
1724 
1725  unsigned int N;
1726  std::stringstream line(std::stringstream::in | std::stringstream::out);
1727  is >> dummy >> N;
1728  wallHandler.clear();
1730  for (unsigned int i = 0; i < N; i++)
1731  {
1733  wallHandler.readObject(line);
1734  }
1735 
1736  is >> dummy >> N;
1739  for (unsigned int i = 0; i < N; i++)
1740  {
1743  }
1744 
1745  is >> dummy >> N;
1748  for (unsigned int i = 0; i < N; i++)
1749  {
1753  //particleHandler.getLastObject()->computeMass();
1754  }
1756  }
1757  else if (!restartVersion_.compare("3"))
1758  {
1759  logger.log(Log::INFO, "DPMBase::read(is): restarting from an old restart file (restart_version %).", restartVersion_);
1760  readOld(is);
1761  }
1762  else
1763  {
1764  //only very old files did not have a restart_version
1765  logger.log(Log::FATAL, "Error in DPMBase::read(is): restart_version % cannot be read; use an older version of Mercury to upgrade the file", restartVersion_);
1766  }
1767  }
1768 }
1772 void DPMBase::readOld(std::istream &is)
1773 {
1774  std::string dummy;
1775  is >> dummy >> dummy;
1776  setName(dummy);
1777 
1778  unsigned int saveCountData, saveCountEne, saveCountStat, saveCountFStat;
1779  unsigned int fileTypeFstat, fileTypeData, fileTypeEne, fileTypeRestart;
1780  is >> dummy >> xMin_
1781  >> dummy >> xMax_
1782  >> dummy >> yMin_
1783  >> dummy >> yMax_
1784  >> dummy >> zMin_
1785  >> dummy >> zMax_
1786  >> dummy >> timeStep_
1787  >> dummy >> time_
1788  >> dummy >> timeMax_
1789  >> dummy >> saveCountData
1790  >> dummy >> saveCountEne
1791  >> dummy >> saveCountStat
1792  >> dummy >> saveCountFStat
1793  >> dummy >> systemDimensions_
1794  >> dummy >> gravity_
1795  >> dummy >> fileTypeFstat
1796  >> dummy >> fileTypeData
1797  >> dummy >> fileTypeEne;
1798  dataFile.setSaveCount(saveCountData);
1799  eneFile.setSaveCount(saveCountEne);
1800  statFile.setSaveCount(saveCountStat);
1801  fStatFile.setSaveCount(saveCountFStat);
1802 
1803  fStatFile.setFileType(static_cast<FileType>(fileTypeFstat));
1804  dataFile.setFileType(static_cast<FileType>(fileTypeData));
1805  eneFile.setFileType(static_cast<FileType>(fileTypeEne));
1806 
1807  //this is optional to allow restart files with and without restartFile.getFileType()
1808  is >> dummy;
1809  if (!strcmp(dummy.c_str(), "options_restart"))
1810  {
1811  is >> fileTypeRestart;
1812  restartFile.setFileType(static_cast<FileType>(fileTypeRestart));
1813  }
1814 
1815  speciesHandler.read(is);
1816  wallHandler.read(is);
1817  boundaryHandler.read(is);
1818  particleHandler.read(is);
1819 }
1820 
1825 {
1827  {
1828  std::cerr << "Error in solve(): at least one species has to be defined" << std::endl;
1829  exit(-1);
1830  }
1831  if (getParticleDimensions() == 0)
1832  {
1833  std::cerr << "Error in solve(): particleDimensions not specified" << std::endl;
1834  exit(-1);
1835  }
1836  if (getSystemDimensions() == 0)
1837  {
1838  std::cerr << "Error in solve(): systemDimensions not specified" << std::endl;
1839  exit(-1);
1840  }
1841  if (getTimeStep() == 0.0)
1842  {
1843  std::cerr << "Error in solve(): timeStep not specified" << std::endl;
1844  exit(-1);
1845  }
1846 }
1847 
1849 {
1852 
1854  {
1858  }
1859 
1861  {
1862  printTime();
1866  }
1867 
1868 // if (statFile.saveCurrentTimestep(ntimeSteps_))
1869 // {
1870 // outputStatistics();
1871 // gatherContactStatistics();
1872 // processStatistics(true);
1873 // }
1874 
1875  //write restart file last, otherwise the output cunters are wrong
1877  {
1878  writeRestartFile();
1879  restartFile.close(); //overwrite old restart file if FileType::ONE_FILE
1880  }
1881 }
1882 
1896 {
1897 #ifdef DEBUG_OUTPUT
1898  std::cerr << "Entered solve" << std::endl;
1899 #endif
1900 #ifdef CONTACT_LIST_HGRID
1901  std::cout << "Using CONTACT_LIST_HGRID"<<std::endl;
1902 #endif
1903 
1908  if (getRestarted()==false)
1909  {
1910  ntimeSteps_ = 0;
1911  resetFileCounter();
1912  setTime(0.0);
1913  //this is to ensure that the interaction time stamps agree with the resetting of the time value
1914  for (auto& i : interactionHandler)
1915  i->setTimeStamp(0);
1917  setNextSavedTimeStep(0); //reset the counter
1918 #ifdef DEBUG_OUTPUT
1919  std::cerr << "Have created the particles initial conditions " << std::endl;
1920 #endif
1921  }
1922  else
1923  {
1924  actionsOnRestart();
1925  }
1926 
1927  checkSettings();
1928 
1929  if (getRunNumber()>0)
1930  {
1931  std::stringstream name;
1932  name << getName() << "." << getRunNumber();
1933  setName(name.str());
1934  }
1935 
1936  //append_ determines if files have to be appended or not
1937  if (getAppend())
1938  {
1939  setOpenMode(std::fstream::out | std::fstream::app);
1940  restartFile.setOpenMode(std::fstream::out); //Restart files should always be overwritten.
1941  }
1942  else
1943  setOpenMode(std::fstream::out);
1944 
1946 
1947  // Setup the mass of each particle.
1949 
1950  // Other initialisations
1951  //max_radius = getLargestParticle()->getRadius();
1954 
1955  // do a first force computation
1958  computeAllForces();
1960 
1961 
1962 #ifdef DEBUG_OUTPUT
1963  std::cerr << "Have computed the initial values for the forces " << std::endl;
1964 #endif
1965 
1966  // This is the main loop over advancing time
1967  while (getTime() < getTimeMax() && continueSolve())
1968  {
1969  writeOutputFiles(); //everything is written at the beginning of the timestep!
1970 
1971  // Loop over all particles doing the time integration step
1974  checkInteractionWithBoundaries(); // INSERTION boundaries handled
1976 
1977  // Compute forces
1978 
1980  // INSERTION/DELETION boundary flag change
1981  for (std::vector<BaseBoundary*>::iterator it = boundaryHandler.begin(); it != boundaryHandler.end(); ++it)
1982  {
1983  (*it)->checkBoundaryBeforeTimeStep(this);
1984  }
1985 
1987 
1989 
1991 
1992  computeAllForces();
1993 
1995 
1997 
1998  // Loop over all particles doing the time integration step
2001 
2002  checkInteractionWithBoundaries(); // DELETION boundaries handled
2004 
2005  //erase interactions that have not been used during the last timestep
2007 
2008  time_ += timeStep_;
2009  ntimeSteps_ ++;
2010  }
2011  //force writing of the last time step
2013  writeOutputFiles();
2014 
2015  //end loop over interaction count
2017 
2018  std::cout << std::endl;
2019  //To make sure getTime gets the correct time for outputting statistics
2020  finishStatistics();
2021 
2022  closeFiles();
2023 }
2024 
2029 bool DPMBase::readArguments(int argc, char *argv[])
2030 {
2031  bool isRead = true;
2032  for (int i = 1; i < argc; i += 2)
2033  {
2034  std::cout << "interpreting input argument " << argv[i];
2035  for (int j = i + 1; j < argc; j++)
2036  {
2037  if (argv[j][0] == '-')
2038  break;
2039  std::cout << " " << argv[j];
2040  }
2041  std::cout << std::endl;
2042  isRead &= readNextArgument(i, argc, argv);
2043  if (!isRead)
2044  {
2045  std::cerr << "Warning: not all arguments read correctly!" << std::endl;
2046  }
2047  }
2048  return isRead;
2049 }
2050 
2057 bool DPMBase::readNextArgument(int& i, int argc, char *argv[])
2058 {
2060  if (!strcmp(argv[i], "-name"))
2061  {
2062  setName(argv[i + 1]);
2063  }
2064  else if (!strcmp(argv[i], "-xmin"))
2065  {
2066  setXMin(atof(argv[i + 1]));
2067  }
2068  else if (!strcmp(argv[i], "-ymin"))
2069  {
2070  setYMin(atof(argv[i + 1]));
2071  }
2072  else if (!strcmp(argv[i], "-zmin"))
2073  {
2074  setZMin(atof(argv[i + 1]));
2075  }
2076  else if (!strcmp(argv[i], "-xmax"))
2077  {
2078  setXMax(atof(argv[i + 1]));
2079  }
2080  else if (!strcmp(argv[i], "-ymax"))
2081  {
2082  setYMax(atof(argv[i + 1]));
2083  }
2084  else if (!strcmp(argv[i], "-zmax"))
2085  {
2086  setZMax(atof(argv[i + 1]));
2087  //} else if (!strcmp(argv[i],"-svn")) {
2088  // std::cout << "svn version " << SVN_VERSION << std::endl;
2089  // i--;
2090  }
2091  else if (!strcmp(argv[i], "-dt"))
2092  {
2093  Mdouble old = getTimeStep();
2094  setTimeStep(atof(argv[i + 1]));
2095  std::cout << " reset dt from " << old << " to " << getTimeStep() << std::endl;
2096  }
2097 // else if (!strcmp(argv[i], "-Hertz"))
2098 // {
2099 // speciesHandler.getObject(0)->setForceType(ForceType::HERTZ);
2100 // i--;
2101 // }
2102  else if (!strcmp(argv[i], "-tmax"))
2103  {
2104  Mdouble old = getTimeMax();
2105  setTimeMax(atof(argv[i + 1]));
2106  std::cout << " reset timeMax from " << old << " to " << getTimeMax() << std::endl;
2107  }
2108  else if (!strcmp(argv[i], "-saveCount"))
2109  {
2110  setSaveCount(static_cast<unsigned int>(atoi(argv[i + 1])));
2111  }
2112  else if (!strcmp(argv[i], "-saveCountData"))
2113  {
2114  dataFile.setSaveCount(static_cast<unsigned int>(atoi(argv[i + 1])));
2115  }
2116  else if (!strcmp(argv[i], "-saveCountFStat"))
2117  {
2118  fStatFile.setSaveCount(static_cast<unsigned int>(atoi(argv[i + 1])));
2119  }
2120  else if (!strcmp(argv[i], "-saveCountStat"))
2121  {
2122  statFile.setSaveCount(static_cast<unsigned int>(atoi(argv[i + 1])));
2123  }
2124  else if (!strcmp(argv[i], "-saveCountEne"))
2125  {
2126  eneFile.setSaveCount(static_cast<unsigned int>(atoi(argv[i + 1])));
2127  }
2128  else if (!strcmp(argv[i], "-saveCountRestart"))
2129  {
2130  restartFile.setSaveCount(static_cast<unsigned int>(atoi(argv[i + 1])));
2131  }
2132  else if (!strcmp(argv[i], "-dim"))
2133  {
2134  setSystemDimensions(static_cast<unsigned int>(atoi(argv[i + 1])));
2135  }
2136  else if (!strcmp(argv[i], "-gravity"))
2137  {
2139  setGravity(Vec3D(atof(argv[i + 1]), atof(argv[i + 2]), atof(argv[i + 3])));
2140  i += 2;
2141  }
2142  else if (!strcmp(argv[i], "-fileType"))
2143  { //uses int input
2144  setFileType(static_cast<FileType>(atoi(argv[i + 1])));
2145  }
2146  else if (!strcmp(argv[i], "-fileTypeFStat"))
2147  { //uses int input
2148  fStatFile.setFileType(static_cast<FileType>(atoi(argv[i + 1])));
2149  }
2150  else if (!strcmp(argv[i], "-fileTypeRestart"))
2151  {
2152  restartFile.setFileType(static_cast<FileType>(atoi(argv[i + 1])));
2153  }
2154  else if (!strcmp(argv[i], "-fileTypeData"))
2155  {
2156  dataFile.setFileType(static_cast<FileType>(atoi(argv[i + 1])));
2157  }
2158  else if (!strcmp(argv[i], "-fileTypeStat"))
2159  {
2160  statFile.setFileType(static_cast<FileType>(atoi(argv[i + 1])));
2161  }
2162  else if (!strcmp(argv[i], "-fileTypeEne"))
2163  {
2164  eneFile.setFileType(static_cast<FileType>(atoi(argv[i + 1])));
2165  }
2166  else if (!strcmp(argv[i], "-auto_number"))
2167  {
2168  autoNumber();
2169  i--;
2170  }
2171 // else if (!strcmp(argv[i], "-number_of_saves"))
2172 // {
2173 // set_number_of_saves_all(atof(argv[i + 1]));
2174 // }
2175  else if (!strcmp(argv[i], "-restart") || !strcmp(argv[i], "-r"))
2176  {
2180  std::string filename;
2181 
2182  //use default filename if no argument is given
2183  if (i + 1 >= argc || argv[i + 1][0] == '-')
2184  {
2185  i--;
2186  filename = getName();
2187  std::cout << getName() << std::endl;
2188  }
2189  else
2190  filename = argv[i + 1];
2191 
2192  //add ".restart" if necessary
2193  if (filename.find(".restart") == std::string::npos)
2194  {
2195  filename = filename + ".restart";
2196  }
2197 
2198  std::cout << "restart from " << filename << std::endl;
2199  readRestartFile(filename);
2200  }
2201  else if (!strcmp(argv[i], "-clean") || !strcmp(argv[i], "-c"))
2202  {
2203  std::cout<< "Remove old " << getName() << ".* files" << std::endl;
2205 // std::string filename;
2206  std::ostringstream filename;
2207  std::vector<std::string> ext {".restart",".stat",".fstat",".data",".ene",".xballs"};
2208  for (unsigned int j=0; j<ext.size(); j++)
2209  {
2210  // remove files with given extension for FileType::ONE_FILE
2211  filename.clear();
2212  filename << getName() <<ext[j];
2213  if( !remove( filename.str().c_str() ) )
2214  {
2215  std::cout<< " File " << filename.str() << " successfully deleted" << std::endl;
2216  }
2217  // remove files with given extension for FileType::MULTIPLE_FILES
2218  unsigned int k=0;
2219  filename.clear(); filename << getName() << ext[j] << '.' << k;
2220  while( !remove( filename.str().c_str() ) )
2221  {
2222  std::cout<< " File " << filename.str() << " successfully deleted" << std::endl;
2223  filename.clear();
2224  filename << getName() << ext[j] << '.' << ++k;
2225  }
2226  // remove files with given extension for FileType::MULTIPLE_FILES_PADDED
2227  k=0;
2228  filename.clear(); filename << getName() << ext[j] << '.' << to_string_padded(k);
2229  while( !remove( filename.str().c_str() ) )
2230  {
2231  std::cout<< " File " << filename.str() << " successfully deleted" << std::endl;
2232  filename.clear();
2233  filename << getName() << ext[j] << '.' << to_string_padded(++k);
2234  }
2235  }
2236  i--;
2237  }
2238  else if (!strcmp(argv[i], "-data"))
2239  {
2240  std::string filename = argv[i + 1];
2241  readDataFile(filename.c_str());
2242  }
2243 // else if (!strcmp(argv[i], "-k"))
2244 // {
2245 // Mdouble old = getSpecies(0)->getStiffness();
2246 // getSpecies(0)->setStiffness(atof(argv[i + 1]));
2247 // std::cout << " reset k from " << old << " to " << getSpecies(0)->getStiffness() << std::endl;
2248 // }
2249 // else if (!strcmp(argv[i], "-dissipation") || !strcmp(argv[i], "-disp"))
2250 // {
2251 // Mdouble old = getSpecies(0)->getDissipation();
2252 // getSpecies(0)->setDissipation(atof(argv[i + 1]));
2253 // std::cout << " reset getDissipation() from " << old << " to " << getSpecies(0)->getDissipation() << std::endl;
2254 // }
2255 // else if (!strcmp(argv[i], "-kt"))
2256 // {
2257 // Mdouble old = getSpecies(0)->getSlidingStiffness();
2258 // getSpecies(0)->setSlidingStiffness(atof(argv[i + 1]));
2259 // std::cout << " reset kt from " << old << " to " << getSpecies(0)->getSlidingStiffness() << std::endl;
2260 // }
2261 // else if (!strcmp(argv[i], "-dispt"))
2262 // {
2263 // Mdouble old = getSpecies(0)->getSlidingDissipation();
2264 // getSpecies(0)->setSlidingDissipation(atof(argv[i + 1]));
2265 // std::cout << " reset dispt from " << old << " to " << getSpecies(0)->getSlidingDissipation() << std::endl;
2266 // }
2267 // else if (!strcmp(argv[i], "-krolling"))
2268 // {
2269 // Mdouble old = getSpecies(0)->getRollingStiffness();
2270 // getSpecies(0)->setRollingStiffness(atof(argv[i + 1]));
2271 // std::cout << " reset krolling from " << old << " to " << getSpecies(0)->getRollingStiffness() << std::endl;
2272 // }
2273 // else if (!strcmp(argv[i], "-disprolling"))
2274 // {
2275 // Mdouble old = getSpecies(0)->getRollingDissipation();
2276 // getSpecies(0)->setRollingDissipation(atof(argv[i + 1]));
2277 // std::cout << " reset disprolling from " << old << " to " << getSpecies(0)->getRollingDissipation() << std::endl;
2278 // }
2279 // else if (!strcmp(argv[i], "-mu"))
2280 // {
2281 // Mdouble old = getSpecies(0)->getSlidingFrictionCoefficient();
2282 // getSpecies(0)->setSlidingFrictionCoefficient(atof(argv[i + 1]));
2283 // std::cout << " reset mu from " << old << " to " << getSpecies(0)->getSlidingFrictionCoefficient() << std::endl;
2284 // }
2285 // else if (!strcmp(argv[i], "-murolling"))
2286 // {
2287 // Mdouble old = getSpecies(0)->getRollingFrictionCoefficient();
2288 // getSpecies(0)->setRollingFrictionCoefficient(atof(argv[i + 1]));
2289 // std::cout << " reset murolling from " << old << " to " << getSpecies(0)->getRollingFrictionCoefficient() << std::endl;
2290 // }
2291  else if (!strcmp(argv[i], "-randomise") || !strcmp(argv[i], "-randomize"))
2292  {
2293  random.randomise();
2294  i--;
2295  }
2296 // else if (!strcmp(argv[i], "-k0"))
2297 // {
2298 // Mdouble old = speciesHandler.getObject(0)->getAdhesionStiffness();
2299 // speciesHandler.getObject(0)->setAdhesionStiffness(atof(argv[i + 1]));
2300 // std::cout << " reset k0 from " << old << " to " << speciesHandler.getObject(0)->getAdhesionStiffness() << std::endl;
2301 // }
2302 // else if (!strcmp(argv[i], "-f0"))
2303 // {
2304 // Mdouble old = speciesHandler.getObject(0)->getAdhesionForceMax();
2305 // speciesHandler.getObject(0)->setAdhesionForceMax(atof(argv[i + 1]));
2306 // std::cout << " reset f0 from " << old << " to " << speciesHandler.getObject(0)->getAdhesionForceMax() << std::endl;
2307 // }
2308 // else if (!strcmp(argv[i], "-AdhesionForceType"))
2309 // {
2310 // AdhesionForceType old = speciesHandler.getObject(0)->getAdhesionForceType();
2311 // speciesHandler.getObject(0)->setAdhesionForceType(argv[i + 1]);
2312 // std::cout << " reset AdhesionForceType from "
2313 // << static_cast<signed char>(old) << " to "
2314 // << static_cast<signed char>(speciesHandler.getObject(0)->getAdhesionForceType()) << std::endl;
2315 // }
2316  else if (!strcmp(argv[i], "-append"))
2317  {
2318  setAppend(true);
2319  i--;
2320  }
2321  else if (!strcmp(argv[i], "-fixedParticles"))
2322  {
2323  setFixedParticles(static_cast<unsigned int>(atoi(argv[i + 1])));
2324  }
2325 // else if (!strcmp(argv[i], "-rho"))
2326 // {
2327 // Mdouble old = speciesHandler.getObject(0)->getDensity();
2328 // speciesHandler.getObject(0)->setDensity(atof(argv[i + 1]));
2329 // std::cout << " reset rho from " << old << " to " << speciesHandler.getObject(0)->getDensity() << std::endl;
2330 // }
2331 // else if (!strcmp(argv[i], "-dim_particle"))
2332 // {
2333 // setParticleDimensions(atoi(argv[i + 1]));
2334 // }
2335  else if (!strcmp(argv[i], "-counter"))
2336  {
2337  setRunNumber(atoi(argv[i + 1]));
2338  }
2339  else
2340  return false;
2341  return true; //returns true if argv is found
2342 }
2343 
2354 {
2355  Mdouble distance;
2356  Vec3D normal;
2357 
2358  //Check if it has no collision with walls
2359  for (std::vector<BaseWall*>::const_iterator it = wallHandler.begin(); it != wallHandler.end(); it++)
2360  {
2361  if ((*it)->getDistanceAndNormal(p, distance, normal))
2362  {
2363  //std::cout<<"failure: Collision with wall: "<<**it<<std::endl;
2364  return false;
2365  }
2366  else
2367  {
2368  //std::cout<<"No collision with wall: "<<**it<<std::endl;
2369  }
2370  }
2371 
2372  //Check if it has no collision with other particles
2373  for (std::vector<BaseParticle*>::const_iterator it = particleHandler.begin(); it != particleHandler.end(); it++)
2374  {
2375  if (Vec3D::getDistanceSquared(p.getPosition(), (*it)->getPosition()) < mathsFunc::square(p.getInteractionRadius() + (*it)->getInteractionRadius()))
2376  {
2377  //std::cout<<"failure: Collision with particle "<<**it<<std::endl;
2378  return false;
2379  }
2380  else
2381  {
2382  //std::cout<<"No collision with particle "<<**it<<std::endl;
2383  }
2384  }
2385  return true;
2387 }
2388 
2395 {
2396  for (unsigned int i = particleHandler.getNumberOfObjects(); i >= 1 && particleHandler.getObject(i - 1)->getPeriodicFromParticle() != nullptr; i--)
2397  {
2398  while (particleHandler.getObject(i - 1)->getInteractions().size() > 0)
2399  {
2401  }
2403  }
2404 }
2405 
2410 {
2411  for (BaseBoundary* it : boundaryHandler) // For all pointers of type BaseBoundary in Boundary handler
2412  {
2413  unsigned int N = particleHandler.getNumberOfObjects(); //Required because the number of particles increases
2414  for (unsigned int i = 0; i < N; i++)
2415  {
2416  it->createPeriodicParticles(particleHandler.getObject(i), particleHandler);
2417  }
2418  }
2419 }
2425 {
2426  std::cout << "Interactions currently in the handler:" << std::endl;
2427  for (std::vector<BaseInteraction*>::const_iterator it = interactionHandler.begin(); it != interactionHandler.end(); ++it)
2428  {
2429  (*it)->write(std::cout);
2430  std::cout << std::endl;
2431  std::cout << "Interaction " << (*it)->getName() << " " << (*it)->getId() << " between " << (*it)->getP()->getId() << " and " << (*it)->getI()->getId() << std::endl;
2432  }
2433  /*std::cout << "Interactions currently in the particles:" << std::endl;
2434  for (std::vector<BaseParticle*>::const_iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
2435  {
2436  std::cout << "Base particle " << (*it)->getId() << " has interactions:" << std::endl;
2437  for (std::list<BaseInteraction*>::const_iterator it2 = (*it)->getInteractions().begin(); it2 != (*it)->getInteractions().end(); ++it2)
2438  {
2439  std::cout << (*it2)->getId() << " between " << (*it2)->getP()->getId() << " and " << (*it2)->getI()->getId() << std::endl;
2440  }
2441  }*/
2442 }
2447 {
2448  return getTime()<=time && getTime()+getTimeStep()>time;
2449 }
const Vec3D & getForce() const
Gets the current force (vector) between the two interacting objects.
Mdouble timeMax_
Stores the duration of the simulation.
Definition: DPMBase.h:801
void setTime(Mdouble time)
Access function for the time.
Definition: DPMBase.cc:172
BaseParticle * getLargestParticle() const
Gets a pointer to the largest BaseParticle (by interactionRadius) in this ParticleHandler.
virtual void actionsBeforeTimeLoop()
A virtual function. Allows one to carry out any operations before the start of the time loop...
Definition: DPMBase.cc:598
unsigned int getId() const
Returns the unique identifier of any particular object.
Definition: BaseObject.cc:113
void setXBallsVectorScale(double newVScale)
Set the scale of vectors in xballs.
Definition: DPMBase.cc:389
virtual void write(std::ostream &os, bool writeAllParticles=true) const
Loads all MD data and plots statistics for all timesteps in the .data file.
Definition: DPMBase.cc:1642
virtual void hGridUpdateParticle(BaseParticle *obj UNUSED)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:633
void set(Vec3D normal, Mdouble distanceLeft, Mdouble distanceRight)
Defines a periodic wall.
void setXMax(Mdouble newXMax)
If the length of the problem domain in x-direction is XMax - XMin, this method sets XMax...
Definition: DPMBase.cc:309
void write(std::ostream &os) const
void solve()
The work horse of the code.
Definition: DPMBase.cc:1895
Mdouble yMax_
If the length of the problem domain in y-direction is YMax - XMin, the above variable stores YMax...
Definition: DPMBase.h:769
virtual void hGridInsertParticle(BaseParticle *obj UNUSED)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:626
The DPMBase header includes quite a few header files, defining all the handlers, which are essential...
Definition: DPMBase.h:61
Mdouble X
the vector components
Definition: Vector.h:52
each time-step will be written into/read from separate files numbered consecutively, with numbers padded by zeros to a minimum of four digits: name_.0000, name_.0001, ..
virtual void integrateAfterForceComputation()
Integration is done after force computations. We apply the Velocity verlet scheme. See http://en.wikipedia.org/wiki/Verlet_integration#Velocity_Verlet.
Definition: DPMBase.cc:1524
void checkAndDuplicatePeriodicParticles()
In case of periodic boundaries, the below methods checks and adds particles when necessary into the p...
Definition: DPMBase.cc:2409
int getXBallsColourMode() const
Get the xball colour mode (CMode)
Definition: DPMBase.cc:382
void setNextSavedTimeStep(unsigned int nextSavedTimeStep)
Sets the next time step for all the files (ene, data, fstat, restart, stat) at which the data is to b...
Definition: Files.cc:261
void setTimeMax(Mdouble newTMax)
Allows the upper time limit to be changed.
Definition: DPMBase.cc:179
bool areInContact(const BaseParticle *pI, const BaseParticle *pJ) const
Checks if two particle are in contact or is there any positive overlap.
Definition: DPMBase.cc:590
void constructor()
A function which initialises the member variables to default values, so that the problem can be solve...
Definition: DPMBase.cc:777
void write(std::ostream &os) const
Writes the InteractionHandler to an output stream, for example a restart file.
unsigned int getSystemDimensions() const
Returns the dimension of the simulation. Note there is also a particle dimension. ...
Definition: DPMBase.cc:466
bool readArguments(int argc, char *argv[])
Can interpret main function input arguments that are passed by the driver codes.
Definition: DPMBase.cc:2029
FileType getFileType() const
Gets the file type e.g. NOFILE, ONEFILE and MULTIPLE FILES. File::fileType_.
Definition: File.cc:202
BaseParticle * getP1()
Gets a pointer to the first BaseParticle in this PossibleContact.
Logger< MERCURY_LOGLEVEL > logger("MercuryKernel")
unsigned int particleDimensions_
determines if 2D or 3D particle volume is used for mass calculations
Definition: DPMBase.h:740
Mdouble yMin_
If the length of the problem domain in y-direction is YMax - YMin, the above variable stores YMin...
Definition: DPMBase.h:763
void setDPMBase(DPMBase *DPMBase)
Sets the problem that is solved using this handler.
Definition: BaseHandler.h:506
void setYMin(Mdouble newYMin)
If the length of the problem domain in y-direction is YMax - YMin, this method sets YMin...
Definition: DPMBase.cc:280
virtual void computeInternalForces(BaseParticle *i)
Computes the forces between particles (internal in the sense that the sum over all these forces is ze...
Definition: DPMBase.cc:1633
Mdouble getZMax() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMax() returns ZMax...
Definition: DPMBase.cc:259
Mdouble getXMin() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMin() returns XMin...
Definition: DPMBase.cc:224
const ParticleSpecies * getSpecies() const
Returns a pointer to the species of this BaseInteractable.
void setStorageCapacity(const unsigned int N)
Sets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:476
unsigned int getParticleDimensions() const
Returns the particle dimensions.
Definition: DPMBase.cc:492
bool readDataFile(const std::string fileName, unsigned int format=0)
This allows particle data to be reloaded from data files.
Definition: DPMBase.cc:989
void computeAllMasses(unsigned int indSpecies)
Computes the mass for all BaseParticle of the given species in this ParticleHandler.
virtual void initialiseStatistics()
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:676
File restartFile
An instance of class File to handle in- and output into a .restart file.
Definition: Files.h:219
Mdouble getYMin() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMin() returns YMin...
Definition: DPMBase.cc:238
void setXBallsColourMode(int newCMode)
Set the xball output mode.
Definition: DPMBase.cc:375
const std::vector< T * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:494
double Mdouble
virtual void readOld(std::istream &is)
Reads all particle data into a restart file; old version.
Definition: DPMBase.cc:1772
void closeFiles()
Closes all files (ene, data, fstat, restart, stat) that were opened to read or write.
Definition: Files.cc:250
void setParticleDimensions(unsigned int particleDimensions)
Allows the dimension of the particle (f.e. for mass) to be changed. e.g. discs or spheres...
Definition: DPMBase.cc:474
virtual ~DPMBase()
virtual destructor
Definition: DPMBase.cc:142
virtual void actionsAfterTimeStep()
A virtual function which allows to define operations to be executed after time step.
Definition: DPMBase.cc:669
void readObject(std::istream &is)
Reads BaseParticle into the ParticleHandler from restart data.
void setZMax(Mdouble newZMax)
If the length of the problem domain in z-direction is XMax - XMin, this method sets ZMax...
Definition: DPMBase.cc:338
void write(std::ostream &os) const
Accepts an output stream read function, which accepts an input stream std::ostream.
bool openNextFile()
This function should be called before a data corresponding to the new time step is written or read...
Definition: File.cc:230
void setDimension(unsigned int newDim)
Sets the system and particle dimension.
Definition: DPMBase.cc:445
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:187
BaseParticle * getP2()
Gets a pointer to the second BaseParticle in this PossibleContact.
void setAppend(bool newAppendFlag)
Allows to set the append option.
Definition: DPMBase.cc:544
virtual void writeOutputFiles()
Writes the simulation data onto all the files i.e. .data, .ene, .fstat ...
Definition: DPMBase.cc:1848
void setSystemDimensions(unsigned int newDim)
Allows for the dimension of the simulation to be changed.
Definition: DPMBase.cc:453
Species< LinearViscoelasticNormalSpecies, SlidingFrictionSpecies > LinearViscoelasticSlidingFrictionSpecies
void setFileType(FileType fileType)
Sets File::fileType_ for all files (ene, data, fstat, restart, stat)
Definition: Files.cc:169
void read(std::istream &is)
Reads all objects from restart data.
Definition: BaseHandler.h:374
virtual void write(std::ostream &os) const
Write all the species and mixed species to an output stream.
void setGravity(Vec3D newGravity)
Allows to modify the gravity vector.
Definition: DPMBase.cc:431
T square(T val)
squares a number
Definition: ExtendedMath.h:91
virtual void outputXBallsData(std::ostream &os) const
This function writes the location of the walls and particles in a format the XBalls program can read...
Definition: DPMBase.cc:947
void logWriteAndDie(std::string module, std::string message)
todo strcmp relies on this, should be changed to more modern version
Definition: DPMBase.cc:63
virtual bool getHGridUpdateEachTimeStep() const
Definition: DPMBase.cc:647
bool rotation_
A flag to turn on/off particle rotation.
Definition: DPMBase.h:831
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Stores information about interactions between two interactable objects; often particles but could be ...
void randomise()
sets the random variables such that they differ for each run
Definition: RNG.cc:59
void eraseOldInteractions(Mdouble lastTimeStep)
erases interactions which have an old timestamp.
void setRunNumber(int runNumber)
This sets the counter/Run number, overriding the defaults.
Mdouble zMax_
If the length of the problem domain in z-direction is ZMax - ZMin, the above variable stores ZMax...
Definition: DPMBase.h:781
FileType
With FileType options, one is able to choose if data is to be read/written from/into no or single or ...
Definition: File.h:35
bool restarted_
A bool to check if the simulation was restarted or not.
Definition: DPMBase.h:820
const std::vector< T * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
Definition: BaseHandler.h:482
Defines a pair of periodic walls. Inherits from BaseBoundary.
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
Mdouble getXMax() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMax() returns XMax...
Definition: DPMBase.cc:231
void clear()
Empties the whole ParticleHandler by removing all BaseParticle.
void setRotation(bool newRotFlag)
Allows to set the flag for enabling or disabling particle rotation in the simulations.
Definition: DPMBase.cc:210
void readObject(std::istream &is)
Reads BaseWall into the WallHandler from restart data.
Definition: WallHandler.cc:111
PossibleContact * getNext()
Gets the next PossibleContact in the general linked list of PossibleContact.
void setOpenMode(std::fstream::openmode openMode)
Sets File::openMode_ for all files (ene, data, fstat, restart, stat)
Definition: Files.cc:200
virtual void processStatistics(bool usethese UNUSED)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:703
void close()
Closes the file by calling fstream_.close()
Definition: File.cc:360
bool findNextExistingDataFile(Mdouble tMin, bool verbose=true)
Useful when fileType is chosen as Multiple Files or Multiple files with padded.
Definition: DPMBase.cc:1191
void setYMax(Mdouble newYMax)
If the length of the problem domain in y-direction is YMax - YMin, this method sets YMax...
Definition: DPMBase.cc:324
unsigned int systemDimensions_
The dimensions of the simulation i.e. 2D or 3D.
Definition: DPMBase.h:735
void readObject(std::istream &is)
Reads BaseBoundary into the BoundaryHandler from restart data.
const Vec3D & getContactPoint() const
Gets constant reference to contact point (vector).
File eneFile
An instance of class File to handle in- and output into a .ene file.
Definition: Files.h:214
Mdouble zMin_
If the length of the problem domain in z-direction is ZMax - ZMin, the above variable stores ZMin...
Definition: DPMBase.h:775
Mdouble getElasticEnergy() const
Returns the global elastic energy within the system.
Definition: DPMBase.cc:552
Mdouble xMax_
If the length of the problem domain in x-direction is XMax - XMin, the above variable stores XMax...
Definition: DPMBase.h:757
unsigned int getCounter() const
In case of multiple files, File::getCounter() returns the the number (FILE::Counter_) of the next fil...
Definition: File.cc:216
void removeObjectKeepingPeriodics(unsigned const int id)
Removes interactions of periodic particles when the periodic particles get deleted (see DPMBase::remo...
file will not be created/read
unsigned int ntimeSteps_
Stores the number of time steps.
Definition: DPMBase.h:791
virtual void writeEneTimestep(std::ostream &os) const
This function enables one to write the global energy available in the system after each time step...
Definition: DPMBase.cc:912
int readRestartFile()
Reads all the particle data corresponding to the current saved time step. Which is what the restart f...
Definition: DPMBase.cc:1375
std::fstream & getFstream()
Allows to access the member variable File::fstream_.
Definition: File.cc:150
virtual void hGridActionsBeforeIntegration()
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:724
BaseParticle * getSmallestParticle() const
Gets a pointer to the smallest BaseParticle (by interactionRadius) in this ParticleHandler.
bool getAppend() const
Returns the flag denoting if the append option is on or off.
Definition: DPMBase.cc:536
virtual bool readNextArgument(int &i, int argc, char *argv[])
Definition: DPMBase.cc:2057
virtual bool checkParticleForInteraction(const BaseParticle &P)
Checks if the particle having any interaction with walls or other particles.
Definition: DPMBase.cc:2353
void setName(const std::string &name)
Allows to set the name of all the files (ene, data, fstat, restart, stat)
Definition: Files.cc:149
U * copyAndAddObject(const U &O)
Creates a copy of a Object and adds it to the BaseHandler.
Definition: BaseHandler.h:268
void resetFileCounter()
Resets the file counter for each file i.e. for ene, data, fstat, restart, stat)
Definition: Files.cc:189
bool getRestarted() const
Returns the flag denoting if the simulation was restarted or not.
Definition: DPMBase.cc:519
Mdouble getMass() const
Returns the particle's mass_.
void getLineFromStringStream(std::istream &in, std::stringstream &out)
Reads a line from one stringstream into another, and prepares the latter for reading in...
Definition: Helpers.cc:389
virtual void addObject(ParticleSpecies *const S)
Adds a new ParticleSpecies to the SpeciesHandler.
int xBallsColourMode_
XBalls is a package to view the particle data. As an alternative MercuryDPM also supports Paraview...
Definition: DPMBase.h:839
BoundaryHandler boundaryHandler
An object of the class BoundaryHandler which concerns insertion and deletion of particles into or fro...
Definition: DPMBase.h:888
Mdouble xBallsScale_
sets the xballs argument scale (see XBalls/xballs.txt)
Definition: DPMBase.h:849
void setXMin(Mdouble newXMin)
If the length of the problem domain in x-direction is XMax - XMin, this method sets XMin...
Definition: DPMBase.cc:266
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created...
Definition: DPMBase.h:878
void removeLastObject()
Removes the last BaseParticle from the ParticleHandler.
all data will be written into/ read from a single file called name_
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:415
unsigned int getNtimeSteps() const
Returns the current counter of time steps.
Definition: DPMBase.cc:165
Mdouble getKineticEnergy() const
Returns the global kinetic energy stored in the system.
Definition: DPMBase.cc:563
virtual void outputXBallsDataParticle(const unsigned int i, const unsigned int format, std::ostream &os) const
This function writes out the particle locations into an output stream in a format the XBalls program ...
Mdouble time_
Stores the current simulation time.
Definition: DPMBase.h:786
void setRestartVersion(std::string newRV)
Sets restart_version.
Definition: DPMBase.cc:510
Vec3D getGravity() const
Returns the gravity vector.
Definition: DPMBase.cc:438
void checkSettings()
Checks if the essentials are set properly to go ahead with solving the problem.
Definition: DPMBase.cc:1824
#define UNUSED
Definition: GeneralDefine.h:37
virtual void hGridActionsBeforeTimeLoop()
A virtual function that allows one to carry out hGrid operations before the start of the time loop...
Definition: DPMBase.cc:605
File fStatFile
An instance of class File to handle in- and output into a .fstat file.
Definition: Files.h:209
void read(std::istream &is)
Accepts an input stream std::istream.
bool readParAndIniFiles(const std::string fileName)
Allows the user to read par.ini files (useful to read MDCLR files)
Definition: DPMBase.cc:1018
void setSaveCount(unsigned int saveCount)
Sets File::saveCount_ for all files (ene, data, fstat, restart, stat)
Definition: Files.cc:138
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:268
virtual void computeAllForces()
Computes all the forces acting on the particles by using the setTorque and setForce methods...
Definition: DPMBase.cc:1586
File dataFile
An instance of class File to handle in- and output into a .data file.
Definition: Files.h:204
Mdouble getRadius() const
Returns the particle's radius_.
bool readNextDataFile(unsigned int format=0)
Reads the next data file with default format=0. However, one can modify the format based on whether t...
Definition: DPMBase.cc:1224
Basic class for walls.
Definition: BaseWall.h:39
void setZMin(Mdouble newZMin)
If the length of the problem domain in z-direction is ZMax - ZMin, this method sets ZMin...
Definition: DPMBase.cc:295
virtual void actionsAfterSolve()
A virtual function which allows to define operations to be executed after the solve().
Definition: DPMBase.cc:662
void setSaveCount(unsigned int saveCount)
Sets File::saveCount_.
Definition: File.cc:282
void addTorque(Vec3D addTorque)
Adds an amount to the torque on this BaseInteractable.
virtual void printTime() const
Displays the current simulation time onto your screen for example.
Definition: DPMBase.cc:758
unsigned int getNumberOfObjects() const
Gets the number of Object in this BaseHandler.
Definition: BaseHandler.h:464
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. elastic, linear visco-elastic... et cetera...
Definition: DPMBase.h:868
InteractionHandler interactionHandler
An object of the class InteractionHandler.
Definition: DPMBase.h:893
virtual void writeXBallsScript() const
This writes a script which can be used to load the xballs problem to display the data just generated...
void outputInteractionDetails() const
Displays the interaction details corresponding to the pointer objects in the interaction handler...
Definition: DPMBase.cc:2424
void setXBallsAdditionalArguments(std::string newXBArgs)
Set the additional arguments for xballs.
Definition: DPMBase.cc:403
BaseInteraction * getInteractionWith(BaseParticle *P, Mdouble timeStamp, InteractionHandler *interactionHandler)
Checks if particle is in interaction with given particle P, and if so, returns pointer to the associa...
void setFixedParticles(unsigned int n)
Definition: DPMBase.cc:749
Mdouble getYMax() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMax() returns XMax...
Definition: DPMBase.cc:245
Mdouble Y
Definition: Vector.h:52
Mdouble xBallsVectorScale_
sets the xballs argument vscale (see XBalls/xballs.txt)
Definition: DPMBase.h:844
Mdouble xMin_
If the length of the problem domain in x-direction is XMax - XMin, the above variable stores XMin...
Definition: DPMBase.h:751
virtual void actionsBeforeTimeStep()
A virtual function which allows to define operations to be executed before the new time step...
Definition: DPMBase.cc:655
LoggerOutput * loggerOutput
Declaration of the output functions. If the output needs to be redirected, please swap the loggerOutp...
Definition: Logger.cc:110
Mdouble timeStep_
Stores the simulation time step.
Definition: DPMBase.h:796
void setFileType(FileType fileType)
Sets the type of file needed to write into or read from. File::fileType_.
Definition: File.cc:209
void setRandomSeed(unsigned long int new_seed)
This is the seed for the random number generator. (note the call to seed_LFG is only required really ...
Definition: RNG.cc:46
WallHandler wallHandler
An object of the class WallHandler. Contains pointers to all the walls created.
Definition: DPMBase.h:883
RNG random
This is a random generator, often used for setting up the initial conditions etc...
Definition: DPMBase.h:873
std::string to_string_padded(unsigned int value)
Pads the number This function tries to pad the number to 4 digits, which is used when you create mult...
Definition: File.cc:60
virtual void hGridRemoveParticle(BaseParticle *obj UNUSED)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:640
virtual double getInfo(const BaseParticle &P) const
A virtual method that allows the user to overrride and set what is written into the info column in th...
Definition: DPMBase.cc:580
virtual void actionsOnRestart()
A virtual function where the users can add extra code which is executed only when the code is restart...
Definition: DPMBase.cc:612
void autoNumber()
The autoNumber() function is the trigger. It calls three functions. setRunNumber(), readRunNumberFromFile() and incrementRunNumberInFile().
Manages the linked list of PossibleContact.
virtual void writeEneHeader(std::ostream &os) const
Writes a header with a certain format for ENE file.
Definition: DPMBase.cc:840
bool open()
Checks if the file stream fstream_ has any issues while opening. Alongside, it also increments the ne...
Definition: File.cc:318
void set(Vec3D normal, Vec3D point)
Defines a standard wall, given an outward normal vector s.t. normal*x=normal*point for all x of the w...
Definition: InfiniteWall.cc:70
Mdouble getZMin() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMin() returns ZMin...
Definition: DPMBase.cc:252
bool saveCurrentTimestep(unsigned int ntimeSteps)
Definition: File.cc:307
void gatherContactStatistics()
Definition: DPMBase.cc:687
virtual void outputStatistics()
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:683
void setTimeStep(Mdouble newDt)
Allows the time step dt to be changed.
Definition: DPMBase.cc:353
void removeDuplicatePeriodicParticles()
Removes periodic duplicate Particles.
Definition: DPMBase.cc:2394
const Vec3D & getTorque() const
Gets the current torque (vector) between the two interacting objects.
virtual void integrateBeforeForceComputation()
This is were the integration is done, at the moment it is velocity Verlet integration and is done bef...
Definition: DPMBase.cc:1495
virtual void writeRestartFile()
Stores all the particle data for current save time step. Calls the write function.
Definition: DPMBase.cc:1365
std::string xBallsAdditionalArguments_
A string of additional arguments for xballs can be specified (see XBalls/xballs.txt). e.g. "-solidf -v0".
Definition: DPMBase.h:854
double getXBallsVectorScale() const
Returns the scale of vectors used in xballs.
Definition: DPMBase.cc:396
This is a class defining walls.
Definition: InfiniteWall.h:43
virtual bool continueSolve() const
Definition: DPMBase.cc:769
each time-step will be written into/read from separate files numbered consecutively: name_...
It is publicly inherited from class Files. It defines an awesome feature that is ideal when doing a p...
static Mdouble getDistanceSquared(const Vec3D &a, const Vec3D &b)
Calculates the squared distance between two Vec3D: .
Definition: Vector.cc:293
std::ostream & operator<<(std::ostream &os, DPMBase &md)
Definition: DPMBase.cc:75
virtual void hGridUpdateMove(BaseParticle *, Mdouble)
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:717
virtual void computeForcesDueToWalls(BaseParticle *PI)
Computes the forces on the particles due to the walls (normals are outward normals) ...
Definition: DPMBase.cc:1465
Class that describes a possible contact between two BaseParticle.
std::string restartVersion_
Previous versions of MercuryDPM had a different restart file format, the below member variable allows...
Definition: DPMBase.h:815
const std::list< BaseInteraction * > & getInteractions() const
Returns a reference to the list of interactions in this BaseInteractable.
virtual void computeForce()
Virtual function that contains the force law between the two objects interacting. ...
void setRestarted(bool newRestartedFlag)
Allows to set the flag stating if the simulation is to be restarted or not.
Definition: DPMBase.cc:527
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:45
void setName(const std::string &name)
Sets the file name, e.g. "Name.data".
Definition: File.cc:195
std::string getXBallsAdditionalArguments() const
Definition: DPMBase.cc:410
virtual void hGridActionsAfterIntegration()
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:731
void addForce(Vec3D addForce)
Adds an amount to the force on this BaseInteractable.
Mdouble getTimeStep() const
Allows the time step dt to be accessed.
Definition: DPMBase.cc:368
File statFile
An instance of class File to handle in- and output into a .stat file.
Definition: Files.h:224
double getXBallsScale() const
Returns the scale of the view in xballs.
Definition: DPMBase.cc:424
bool isFixed() const
Is fixed Particle function. It returns whether a Particle is fixed or not, by checking its inverse Ma...
virtual void hGridActionsBeforeTimeStep()
A virtual function that allows one to set or execute hGrid parameters or operations before every simu...
Definition: DPMBase.cc:619
void setXBallsScale(Mdouble newScale)
Sets the scale of the view (either normal, zoom in or zoom out) to display in xballs. The default is fit to screen.
Definition: DPMBase.cc:417
Mdouble Z
Definition: Vector.h:52
Mdouble getInteractionRadius() const
Returns the particle's interaction radius, which might be different from radius_ (e.g., when dealing with wet particles)
bool getRotation() const
Returns a flag indicating if particle rotation is enabled or disabled.
Definition: DPMBase.cc:217
virtual void finishStatistics()
no implementation but can be overidden in its derived classes.
Definition: DPMBase.cc:710
virtual void broadPhase(BaseParticle *i)
By broad one means to screen and determine an approximate number of particles that a given particle c...
Definition: DPMBase.cc:738
Mdouble getTime() const
Access function for the time.
Definition: DPMBase.cc:158
const std::string & getName() const
Returns the name of the file. Does not allow to change it though.
Definition: Files.cc:131
virtual void checkInteractionWithBoundaries()
There are a range of boundaries one could implement depending on ones' problem. This methods checks f...
Definition: DPMBase.cc:1509
virtual void removeObject(unsigned const int id)
Removes a BaseParticle from the ParticleHandler.
virtual void writeFstatHeader(std::ostream &os) const
Writes a header with a certain format for FStat file.
Definition: DPMBase.cc:861
virtual void read(std::istream &is)
Reads all particle data into a restart file.
Definition: DPMBase.cc:1695
Mdouble getTimeMax() const
Allows the user to access the total simulation time during the simulation. Cannot change it though...
Definition: DPMBase.cc:194
int getRunNumber() const
This returns the current value of the counter (runNumber_)
const std::string & getName() const
Allows to access the file name, e.g., "problem.data".
Definition: File.cc:162
DPMBase()
Constructor that calls the "void constructor()".
Definition: DPMBase.cc:135
void setOpenMode(std::fstream::openmode openMode)
Allows the user to Sets File::openMode_.
Definition: File.cc:267
Vec3D gravity_
Gravity vector.
Definition: DPMBase.h:745
std::function< void(std::string, std::string)> onFatal
Definition: Logger.h:142
void clear()
Empties the whole BaseHandler by removing all Objects and setting all other variables to 0...
Definition: BaseHandler.h:360
virtual void setupInitialConditions()
This function allows to set the initial conditions for our problem to be solved, by default particle ...
Definition: DPMBase.cc:833
void fixParticle()
Fix Particle function. It fixes a Particle by setting its inverse mass and inertia and velocities to ...
bool append_
A flag to determine if the file has to be appended or not. See DPMBase::Solve() for example...
Definition: DPMBase.h:826
virtual void computeExternalForces(BaseParticle *PI)
Computes the external forces acting on particles (e.g. gravitational)
Definition: DPMBase.cc:1451
std::string getRestartVersion() const
This is to take into account for different Mercury versions. Returns the version of the restart file...
Definition: DPMBase.cc:501
bool isTimeEqualTo(Mdouble time) const
Checks if the input variable "time" is the current time in the simulation.
Definition: DPMBase.cc:2446