MercuryDPM  0.10
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
StatisticsVector.hcc
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 
27 std::ostream& operator<<(std::ostream& os, const StatType S) {
28  if (S==O) os << "O";
29  else if (S==X) os << "X";
30  else if (S==Y) os << "Y";
31  else if (S==Z) os << "Z";
32  else if (S==XY) os << "XY";
33  else if (S==XZ) os << "XZ";
34  else if (S==YZ) os << "YZ";
35  else if (S==XYZ) os << "XYZ";
36  else if (S==RAZ) os << "RAZ";
37  else if (S==RA) os << "RA";
38  else if (S==AZ) os << "AZ";
39  else if (S==RZ) os << "RZ";
40  else if (S==R) os << "R";
41  else if (S==A) os << "A";
42  return os;
43 }
44 
45 template <StatType T>
47  // set w2
48  if (new_>0.0) w2 = new_;
49  else w2 = sqr(w_over_rmax*getLargestParticle()->get_Radius());
50  //(2.0*get_xmax()/nx);
51 
52  // set cutoff radius
53  if (get_CG_type()==HeavisideSphere||get_CG_type()==Polynomial) {
54  cutoff = sqrt(w2);
55  } else if (get_CG_type()==Gaussian) {
56  if (get_superexact()) cutoff = 5.0*sqrt(w2);
57  else cutoff = 3.0*sqrt(w2);
59  } else { std::cerr << "error in CG_function" << std::endl; exit(-1); }
60 }
61 
62 template <StatType T>
64  for (unsigned int i=0; i<Points.size(); i++) Points[i].set_zero();
65  if (get_doGradient()) for (unsigned int i=0; i<Points.size(); i++) {
66  dx[i].set_zero(); dy[i].set_zero(); dz[i].set_zero();
67  }
68  for (std::vector<BaseParticle*>::iterator it = getParticleHandler().begin(); it!=getParticleHandler().end(); ++it) {
69  (*it)->set_PreviousPosition((*it)->get_Position());
70  }
71 }
72 
73 template <StatType T>
75  //stores the template parameter Stattype in a variable
76  set_statType();
77 
78  // sets connection between StatisticsPoint and StatisticsVector
80  // set nx, ny,nz
81  nx = ny = nz = 1;
82  nxMirrored=nyMirrored=nzMirrored=0;
83 
84  // set default CG variables
85  CG_type = Gaussian;
86  // in get_statistics_..., w2 is set to w_over_rmax*rmax if w2==0
87  w_over_rmax = 1;
88 
89  // bounded domain
90  //~ boundedDomain = false;
91 
92  // set default values; variables will only be used if the default
93  // is overwritten; thus the default is a nonsense value
94  w2 = 0.0;
95  set_tintStat(0);
96  set_tminStat(-1e20);
97  set_tmaxStat(NAN);
98  rmin = 0;
99  hmax = 1e20;
100  rmax = 1e20;
101  indSpecies = -1; //all species
102 
103 
104  //set default options - Not used it physially don't make sense i.e if ?max<?min
105  xminStat = NAN;
106  xmaxStat = NAN;
107  yminStat = NAN;
108  ymaxStat = NAN;
109  zminStat = NAN;
110  zmaxStat = NAN;
111 
112 
113  // set default options
114  ignoreFixedParticles = true; //this should be true if you want statistics only of the flow
115  StressTypeForFixedParticles = 1;
116  verbosity = 1;
117  walls = true;
118  periodicWalls = true;
119  format = 0;
120  mirrorAtDomainBoundary = false;
121  set_superexact(false);
122  VelocityProfile.resize(0); //equivalent to do not use velocityprofile
123 
124  // time averaging
125  set_doTimeAverage(true);
126  nTimeAverage = 0;
127  nTimeAverageReset = -1;
128  //calculate variance
129  set_doVariance(false);
130  //calculate gradient
131  set_doGradient(false);
132  doublePoints=false;
133 
134  // additional stuff
135  set_options_stat(1);
136 }
137 
138 template <StatType T>
140 {
141  //assumes that we want the statistical method copied, but resets the time averaging
142  constructor();
143  //~ StatType statType; //this has to be constant, right?
144  nx = other.nx;
145  ny = other.ny;
146  nz = other.nz;
147  xminStat = other.xminStat;
148  yminStat = other.yminStat;
149  zminStat = other.zminStat;
150  xmaxStat = other.xmaxStat;
151  ymaxStat = other.ymaxStat;
152  zmaxStat = other.zmaxStat;
153  nxMirrored = other.nxMirrored;
154  nyMirrored = other.nyMirrored;
155  nzMirrored = other.nzMirrored;
156  Points = other.Points;
157  dx = other.dx;
158  dy = other.dy;
159  dz = other.dz;
160 
161  timeAverage = other.timeAverage;
162  timeVariance = other.timeVariance;
167  nTimeAverage = 0;
168  for (unsigned int i=0; i<timeAverage.size(); i++) timeAverage[i].set_zero();
169  for (unsigned int i=0; i<timeVariance.size(); i++) timeVariance[i].set_zero();
170  for (unsigned int i=0; i<dxTimeAverage.size(); i++) dxTimeAverage[i].set_zero();
171  for (unsigned int i=0; i<dyTimeAverage.size(); i++) dyTimeAverage[i].set_zero();
172  for (unsigned int i=0; i<dzTimeAverage.size(); i++) dzTimeAverage[i].set_zero();
173  doVariance = other.doVariance;
174  doGradient = other.doGradient;
175  CG_type = other.CG_type;
176  CGPolynomial = other.CGPolynomial;
177  w2 = other.w2;
178  cutoff = other.cutoff;
179  cutoff2 = other.cutoff2;
180  w_over_rmax = other.w_over_rmax;
181  tminStat = other.tminStat;
182  tmaxStat = other.tmaxStat;
183  tintStat = other.tintStat;
184  rmin = other.rmin;
185  rmax = other.rmax;
186  hmax = other.hmax;
187  indSpecies = other.indSpecies;
188  walls = other.walls;
192  verbosity = other.verbosity;
193  format = other.format;
195  isMDCLR = other.isMDCLR;
196  superexact = other.superexact;
197 }
198 
199 
200 
201 template <StatType T>
202 void StatisticsVector<T>::constructor(std::string name) {
203  //call default constructor
204  constructor();
205 
206  // set name
207  set_name(name.c_str());
208 
209  if (!strcmp(get_name().c_str(),"c3d")) {
210  //write here what to do with Stefan's data
211  std::cout << "MDCLR data" << std::endl;
212  exit(-1);
213  } else {
214  //write here what to do with Mercury data
215  isMDCLR = false;
216  load_restart_data();
217  set_append(false);
218  //~ set_tmaxStat(t+dt); //note:doesn't work if restart data is not the latest
219  }
220 }
221 
222 //Constructor that accepts arguments from the command line
223 template <StatType T>
224 StatisticsVector<T>::StatisticsVector(unsigned int argc, char *argv[])
225 {
226  //check if filename is given
227  if (argc<2) {
228  std::cerr<<"fstatistics.exe filename [-options]"<< std::endl
229  << "Type -help for more information" << std::endl;
230  exit(-1);
231  }
232 
233  //print help if required
234  if (!strcmp(argv[1],"-help")) {
235  print_help();
236  }
237 
238  //create StatisticsVector
239  std::string filename(argv[1]);
240  constructor(filename);
241 
242  //check for options (standardly '-option argument')
243  readStatArguments(argc, argv);
244 }
245 
246 template <StatType T>
247 bool StatisticsVector<T>::loadVelocityProfile (const char* filename)
248 {
249  //This opens the file the data will be recalled from
250  std::fstream is;
251  is.open(filename, std::fstream::in);
252  if (!is.is_open()||is.bad()) {
253  std::cout << "Loading data file " << filename << " failed" << std::endl;
254  return false;
255  }
256 
257  //Read the file; we assume that the stat file we read in has the same stattype and domain size as the problem.
258  std::string line_string;
259  getline(is,line_string);
260  std::string dummy;
261  is >> dummy >> dummy;
262  is >> dummy >> dummy;
263  double xmin, xmax, ymin, ymax, zmin, zmax;
264  is >> dummy >> xmin >> xmax >> ymin >> ymax >> zmin >> zmax;
265  VelocityProfile_Min = Vec3D(xmin,ymin,zmin);
266  double nx, ny, nz;
267  is >> dummy >> nx >> ny >> nz;
268  double dx = (xmax-xmin)/(nx-1);
269  double dy = (ymax-ymin)/(ny-1);
270  double dz = (zmax-zmin)/(nz-1);
271  VelocityProfile_D = Vec3D(dx,dy,dz);
272  std::string statType;
273  is >> dummy >> statType;
274  getline(is,line_string);
275  getline(is,line_string);
276 
277  set_nx(nx);
278  set_ny(ny);
279  set_nz(nz);
280  set_xminStat(xmin);
281  set_yminStat(ymin);
282  set_zminStat(zmin);
283  set_xmaxStat(xmax);
284  set_ymaxStat(ymax);
285  set_zmaxStat(zmax);
286 
287  VelocityProfile.resize(nx*ny*nz);
288  Vec3D M;
289  double rho;
290  int n=0;
291  for (int i=0; i<nx; i++)
292  for (int j=0; j<ny; j++)
293  for (int k=0; k<nz; k++) {
294  is >> dummy >> dummy >> dummy >> dummy >> rho >> M.X >> M.Y >> M.Z;
295  getline(is,line_string);
296  VelocityProfile[n]=M/rho;
297  n++;
298  }
299 
300  //Close the file
301  is.close();
302  std::cout << "Loaded data file " << filename << std::endl;
303  return true;
304 }
305 
306 template <StatType T>
308 {
309  double i,j,k;
310  double l,m,n;
311  l = modf ((double)(Position.X-VelocityProfile_Min.X)/VelocityProfile_D.X, &i);
312  m = modf ((double)(Position.Y-VelocityProfile_Min.Y)/VelocityProfile_D.Y, &j);
313  n = modf ((double)(Position.Z-VelocityProfile_Min.Z)/VelocityProfile_D.Z, &k);
314  if (nx<1) i=0;
315  if (ny<1) j=0;
316  if (ny<1) k=0;
317  int ix = (i*ny+j)*nz+k;
318  Vec3D V;
319  if (nx<=1) V.X = VelocityProfile[ix].X;
320  else V.X=VelocityProfile[ix].X*(1-l)+VelocityProfile[ix+ny*nz].X*l;
321  if (ny<=1) V.Y = VelocityProfile[ix].Y;
322  else V.Y=VelocityProfile[ix].Y*(1-m)+VelocityProfile[ix+nz].Y*m;
323  if (nz<=1) V.Z = VelocityProfile[ix].Z;
324  else V.Z=VelocityProfile[ix].Z*(1-n)+VelocityProfile[ix+1].Z*n;
325  return V;
326 }
327 
328 
329 //Constructor that accepts arguments from the command line
330 template <StatType T>
331 void StatisticsVector<T>::readStatArguments(unsigned int argc, char *argv[])
332 {
333  //check for options (standardly '-option argument')
334  for (unsigned int i = 2; i<argc; i+=2) {
335  std::cout << "interpreting input argument " << argv[i];
336  if (i+1<argc) std::cout << " " << argv[i+1];
337  std::cout << std::endl;
338 
339  if (!strcmp(argv[i],"-CGtype")) {
340  //CG_type_todo
341  if (!strcmp(argv[i+1],"HeavisideSphere")) {
342  set_CG_type(HeavisideSphere);
343  } else if (!strcmp(argv[i+1],"Gaussian")) {
344  set_CG_type(Gaussian);
345  } else {
346  set_CG_type(argv[i+1]);
347  }
348  } else if (!strcmp(argv[i],"-w")) {
349  double old = get_w();
350  set_w (atof(argv[i+1]));
351  std::cout << " w changed from " << old << " to " << get_w() << std::endl;
352  } else if (!strcmp(argv[i],"-help")) {
353  print_help();
354  i--; //requires no argument
355  } else if (!strcmp(argv[i],"-velocityprofile")) {
356  loadVelocityProfile(argv[i+1]);
357  } else if (!strcmp(argv[i],"-h")) {
358  set_h (atof(argv[i+1]));
359  } else if (!strcmp(argv[i],"-hx")) {
360  set_hx(atof(argv[i+1]));
361  } else if (!strcmp(argv[i],"-hy")) {
362  set_hy(atof(argv[i+1]));
363  } else if (!strcmp(argv[i],"-hz")) {
364  set_hz(atof(argv[i+1]));
365  } else if (!strcmp(argv[i],"-n")) {
366  set_n(atoi(argv[i+1]));
367  } else if (!strcmp(argv[i],"-nx")) {
368  set_nx(atoi(argv[i+1]));
369  } else if (!strcmp(argv[i],"-ny")) {
370  set_ny(atoi(argv[i+1]));
371  } else if (!strcmp(argv[i],"-nz")) {
372  set_nz(atoi(argv[i+1]));
373  } else if (!strcmp(argv[i],"-x")) {
374  set_xminStat(atof(argv[i+1]));
375  set_xmaxStat(atof(argv[i+2]));
376  i++; //requires two arguments
377  } else if (!strcmp(argv[i],"-y")) {
378  set_yminStat(atof(argv[i+1]));
379  set_ymaxStat(atof(argv[i+2]));
380  i++; //requires two arguments
381  } else if (!strcmp(argv[i],"-z")) {
382  set_zminStat(atof(argv[i+1]));
383  set_zmaxStat(atof(argv[i+2]));
384  i++; //requires two arguments
385  } else if (!strcmp(argv[i],"-indSpecies")) {
386  indSpecies = atoi(argv[i+1]);
387  } else if (!strcmp(argv[i],"-rmin")) {
388  rmin = atof(argv[i+1]);
389  } else if (!strcmp(argv[i],"-rmax")) {
390  rmax = atof(argv[i+1]);
391  } else if (!strcmp(argv[i],"-hmax")) {
392  hmax = atof(argv[i+1]);
393  } else if (!strcmp(argv[i],"-periodicwalls")) {
394  set_periodicWalls(atoi(argv[i+1]));
395  } else if (!strcmp(argv[i],"-walls")) {
396  set_walls(atoi(argv[i+1]));
397  } else if (!strcmp(argv[i],"-verbosity")) {
398  set_verbosity(atoi(argv[i+1]));
399  } else if (!strcmp(argv[i],"-verbose")) {
400  verbose();
401  i--; //requires no argument
402  } else if (!strcmp(argv[i],"-format")) {
403  format = atoi(argv[i+1]);
404  } else if (!strcmp(argv[i],"-doublePoints")) {
405  if (argc<=i+1||argv[i+1][0]=='-') {
406  set_doublePoints(true);
407  i--; //no argument
408  } else set_doublePoints(atoi(argv[i+1]));
409  std::cout << "set doublePoints=" << get_doublePoints() << std::endl;
410  } else if (!strcmp(argv[i],"-w_over_rmax")) {
411  set_w_over_rmax(atof(argv[i+1]));
412  } else if (!strcmp(argv[i],"-tmin")) {
413  set_tminStat(atof(argv[i+1]));
414  } else if (!strcmp(argv[i],"-tmax")) {
415  set_tmaxStat(atof(argv[i+1]));
416  } else if (!strcmp(argv[i],"-tint")) {
417  set_tintStat(atof(argv[i+1]));
418  //~ } else if (!strcmp(argv[i],"-timesteps")) {
419  //~ set_tintStat(atof(argv[i+1])*get_dt());
420  } else if (!strcmp(argv[i],"-stepsize")) {
421  int step_size = atoi(argv[i+1]);
422  set_step_size(step_size);
423  } else if (!strcmp(argv[i],"-loaddatafile")) {
424  load_from_data_file(argv[i+1]);
425  set_tminStat(get_t());
426  set_tmaxStat(get_tmax());
427  } else if (!strcmp(argv[i],"-statfilename") | !strcmp(argv[i],"-o")) {
428  stat_filename.str(argv[i+1]);
430  // set_name(argv[i+1]);
431  } else if (!strcmp(argv[i],"-timeaverage")) {
432  set_doTimeAverage(atoi(argv[i+1]));
433  } else if (!strcmp(argv[i],"-timeaveragereset")) {
434  nTimeAverageReset = atoi(argv[i+1]);
435  } else if (!strcmp(argv[i],"-gradient")) {
436  // use default argument if no argument is given
437  if (argc<=i+1||argv[i+1][0]=='-') {
438  set_doGradient(true);
439  i--; //no argument
440  } else set_doGradient(atoi(argv[i+1]));
441  } else if (!strcmp(argv[i],"-timevariance")) {
442  // use default argument if no argument is given
443  if (argc<=i+1||argv[i+1][0]=='-') {
444  set_doVariance(true);
445  i--; //no argument
446  } else set_doVariance(atoi(argv[i+1]));
447  } else if (!strcmp(argv[i],"-superexact")) {
448  // use default argument if no argument is given
449  if (argc<=i+1||argv[i+1][0]=='-') {
450  set_superexact(true);
451  i--; //no argument
452  } else set_superexact(atoi(argv[i+1]));
453  } else if (!strcmp(argv[i],"-ignoreFixedParticles")) {
454  // use default argument if no argument is given
455  if (argc<=i+1||argv[i+1][0]=='-') {
456  set_ignoreFixedParticles(true);
457  i--; //no argument
458  } else set_ignoreFixedParticles(atoi(argv[i+1]));
459  } else if (!strcmp(argv[i],"-StressTypeForFixedParticles")) {
460  StressTypeForFixedParticles = atoi(argv[i+1]);
461  } else if (!strcmp(argv[i],"-mirrorAtDomainBoundary")) {
462  set_mirrorAtDomainBoundary(atof(argv[i+1]));
463  } else if (!strcmp(argv[i],"-stattype")) {
464  //this was already used in Statistics()
465  } else if (readNextArgument(i, argc, argv)) {
466  //~ std::cout << " (read as MD argument, not statistics)" << std::endl;
467  } else {
468  std::cerr << "Error: option unknown: " << argv[i] << std::endl;
469  exit(-1);
470  }
471  }
472 }
473 
474 //Constructor that accepts arguments from the command line
475 template <StatType T>
477 {
478  std::cout << "fstatistics.exe filename [-options]: " << std::endl
479  << "This program evaluates statistical data from .fstat, .data, and. restart files and writes it into a .stat file" << std::endl << std::endl;
480  std::cout << "OPTIONS:" << std::endl << std::endl;
481  std::cout << "-stattype [X,Y,Z,XY,XZ,YZ,XYZ,RAZ,RA,AZ,RZ,R,A]: " << std::endl
482  << "Used to obtain statistics averaged in all coordinate directions but the ones specified; f.e. -stattype Z yields depth-profiles. Default is XYZ." << std::endl << std::endl
483  << "-CGtype [HeavisideSphere,Gaussian]: " << std::endl
484  << "Averaging function; default: Gaussian" << std::endl << std::endl
485  << "-w,-w_over_rmax [Mdouble]: " << std::endl
486  << "Averaging width, absolute or in multiples of the radius of the largest particle in the restart file; default: w_over_rmax=1" << std::endl << std::endl
487  << "-n,nx,ny,nz [uint]: " << std::endl
488  << "Specifies the amount of grid points in coordinate directions for which statistics are evaluated; use -n to set all 3 directions at once; is set to one in averaged directions (see stattype). Default n=1" << std::endl << std::endl
489  << "-h,hx,hy,hz [Mdouble]: " << std::endl
490  << "Defines the amount of grid points by setting the mesh size " << std::endl << std::endl
491  << "-x,y,z [Mdouble Mdouble]: " << std::endl
492  << "Specifies the domain of the grid; f.e. for -x 0 1 all grid points will have x-values within [0,1]. Default -x xmin xmax (from restart file)" << std::endl << std::endl
493  << "-indSpecies [int]: " << std::endl
494  << "-rmin,rmax [Mdouble]: " << std::endl
495  << "-hmax [Mdouble]: " << std::endl
496  << "Allows to only obtain statistics for specific particles" << std::endl << std::endl
497  << "-periodicwalls [bool]: " << std::endl
498  << "neglects periodic walls" << std::endl << std::endl
499  << "-walls [uint]: " << std::endl
500  << "only takes into account the first n walls" << std::endl << std::endl
501  << "-verbosity [uint]: " << std::endl
502  << "amount of screen output (0 minimal, 1 normal, 2 maximal)" << std::endl << std::endl
503  << "-verbose: " << std::endl
504  << "identical to -verbosity 2" << std::endl << std::endl
505  << "-format [uint]: " << std::endl
506  << "???" << std::endl << std::endl
507  << "-tmin,tmax,tint [Mdouble]: " << std::endl
508  << "redefines the time interval [tmin,tmax] for which statistics are evaluated. Default values from restart file; tint sets tmin to tmax-tint." << std::endl << std::endl
509  << "-stepsize [uint]: " << std::endl
510  << "to skip some timesteps. Default: 1 " << std::endl << std::endl
511  << "-statfilename [std::string]: " << std::endl
512  << "to change the name of the output file" << std::endl << std::endl
513  << "-timeaverage [bool]: " << std::endl
514  << "To average in time (1) or to print statistics for all time steps (0). Default: 1" << std::endl << std::endl
515  << "-timevariance [bool]: " << std::endl
516  << "to print the time variance; only for time averaged data. Default: ?" << std::endl << std::endl
517  << "-gradient: " << std::endl
518  << "to plot the first derivative of each statistical value" << std::endl << std::endl
519  << "-ignoreFixedParticles: " << std::endl
520  << "-StressTypeForFixedParticles: " << std::endl
521  << "-mirrorAtDomainBoundary [Mdouble]" << std::endl << std::endl
522  << "" << std::endl << std::endl
523  << "OUTPUT:" << std::endl << std::endl
524  << "1-3: Coordinates " << std::endl
525  << "4: Nu " << std::endl
526  << "5: Density " << std::endl
527  << "6-8: Momentum " << std::endl
528  << "9-11: DisplacementMomentum " << std::endl
529  << "12-17: Displacement" << std::endl
530  << "18-23: MomentumFlux" << std::endl
531  << "24-29: DisplacementMomentumFlux" << std::endl
532  << "30-32: EnergyFlux " << std::endl
533  << "33-41: NormalStress " << std::endl
534  << "42-50: TangentialStress " << std::endl
535  << "51-53: NormalTraction " << std::endl
536  << "54-56: TangentialTraction " << std::endl
537  << "57-62: Fabric " << std::endl
538  << "63-65: CollisionalHeatFlux " << std::endl
539  << "66: Dissipation " << std::endl
540  << "67: Potential " << std::endl
541  << "68-70: LocalAngularMomentum " << std::endl
542  << "71-79: LocalAngularMomentumFlux " << std::endl
543  << "80-88: ContactCoupleStress " << std::endl;
544  exit(0);
545 }
546 
547 template <StatType T>
548 void StatisticsVector<T>::set_CG_type(const char* new_) {
549  if (!strcmp(new_,"Heaviside")) {
550  int dim = 3;
551  int numcoeff = 1;
552  double heavisidecoeff[] = {1};
553  set_Polynomial(heavisidecoeff, numcoeff, dim);
554  } else if (!strcmp(new_,"Linear")) {
555  int dim = 3;
556  int numcoeff = 2;
557  double lincoeff[] = {-1,1};
558  set_Polynomial(lincoeff, numcoeff, dim);
559  } else if (!strcmp(new_,"Lucy")) {
560  int dim = 3;
561  int numcoeff = 5;
562  double lucycoeff[] = {-3,8,-6,0,1};
563  set_Polynomial(lucycoeff, numcoeff, dim);
564  } else if (!strcmp(new_,"Gaussian")) {
565  set_CG_type(Gaussian); return;
566  } else if (!strcmp(new_,"HeavisideSphere")) {
567  set_CG_type(HeavisideSphere); return;
568  } else {
569  std::cerr << "Error: unknown CG_type: " << new_ << std::endl;
570  exit(-1);
571  }
572  set_PolynomialName(new_);
573  set_CG_type(Polynomial);
574 }
575 
576 template <StatType T>
578  if (new_==Polynomial&&CGPolynomial.get_Order()<0) {std::cerr << "Polynomial is not specified" << std::endl; exit(-1);}
579  CG_type = new_;
580 }
581 
583 template <StatType T>
585  std::stringstream ss;
586  ss << "Statistical parameters: name=" << get_name()
587  << ",\n nx=" << nx
588  << ", ny=" << ny
589  << ", nz=" << nz
590  << ", CG_type=";
591  if (get_CG_type()==HeavisideSphere) {
592  ss << "HeavisideSphere";
593  } else if (get_CG_type()==Gaussian) {
594  ss << "Gaussian";
595  } else if (get_CG_type()==Polynomial) {
596  ss << get_PolynomialName();
597  } else { std::cerr << "error in CG_function" << std::endl; exit(-1); }
598 
599  ss << ", w=" << sqrt(w2)
600  << ", cutoff=" << cutoff
601  << ",\n tStat=[" << get_tminStat() << "," << get_tmaxStat() << "]"
602  << ", xStat=[" << get_xminStat() << "," << get_xmaxStat() << "]"
603  << ", yStat=[" << get_yminStat() << "," << get_ymaxStat() << "]"
604  << ", zStat=[" << get_zminStat() << "," << get_zmaxStat() << "]"
605  << ",\n ignoreFixedParticles=" << ignoreFixedParticles
606  << ", StressTypeForFixedParticles=" << StressTypeForFixedParticles
607  << ",\n mirrorAtDomainBoundary=" << get_mirrorAtDomainBoundary()
608  << ",\n doTimeAverage=" << get_doTimeAverage()
609  << ", doVariance=" << get_doVariance()
610  << ", doGradient=" << get_doGradient()
611  << ", verbosity=" << verbosity
612  << std::endl;
613  return ss.str();
614 }
615 
618 template <StatType T>
620  std::stringstream ss;
621  ss << "w " << sqrt(get_w2())
622  << " dim " << get_dim()
623  << " domainStat " << get_xminStat() << " " << get_xmaxStat()
624  << " " << get_yminStat() << " " << get_ymaxStat()
625  << " " << get_zminStat() << " " << get_zmaxStat()
626  << " n " << nx << " " << ny << " " << nz
627  << " statType " << statType;
628  if (CG_type==Polynomial) ss << " CGPolynomial " << CGPolynomial;
629  else ss << " CG_type " << CG_type << " cutoff " << cutoff;
630  if (doVariance) ss << " doVariance";
631  if (doGradient) ss << " doGradient";
632  if (doTimeAverage) {
633  ss << " doTimeAverage";
634  if (nTimeAverageReset!=-1) ss << " nTimeAverageReset " << nTimeAverageReset;
635  }
636  if (indSpecies!=-1) ss << " indSpecies " << indSpecies;
637  if (rmin!=0) ss << " rmin " << rmin;
638  if (rmax!=1e20) ss << " rmax " << rmax;
639  if (hmax!=1e20) ss << " hmax " << hmax;
640  if (!walls) ss << " noWalls";
641  if (!periodicWalls) ss << " noPeriodicWalls";
642  if (!ignoreFixedParticles) ss << " includeFixedParticles";
643  if (StressTypeForFixedParticles!=1) ss << " StressTypeForFixedParticles " << StressTypeForFixedParticles;
644  return ss.str();
645 }
646 
648 template <StatType T>
650  StatisticsPoint<T> avg;
651  avg.set_zero();
652  for (unsigned int i=0; i<P.size(); i++) avg += P[i];
653  avg /= P.size();
654  return avg;
655 }
656 
657 template <StatType T>
659 {
660  reset_statistics();
661 
663 
665 
666  //set tmin and tmax if tint is set
667  if (get_tintStat()) {
668  set_tminStat(get_t());
669  set_tmaxStat(get_tminStat() + get_tintStat());
670  std::cout << "tint set, time goes from: " << get_tminStat() << " to: " << get_tmaxStat() << std::endl;
671  }
672 
674  if (!strcmp(get_stat_filename().c_str(),"")) set_stat_filename(); //set ouput filename to default unless otherwise specified
675  if(!open_stat_file(std::fstream::out)) {std::cerr << "Problem opening stat file aborting" <<std::endl; exit(-1);};
676 
677  get_stat_file() << Points.begin()->write_variable_names() << std::endl;
678  get_stat_file() << print_CG() << std::endl;
679 
680  //std::couts variables
681  if (verbosity>1) std::cout << std::endl;
682  if (verbosity>0) std::cout << std::endl << print() << std::endl;
683 
684 }
685 
686 template <StatType T>
688  static unsigned int count = 0;
689 
690  if (count) for (std::vector<BaseParticle*>::iterator it = getParticleHandler().begin(); it!=getParticleHandler().end(); ++it) {
691  (*it)->set_PreviousPosition((*it)->get_Position());
692  }
693 
694  bool ret_val = MD::read_next_from_data_file (format);
695 
696  if (!count) for (std::vector<BaseParticle*>::iterator it = getParticleHandler().begin(); it!=getParticleHandler().end(); ++it) {
697  (*it)->set_PreviousPosition((*it)->get_Position());
698  }
699 
700  count++;
701  return ret_val;
702 }
703 
704 template <StatType T>
706 {
707  std::cout << "writing statistics for t=" << get_t() << std::endl;
708 
709  // write to .stat file
710  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_t() << std::endl;
711  for (unsigned int i=0; i<Points.size(); i++)
712  get_stat_file() << Points[i];
713  if (get_doGradient())
714  {
715  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_t() << std::endl;
716  for (unsigned int i=0; i<dx.size(); i++)
717  get_stat_file() << dx[i];
718  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_t() << std::endl;
719  for (unsigned int i=0; i<dy.size(); i++)
720  get_stat_file() << dy[i];
721  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_t() << std::endl;
722  for (unsigned int i=0; i<dz.size(); i++)
723  get_stat_file() << dz[i];
724  }
725 
726 }
727 
728 template <StatType T>
730 {
731  if (get_doTimeAverage()) write_time_average_statistics();
732  stat_file.close();
733 }
734 
735 template <StatType T>
737 {
738  if (check_current_time_for_statistics()&&usethese)
739  {
740  if (get_mirrorAtDomainBoundary()) {
741  for (unsigned int i=0; i<Points.size(); i++) {
742  if (Points[i].mirrorParticle>=0) {
743  //add values to the mirrorParticle
744  Points[Points[i].mirrorParticle]+=Points[i];
745  Points[i].set_zero();
746  if (get_doGradient()) {
747  dx[Points[i].mirrorParticle]+=dx[i];
748  dy[Points[i].mirrorParticle]+=dy[i];
749  dz[Points[i].mirrorParticle]+=dz[i];
750  }
751  }
752  }
753  }
754  //~ for (unsigned int i=0; i<Points.size(); i++)
755  //~ Points[i].Displacement /= sqr(Points[i].Density);
756  if (get_doTimeAverage())
757  {
758  for (unsigned int i=0; i<timeAverage.size(); i++)
759  {
760  timeAverage[i] += Points[i];
761  if (get_doVariance())
762  timeVariance[i] += Points[i].getSquared();
763  if (get_doGradient())
764  {
765  dxTimeAverage[i] += dx[i];
766  dyTimeAverage[i] += dy[i];
767  dzTimeAverage[i] += dz[i];
768  }
769  }
770  nTimeAverage++;
771  if (nTimeAverage==nTimeAverageReset) {
772  std::cout << "write time average" << std::endl;
773  write_time_average_statistics();
774  nTimeAverage=0;
775  for (unsigned int i=0; i<timeAverage.size(); i++)
776  timeAverage[i].set_zero();
777  }
778  }
779  else
780  {
781  write_statistics();
782  }
783  }
784  reset_statistics();
785 }
786 
787 template <StatType T>
789 {
790  static bool first = true;
791 
792  if (verbosity) std::cout << std::endl << "averaging " << nTimeAverage << " timesteps " << std::endl;
793  if(nTimeAverage==0)
794  {
795  fprintf(stderr, "\n\n\tERROR :: Can not do TimeAverage of 0 timesteps\n\n");
796  //exit(-1);
797  return;
798  }
799  if (first) {
800  std::cout << "first" << nTimeAverage << std::endl;
801  for (unsigned int i=0; i<timeAverage.size(); i++) {
802  timeAverage[i].firstTimeAverage(nTimeAverage);
803  if (get_doVariance()) {
804  timeVariance[i].firstTimeAverage(nTimeAverage);
805  timeVariance[i] -= timeAverage[i].getSquared();
806  }
807  if (get_doGradient()) {
808  dxTimeAverage[i].firstTimeAverage(nTimeAverage);
809  dyTimeAverage[i].firstTimeAverage(nTimeAverage);
810  dzTimeAverage[i].firstTimeAverage(nTimeAverage);
811  }
812  }
813  first=false;
814  } else {
815  std::cout << "next" << nTimeAverage << std::endl;
816  for (unsigned int i=0; i<timeAverage.size(); i++) {
817  timeAverage[i] /= nTimeAverage;
818  if (get_doVariance()) {
819  timeVariance[i] /= nTimeAverage;
820  timeVariance[i] -= timeAverage[i].getSquared();
821  }
822  if (get_doGradient()) {
823  dxTimeAverage[i] /= nTimeAverage;
824  dyTimeAverage[i] /= nTimeAverage;
825  dzTimeAverage[i] /= nTimeAverage;
826  }
827  }
828  }
829 
830  // write average to .stat file
831  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_tminStat() << " " << get_t() << std::endl;
832  for (unsigned int i=0; i<timeAverage.size(); i++) get_stat_file() << timeAverage[i];
833  // write to std::cout
834  StatisticsPoint<T> avg = average(timeAverage);
835  std::cout << "Averages: " << avg.print() << std::endl;
836 
837  if (get_doVariance()) {
838  // write variance to .stat file
839  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_tminStat() << " " << get_t() << " " << std::endl;
840  for (unsigned int i=0; i<timeVariance.size(); i++)
841  get_stat_file() << timeVariance[i];
842  //StatisticsPoint<T> var = average(timeVariance);
843  } //end if (get_doVariance)
844 
845  if (get_doGradient()) {
846  // write variance to .stat file
847  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_tminStat() << " " << get_t() << " " << std::endl;
848  for (unsigned int i=0; i<timeAverage.size(); i++) get_stat_file() << dxTimeAverage[i];
849  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_tminStat() << " " << get_t() << " " << std::endl;
850  for (unsigned int i=0; i<timeAverage.size(); i++) get_stat_file() << dyTimeAverage[i];
851  get_stat_file() << std::left << std::setprecision(8) << std::setw(6) << get_tminStat() << " " << get_t() << " " << std::endl;
852  for (unsigned int i=0; i<timeAverage.size(); i++) get_stat_file() << dzTimeAverage[i];
853  }
854 
855  set_tminStat(get_t());
856 
857 }
858 
859 template <StatType T>
861 {
862  //This opens the file the data will be recalled from
863  set_data_filename();
864  open_data_file(std::fstream::in);
865 
866  //load first set of timesteps to obtain xdim, ydim, zdim
867 
868  //try to read data files; if data.0000 does not exist, try the next, up to .9999
869  for (int i=1; i<10000; i++) {
870  if(read_next_from_data_file(format)) break;
871  set_file_counter(i);
872  }
873 
874  //set tminstat to smallest time evaluated
875  if (get_t()>=get_tminStat()) set_tminStat(get_t()-get_dt());
876 
877  //This opens the file the force data will be recalled from
878  set_fstat_filename();
879  open_fstat_file(std::fstream::in);
880 
881  //This creates the file statistics will be saved to
882  //open_stat_file(std::fstream::out);
883 
884  if (verbosity>1) {
885  std::cout << "Input from " << get_data_filename() << std::endl;
886  std::cout << "Input from " << get_fstat_filename() << std::endl;
887  std::cout << "Output to " << get_stat_filename() << std::endl << std::endl;
888  }
889 
890  initialize_statistics();
891 
892  //std::couts collision time
893  Mdouble mass = get_Mass_from_Radius(getLargestParticle()->get_Radius());
894  if (verbosity>1) std::cout << "Collision Time " << get_collision_time(mass)
895  << " and restitution coefficient " << get_restitution_coefficient(mass)
896  << " for mass " << mass << std::endl
897  << std::endl;
898  //std::couts particles
899  if (verbosity>2) {MD::print(std::cout,true); std::cout << std::endl;}
900  else if (verbosity) {MD::print(std::cout); std::cout << std::endl;}
901 
902  //this increases the file counter
903  if (get_options_data()==2 && get_t()<get_tminStat()) {
904  if (verbosity>1) find_next_data_file(get_tminStat());
905  else find_next_data_file(get_tminStat(), false);
906  for(int i=1;i<get_file_counter();i++) jump_fstat();
907 
908  }
909 
910  //Output statistics for each time step
911  std::cout<<"Start statistics"<<std::endl;
912  do {
913  if (get_t()>get_tmaxStat()) {
914  std::cout << "reached end t="<<std::setprecision (9) <<get_t()<<" tmaxStat=" << std::setprecision (9) <<get_tmaxStat()<< std::endl; break;
915  } else if (get_t()>=get_tminStat()) {
916  if (verbosity>1) std::cout << "Get statistics for t=" << std::setprecision (9) << get_t() << std::endl;
917  else if (verbosity) std::cout << "Get statistics for t=" << std::setprecision (9) << get_t() << " \r";
918  if (verbosity>1) std::cout << "#particles="<< getParticleHandler().getNumberOfObjects() << std::endl;
919 
920  if (!walls) getWallHandler().clear();
922  if (!periodicWalls) getBoundaryHandler().clear();
923 
924  output_statistics();
925  gather_force_statistics_from_fstat_and_data();
926  process_statistics(true);
927 
928  } else {
929  if (verbosity>1) std::cout<<"Jumping statistics t="<<get_t()<<" tminStat()="<<get_tminStat()<<std::endl;
930  jump_fstat();
931  }
932  //if step size>1, skip a number of steps.
933  if (get_options_data()!=2) for (unsigned int i=1; i<get_step_size(); i++) {
934  //you only get here if you change the step size and you use a single data file
935  read_next_from_data_file(format);
936  jump_fstat();
937  }
938  } while (read_next_from_data_file(format));
939  //set tmax to largest time evaluated
940  if (get_t()<get_tmaxStat()) set_tmaxStat(get_t());
941 
942  finish_statistics();
943  get_data_file().close();
944  get_fstat_file().close();
945 }
946 
947 template <StatType T>
949  if (getParticleHandler().getNumberOfObjects()<1) return;
950  std::vector<BaseParticle*>::iterator it = getParticleHandler().begin();
951  set_xmin((*it)->get_Position().X-(*it)->get_Radius());
952  set_ymin((*it)->get_Position().Y-(*it)->get_Radius());
953  set_zmin((*it)->get_Position().Z-(*it)->get_Radius());
954  set_xmax((*it)->get_Position().X+(*it)->get_Radius());
955  set_ymax((*it)->get_Position().Y+(*it)->get_Radius());
956  set_zmax((*it)->get_Position().Z+(*it)->get_Radius());
957  for (std::vector<BaseParticle*>::iterator it = getParticleHandler().begin(); it!=getParticleHandler().end(); ++it) {
958  set_xmin(std::min(get_xmin(),(*it)->get_Position().X-(*it)->get_Radius()));
959  set_ymin(std::min(get_ymin(),(*it)->get_Position().Y-(*it)->get_Radius()));
960  set_zmin(std::min(get_zmin(),(*it)->get_Position().Z-(*it)->get_Radius()));
961  set_xmax(std::max(get_xmax(),(*it)->get_Position().X+(*it)->get_Radius()));
962  set_ymax(std::max(get_ymax(),(*it)->get_Position().Y+(*it)->get_Radius()));
963  set_zmax(std::max(get_zmax(),(*it)->get_Position().Z+(*it)->get_Radius()));
964  } //end for all particles
965 }
966 
967 template <StatType T>
969 {
970  //uncomment if you want data file output
971  //MD::output_xballs_data();
972 
973  unsigned int N;
974  Mdouble dummy;
975  std::string dummyStr;
976 
977  //read first parameters and check if we reached the end of the file
978 
979  //Ignoring first line
980  getline(p3p_file,dummyStr);
981  std::cout << dummyStr << std::endl;
982  //Reading second line
983  p3p_file >> dummy; set_t(dummy);
984  p3p_file >> N;
985  std::cout << "t= " << get_t() << ": loading " << N << " particles ..." << std::endl;
986  getline(p3p_file,dummyStr);
987  //std::cout << dummyStr << std::endl;
988  //Ignoring third line
989  getline(p3p_file,dummyStr);
990  std::cout << dummyStr << std::endl;
991  if (p3p_file.eof()||p3p_file.peek()==-1) {std::cout << "reached end of p3p file" << std::endl; return false;}
992 
993  BaseParticle P0;
994  if(getParticleHandler().getNumberOfObjects()<N)
995  while(getParticleHandler().getNumberOfObjects()<N)
996  getParticleHandler().copyAndAddParticle(P0);
997  else
998  while(getParticleHandler().getNumberOfObjects()>N)
999  getParticleHandler().removeLastParticle();
1000 
1001  //Read forth to (N+3)rd line
1002  Vec3D dummyVec;
1003  Vec3D position,velocity,angle,angularVelocity;
1004  int dummyInt;
1005  for (std::vector<BaseParticle*>::iterator it = getParticleHandler().begin(); it!=getParticleHandler().end(); ++it) {
1006  p3p_file >> dummyInt; (*it)->set_Index(dummyInt); //ID
1007  //std::cout << " ID " << (*it)->get_Index() << std::endl;
1008  p3p_file >> dummyInt; (*it)->set_species(dummyInt-1); //Group
1009  p3p_file >> dummy; (*it)->set_Radius(pow(dummy/(4./3.*constants::pi),1./3.)); //Volume
1010  p3p_file >> dummy; (*it)->set_Mass(dummy); //Mass
1011  p3p_file
1012  >> position
1013  >> velocity
1014  >> angularVelocity;
1015  (*it)->set_Position(position);
1016  (*it)->set_Velocity(velocity);
1017  (*it)->set_AngularVelocity(angularVelocity);
1018  //clean up tangential springs
1019  } //end for all particles
1020  //auto_setdim();
1021 
1022  getline(p3p_file,dummyStr);
1023  std::cout << dummyStr << std::endl;
1024 
1025  //fix particles, if data_FixedParticles!=0
1026 
1027  return true;
1028 }
1029 
1030 
1032 template <StatType T>
1034 {
1035  //This opens the files the data will be recalled from
1036  std::string p3p_filename = problem_name.str().c_str(); p3p_filename += ".p3p";
1037  bool opened = open_file (p3p_file, p3p_filename, 1,std::fstream::in);
1038  std::string p3c_filename = problem_name.str().c_str(); p3c_filename += ".p3c";
1039  open_file (p3c_file, p3c_filename, 1,std::fstream::in);
1040  std::string p3w_filename = problem_name.str().c_str(); p3w_filename += ".p3w";
1041  open_file (p3w_file, p3w_filename, 1,std::fstream::in);
1042  int version=3;
1043  //If p3 is not available, open p4 files
1044  if (!opened) {
1045  std::cerr << "Warning could not open " << p3p_filename << std::endl;
1046  version=4;
1047  p3p_filename = problem_name.str().c_str(); p3p_filename += ".p4p";
1048  opened = open_file (p3p_file, p3p_filename, 1,std::fstream::in);
1049  p3c_filename = problem_name.str().c_str(); p3c_filename += ".p4c";
1050  opened = open_file (p3c_file, p3c_filename, 1,std::fstream::in);
1051  p3w_filename = problem_name.str().c_str(); p3w_filename += ".p4w";
1052  opened = open_file (p3w_file, p3w_filename, 1,std::fstream::in);
1053  if (!opened) {
1054  std::cerr << "could not open " << p3p_filename << std::endl;
1055  exit(-1);
1056  }
1057  }
1058  std::cout << "opened " << p3p_filename << std::endl;
1059 
1060  //load first set of timesteps to obtain xdim, ydim, zdim
1061 
1062  //try to read data files; if data.0000 does not exist, try the next, up to .9999
1063  read_next_from_p3p_file();
1064 
1065  //set tminstat to smallest time evaluated
1066  if (get_t()>=get_tminStat()) set_tminStat(get_t()-get_dt());
1068 
1069  set_data_filename();
1070  open_data_file(std::fstream::out);
1071  MD::set_format(14);
1072  MD::set_dim(3);
1073  Species[0].set_dim_particle(3);
1076  //exit(-1);
1077 
1078  //This creates the file statistics will be saved to
1079  //open_stat_file(std::fstream::out);
1080 
1081  initialize_statistics();
1082 
1083  //std::couts collision time
1084  Mdouble mass = get_Mass_from_Radius(getLargestParticle()->get_Radius());
1085  if (verbosity>1) std::cout << "Collision Time " << get_collision_time(mass)
1086  << " and restitution coefficient " << get_restitution_coefficient(mass)
1087  << " for mass " << mass << std::endl
1088  << std::endl;
1089  //std::couts particles
1090  if (verbosity>2) {MD::print(std::cout,true); std::cout << std::endl;}
1091  else if (verbosity) {MD::print(std::cout); std::cout << std::endl;}
1092 
1093  //Output statistics for each time step
1094  std::cout<<"Start statistics"<<std::endl;
1095  do {
1096  if (get_t()>get_tmaxStat()) {
1097  std::cout << "reached end t="<<std::setprecision (9) <<get_t() <<" tmaxStat=" << std::setprecision (9) <<get_tmaxStat()<< std::endl;
1098  break;
1099  } else if (get_t()>=get_tminStat()) {
1100  if (verbosity>1) std::cout << "Get statistics for t=" << std::setprecision (9) << get_t() << std::endl;
1101  else if (verbosity) std::cout << "Get statistics for t=" << std::setprecision (9) << get_t() << " \r";
1102  if (verbosity>1) std::cout << "#particles="<< getParticleHandler().getNumberOfObjects() << std::endl;
1103 
1104  if (!walls) getWallHandler().clear();
1106  if (!periodicWalls) getBoundaryHandler().clear();
1107 
1108  output_statistics();
1109  gather_force_statistics_from_p3c(version);
1110  process_statistics(true);
1111 
1112  } else {
1113  if (verbosity>1) std::cout
1114  << "Jumping statistics t=" << get_t()
1115  << " tminStat()=" << get_tminStat() << std::endl;
1116  jump_p3c();
1117  }
1118  //if step size>1, skip a number of steps.
1119  for (unsigned int i=1; i<get_step_size(); i++) {
1120  //you only get here if you change the step size and you use a single data file
1121  read_next_from_p3p_file();
1122  jump_p3c();
1123  }
1124  } while (read_next_from_p3p_file());
1125  //set tmax to largest time evaluated
1126  if (get_t()<get_tmaxStat()) set_tmaxStat(get_t());
1127 
1128  finish_statistics();
1129  p3p_file.close();
1130  p3c_file.close();
1131  p3w_file.close();
1132 }
1133 
1135 template <StatType T>
1137 {
1138  std::string dummyStr;
1139  Mdouble N, dummy;
1140 
1141  //Ignoring first line
1142  getline(p3c_file, dummyStr);
1143  std::cout << dummyStr << std::endl;
1144  //Reading second line
1145  p3c_file >> dummy; set_t(dummy);
1146  p3c_file >> N;
1147  std::cout << "ignoring t= " << get_t() << ": loading " << N << " contacts ..." << std::endl;
1148  getline(p3c_file,dummyStr);
1149  //Ignoring third line
1150  getline(p3c_file,dummyStr);
1151  std::cout << dummyStr << std::endl;
1152  //go through N lines in the p3c file
1153  for (int i=0; i<N; i++) getline(p3c_file,dummyStr);
1154 
1155  //Ignoring first line
1156  getline(p3w_file, dummyStr);
1157  std::cout << dummyStr << std::endl;
1158  //Reading second line
1159  p3w_file >> dummy; set_t(dummy);
1160  p3w_file >> N;
1161  std::cout << "ignoring t= " << get_t() << ": loading " << N << " wall contacts ..." << std::endl;
1162  getline(p3w_file,dummyStr);
1163  //Ignoring third line
1164  getline(p3w_file,dummyStr);
1165  //go through N lines in the p3w file
1166  for (int i=0; i<N; i++) getline(p3w_file,dummyStr);
1167 
1168 }
1169 
1171 template <StatType T>
1173 {
1174  std::string dummyStr;
1175  Mdouble N, dummy;
1176 
1177  //Ignoring first line
1178  getline(p3c_file, dummyStr);
1179  std::cout << dummyStr << std::endl;
1180  //Reading second line
1181  p3c_file >> dummy; set_t(dummy);
1182  p3c_file >> N;
1183  std::cout << "t= " << get_t() << ": loading " << N << " contacts ..." << std::endl;
1184  getline(p3c_file,dummyStr);
1185  //Ignoring third line
1186  getline(p3c_file,dummyStr);
1187  std::cout << dummyStr << std::endl;
1188  //Checking for end of file
1189  //if (p3c_file.eof()||p3c_file.peek()==-1) return false;
1190 
1191  //set up index list
1192  int Nmax = 0;
1193  for (std::vector<BaseParticle*>::iterator it = getParticleHandler().begin(); it!=getParticleHandler().end(); ++it)
1194  Nmax = std::max(Nmax,(*it)->get_Index());
1195  static std::vector<int> index;
1196  index.resize(Nmax);
1197  int i=0;
1198  for (std::vector<BaseParticle*>::iterator it = getParticleHandler().begin(); it!=getParticleHandler().end(); ++it) {
1199  index[(*it)->get_Index()]=i;
1200  i++;
1201  }
1202 
1203  // ==> Particledata_4.2to4.25s.csv.p4c <==
1204  // TIMESTEP CONTACTS
1205  // 4.2001 31367
1206  // P1 P2 CX CY CZ FX FY FZ
1207  // 9711 9424 0.0549396 0.009705380.149582 4.37283e-05 2.02347e-05 -0.000250662
1208 
1209  // ==> /Users/weinhartt/CarlosLabra/ConfinedCompression_P3P_Spheres.csv.p3c <==
1210  // TIMESTEP CONTACTS
1211  // 6.500010000000e-01 21886
1212  // P1 P2 FX FY FZ
1213  // 1126 218 -1.899612000000e-02 6.716474700000e-02 -1.527340000000e-02
1214 
1215  int index1_p3, index2_p3;
1216  int index1, index2;
1217  Vec3D Contact, Force;
1218  Mdouble delta, fdotn, fdott;
1219  Vec3D P1_P2_normal, P1_P2_tangential;
1220  Mdouble dist;
1221  BaseParticle* P1;
1222  BaseParticle* P2;
1223 
1224  Vec3D contact;
1225  int counter = 0;
1226  //go through N lines in the p4c file
1227  for (int i=0; i<N; i++) {
1228  counter++;
1229  if (version==3) {
1230  p3c_file
1231  >> index1_p3
1232  >> index2_p3
1233  >> Force;
1234  } else {
1235  p3c_file
1236  >> index1_p3
1237  >> index2_p3
1238  >> Contact
1239  >> Force;
1240  }
1241  index1=index[index1_p3];
1242  index2=index[index2_p3];
1243  P1 = getParticleHandler().getObject(index1);
1244  P2 = getParticleHandler().getObject(index2);
1245  P1_P2_normal = P1->get_Position() - P2->get_Position();
1246  dist = GetLength(P1_P2_normal);
1247  P1_P2_normal /= dist;
1248  delta = P1->get_Radius() + P2->get_Radius() - dist;
1249  if (version==3) {
1250  Contact = P2->get_Position() + P1_P2_normal * (P2->get_Radius()-delta/2);
1251  }
1252  fdotn = -Dot(Force,P1_P2_normal)/GetLength2(P1_P2_normal);
1253  P1_P2_tangential = Force + fdotn * P1_P2_normal; //get tangential force
1254  fdott = GetLength(P1_P2_tangential);
1255  if (fdott==0) {
1256  P1_P2_tangential = Vec3D(0,0,0);
1257  } else {
1258  P1_P2_tangential /= fdott;
1259  }
1260  //Finished reading file
1261  gather_statistics_collision(index1,index2,Contact,delta,0,fdotn,fdott, P1_P2_normal,-P1_P2_tangential);
1262  gather_statistics_collision(index2,index1,Contact,delta,0,fdotn,fdott, -P1_P2_normal, P1_P2_tangential);
1263  }
1264 
1265 
1266  if (verbosity>1) std::cout << "#forces="<< counter << std::endl;
1267  //Ignoring last line
1268  getline(p3c_file,dummyStr);
1269  std::cout << dummyStr << std::endl;
1270 
1271  gather_force_statistics_from_p3w(version,index);
1272 }
1273 
1275 template <StatType T>
1276 void StatisticsVector<T>::gather_force_statistics_from_p3w(int version, std::vector<int>& index)
1277 {
1278  std::string dummyStr;
1279  Mdouble N, dummy;
1280 
1281  //Ignoring first line
1282  getline(p3w_file, dummyStr);
1283  std::cout << dummyStr << std::endl;
1284  //Reading second line
1285  p3w_file >> dummy; set_t(dummy);
1286  p3w_file >> N;
1287  std::cout << "t= " << get_t() << ": loading " << N << " wall contacts ..." << std::endl;
1288  getline(p3w_file,dummyStr);
1289  //Ignoring third line
1290  getline(p3w_file,dummyStr);
1291  std::cout << dummyStr << std::endl;
1292 
1293  // ==> /Users/weinhartt/CarlosLabra/ConfinedCompression_P3P_Spheres.csv.p3w <==
1294  // TIMESTEP CONTACTS
1295  // 6.500010000000e-01 3778
1296  // P1 FX FY FZ NX NY NZ (N=Branch)
1297  // 671 0.000000000000e+00 0.000000000000e+00 1.965970000000e-01 0.000000000000e+00 0.000000000000e+00 -1.991510000000e-03
1298  // ==> Particledata_4.2to4.25s.csv.p4w <==
1299  // TIMESTEP CONTACTS
1300  // 4.2001 5770
1301  // P1 CX CY CZ FX FY FZ
1302  // 10590 0.00944221 0.0120.130307 -3.14611e-06 -0.000512936 0.000102539
1303  // 10146 0.0615829 00.162907 2.02968e-05 0.000948522 0.000188616
1304 
1305  int index1_p3;
1306  int index1, index2;
1307  Vec3D Contact, Force, Branch;
1308  Mdouble delta, fdotn, fdott;
1309  Vec3D P1_P2_normal, P1_P2_tangential;
1310  Mdouble dist;
1311  BaseParticle* P1;
1312 
1313  Vec3D contact;
1314  int counter = 0;
1315  //go through each line in the fstat file; break when eof or '#' or newline
1316  for (int i=0; i<N; i++) {
1317  counter++;
1318  if (version==3) {
1319  p3w_file
1320  >> index1_p3
1321  >> Force
1322  >> Branch;
1323  } else {
1324  p3w_file
1325  >> index1_p3
1326  >> Contact
1327  >> Force;
1328  }
1329  index1=index[index1_p3];
1330  index2=-1;
1331  P1 = getParticleHandler().getObject(index1);
1332  if (version==3) {
1333  //Branch *= -1;
1334  Contact = P1->get_Position() + Branch;
1335  } else {
1336  Branch = Contact - P1->get_Position();
1337  }
1338  dist = GetLength(Branch);
1339  P1_P2_normal = Branch / dist;
1340  delta = P1->get_Radius() - dist; //check
1341  fdotn = -Dot(Force,P1_P2_normal)/GetLength2(P1_P2_normal);
1342  P1_P2_tangential = Force + fdotn * P1_P2_normal; //get tangential force
1343  fdott = GetLength(P1_P2_tangential);
1344  if (fdott==0) {
1345  P1_P2_tangential = Vec3D(0,0,0);
1346  } else {
1347  P1_P2_tangential /= fdott;
1348  }
1349  //Finished reading fstat file
1350  gather_statistics_collision(index1,index2,Contact,delta,0,fdotn,fdott, P1_P2_normal, -P1_P2_tangential);
1351  }
1352 
1353  if (verbosity>1) std::cout << "#wall forces="<< counter << std::endl;
1354  //Ignoring last line
1355  getline(p3w_file,dummyStr);
1356  std::cout << dummyStr << std::endl;
1357 }
1358 
1359 
1360 
1361 
1362 
1364 template <StatType T>
1366 {
1367  //Dimensions of the domain / n
1368  Vec3D diff = Vec3D(
1369  (get_xmaxStat()-get_xminStat())/nx,
1370  (get_ymaxStat()-get_yminStat())/ny,
1371  (get_zmaxStat()-get_zminStat())/nz);
1372  //Center of the domain
1373  Vec3D avg = 0.5 * Vec3D(
1374  get_xmaxStat()+get_xminStat(),
1375  get_ymaxStat()+get_yminStat(),
1376  get_zmaxStat()+get_zminStat());
1377  //Left endpoint of the domain
1378  Vec3D Min = Vec3D(
1379  get_xminStat(),
1380  get_yminStat(),
1381  get_zminStat());
1382 
1383  int num[3]={0,0,0};
1384  if (get_mirrorAtDomainBoundary()) {
1385  if (statType==X||statType==XY||statType==XZ||statType==XYZ) {
1386  //add so many points to domain on both ends
1387  //todo: the 8 is arbitrary
1388  num[0] = floor(std::max(get_mirrorAtDomainBoundary(),get_cutoff())/diff.X);
1389  nx+=2*num[0];
1390  Min.X-=num[0]*diff.X;
1391  }
1392  if (statType==Y||statType==XY||statType==YZ||statType==XYZ) {
1393  num[1] = floor(std::max(get_mirrorAtDomainBoundary(),get_cutoff())/diff.Y);
1394  ny+=2*num[1];
1395  Min.Y-=num[1]*diff.Y;
1396  }
1397  if (statType==Z||statType==XZ||statType==XZ||statType==XYZ) {
1398  num[2] = floor(std::max(get_mirrorAtDomainBoundary(),get_cutoff())/diff.Z);
1399  nz+=2*num[2];
1400  Min.Z-=num[2]*diff.Z;
1401  }
1402  }
1403 
1404  //Set position of statistics points and set variables to 0
1405  int N =std::max(nx,1)*std::max(ny,1)*std::max(nz,1);
1406  Points.resize(N);
1407  int n = 0;
1408  for (int i=0; i<std::max(nx,1); i++)
1409  for (int j=0; j<std::max(ny,1); j++)
1410  for (int k=0; k<std::max(nz,1); k++) {
1411  Points[n].set_Position( Vec3D( (nx>1)?(Min.X+diff.X*(i+0.5)):avg.X,
1412  (ny>1)?(Min.Y+diff.Y*(j+0.5)):avg.Y,
1413  (nz>1)?(Min.Z+diff.Z*(k+0.5)):avg.Z ));
1414  if (doublePoints) Points[n].set_Position( Points[n].get_Position()
1415  -Vec3D((i%2)?(0.99*diff.X):0,(j%2)?(0.99*diff.Y):0,(k%2)?(0.99*diff.Z):0) );
1416  Points[n].set_CG_invvolume();
1417  Points[n].set_zero();
1418  if (get_mirrorAtDomainBoundary())
1419  if ((i<num[0])||(i>nx-num[0])||(j<num[1])||(j>ny-num[1])||(k<num[2])||(k>nz-num[2])) {
1420  Points[n].mirrorParticle = n +
1421  + ((i<num[0])?(2*(num[0]-i)-1)*ny*nz:0)+((i>nx-num[0])?(2*(nx-num[0]-i)+1)*ny*nz:0)
1422  + ((j<num[1])?(2*(num[1]-j)-1)*nz:0 )+((j>ny-num[1])?(2*(ny-num[1]-j)+1)*nz:0)
1423  + ((k<num[2])?(2*(num[2]-k)-1):0 )+((k>nz-num[2])?(2*(nz-num[2]-k)+1):0);
1424  }
1425  n++;
1426  }
1427  if (statType==RAZ || statType==RZ || statType==RA || statType==AZ || statType==R || statType==A) {
1428  for (unsigned int k=0; k<Points.size(); k++) {
1429  Points[k].set_Position(Points[k].get_Position().GetFromCylindricalCoordinates());
1430  }
1431  }
1432  if (get_doGradient()) {
1433  dx.resize(N);
1434  dy.resize(N);
1435  dz.resize(N);
1436  for (int n=0; n<N; n++) {
1437  dx[n].set_Position(Points[n].get_Position());
1438  dx[n].mirrorParticle=Points[n].mirrorParticle;
1439  dx[n].set_zero();
1440  dy[n].set_Position(Points[n].get_Position());
1441  dy[n].mirrorParticle=Points[n].mirrorParticle;
1442  dy[n].set_zero();
1443  dz[n].set_Position(Points[n].get_Position());
1444  dz[n].mirrorParticle=Points[n].mirrorParticle;
1445  dz[n].set_zero();
1446  }
1447  }
1448 
1449  //Set TimeAverage the same way
1450  if (get_doTimeAverage()) {
1451  timeAverage.resize(N);
1452  int n = 0;
1453  for (int i=0; i<std::max(nx,1); i++)
1454  for (int j=0; j<std::max(ny,1); j++)
1455  for (int k=0; k<std::max(nz,1); k++) {
1456  timeAverage[n].set_Position(Points[n].get_Position());
1457  timeAverage[n].set_zero();
1458  timeAverage[n].mirrorParticle=Points[n].mirrorParticle;
1459  n++;
1460  }
1461 
1462  if (get_doVariance()) {
1463  timeVariance.resize(N);
1464  for (int n=0; n<N; n++) {
1465  timeVariance[n].set_Position(timeAverage[n].get_Position());
1466  timeVariance[n].mirrorParticle=Points[n].mirrorParticle;
1467  timeVariance[n].set_zero();
1468  }
1469  }
1470 
1471  if (get_doGradient()) {
1472  dxTimeAverage.resize(N);
1473  dyTimeAverage.resize(N);
1474  dzTimeAverage.resize(N);
1475  for (int n=0; n<N; n++) {
1476  dxTimeAverage[n].set_Position(timeAverage[n].get_Position());
1477  dxTimeAverage[n].mirrorParticle=Points[n].mirrorParticle;
1478  dxTimeAverage[n].set_zero();
1479  dyTimeAverage[n].set_Position(timeAverage[n].get_Position());
1480  dyTimeAverage[n].mirrorParticle=Points[n].mirrorParticle;
1481  dyTimeAverage[n].set_zero();
1482  dzTimeAverage[n].set_Position(timeAverage[n].get_Position());
1483  dzTimeAverage[n].mirrorParticle=Points[n].mirrorParticle;
1484  dzTimeAverage[n].set_zero();
1485  }
1486  }
1487 
1488  } //end if (get_doTimeAverage())
1489 }
1490 
1492 template <StatType T>
1494 {
1495  if (get_options_fstat()==2) {
1496  increase_counter_fstat(std::fstream::in);
1497  if (verbosity>1) std::cout << "Using fstat file counter: "<<get_file_counter() << std::endl;
1498  } else {
1499  //read in first three lines (should start with '#')
1500  std::string dummy;
1501  getline (get_fstat_file(), dummy);
1502  getline (get_fstat_file(), dummy);
1503  getline (get_fstat_file(), dummy);
1504  //read in all lines belonging to this timestep
1505  while ( (get_fstat_file().peek() != -1) && (get_fstat_file().peek() != '#') )
1506  getline (get_fstat_file(), dummy);
1507  }
1508 }
1509 
1510 template <StatType T>
1512  return P->get_Radius()>rmin
1513  && P->get_Radius()<rmax
1514  && P->get_Position().Z<hmax;
1515 }
1516 
1517 template <StatType T>
1518 void StatisticsVector<T>::gather_statistics_collision(int index1,int index2, Vec3D Contact, Mdouble delta, Mdouble ctheta, Mdouble fdotn, Mdouble fdott, Vec3D P1_P2_normal_, Vec3D P1_P2_tangential)
1519 {
1520  Vec3D P1_P2_VelocityAverage, P1_P2_VelocityDifference, P1_P2_Force;
1521  Mdouble norm_dist;
1522  if(check_current_time_for_statistics())
1523  {
1524  //make sure that for a particle-fixed particle collision the fixed particle is on index2 (switch particles if needed)
1525  if (getParticleHandler().getObject(index1)->isFixed()) {
1526  int tmp = index1; index1 = index2; index2 = tmp;
1527  P1_P2_normal_*=-1;
1528  }
1529 
1530  if (satisfiesInclusionCriteria(getParticleHandler().getObject(index1)))
1531  {
1532  P1_P2_normal=P1_P2_normal_;
1533 
1534  if (get_dim()==2) Contact.Z = 0.0;
1535 
1536  if (index2<0)
1537  { //wall-particle collision
1538  P1_P2_distance = getParticleHandler().getObject(index1)->get_Radius()-delta;
1539  P2 = Contact;
1540  P1 = Contact-P1_P2_normal*P1_P2_distance; //note, here we use a minus
1541  norm_dist=P1_P2_distance;
1542  P1_P2_VelocityAverage = (getParticleHandler().getObject(index1)->get_Velocity())/2;
1543  P1_P2_VelocityDifference = (getParticleHandler().getObject(index1)->get_Velocity());
1544 
1545  if (StressTypeForFixedParticles==3) {
1547  P1_P2_distance += 300;
1549  P2 += 300*P1_P2_normal;
1550  //this is because wall-particle collisions appear only once in fstat
1551  norm_dist=P1_P2_distance;
1552  }
1553  }
1554  else if (getParticleHandler().getObject(index2)->isFixed()||!satisfiesInclusionCriteria(getParticleHandler().getObject(index2)))
1555  { //particle-fixed particle collision (external force acts at contact point)
1556  if (getParticleHandler().getObject(index2)->isFixed()&&StressTypeForFixedParticles==3) {
1557  //infinite extension of stress
1558  P1_P2_distance = getParticleHandler().getObject(index1)->get_Radius()+getParticleHandler().getObject(index2)->get_Radius()-delta;
1559  P1 = Contact+P1_P2_normal*(0.5*P1_P2_distance); //flowing particle
1560  P2 = Contact-P1_P2_normal*(0.5*P1_P2_distance); //fixed particle
1561  if (P1_P2_normal.Z<0) { //in this case revert flowing and fixed particle
1562  //std::cerr << "Warning: Force normal upwards on base z=" << P1.Z << "." << P2.Z << std::endl;
1563  //turning force the other way to achieve sigma=0 at z=inf
1564  P1_P2_normal*=-1.0;
1565  fdotn *=-1.0;
1566  }
1568  P1_P2_distance=setInfinitelyLongDistance();
1570  P2 = P1 - P1_P2_normal*P1_P2_distance; //move endpoint of force line downwards beyond fixed particles out of the domain
1571  if (P1_P2_normal.Z<0) std::cout << P1_P2_distance << " z" << P1.Z << " " << P2.Z << " f" << fdotn << std::endl;
1573  } else if (StressTypeForFixedParticles==1|| (!getParticleHandler().getObject(index2)->isFixed()&&StressTypeForFixedParticles==3)) {
1574  //add force from flowing particle to contact point to stress
1575  P1_P2_distance = getParticleHandler().getObject(index1)->get_Radius()+getParticleHandler().getObject(index2)->get_Radius()-delta;
1576  P1 = Contact+P1_P2_normal*(0.5*P1_P2_distance); //1st particle
1577  //P2 = Contact; //Contact point;
1578  //P1_P2_distance /= 2.0;
1579  P1_P2_distance = getParticleHandler().getObject(index1)->get_Radius()-delta/2; //Contact point;
1580  P2 = P1 - P1_P2_normal*P1_P2_distance; //Contact point (corrected for polydispersed particles);
1581  } else {
1582  //add force from flowing particle to fixed particle to stress
1583  P1_P2_distance = getParticleHandler().getObject(index1)->get_Radius()+getParticleHandler().getObject(index2)->get_Radius()-delta;
1584  P1 = Contact+P1_P2_normal*(0.5*P1_P2_distance);
1585  P2 = Contact-P1_P2_normal*(0.5*P1_P2_distance);
1586  }
1588  norm_dist=P1_P2_distance;//*2.0*Particles[index1].Radius/(Particles[index2].Radius+Particles[index1].Radius);
1589  //This is the length of the contact in particle 1.
1590  P1_P2_VelocityAverage = getParticleHandler().getObject(index2)->get_Velocity()/2;
1591  P1_P2_VelocityDifference = -getParticleHandler().getObject(index2)->get_Velocity();
1592  }
1593  else
1594  {//particle-particle collision
1595 
1596  if (getParticleHandler().getObject(index2)->isFixed()) std::cout << "ERROR" << std::endl;
1597  P1_P2_distance = getParticleHandler().getObject(index1)->get_Radius()+getParticleHandler().getObject(index2)->get_Radius()-delta;
1598 
1599  P1 = Contact+P1_P2_normal*(0.5*P1_P2_distance);
1600  P2 = Contact-P1_P2_normal*(0.5*P1_P2_distance);
1601  //This is the length of the contact in particle 1.
1602  norm_dist=P1_P2_distance*getParticleHandler().getObject(index1)->get_Radius()/(getParticleHandler().getObject(index2)->get_Radius()+getParticleHandler().getObject(index1)->get_Radius());
1603  P1_P2_VelocityAverage = (getParticleHandler().getObject(index1)->get_Velocity()+getParticleHandler().getObject(index2)->get_Velocity())/2;
1604  P1_P2_VelocityDifference = (getParticleHandler().getObject(index1)->get_Velocity()-getParticleHandler().getObject(index2)->get_Velocity());
1605  }
1607  //Particles[max(index1,index2)] is chosen so that it is the non-wall, non-fixed particle
1609  P1_P2_Fabric = SymmetrizedDyadic(P1_P2_normal, P1_P2_normal) * getParticleHandler().getObject(index1)->get_Volume(get_Species());
1610  //fix
1611  //~ P1_P2_Fabric = SymmetrizedDyadic(P1_P2_normal, P1_P2_normal) * getParticleHandler().getObject(max(index1,index2))->get_Volume(get_Species());
1613  P1_P2_NormalStress = Dyadic(P1_P2_normal,P1_P2_normal) * (fdotn*norm_dist);
1614  P1_P2_TangentialStress = Dyadic(P1_P2_tangential,P1_P2_normal) * (fdott*norm_dist);
1615  P1_P2_NormalTraction = P1_P2_normal * fdotn;
1616  P1_P2_TangentialTraction = P1_P2_tangential * fdott;
1617  P1_P2_ContactCoupleStress = Dyadic(P1_P2_NormalTraction+P1_P2_TangentialTraction, -0.5*P1_P2_normal*norm_dist);
1618  P1_P2_Contact = Contact;
1619  P1_P2_Potential = (get_k()*sqr(delta)+get_kt()*sqr(ctheta))/2;
1620  P1_P2_Force = fdotn*P1_P2_normal+fdott*P1_P2_tangential;
1621  P1_P2_Dissipation = Dot(P1_P2_VelocityDifference,P1_P2_Force)/2;
1622  P1_P2_CollisionalHeatFlux = P1_P2_normal * (P1_P2_distance/2 * Dot(P1_P2_VelocityAverage,fdotn*P1_P2_normal+fdott*P1_P2_tangential)) + P1_P2_Potential * P1_P2_VelocityAverage;
1623  //Now P1_P2 distance and normal are in non-averaged directions - This is the projection of the distance on to the CG directions. Required for the later statistics hence done now, not before.
1624  P1_P2_distance *= sqrt(Points[0].dot(P1_P2_normal,P1_P2_normal));
1625 
1626  //If the normal to the contact and the averaging direction are EXACTLY+- parallel then set the normal to zero. Otherwise you would end up with nan, which is not good.
1628  if (P1_P2_distance>1e-12)
1629  P1_P2_normal = (P1-P2)/P1_P2_distance;
1630  else
1631  P1_P2_normal = Vec3D(0.0,0.0,0.0);
1632  //P1_P2_normal = (P1-P2)/P1_P2_distance;
1633 
1634  //if 2nd particle is wall, fixed particle or not-included particle
1635  if (index2<0 || getParticleHandler().getObject(index2)->isFixed() || !satisfiesInclusionCriteria(getParticleHandler().getObject(index2)))
1636  {
1637  // << "/" << P2 << std::endl;
1639  if (StressTypeForFixedParticles!=0) { //only if wall - flow contact adds anything to the stress
1640  evaluate_force_statistics();
1641  }
1642  if (StressTypeForFixedParticles!=3 || !(index2<0 || getParticleHandler().getObject(index2)->isFixed())) { //only if stress is not infinitely extended
1643  Vec3D P;
1644  if (StressTypeForFixedParticles==0) {
1645  P=P1; //Traction at flow particle
1646  } else {
1647  P=P2; //Traction at contact point, resp wall particle
1648  }
1649  evaluate_wall_force_statistics(P);
1650  }
1651  }
1652  else
1653  {
1654  evaluate_force_statistics();
1655  }
1656  }
1657  }
1658 }
1659 
1661 template <StatType T>
1663 {
1664  //read in first three lines (should start with '#')
1665  std::string dummy;
1666  if (get_options_fstat()==2) increase_counter_fstat(std::fstream::in);
1667  getline (get_fstat_file(), dummy);
1668  getline (get_fstat_file(), dummy);
1669  getline (get_fstat_file(), dummy);
1670 
1671 
1672  static Mdouble time;
1673  static int index1, index2;
1674  static Vec3D Contact;
1675  static Mdouble delta, ctheta, fdotn, fdott;
1676  static Vec3D P1_P2_normal_, P1_P2_tangential;
1677  static BaseParticle PI;
1678  static BaseParticle PJ;
1679 
1680  int counter = 0;
1681  //go through each line in the fstat file; break when eof or '#' or newline
1682  while ( (get_fstat_file().peek() != -1) && (get_fstat_file().peek() != '#') ) { //(!get_fstat_file().eof())
1683  counter++;
1684  /* # 1: time
1685  # 2: particle Number i
1686  # 3: contact partner j (particles >= 0, walls < 0)
1687  # 4: x-position \
1688  # 5: y-position > of the contact point (I hope)
1689  # 6: z-position /
1690  # 7: delta = overlap at the contact
1691  # 8: ctheta = length of the tangential spring
1692  # 9: P1_P2_normal force |f^n|
1693  # 10: remaining (tangential) force |f^t|=|f-f^n|
1694  # 11-13: P1_P2_normal unit vector nx, ny, nz
1695  # 14-16: tangential unit vector tx, ty, tz
1696  */
1697  get_fstat_file()
1698  >> time
1699  >> index1
1700  >> index2
1701  >> Contact
1702  >> delta
1703  >> ctheta
1704  >> fdotn
1705  >> fdott
1706  >> P1_P2_normal_
1707  >> P1_P2_tangential;
1709  get_fstat_file().ignore(256,'\n');
1710  //Finished reading fstat file
1711  gather_statistics_collision(index1,index2,Contact,delta,ctheta,fdotn,fdott, P1_P2_normal_, P1_P2_tangential);
1712 
1713  }
1714  if (verbosity>1) std::cout << "#forces="<< counter << std::endl;
1715 }
1716 
1718 template <StatType T>
1720 {
1722  if(periodicWalls)
1723  for (unsigned int k=wp; k<getBoundaryHandler().getNumberOfObjects(); k++)
1724  {
1725  PeriodicBoundary* b0=dynamic_cast<PeriodicBoundary*>(getBoundaryHandler().getObject(k));
1726  if(b0)
1727  {
1728  b0->distance(P1);
1729  b0->shift_positions(P1,P2);
1730  evaluate_force_statistics(k+1);
1731  b0->shift_positions(P1,P2);
1732  }
1733  }
1734 
1736  //evaluate fields that only depend on CParticle parameters
1737  Mdouble psi; //Course graining integral
1738  Vec3D rpsi=Vec3D(0,0,0);
1739  static unsigned int counter = 0;
1740  for (unsigned int i=0; i<Points.size(); i++) {
1741  psi = Points[i].CG_integral(P1, P2, P1_P2_normal, P1_P2_distance, rpsi);
1742  if (psi) {
1743  counter++;
1744  if (!std::isfinite(psi)) {
1745  std::cerr << "error: psi =" << psi << " is infinite for P1=" << P1 << ", P2=" << P2 << ", t=" << get_t() << std::endl;
1746  psi=0;
1747  }
1748  Points[i].ContactCoupleStress += (Cross(P1_P2_Contact*psi,P1_P2_ContactCoupleStress) - Cross(rpsi,P1_P2_ContactCoupleStress))*(-0.5);
1749  Points[i].NormalStress += P1_P2_NormalStress * psi;
1750  Points[i].TangentialStress += P1_P2_TangentialStress * psi;
1751  Points[i].Fabric += P1_P2_Fabric * psi;
1752  Points[i].CollisionalHeatFlux += P1_P2_CollisionalHeatFlux * psi;
1753  Points[i].Dissipation += P1_P2_Dissipation * psi;
1754  Points[i].Potential += P1_P2_Potential * psi;
1755  if (get_doGradient()) {
1756  Vec3D d_psi = Points[i].CG_integral_gradient(P1, P2, P1_P2_normal, P1_P2_distance);
1757 
1758  dx[i].NormalStress += P1_P2_NormalStress * d_psi.X;
1759  dx[i].TangentialStress += P1_P2_TangentialStress * d_psi.X;
1760  dx[i].Fabric += P1_P2_Fabric * d_psi.X;
1761  dx[i].CollisionalHeatFlux += P1_P2_CollisionalHeatFlux * d_psi.X;
1762  dx[i].Dissipation += P1_P2_Dissipation * d_psi.X;
1763  dx[i].Potential += P1_P2_Potential * d_psi.X;
1764 
1765  dy[i].NormalStress += P1_P2_NormalStress * d_psi.Y;
1766  dy[i].TangentialStress += P1_P2_TangentialStress * d_psi.Y;
1767  dy[i].Fabric += P1_P2_Fabric * d_psi.Y;
1768  dy[i].CollisionalHeatFlux += P1_P2_CollisionalHeatFlux * d_psi.Y;
1769  dy[i].Dissipation += P1_P2_Dissipation * d_psi.Y;
1770  dy[i].Potential += P1_P2_Potential * d_psi.Y;
1771 
1772  dz[i].NormalStress += P1_P2_NormalStress * d_psi.Z;
1773  dz[i].TangentialStress += P1_P2_TangentialStress * d_psi.Z;
1774  dz[i].Fabric += P1_P2_Fabric * d_psi.Z;
1775  dz[i].CollisionalHeatFlux += P1_P2_CollisionalHeatFlux * d_psi.Z;
1776  dz[i].Dissipation += P1_P2_Dissipation * d_psi.Z;
1777  dz[i].Potential += P1_P2_Potential * d_psi.Z;
1778  } //end if get_doGradient
1779  } //end if phi
1780  } // end forall Points
1781  //std::cout << "NCeval" << counter << std::endl;
1782 }
1783 
1784 
1786 template <StatType T>
1788 {
1790  if(periodicWalls)
1791  for (unsigned int k=wp; k<getBoundaryHandler().getNumberOfObjects(); k++)
1792  {
1793  PeriodicBoundary* b0=dynamic_cast<PeriodicBoundary*>(getBoundaryHandler().getObject(k));
1794  if(b0)
1795  {
1796  b0->distance(P1);
1797  b0->shift_positions(P1,P2);
1798  evaluate_force_statistics(k+1);
1799  b0->shift_positions(P1,P2);
1800  }
1801  }
1802 
1803  //evaluate fields that only depend on CParticle parameters
1804  Mdouble phi; //Course graining integral
1805  for (unsigned int i=0; i<Points.size(); i++) {
1806  phi = Points[i].CG_function(P);
1807  if (phi) {
1808  Points[i].NormalTraction += P1_P2_NormalTraction * phi;
1809  Points[i].TangentialTraction += P1_P2_TangentialTraction * phi;
1810  if (get_doGradient()) {
1812  Vec3D d_phi = Points[i].CG_gradient(P, phi);
1813  dx[i].NormalTraction += P1_P2_NormalTraction * d_phi.X;
1814  dy[i].NormalTraction += P1_P2_NormalTraction * d_phi.Y;
1815  dz[i].NormalTraction += P1_P2_NormalTraction * d_phi.Z;
1816  dx[i].TangentialTraction += P1_P2_TangentialTraction * d_phi.X;
1817  dy[i].TangentialTraction += P1_P2_TangentialTraction * d_phi.Y;
1818  dz[i].TangentialTraction += P1_P2_TangentialTraction * d_phi.Z;
1819  } //end if get_doGradient
1820  } //end if phi
1821  } // end forall Points
1822 
1823 }
1824 
1825 template <StatType T>
1827  if(check_current_time_for_statistics())
1828  {
1830  for (unsigned int i=0; i<Points.size(); i++)
1831  Points[i].set_CG_invvolume();
1832 
1833  for (std::vector<BaseParticle*>::iterator P = getParticleHandler().begin(); P!=getParticleHandler().end(); ++P) {
1835  //unfix particles (turn off to ignore fixed particles)
1836  if ((!ignoreFixedParticles) && (*P)->isFixed()) {
1837  (*P)->unfix(get_Species());
1838  }
1839  //ignore fixed particles
1840 
1842  if (satisfiesInclusionCriteria(*P) && !(*P)->isFixed()) {
1843  evaluate_particle_statistics(P);
1844  }
1845 
1846  }
1847  }
1848 }
1849 
1850 template <StatType T>
1851 void StatisticsVector<T>::evaluate_particle_statistics(std::vector<BaseParticle*>::iterator P, int wp) {
1853  bool doDisplacement = false;
1854 
1855  if (periodicWalls)
1856  for (unsigned int k=wp; k<getBoundaryHandler().getNumberOfObjects(); k++)
1857  {
1858  PeriodicBoundary* b0=dynamic_cast<PeriodicBoundary*>(getBoundaryHandler().getObject(k));
1859  if(b0)
1860  {
1861  Mdouble dist = b0->distance(P1);
1862  if (sqr(dist-(*P)->get_Radius())<9.0*get_w2())
1863  {
1864  b0->shift_position(*P);
1865  evaluate_particle_statistics(P, k+1);
1866  b0->shift_position(*P);
1867  }
1868  }
1869  }
1870 
1871  //evaluate fields that only depend on CParticle parameters
1872  Mdouble phi; //Course graining function
1873  Vec3D V = Vec3D(0,0,0);
1874  if (VelocityProfile.size()) V = getVelocityProfile ((*P)->get_Position());
1875 
1876  for (unsigned int i=0; i<Points.size(); i++) {
1877  phi = Points[i].CG_function((*P)->get_Position());
1878  if (phi) {
1879  if (!std::isfinite(phi)) {
1880  std::cout
1881  << "t =" << MD::get_t()
1882  << "error: phi =" << phi
1883  << " is infinite for P=" << (*P)->get_Position()
1884  << ", Point=" << Points[i].get_Position()
1885  << std::endl;
1886  phi=0;
1887  }
1888  Points[i].Nu += (*P)->get_Volume(get_Species()) * phi;
1889  Points[i].Density += (*P)->get_Mass() * phi;
1890  if (VelocityProfile.size()) {
1891  Points[i].Momentum += ((*P)->get_Velocity()-V) * ((*P)->get_Mass() * phi);
1892  Points[i].MomentumFlux += SymmetrizedDyadic((*P)->get_Velocity()-V, (*P)->get_Velocity()-V) * ((*P)->get_Mass() * phi);
1893  } else {
1894  Points[i].Momentum += (*P)->get_Velocity() * ((*P)->get_Mass() * phi);
1895  Points[i].MomentumFlux += SymmetrizedDyadic((*P)->get_Velocity(), (*P)->get_Velocity()) * ((*P)->get_Mass() * phi);
1896  }
1897  Points[i].DisplacementMomentum += (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()) * ((*P)->get_Mass() * phi);
1898  Points[i].DisplacementMomentumFlux += SymmetrizedDyadic((*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()), (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount())) * ((*P)->get_Mass() * phi);
1899  Points[i].EnergyFlux += (*P)->get_Velocity() * ((*P)->get_Mass()*(*P)->get_Velocity().GetLength2()/2 * phi);
1900 
1901  Vec3D LocalAngularMomentum = Cross(Points[0].clearAveragedDirections((*P)->get_Position()-Points[i].get_Position()), (*P)->get_Velocity()) * (*P)->get_Mass()
1902  + (*P)->get_AngularVelocity() * (*P)->get_Inertia();
1903  Points[i].LocalAngularMomentum += phi * LocalAngularMomentum;
1904  Points[i].LocalAngularMomentumFlux += Dyadic(LocalAngularMomentum, (*P)->get_Velocity() * phi);
1905 
1906  //Note: Displacement is only computed directly if gradients are cmputed
1907  if (get_doGradient()) {
1908 
1909  Vec3D d_phi = Points[i].CG_gradient((*P)->get_Position(), phi);
1910 
1911  if (doDisplacement) {
1912  //begin: Linear displacement, \f$1/(2 \rho^2) \sum_{pq} m_p m_q \phi_q *(v_{pqa} \partial_b \phi_p + v_{pqb} \partial_a \phi_p) \f$
1913  for (std::vector<BaseParticle*>::iterator Q = getParticleHandler().begin(); Q!=getParticleHandler().end(); ++Q) {
1914  double phiQ = Points[i].CG_function((*Q)->get_Position()); //Course graining function
1915  Points[i].Displacement += SymmetrizedDyadic((*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()) - (*Q)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()), d_phi)
1916  * ((*P)->get_Mass() * (*Q)->get_Mass() * phiQ);
1917  }
1918  //end:Displacement
1919  }
1920 
1921  dx[i].Nu += (*P)->get_Volume(get_Species()) * d_phi.X;
1922  dx[i].Density += (*P)->get_Mass() * d_phi.X;
1923  dx[i].Momentum += (*P)->get_Velocity() * ((*P)->get_Mass() * d_phi.X);
1924  dx[i].DisplacementMomentum += (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()) * ((*P)->get_Mass() * d_phi.X);
1925  dx[i].MomentumFlux += SymmetrizedDyadic((*P)->get_Velocity(), (*P)->get_Velocity()) * ((*P)->get_Mass() * d_phi.X);
1926  dx[i].DisplacementMomentumFlux += SymmetrizedDyadic((*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()), (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount())) * ((*P)->get_Mass() * d_phi.X);
1927  dx[i].EnergyFlux += (*P)->get_Velocity() * ((*P)->get_Mass()*(*P)->get_Velocity().GetLength2()/2 * d_phi.X);
1928 
1929  dy[i].Nu += (*P)->get_Volume(get_Species()) * d_phi.Y;
1930  dy[i].Density += (*P)->get_Mass() * d_phi.Y;
1931  dy[i].Momentum += (*P)->get_Velocity() * ((*P)->get_Mass() * d_phi.Y);
1932  dy[i].DisplacementMomentum += (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()) * ((*P)->get_Mass() * d_phi.Y);
1933  dy[i].MomentumFlux += SymmetrizedDyadic((*P)->get_Velocity(), (*P)->get_Velocity()) * ((*P)->get_Mass() * d_phi.Y);
1934  dy[i].DisplacementMomentumFlux += SymmetrizedDyadic((*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()), (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount())) * ((*P)->get_Mass() * d_phi.Y);
1935  dy[i].EnergyFlux += (*P)->get_Velocity() * ((*P)->get_Mass()*(*P)->get_Velocity().GetLength2()/2 * d_phi.Y);
1936 
1937  dz[i].Nu += (*P)->get_Volume(get_Species()) * d_phi.Z;
1938  dz[i].Density += (*P)->get_Mass() * d_phi.Z;
1939  dz[i].Momentum += (*P)->get_Velocity() * ((*P)->get_Mass() * d_phi.Z);
1940  dz[i].DisplacementMomentum += (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()) * ((*P)->get_Mass() * d_phi.Z);
1941  dz[i].MomentumFlux += SymmetrizedDyadic((*P)->get_Velocity(), (*P)->get_Velocity()) * ((*P)->get_Mass() * d_phi.Z);
1942  dz[i].DisplacementMomentumFlux += SymmetrizedDyadic((*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount()), (*P)->get_Displacement2(get_xmin(),get_xmax(),get_ymin(),get_ymax(),get_zmin(),get_zmax(),get_dt()*get_savecount())) * ((*P)->get_Mass() * d_phi.Z);
1943  dz[i].EnergyFlux += (*P)->get_Velocity() * ((*P)->get_Mass()*(*P)->get_Velocity().GetLength2()/2 * d_phi.Z);
1944  } //end if get_doGradient
1945  } //end if phi
1946  } // end forall Points
1947 }
1948 
1949 //template class StatisticsPoint<XYZ>;
1950 
1951 //Templated functions
1952 
1953 template<> void StatisticsVector<XY>::set_nz(int new_ UNUSED) { nz = 1; }
1954 template<> void StatisticsVector<XZ>::set_ny(int new_ UNUSED) { ny = 1; }
1955 template<> void StatisticsVector<YZ>::set_nx(int new_ UNUSED) { nx = 1; }
1956 template<> void StatisticsVector<X>::set_ny(int new_ UNUSED) { ny = 1; }
1957 template<> void StatisticsVector<X>::set_nz(int new_ UNUSED) { nz = 1; }
1958 template<> void StatisticsVector<Y>::set_nx(int new_ UNUSED) { nx = 1; }
1959 template<> void StatisticsVector<Y>::set_nz(int new_ UNUSED) { nz = 1; }
1960 template<> void StatisticsVector<Z>::set_nx(int new_ UNUSED) { nx = 1; }
1961 template<> void StatisticsVector<Z>::set_ny(int new_ UNUSED) { ny = 1; }
1962 template<> void StatisticsVector<O>::set_nx(int new_ UNUSED) { nx = 1; }
1963 template<> void StatisticsVector<O>::set_ny(int new_ UNUSED) { ny = 1; }
1964 template<> void StatisticsVector<O>::set_nz(int new_ UNUSED) { nz = 1; }
1965 
1966 template<> void StatisticsVector<RAZ>::set_statType() { statType=RAZ; }
1967 template<> void StatisticsVector<RZ>::set_statType() { statType=RZ; }
1968 template<> void StatisticsVector<AZ>::set_statType() { statType=AZ; }
1969 template<> void StatisticsVector<RA>::set_statType() { statType=RA; }
1970 template<> void StatisticsVector<A>::set_statType() { statType=A; }
1971 template<> void StatisticsVector<R>::set_statType() { statType=R; }
1972 template<> void StatisticsVector<XYZ>::set_statType() { statType=XYZ; }
1973 template<> void StatisticsVector<XY>::set_statType() { statType=XY; }
1974 template<> void StatisticsVector<XZ>::set_statType() { statType=XZ; }
1975 template<> void StatisticsVector<YZ>::set_statType() { statType=YZ; }
1976 template<> void StatisticsVector<X>::set_statType() { statType=X; }
1977 template<> void StatisticsVector<Y>::set_statType() { statType=Y; }
1978 template<> void StatisticsVector<Z>::set_statType() { statType=Z; }
1979 template<> void StatisticsVector<O>::set_statType() { statType=O; }
1980 
1983  return std::min(std::min(fabs((P1.Z-get_zminStat()+5*get_w())/P1_P2_normal.Z),
1984  std::max((get_xmaxStat()-P2.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P2.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X)),
1985  std::max((get_ymaxStat()-P2.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P2.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y));
1986 }
1988  return std::min(std::max((get_ymaxStat()-P2.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P2.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y),
1989  std::max((get_xmaxStat()-P2.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P2.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X));
1990 }
1992  return std::min(fabs((P1.Z-get_zminStat()+5*get_w())/P1_P2_normal.Z),
1993  std::max((get_xmaxStat()-P2.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P2.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X));
1994 }
1996  return std::min(fabs((P1.Z-get_zminStat()+5*get_w())/P1_P2_normal.Z),
1997  std::max((get_ymaxStat()-P2.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P2.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y));
1998 }
2000  return std::max((get_xmaxStat()-P2.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P2.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X);
2001 }
2003  return std::max((get_ymaxStat()-P2.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P2.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y);
2004 }
2005 
2006 
2008  return std::min(std::min(fabs((P1.Z-get_zminStat()+5*get_w())/P1_P2_normal.Z),
2009  std::max((get_xmaxStat()-P1.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P1.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X)),
2010  std::max((get_ymaxStat()-P1.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P1.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y));
2011 }
2013  return std::min(std::max((get_ymaxStat()-P1.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P1.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y),
2014  std::max((get_xmaxStat()-P1.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P1.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X));
2015 }
2017  return std::min(fabs((P1.Z-get_zminStat()+5*get_w())/P1_P2_normal.Z),
2018  std::max((get_xmaxStat()-P1.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P1.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X));
2019 }
2021  return std::min(fabs((P1.Z-get_zminStat()+5*get_w())/P1_P2_normal.Z),
2022  std::max((get_ymaxStat()-P1.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P1.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y));
2023 }
2025  return std::max((get_xmaxStat()-P1.X+5*sqrt(get_w2()))/P1_P2_normal.X,-(P1.X-get_xminStat()+5*sqrt(get_w2()))/P1_P2_normal.X);
2026 }
2028  return std::max((get_ymaxStat()-P1.Y+5*sqrt(get_w2()))/P1_P2_normal.Y,-(P1.Y-get_yminStat()+5*sqrt(get_w2()))/P1_P2_normal.Y);
2029 }
2031  return fabs((P1.Z-get_zminStat()+5*get_w())/P1_P2_normal.Z);
2032 }
2034  return 0;
2035 }
2036 
StatisticsVector()
Basic constructor only calls constructor()
bool periodicWalls
Turns off periodic walls before evaluation (needed for averaging, because we do not yet check if part...
bool read_next_from_data_file(unsigned int format)
StatisticsPoint< T > average(std::vector< StatisticsPoint< T > > &P)
Output average of statistical variables.
void initialize_statistics()
Initializes statistics, i.e. setting w2, setting the grid and writing the header lines in the ...
void gather_force_statistics_from_fstat_and_data()
get force statistics from particle collisions
std::vector< StatisticsPoint< T > > dyTimeAverage
a vector used to sum up all statistical gradients in dy for time-averaging
void output_statistics()
Calculates statistics for Particles (i.e. not collisions)
Mdouble X
Definition: Vector.h:44
void finish_statistics()
Finish all statistics (i.e. write out final data)
bool walls
Turns off walls before evaluation.
StatType
Creates averaged statistics (only valid if density field is homogenous along averaged direction) ...
void write_time_average_statistics()
Writes out time averaged statistics.
bool satisfiesInclusionCriteria(BaseParticle *P)
Mdouble w_over_rmax
if w is not set manually then w will be set by multiplying this value by the largest particle radius ...
Mdouble tmaxStat
Statistical output will only be created if t
std::vector< StatisticsPoint< T > > dz
A vector that stores the gradient in z of all statistical variables at a given position.
Mdouble cutoff
The distance from the origin at which the cg function vanishes; cutoff=w for HeavisideSphere or Polyn...
void gather_force_statistics_from_p3w(int version, std::vector< int > &index)
get force statistics from particle collisions
std::vector< StatisticsPoint< T > > dy
A vector that stores the gradient in y of all statistical variables at a given position.
Mdouble xminStat
By default the points of evaluation are placed in an grid on the domain [xminStat,xmaxStat]x[yminStat,ymaxStat]x[zminStat,zmaxStat].
void constructor()
Sets up all basic things.
Matrix3D Cross(const Vec3D &A, const Matrix3D &B)
Definition: Matrix.h:198
#define sqr(a)
Definition: ExtendedMath.h:36
bool loadVelocityProfile(const char *filename)
Mdouble w2
coarse graining width squared; for HeavisideSphere and Gaussian
Mdouble tintStat
Statistical output will only be created if tmaxStat-tintStat< t< tmaxStat.
void write_statistics()
Writes regular statistics.
void jump_p3c()
get force statistics from particle collisions
std::vector< StatisticsPoint< T > > dx
A vector that stores the gradient in x of all statistical variables at a given position.
void set_nz(int new_)
void evaluate_wall_force_statistics(Vec3D P, int wp=0)
get force statistics (i.e. first particle is a wall particle)
int nx
Grid size nx,ny,nz (by default the points of evaluation are placed in an grid on the domain [xminStat...
void set_CG_type(const char *new_)
void set_nx(int new_)
virtual void save_restart_data()
Stores all MD data.
Definition: MD.cc:654
Defines a pair of periodic walls. The particles are in {x: position_left<=normal*x
Mdouble get_Radius() const
CG
enum used to store the type of coarse-graining function used
void set_w2(Mdouble new_)
Set CG variables w2 and CG_invvolume.
void set_Positions()
Set position of StatisticsPoint points and set variables to 0.
int nTimeAverage
A counter needed to average over time.
std::vector< StatisticsPoint< T > > dxTimeAverage
a vector used to sum up all statistical gradients in dx for time-averaging
std::ostream & operator<<(std::ostream &os, const StatType S)
std::string print()
Outputs member variable values to a std::string.
std::vector< StatisticsPoint< T > > dzTimeAverage
a vector used to sum up all statistical gradients in dz for time-averaging
std::string print() const
Outputs statistical variables in human-readable format.
Mdouble get_t()
Access function for the time.
Definition: MD.h:108
Mdouble indSpecies
defines the species for which statistics are extracted (-1 for all species)
void shift_positions(Vec3D &PI, Vec3D &PJ)
shifts two particles
void evaluate_force_statistics(int wp=0)
get force statistics
void statistics_from_p3()
this is a modified version of statistics_from_fstat_and_data. It is used to read p3d files ...
Mdouble distance(BaseParticle &P)
Returns the distance of the wall to the particle, and sets left_wall = true, if the left wall is the ...
Mdouble tminStat
Statistical output will only be created if t>tminStat.
MatrixSymmetric3D SymmetrizedDyadic(Vec3D A, Vec3D B)
calculates the symmetrized dyadic product ( )
Mdouble rmin
defines the minimum radius of the particles for which statistics are extracted
const Mdouble pi
Definition: ExtendedMath.h:54
double Mdouble
Definition: ExtendedMath.h:33
Vec3D getVelocityProfile(Vec3D Position)
void set_zero()
Sets all statistical variables to zero.
NORMALIZED_POLYNOMIAL< T > CGPolynomial
Stores the Polynomial, if the cg function is an axisymmetric function Polynomial in r...
void statistics_from_fstat_and_data()
get StatisticsPoint
Matrix3D Dyadic(Vec3D A, Vec3D B)
calculates the dyadic product ( )
Definition: Matrix.h:191
void evaluate_particle_statistics(std::vector< BaseParticle * >::iterator P, int wp=0)
Calculates statistics for a single Particle.
bool doTimeAverage
Determines if output is averaged over time.
void set_format(int new_)
Definition: MD.h:507
void process_statistics(bool usethese)
Processes all gathered statistics and resets them afterwards. (Processing means either calculating ti...
void shift_position(BaseParticle *F0)
shifts the particle (after distance set the left_wall value)
std::vector< StatisticsPoint< T > > timeVariance
a vector used to sum up the variance in time of all statistical values
const Vec3D & get_Position() const
Mdouble mirrorAtDomainBoundary
bool doVariance
Determines if variance is outputted.
Mdouble Y
Definition: Vector.h:44
#define UNUSED
Definition: ExtendedMath.h:38
std::vector< StatisticsPoint< T > > Points
A vector that stores the values of the statistical variables at a given position. ...
A class that defines and solves a MD problem.
Definition: MD.h:70
virtual void output_xballs_data()
Output xball data for Particle i.
Definition: MD.cc:209
This class stores statistical values for a given spatial position; to be used in combination with Sta...
int verbosity
0 no output 1 basic output (timesteps) 2 full output (number of forces and particles, md and stat parameters)
void gather_statistics_collision(int index1, int index2, Vec3D Contact, Mdouble delta, Mdouble ctheta, Mdouble fdotn, Mdouble fdott, Vec3D P1_P2_normal_, Vec3D P1_P2_tangential)
Calculates statistics for one collision (can be any kind of collision)
CG CG_type
coarse graining type (Gaussian, Heaviside, Polynomial)
Mdouble hmax
defines the maximum height of the particles for which statistics are extracted
This class is used to extract statistical data from MD simulations.
std::vector< StatisticsPoint< T > > timeAverage
A vector used to sum up all statistical values in Points for time-averaging.
void set_dim(int new_dim)
Allows the dimension of the simulation to be changed.
Definition: MD.h:367
void set_ny(int new_)
Mdouble setInfinitelyLongDistance()
bool superexact
If true, cutoff radius for Gaussian is set to 5*w (from 3*w)
virtual void reset_statistics()
Set all statistical variables to zero.
bool ignoreFixedParticles
Determines if fixed particles contribute to particle statistics (density, ...)
static void set_gb(StatisticsVector< T > *new_gb)
see StatisticsVector::set_CG_type
Implementation of a 3D vector (by Vitaliy).
Definition: Vector.h:40
bool read_next_from_data_file(unsigned int format=0)
by default format do not pass an argument; only specify format if you have to read a special format (...
Definition: MD.cc:453
int StressTypeForFixedParticles
0 no Stress from fixed particles 1 Stress from fixed particles distributed between Contact and flowin...
Mdouble Z
Definition: Vector.h:44
Mdouble rmax
defines the maximum radius of the particles for which statistics are extracted
void readStatArguments(unsigned int argc, char *argv[])
std::string print_CG()
Output coarse graining variables.
bool doGradient
Determines if gradient is outputted.
virtual void print(std::ostream &os, bool print_all=false)
Outputs MD.
Definition: MD.cc:1806
void gather_force_statistics_from_p3c(int version)
get force statistics from particle collisions
int nxMirrored
extension of grid size from mirrored points
virtual void create_xballs_script()
This creates a scipt which can be used to load the xballs problem to display the data just generated...
Definition: MD_xballs.icc:84