ChuteWithPeriodicInflow.h
Go to the documentation of this file.
1 // This file is part of the MercuryDPM project (https://www.mercurydpm.org).
2 // Copyright (c), The MercuryDPM Developers Team. All rights reserved.
3 // License: BSD 3-Clause License; see the LICENSE file in the root directory.
4 
5 //updated force calculation to the changes in MD.cc (further, a few variables needed to be privatized)
6 #include <sstream>
7 #include <fstream>
8 #include <iostream>
9 #include <iomanip>
10 #include <cmath>
11 
12 #include "Chute.h"
14 #include "sys/stat.h"
17 {
18 public:
20  {
21  loadPeriodicBox(restart_file);
22  }
23 
24  ChuteWithPeriodicInflow(std::string restart_file, int numRepetitions)
25  {
26  loadPeriodicBox(restart_file);
27  AddContinuingBottom(numRepetitions);
28  }
29 
30  ChuteWithPeriodicInflow(std::string restart_file, int numRepetitions, int numRepetitionsInWidth)
31  {
32  loadPeriodicBox(restart_file);
33  AddContinuingBottom(numRepetitions);
34  ExtendInWidth(numRepetitionsInWidth);
35  }
36 
37  double getInfo(const BaseParticle& P) const override
38  {
39  return P.getIndSpecies();
40  }
41 
43  void loadPeriodicBox(std::string const restart_file)
44  {
45  FillChute = false;
46 
47  std::cout << "constructor" << std::endl;
48 
49  //load particles and chute setup into periodic chute
50  setName(restart_file.c_str());
52 
55 
56  //we don't want to treat the data as restarted, i.e. we start the program at time=0 and create new output files
57  setRestarted(false);
58 
59  //keep file name but create files in the local directory, i.e. remove folder
60  size_t found = restart_file.find_last_of("/\\");
61  setName(restart_file.substr(found + 1).c_str());
62 
63  // adds new species for the flow particles (0 for the periodic inflow particles)
64  for (int i = 0; i < get_PeriodicBoxNSpecies(); i++)
65  addSpecies(Species[i]);
66 
67  setName("ChuteWithPeriodicInflow");
68  }
69 
70  void AddContinuingBottom(int numRepetitions)
71  {
72  // creates bottom outside periodic chute of species 1
73  double lengthPeriodicChute = getXMax();
75  particleHandler.setStorageCapacity(N * (2. + numRepetitions));
76  //allows for a gap between the infow and flow regimes
77  double Gap = 0.;
78 
79  for (int j = 1; j < numRepetitions; j++)
80  {
81  for (int i = 0; i < N; i++)
82  {
84  {
87  particleHandler.getLastObject()->move(Vec3D(Gap + lengthPeriodicChute * j, 0., 0.));
88  }
89  }
90  }
91 
92  setXMax(numRepetitions * lengthPeriodicChute);
93  //setHGridNumberOfBucketsToPower(particleHandler.getStorageCapacity());
94  }
95 
96  void ExtendInWidth(int numRepetitionsInWidth)
97  {
99  // creates bottom outside periodic chute of species 1
100  double widthPeriodicChute = getYMax();
102  particleHandler.setStorageCapacity(N * numRepetitionsInWidth);
103  for (int j = 1; j < numRepetitionsInWidth; j++)
104  {
105  for (int i = 0; i < N; i++)
106  {
107  //if (particleHandler.getObject(i)->isFixed()) {
109  //Particles.back()->get_IndSpecies()=1;
110  particleHandler.getLastObject()->move(Vec3D(0.0, widthPeriodicChute * j, 0.0));
111  //}
112  }
113  }
114  setYMax(numRepetitionsInWidth * widthPeriodicChute);
115  perw->set(Vec3D(0, 1, 0), getYMin(), getYMax());
116  //setHGridNumberOfBucketsToPower(particleHandler.getNumberOfObjects());
117  }
118 
120  void actionsBeforeTimeStep() override
121  {
122  cleanChute();
123  }
124 
126  void cleanChute()
127  {
128  //clean outflow every 100 time steps
129  static int count = 0, maxcount = 100;
130  if (count > maxcount)
131  {
132  count = 0;
133  // delete all outflowing particles
134  for (unsigned int i = 0; i < particleHandler.getNumberOfObjects();)
135  {
136  //~ if (particleHandler.getObject(i)->getPosition().Z<getZMin()-10*getInflowParticleRadius()){
138  {
139  //~ cout << "Remove particle" << endl;
141  }
142  else
143  i++;
144  }
145  }
146  else
147  count++;
148  }
149 
151  void setupInitialConditions() override
152  {
153  }
154 
156  {
157  for (std::vector<BaseParticle*>::iterator it = particleHandler.begin(); it != particleHandler.end(); ++it)
158  {
159  (*it)->integrateBeforeForceComputation(getTimeStep());
160 
161  // This shifts particles that moved through periodic walls
163  PeriodicBoundary* perw1 = static_cast<PeriodicBoundary*>(boundaryHandler.getObject(1));
164  if ((*it)->getIndSpecies() == 0 && perw->getDistance(**it) < 0)
165  {
166  //if (iP->getIndSpecies()==0 && static_cast<PeriodicWall*>(boundaryHandler.getObject(0))->getDistance(*iP)<0) {
167  if (!perw->isClosestToLeftBoundary())
168  {
171  particleHandler.addObject((*it)->copy());
174  perw->shiftPosition((*it));
176  {
177  hGridRemoveParticle((*it));
178  hGridUpdateParticle((*it));
179  }
180  }
181  else
182  {
183  static int count = -1;
184  count++;
185  if (!(count % dataFile.getSaveCount()))
186 
187  std::cout << "Warning: Particle " << (*it)->getIndex() << " is left of xmin: x="
188  << (*it)->getPosition().X << ", v_x=" << (*it)->getVelocity().X << std::endl;
189  }
190  }
191  if (getIsPeriodic() > 1 && perw1->getDistance(**it) < 0)
192  {
193  perw1->shiftPosition(*it);
195  {
196  hGridRemoveParticle(*it);
197  hGridUpdateParticle(*it);
198  }
199  }
200  }
201 
202  }
203 
205  void printTime() const override
206  {
207  int counter = 0;
208 
209  double speed1 = 0;
210  double speed0 = 0;
211  double n1 = 0;
212  double n0 = 0;
213  for (int i = 0; i < particleHandler.getNumberOfObjects(); i++)
214  {
216  counter++;
218  {
220  {
221  speed0 += particleHandler.getObject(i)->getVelocity().X;
222  n0++;
223  }
224  else
225  {
226  speed1 += particleHandler.getObject(i)->getVelocity().X;
227  n1++;
228  }
229  }
230  }
231  speed0 /= n0;
232  speed1 /= n1;
233 
234  std::cout << "t=" << std::setprecision(5) << std::left << std::setw(6) << getTime()
235  << ", n=" << n1 << "(inflow:" << n0 << ")"
236  << ", speed= " << speed1 << "(" << speed0 << ")"
237  << std::endl;
238  //~ cout
239  //~ << " A " << PeriodicBoxLength
240  //~ << " A " << PeriodicBoxNSpecies
241  //~ << " A " << FillChute << endl;
242  }
243  //%%%%%%%%%%%%%%%%% Copied from MD.cc and then edited
245  {
246 <<<<<<< .mine
247  // For particles of the same species, set species vector to Species(PI);
248  // for particles of different species, set species vector to MixedSpecies(PI,PJ)
249  BaseSpecies* pSpecies = (PI->getIndSpecies() == PJ->getIndSpecies()) ? &Species[PI->getIndSpecies()] : speciesHandler.getMixedObject(PI->getIndSpecies(), PJ->getIndSpecies());
250 =======
251  //this is because the rough bottom allows overlapping fixed particles
252  if (P1->isFixed() && P2->isFixed())
253  return;
254 >>>>>>> .r824
255 
260 
261  //Dificult cases for tangential springs in comination with periodic walls are:
262  //
263  // A new contact over a periodic wall:
264  // Starting situation: There are no tangential springs stored at all
265  // Creating periodic particles: There are no tangential springs so nothing happens
266  // Contact detection: There are two contacts detected, one (CA) for P1 with P2per and one (CB) for P2 with P1per
267  // Switch to the 4 cases:
268  // CA: PI=P1, PJ=P2per PJreal=P2
269  // CB: PI=P2, PJ=P1per PJreal=P1
270  // Reconnecting springs:
271  // CA: PI=P1 and PJ=P2per do not have a spring, so a new spring is created in either PI or PJ (could be in periodic particle)
272  // CB: PI=P2 and PJ=P1Per do not have a spring, so a new spring is created in either PI or PJ (could be in periodic particle)
273  // Removing periodic particles: One of the springs will be stored in a periodic particle and thus removed, the other spring is kept and used (this is the real particle with the kighest index)
274 
275  // Reconnect to a contact over a periodic wall:
276  // Starting situation: There is a tangential spring stored in the particle with the highest index, lets assume this is P1
277  // Creating periodic particles: P1 has a tangential spring, so P1per has a reversed copy of this spring
278  // Contact detection: There are two contacts detected, one (CA) for P1 with P2per and one (CB) for P2 with P1per
279  // Switch to the 4 cases:
280  // CA: PI=P1, PJ=P2per PJreal=P2
281  // CB: PI=P2, PJ=P1per PJreal=P1
282  // Reconnecting springs:
283  // CA: PI=P1 and PJ=P2per have a spring in P1, so we reconnect to this spring in the normal way and integrate it.
284  // CB: PI=P2 and PJ=P1Per have a spring in P1per, however this spring has to be a reversed spring since it is in PJ.
285  // Removing periodic particles: The spring in P1per is removed
286 
287  //Cases (start from P1 and P2 and go to PI and PJ
288  //1 Normal-Normal ->PI=max(P1,P2), PJ=min(P1,P2)
289  //2 Periodic-Normal ->(PI=P2 PJ=real(P1))
290  //3 Normal-Periodic ->(PI=P1 PJ=real(P2))
291  //4 Periodic-Periodic ->do nothing
292 
293  //Just some statements to handle the 4 cases
294  BaseParticle *PI, *PJ, *PJreal;
295  bool isPeriodic;
296  BaseParticle *P1Per = P1->getPeriodicFromParticle();
297  BaseParticle *P2Per = P2->getPeriodicFromParticle();
298  if (P1Per == NULL)
299  {
300  if (P2Per == NULL) //N-N
301  if (P1->getIndex() < P2->getIndex())
302  {
303  PI = P2;
304  PJ = P1;
305  PJreal = P1;
306  isPeriodic = false;
307  }
308  else
309  {
310  PI = P1;
311  PJ = P2;
312  PJreal = P2;
313  isPeriodic = false;
314  }
315  else //N-P
316  {
317  PI = P1;
318  PJ = P2;
319  PJreal = P2Per;
320  isPeriodic = true;
321  }
322  }
323  else
324  {
325  if (P2Per == NULL) //P-N
326  {
327  PI = P2;
328  PJ = P1;
329  PJreal = P1Per;
330  isPeriodic = true;
331  }
332  else
333  return;
334  }
335 
336 #ifdef DEBUG_OUTPUT
337  std::cerr << "In computing internal forces between particle "<<PI->getPosition()<<" and "<<PJ->getPosition()<<std::endl;
338 #endif
339 
340  //Get the square of the distance between particle i and particle j
341  Mdouble dist_squared = Vec3D::getDistanceSquared(PI->getPosition(), PJ->getPosition());
342  Mdouble interactionRadii_sum = PI->getInteractionRadius() + PJ->getInteractionRadius();
343 
344 #ifdef DEBUG_OUTPUT_FULL
345  std::cerr << "Square of distance between " << dist_squared << " square sum of radii " << radii_sum*radii_sum <<std::endl;
346 #endif
347 
348  // True if the particles are in contact
349  if (dist_squared < (interactionRadii_sum * interactionRadii_sum))
350  {
351  // For particles of the same species, set species vector to Species(PI);
352  // for particles of different species, set species vector to MixedSpecies(PI,PJ)
353  CSpecies* pSpecies = (PI->getIndSpecies() == PJ->getIndSpecies()) ? &Species[PI->getIndSpecies()] : getMixedSpecies(PI->getIndSpecies(), PJ->getIndSpecies());
354 
355  // Calculate distance between the particles
356  Mdouble dist = sqrt(dist_squared);
357 
358  // Compute normal vector
359 
360  Vec3D normal = (PI->getPosition() - PJ->getPosition()) / dist;
361 
362  // Compute the overlap between the particles
363  Mdouble radii_sum = PI->getRadius() + PJ->getRadius();
364  Mdouble deltan = std::max(0.0, radii_sum - dist);
365 
366  Vec3D force = Vec3D(0, 0, 0);
367  ;
368  Vec3D forcet;
369  forcet.setZero();
370  Vec3D forcerolling;
371  forcerolling.setZero();
372  Vec3D forcetorsion;
373  forcetorsion.setZero();
374  Mdouble fdotn = 0;
375  CTangentialSpring* TangentialSpring = NULL;
376 
377  //evaluate shortrange non-contact forces
378  if (pSpecies->getAdhesionForceType() != AdhesionForceType::NONE)
379  fdotn += computeShortRangeForceWithParticle(PI, PJ, PJreal, pSpecies, dist);
380 
381  if (deltan > 0) //if contact forces
382  {
383 
384  // Compute the relative velocity vector v_ij
385  Vec3D vrel;
386  if (!pSpecies->getSlidingFrictionCoefficient())
387  {
388  vrel = (PI->getVelocity() - PJ->getVelocity());
389  }
390  else
391  {
392  vrel = (PI->getVelocity() - PJ->getVelocity()) + Vec3D::cross(normal, PI->getAngularVelocity() * (PI->getRadius() - .5 * deltan) + PJ->getAngularVelocity() * (PJ->getRadius() - .5 * deltan));
393  }
394 
395  // Compute the projection of vrel onto the normal (can be negative)
396  Mdouble vdotn = -Vec3D::dot(vrel, normal);
397 
398  //update restitution coeff
399  if (pSpecies->getIsRestitutionCoefficientConstant())
400  pSpecies->updateDissipation(PI->getMass(), PJ->getMass());
401  Mdouble a = 0, R = 0;
402 
403  // Compute normal force on particle i due to contact
404  if (pSpecies->getForceType() == ForceType::HERTZ_MINDLIN || pSpecies->getForceType() == ForceType::HERTZ_MINDLIN_DERESIEWICZ)
405  {
406  //R is twice the effective radius
407  R = 2.0 * PI->getRadius() * PJ->getRadius() / (PI->getRadius() + PJ->getRadius());
408  a = sqrt(R * deltan);
409  //pSpecies->getStiffness() stores the elastic modulus
410  Mdouble kn = 4. / 3. * pSpecies->getStiffness() * a;
411  fdotn += kn * deltan + pSpecies->getDissipation() * vdotn;
412  }
413  else
414  {
415  fdotn += pSpecies->getStiffness() * deltan + pSpecies->getDissipation() * vdotn;
416  }
417  force += normal * fdotn;
418 
419  //If tangential forces are present
420  if (pSpecies->getSlidingFrictionCoefficient() || pSpecies->getRollingFrictionCoefficient() || pSpecies->getTorsionFrictionCoefficient())
421  {
422  //call tangential spring
423  if (pSpecies->getSlidingStiffness() || pSpecies->getRollingStiffness() || pSpecies->getTorsionStiffness())
424  TangentialSpring = getTangentialSpring(PI, PJ, PJreal);
425 
426  //Compute norm of normal force
427  Mdouble norm_fn = fabs(fdotn);
428 
429  //calculate sliding friction
430  if (pSpecies->getSlidingFrictionCoefficient())
431  {
432  //Compute the tangential component of vrel
433  Vec3D vrelt = vrel + normal * vdotn;
434  //Compute norm of vrelt
435  Mdouble vdott = vrelt.getLength();
436 
437  if (pSpecies->getSlidingStiffness())
438  {
439  Vec3D* delta = &(TangentialSpring->delta);
440 
441  //Integrate the spring
443  //(*delta) += vrelt * dt - Vec3D::Dot(*delta,normal)*normal;
444  Vec3D ddelta = (vrelt - Vec3D::dot(*delta, PI->getVelocity() - PJ->getVelocity()) * normal / dist) * getTimeStep();
445  (*delta) += ddelta;
446 
447  //Calculate test force including viscous force
448  if (pSpecies->getForceType() == ForceType::HERTZ_MINDLIN)
449  {
450  //pSpecies->getSlidingStiffness() stores the elastic shear modulus
451  Mdouble kt = 8. * pSpecies->getSlidingStiffness() * a;
452  TangentialSpring->SlidingForce += -kt * ddelta;
453  forcet = TangentialSpring->SlidingForce - pSpecies->getSlidingDissipation() * vrelt;
454  }
455  else if (pSpecies->getForceType() == ForceType::HERTZ_MINDLIN_DERESIEWICZ)
456  {
457  //pSpecies->getSlidingStiffness() stores the elastic shear modulus
458  forcet = TangentialSpring->SlidingForce - pSpecies->getSlidingDissipation() * vrelt;
459  Mdouble kt = 8. * pSpecies->getSlidingStiffness() * a * std::pow(1 - Vec3D::getLength(forcet) / pSpecies->getSlidingFrictionCoefficient() / fdotn, 0.33);
460  TangentialSpring->SlidingForce += -kt * ddelta;
461  forcet = TangentialSpring->SlidingForce - pSpecies->getSlidingDissipation() * vrelt;
462  }
463  else
464  {
465  forcet = (-pSpecies->getSlidingDissipation()) * vrelt - pSpecies->getSlidingStiffness() * (*delta);
466  }
467  Mdouble forcet2 = forcet.getLengthSquared();
468 
469  //tangential forces are modelled by a spring-damper of elastisity kt and viscosity getSlidingDissipation() (sticking),
470  //but the force is limited by Coulomb friction (sliding):
471  //f_t = -getSlidingDissipation()*vrelt, if getSlidingDissipation()*vrelt<=mu_s*fdotn, f_t=mu+s*fdotn*t, else
472  double muact = (TangentialSpring->sliding) ? (pSpecies->getSlidingFrictionCoefficient()) : (pSpecies->getSlidingFrictionCoefficientStatic()); // select mu from previous sliding mode
473  if (forcet2 <= mathsFunc::square(muact * norm_fn))
474  {
475  //sticking++;
476  TangentialSpring->sliding = false;
477  }
478  else
479  {
480  //sliding++;
481  TangentialSpring->sliding = true;
483  Mdouble norm_forcet = sqrt(forcet2);
484  forcet *= pSpecies->getSlidingFrictionCoefficient() * norm_fn / norm_forcet;
485  TangentialSpring->SlidingForce = forcet + pSpecies->getSlidingDissipation() * vrelt;
486  (*delta) = TangentialSpring->SlidingForce / (-pSpecies->getSlidingStiffness());
487  }
488 
489  //Add tangential force to total force
490  force += forcet;
491 
492  }
493  else
494  { //if no tangential spring
495  //tangential forces are modelled by a damper of viscosity getSlidingDissipation() (sticking),
496  //but the force is limited by Coulomb friction (sliding):
497  //f_t = -getSlidingDissipation()*vrelt, if getSlidingDissipation()*vrelt<=mu_s*fdotn, f_t=mu+s*fdotn*t, else
498  if (vdott * pSpecies->getSlidingDissipation() <= pSpecies->getSlidingFrictionCoefficientStatic() * norm_fn)
499  { //sticking++;
500  forcet = -pSpecies->getSlidingDissipation() * vrelt;
501  }
502  else
503  { //sliding++;
504  //set force to Coulomb limit
505  forcet = -(pSpecies->getSlidingFrictionCoefficient() * norm_fn / vdott) * vrelt;
506  }
507  //Add tangential force to total force
508  force += forcet;
509  }
510  }
511 
512  //calculate rolling friction
513  if (pSpecies->getRollingFrictionCoefficient())
514  {
515  //From Luding2008, objective rolling velocity (eq 15) w/o 2.0!
516  Mdouble reducedRadiusI = PI->getRadius() - .5 * deltan;
517  Mdouble reducedRadiusJ = PJ->getRadius() - .5 * deltan;
518  Mdouble reducedRadiusIJ = 2.0 * reducedRadiusI * reducedRadiusJ / (reducedRadiusI + reducedRadiusJ);
519  Vec3D vrolling = -reducedRadiusIJ * Vec3D::cross(normal, PI->getAngularVelocity() - PJ->getAngularVelocity());
520  if (pSpecies->getRollingStiffness())
521  {
522  Vec3D* RollingSpring = &(TangentialSpring->RollingSpring);
523 
524  //Integrate the spring
525  (*RollingSpring) += vrolling * getTimeStep(); // - Vec3D::Dot(*RollingSpring,normal)*normal;
526 
527  //Calculate test force including viscous force
528  forcerolling = (-pSpecies->getRollingDissipation()) * vrolling - pSpecies->getRollingStiffness() * (*RollingSpring);
529  Mdouble forcerolling2 = forcerolling.getLengthSquared();
530 
531  //tangential forces are modelled by a spring-damper of elastisity kt and viscosity getSlidingDissipation() (sticking),
532  //but the force is limited by Coulomb friction (sliding):
533  //f_t = -getSlidingDissipation()*vrelt, if getSlidingDissipation()*vrelt<=mu_s*fdotn, f_t=mu+s*fdotn*t, else
534  double muact = (TangentialSpring->slidingRolling) ? (pSpecies->getRollingFrictionCoefficient()) : (pSpecies->getRollingFrictionCoefficientStatic()); // select mu from previous sliding mode
535  if (forcerolling2 <= mathsFunc::square(muact * norm_fn))
536  {
537  //sticking++;
538  TangentialSpring->slidingRolling = false;
539  }
540  else
541  {
542  //sliding++;
543  TangentialSpring->slidingRolling = true;
544  forcerolling *= pSpecies->getRollingFrictionCoefficient() * norm_fn / sqrt(forcerolling2);
545  (*RollingSpring) = (forcerolling + pSpecies->getRollingDissipation() * vrolling) / (-pSpecies->getRollingStiffness());
546  }
547 
548  //Add tangential force to torque
549  Vec3D Torque = reducedRadiusIJ * Vec3D::cross(normal, forcerolling);
550  PI->addTorque(Torque);
551  PJreal->addTorque(-Torque);
552  }
553  }
554 
555  //calculate torsive friction
556  if (pSpecies->getTorsionFrictionCoefficient())
557  {
558  //From Luding2008, spin velocity (eq 16) w/o 2.0!
559  Mdouble RadiusIJ = 2.0 * PI->getRadius() * PJ->getRadius() / (PI->getRadius() + PJ->getRadius());
560  Vec3D vtorsion = RadiusIJ * Vec3D::dot(normal, PI->getAngularVelocity() - PJ->getAngularVelocity()) * normal;
561  if (pSpecies->getTorsionStiffness())
562  {
563  //~ std::cout << "Error; not yet implemented" << std::endl;
564  //~ exit(-1);
565  Vec3D* TorsionSpring = &(TangentialSpring->TorsionSpring);
566 
567  //Integrate the spring
568  (*TorsionSpring) = Vec3D::dot((*TorsionSpring) + vtorsion * getTimeStep(), normal) * normal;
569 
570  //Calculate test force including viscous force
571  forcetorsion = (-pSpecies->getTorsionDissipation()) * vtorsion - pSpecies->getTorsionStiffness() * (*TorsionSpring);
572  Mdouble forcetorsion2 = forcetorsion.getLengthSquared();
573 
574  //tangential forces are modelled by a spring-damper of elastisity kt and viscosity getSlidingDissipation() (sticking),
575  //but the force is limited by Coulomb friction (sliding):
576  //f_t = -getSlidingDissipation()*vrelt, if getSlidingDissipation()*vrelt<=mu_s*fdotn, f_t=mu+s*fdotn*t, else
577  double muact = (TangentialSpring->slidingTorsion) ? (pSpecies->getTorsionFrictionCoefficient()) : (pSpecies->getTorsionFrictionCoefficientStatic()); // select mu from previous sliding mode
578  if (forcetorsion2 <= mathsFunc::square(muact * norm_fn))
579  {
580  //sticking++;
581  TangentialSpring->slidingTorsion = false;
582  }
583  else
584  {
585  //sliding++;
586  TangentialSpring->slidingTorsion = true;
587  //~ std::cout << "sliding " << std::endl;
588  forcetorsion *= pSpecies->getTorsionFrictionCoefficient() * norm_fn / sqrt(forcetorsion2);
589  (*TorsionSpring) = (forcetorsion + pSpecies->getTorsionDissipation() * vtorsion) / (-pSpecies->getTorsionStiffness());
590  }
591 
592  //Add tangential force to torque
593  Vec3D torque = RadiusIJ * forcetorsion;
594  PI->addTorque(torque);
595  PJreal->addTorque(-torque);
596 
597  }
598  }
599  } //end if tangential forces
600 
602  //Make force Hertzian (note: deltan is normalized by the normal distanct of two particles in contact, as in Silbert)
603  if (pSpecies->getForceType() == ForceType::HERTZ)
604  force *= sqrt(deltan / (PI->getRadius() + PJ->getRadius()));
605 
606  }
607  else
608  { //end if contact forces
609  force += fdotn * normal;
610  }
611 
612  //Add forces to total force
613  //PI->addForce(force);
614  //if (!isPeriodic)
615  // PJreal->addForce(-force);
616 
617  // Add torque due to tangential forces: t = Vec3D::Cross(l,f), l=dist*Wall.normal
618  //if (pSpecies->getSlidingFrictionCoefficient())
619  //{
620  // Vec3D Vec3D::Cross = Vec3D::Cross(normal, force);
621  // PI->addTorque(-Vec3D::Cross * (PI->getRadius() - .5 * deltan));
622  // if (!isPeriodic)
623  // PJreal->addTorque(-Vec3D::Cross * (PJ->getRadius() - .5 * deltan));
624  //}
625  //BEGIN: CHANGE
626  if (InPeriodicBox(PI) != InPeriodicBox(PJreal))
627  {
628  if (InPeriodicBox(PI))
629  {
631  {
632  //~ if (PJreal->isFixed()) cout << "PJreal" << endl;
633  PJreal->addForce(-force);
634  }
635  }
636  else
637  {
639  {
640  //~ if (Particles[PI].isFixed()) cout << "PI" << endl;
641  PI->addForce(force);
642  }
643  }
644  }
645  else
646  {
647  PI->addForce(force);
648  PJreal->addForce(-force);
649  }
650  //END: CHANGE
651 
652  // Add torque due to tangential forces: t = Vec3D::Cross(l,f), l=dist*Wall.normal
653  //if (pSpecies->getSlidingFrictionCoefficient()) {
654  // Vec3D Vec3D::Cross = Vec3D::Cross(normal, force);
655  // PI ->add_Torque(-Vec3D::Cross * (PI->getRadius() - .5 * deltan));
656  // PJreal->add_Torque(-Vec3D::Cross * (PJ->getRadius() - .5 * deltan));
657  //}
658  //BEGIN: CHANGE
659  if (pSpecies->getSlidingFrictionCoefficient())
660  {
661  Vec3D cross = Vec3D::cross(normal, force);
662  if (InPeriodicBox(PI) != InPeriodicBox(PJreal))
663  {
664  if (InPeriodicBox(PI))
665  {
667  {
668  PJreal->addTorque(-cross * (PJreal->getRadius() - .5 * deltan));
669  }
670  }
671  else
672  {
674  {
675  PI->addTorque(-cross * (PI->getRadius() - .5 * deltan));
676  }
677  }
678  }
679  else
680  {
681  PI->addTorque(-cross * (PI->getRadius() - .5 * deltan));
682  PJreal->addTorque(-cross * (PJreal->getRadius() - .5 * deltan));
683  }
684  }
685  //END:CHANGE
686 
687  // output for ene and stat files:
688  if (eneFile.getSaveCurrentTimeStep())
689  {
690  if (!isPeriodic)
691  addElasticEnergy(0.5 * (pSpecies->getStiffness() * mathsFunc::square(deltan) + (TangentialSpring ? (pSpecies->getSlidingStiffness() * TangentialSpring->delta.getLengthSquared() + pSpecies->getRollingStiffness() * TangentialSpring->RollingSpring.getLengthSquared() + pSpecies->getTorsionStiffness() * TangentialSpring->TorsionSpring.getLengthSquared()) : 0.0)));
692  else
693  addElasticEnergy(0.25 * (pSpecies->getStiffness() * mathsFunc::square(deltan) + (TangentialSpring ? (pSpecies->getSlidingStiffness() * TangentialSpring->delta.getLengthSquared() + pSpecies->getRollingStiffness() * TangentialSpring->RollingSpring.getLengthSquared() + pSpecies->getTorsionStiffness() * TangentialSpring->TorsionSpring.getLengthSquared()) : 0.0)));
694  }
695  if (fStatFile.getSaveCurrentTimeStep() || statFile.getSaveCurrentTimeStep() || getDoCGAlways())
696  {
697 
698  Mdouble fdott = forcet.getLength();
699  Mdouble deltat_norm = TangentialSpring ? (-TangentialSpring->delta.getLength()) : 0.0;
700 
703  Vec3D centre = 0.5 * (PI->getPosition() + PJ->getPosition());
704 
708 
709  if (!PI->isFixed())
710  {
711  if (statFile.getSaveCurrentTimeStep() || getDoCGAlways())
712  gatherContactStatistics(PJreal->getIndex(), PI->getIndex(), centre, deltan, deltat_norm, fdotn, fdott, -normal, -(fdott ? forcet / fdott : forcet));
713  if (fStatFile.getSaveCurrentTimeStep())
714  fStatFile.getFstream() << getTime() << " " << PJreal->getIndex() << " " << PI->getIndex() << " " << centre << " " << radii_sum - dist << " " << deltat_norm << " " << fdotn << " " << fdott << " " << -normal << " " << -(fdott ? forcet / fdott : forcet) << std::endl;
715  }
716  if (!PJreal->isFixed() && !isPeriodic)
717  {
718  if (statFile.getSaveCurrentTimeStep() || getDoCGAlways())
719  gatherContactStatistics(PI->getIndex(), PJreal->getIndex(), centre, deltan, deltat_norm, fdotn, fdott, normal, (fdott ? forcet / fdott : forcet));
720  if (fStatFile.getSaveCurrentTimeStep())
721  fStatFile.getFstream() << getTime() << " " << PI->getIndex() << " " << PJreal->getIndex() << " " << centre << " " << radii_sum - dist << " " << deltat_norm << " " << fdotn << " " << fdott << " " << normal << " " << (fdott ? forcet / fdott : forcet) << std::endl;
722  }
723  }
724  } // end if particle i and j are overlapping
725  }
726 
728  {
729  int C = 0; //Number of particles created
730  for (int k = nWallPeriodic; k < getIsPeriodic(); k++)
731  { //Loop over all still posible walls
734  if ((k ? true : InPeriodicBox(i)) && (perw->getDistance(*i) < i->getRadius() + getMaxInflowParticleRadius()))
735  {
736  SphericalParticle F0 = *i;
737  perw->shiftPosition(i);
738 
739  //If Particle is Mdouble shifted, get correct original particle
740  BaseParticle* From = i;
741  while (From->getPeriodicFromParticle() != NULL)
742  From = From->getPeriodicFromParticle();
743  F0.setPeriodicFromParticle(From);
744 
746  C++;
747 
748  //Check for Mdouble shifted particles
750  }
751  }
752  return (C);
753  }
754 
755  void writeXBallsScript() const
756  {
757 
758  std::stringstream file_name;
759  std::ofstream script_file;
760  file_name << getName() << ".disp";
761  script_file.open((file_name.str()).c_str());
762 
764  script_file << "#!/bin/bash" << std::endl;
765  script_file << "x=$(echo $0 | cut -c2-)" << std::endl;
766  script_file << "file=$PWD$x" << std::endl;
767  script_file << "dirname=`dirname \"$file\"`" << std::endl;
768  script_file << "cd $dirname" << std::endl;
769 
770  double scale;
771  int format;
772 
773  int width = 1570, height = 860;
774  double ratio = getSystemDimensions() < 3 ? (getXMax() - getXMin()) / (getYMax() - getYMin()) : (getXMax() - getXMin()) / (getZMax() - getZMin());
775  if (ratio > width / height)
776  height = width / ratio;
777  else
778  width = height * ratio;
779  //~ cout << ratio << "r" << endl;
780  if (getSystemDimensions() < 3)
781  { // dim = 1 or 2
782  format = 8;
783  if (getXBallsScale() < 0)
784  {
785  scale = 1.0 / std::max(getYMax() - getYMin(), getXMax() - getXMin());
786  }
787  else
788  {
789  scale = getXBallsScale();
790  }
791  }
792  else
793  { //dim==3
794  format = 14;
795  if (getXBallsScale() < 0)
796  {
797  scale = width / 480 / (getXMax() - getXMin());
798  }
799 
800  else
801  {
802  scale = getXBallsScale();
803  }
804 
805  }
806 
807  script_file << "../xballs -format " << format
808  << " -f " << dataFile.getFullName()
809  << " -s " << scale
810  << " -w " << width + 140
811  << " -h " << height + 140
812  << " -cmode " << getXBallsColourMode()
813  << " -cmax -scala 4 -sort -oh 50 "
815  << " $*";
816  if (getXBallsVectorScale() > -1)
817  {
818  script_file << " -vscale " << getXBallsVectorScale();
819  }
820  script_file.close();
821 
822  //This line changes the file permision and gives the owner (i.e. you) read, write and execute permission to the file
823 #ifdef UNIX
824  chmod((file_name.str().c_str()),S_IRWXU);
825 #endif
826  }
827 
828  void outputXBallsDataParticlee(const unsigned int i, const unsigned int format, std::ostream& os) const
829  {
830  os
831  << particleHandler.getObject(i)->getPosition().X << " "
832  << particleHandler.getObject(i)->getPosition().Y << " "
833  << particleHandler.getObject(i)->getPosition().Z << " "
834  << particleHandler.getObject(i)->getVelocity().X << " "
835  << particleHandler.getObject(i)->getVelocity().Y << " "
836  << particleHandler.getObject(i)->getVelocity().Z << " "
837  //~ << (particleHandler.getObject(i)->isFixed()?0.0:particleHandler.getObject(i)->Force.X) << " "
838  //~ << (particleHandler.getObject(i)->isFixed()?0.0:particleHandler.getObject(i)->Force.Y) << " "
839  //~ << (particleHandler.getObject(i)->isFixed()?0.0:particleHandler.getObject(i)->Force.Z) << " "
840  << particleHandler.getObject(i)->getRadius() << " "
842  << particleHandler.getObject(i)->getOrientation().Y << " "
843  << particleHandler.getObject(i)->getOrientation().Z << " "
847  << particleHandler.getObject(i)->getIndSpecies() << std::endl;
848  }
849 
851  {
852  return PeriodicBoxLength;
853  }
854  void set_PeriodicBoxLength(double new_)
855  {
856  PeriodicBoxLength = new_;
857  }
859  {
860  return PeriodicBoxNSpecies;
861  }
862  void set_PeriodicBoxNSpecies(int new_)
863  {
864  PeriodicBoxNSpecies = new_;
865  }
866 
868  {
869  return P->getIndSpecies() < PeriodicBoxNSpecies;
870  }
871 
873 
874 private:
879 
880  bool FillChute;
881 };
AnnoyingScalar sqrt(const AnnoyingScalar &x)
Definition: AnnoyingScalar.h:134
int i
Definition: BiCGSTAB_step_by_step.cpp:9
@ R
Definition: StatisticsVector.h:21
virtual unsigned int getNumberOfObjects() const
Gets the number of real Object in this BaseHandler. (i.e. no mpi or periodic particles)
Definition: BaseHandler.h:656
void setStorageCapacity(const unsigned int N)
Sets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:677
const std::vector< T * >::const_iterator begin() const
Gets the begin of the const_iterator over all Object in this BaseHandler.
Definition: BaseHandler.h:698
std::enable_if<!std::is_pointer< U >::value, U * >::type copyAndAddObject(const U &object)
Creates a copy of a Object and adds it to the BaseHandler.
Definition: BaseHandler.h:360
unsigned int getStorageCapacity() const
Gets the storage capacity of this BaseHandler.
Definition: BaseHandler.h:670
const std::vector< T * >::const_iterator end() const
Gets the end of the const_iterator over all BaseBoundary in this BaseHandler.
Definition: BaseHandler.h:712
T * getObject(const unsigned int id)
Gets a pointer to the Object at the specified index in the BaseHandler.
Definition: BaseHandler.h:621
T * getLastObject()
Gets a pointer to the last Object in this BaseHandler.
Definition: BaseHandler.h:642
const Quaternion & getOrientation() const
Returns the orientation of this BaseInteractable.
Definition: BaseInteractable.h:209
virtual const Vec3D & getAngularVelocity() const
Returns the angular velocity of this interactable.
Definition: BaseInteractable.cc:319
void addTorque(const Vec3D &addTorque)
Adds an amount to the torque on this BaseInteractable.
Definition: BaseInteractable.cc:110
virtual const Vec3D & getVelocity() const
Returns the velocity of this interactable.
Definition: BaseInteractable.cc:307
virtual void move(const Vec3D &move)
Moves this BaseInteractable by adding an amount to the position.
Definition: BaseInteractable.cc:193
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:197
void addForce(const Vec3D &addForce)
Adds an amount to the force on this BaseInteractable.
Definition: BaseInteractable.cc:94
unsigned int getIndSpecies() const
Returns the index of the species associated with the interactable object.
Definition: BaseInteractable.h:67
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.h:97
Definition: BaseParticle.h:33
bool isFixed() const override
Is fixed Particle function. It returns whether a Particle is fixed or not, by checking its inverse Ma...
Definition: BaseParticle.h:72
void setPeriodicFromParticle(BaseParticle *p)
Assigns the pointer to the 'original' particle this one's a periodic copy of (used in periodic bounda...
Definition: BaseParticle.h:416
Mdouble getRadius() const
Returns the particle's radius.
Definition: BaseParticle.h:331
Mdouble getMass() const
Returns the particle's mass.
Definition: BaseParticle.h:305
virtual BaseParticle * copy() const =0
Particle copy method. It calls to copy constructor of this Particle, useful for polymorphism.
BaseParticle * getPeriodicFromParticle() const
Returns the 'original' particle this one's a periodic copy of.
Definition: BaseParticle.h:324
virtual void setSpecies(const ParticleSpecies *species)
Definition: BaseParticle.cc:798
BaseSpecies is the class from which all other species are derived.
Definition: BaseSpecies.h:29
Particles of a single Species.
Definition: ChuteWithPeriodicInflow.h:17
void set_PeriodicBoxNSpecies(int new_)
Definition: ChuteWithPeriodicInflow.h:862
void set_PeriodicBoxLength(double new_)
Definition: ChuteWithPeriodicInflow.h:854
void integrateBeforeForceComputation()
Update particles' and walls' positions and velocities before force computation.
Definition: ChuteWithPeriodicInflow.h:155
int Check_and_Duplicate_Periodic_Particle(BaseParticle *i, int nWallPeriodic)
Definition: ChuteWithPeriodicInflow.h:727
void ExtendInWidth(int numRepetitionsInWidth)
Definition: ChuteWithPeriodicInflow.h:96
void computeInternalForces(BaseParticle *P1, BaseParticle *P2)
Definition: ChuteWithPeriodicInflow.h:244
void setupInitialConditions() override
Do not add bottom.
Definition: ChuteWithPeriodicInflow.h:151
double getInfo(const BaseParticle &P) const override
A virtual function that returns some user-specified information about a particle.
Definition: ChuteWithPeriodicInflow.h:37
void actionsBeforeTimeStep() override
Do not add, only remove particles.
Definition: ChuteWithPeriodicInflow.h:120
void writeXBallsScript() const
This writes a script which can be used to load the xballs problem to display the data just generated.
Definition: ChuteWithPeriodicInflow.h:755
bool FillChute
Definition: ChuteWithPeriodicInflow.h:880
void outputXBallsDataParticlee(const unsigned int i, const unsigned int format, std::ostream &os) const
Definition: ChuteWithPeriodicInflow.h:828
double PeriodicBoxLength
stores the length of the periodic box
Definition: ChuteWithPeriodicInflow.h:876
SphericalParticle inflowParticle_
Definition: ChuteWithPeriodicInflow.h:872
ChuteWithPeriodicInflow(std::string restart_file, int numRepetitions, int numRepetitionsInWidth)
Definition: ChuteWithPeriodicInflow.h:30
void printTime() const override
add some particular output
Definition: ChuteWithPeriodicInflow.h:205
void AddContinuingBottom(int numRepetitions)
Definition: ChuteWithPeriodicInflow.h:70
bool InPeriodicBox(BaseParticle *P)
Definition: ChuteWithPeriodicInflow.h:867
ChuteWithPeriodicInflow(std::string restart_file, int numRepetitions)
Definition: ChuteWithPeriodicInflow.h:24
double get_PeriodicBoxLength()
Definition: ChuteWithPeriodicInflow.h:850
int PeriodicBoxNSpecies
stores the number of species in the periodic box
Definition: ChuteWithPeriodicInflow.h:878
ChuteWithPeriodicInflow(std::string restart_file)
Definition: ChuteWithPeriodicInflow.h:19
void cleanChute()
Remove particles if they fall below a certain height (allows them to become supercritical)
Definition: ChuteWithPeriodicInflow.h:126
int get_PeriodicBoxNSpecies()
Definition: ChuteWithPeriodicInflow.h:858
void loadPeriodicBox(std::string const restart_file)
loads periodic chute data from restart file
Definition: ChuteWithPeriodicInflow.h:43
Creates chutes with different bottoms. Inherits from Mercury3D (-> MercuryBase -> DPMBase).
Definition: Chute.h:44
Mdouble getMaxInflowParticleRadius() const
Returns the maximum radius of inflow particles.
Definition: Chute.cc:926
bool getIsPeriodic() const
Returns whether the chute is periodic in Y.
Definition: Chute.cc:621
int getXBallsColourMode() const
Get the xballs colour mode (CMode).
Definition: DPMBase.cc:1301
Mdouble getXMin() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMin() returns XMin.
Definition: DPMBase.h:603
Mdouble getXMax() const
If the length of the problem domain in x-direction is XMax - XMin, then getXMax() returns XMax.
Definition: DPMBase.h:610
File eneFile
An instance of class File to handle in- and output into a .ene file.
Definition: DPMBase.h:1494
SpeciesHandler speciesHandler
A handler to that stores the species type i.e. LinearViscoelasticSpecies, etc.
Definition: DPMBase.h:1433
double getXBallsVectorScale() const
Returns the scale of vectors used in xballs.
Definition: DPMBase.cc:1321
File fStatFile
An instance of class File to handle in- and output into a .fstat file.
Definition: DPMBase.h:1489
Mdouble getYMin() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMin() returns YMin.
Definition: DPMBase.h:616
void setName(const std::string &name)
Allows to set the name of all the files (ene, data, fstat, restart, stat)
Definition: DPMBase.cc:400
Mdouble getTimeStep() const
Returns the simulation time step.
Definition: DPMBase.cc:1241
const std::string & getName() const
Returns the name of the file. Does not allow to change it though.
Definition: DPMBase.cc:377
Mdouble getTime() const
Returns the current simulation time.
Definition: DPMBase.cc:799
std::string getXBallsAdditionalArguments() const
Returns the additional arguments for xballs.
Definition: DPMBase.cc:1346
File dataFile
An instance of class File to handle in- and output into a .data file.
Definition: DPMBase.h:1484
void setYMax(Mdouble newYMax)
Sets the value of YMax, the upper bound of the problem domain in the y-direction.
Definition: DPMBase.cc:1182
void setRestarted(bool newRestartedFlag)
Allows to set the flag stating if the simulation is to be restarted or not.
Definition: DPMBase.cc:1492
BoundaryHandler boundaryHandler
An object of the class BoundaryHandler which concerns insertion and deletion of particles into or fro...
Definition: DPMBase.h:1458
void gatherContactStatistics()
Definition: DPMBase.cc:1887
void setXMax(Mdouble newXMax)
Sets the value of XMax, the upper bound of the problem domain in the x-direction.
Definition: DPMBase.cc:1156
ParticleHandler particleHandler
An object of the class ParticleHandler, contains the pointers to all the particles created.
Definition: DPMBase.h:1443
double getXBallsScale() const
Returns the scale of the view in xballs.
Definition: DPMBase.cc:1363
Mdouble getYMax() const
If the length of the problem domain in y-direction is YMax - YMin, then getYMax() returns XMax.
Definition: DPMBase.h:622
File statFile
An instance of class File to handle in- and output into a .stat file.
Definition: DPMBase.h:1504
unsigned int getSystemDimensions() const
Returns the system dimensionality.
Definition: DPMBase.cc:1421
Mdouble getZMax() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMax() returns ZMax.
Definition: DPMBase.h:634
Mdouble getZMin() const
If the length of the problem domain in z-direction is ZMax - ZMin, then getZMin() returns ZMin.
Definition: DPMBase.h:628
bool readRestartFile(ReadOptions opt=ReadOptions::ReadAll)
Reads all the particle data corresponding to a given, existing . restart file (for more details regar...
Definition: DPMBase.cc:3043
std::fstream & getFstream()
Allows to access the member variable File::fstream_.
Definition: File.cc:131
const std::string getFullName() const
Also allows to access the file name, however with additional information which is the file counter,...
Definition: File.cc:148
unsigned int getSaveCount() const
Gets File::saveCount_.
Definition: File.cc:233
void hGridUpdateParticle(BaseParticle *obj) override
Updates the cell (not the level) of a BaseParticle.
Definition: Mercury3D.cc:340
void hGridRemoveParticle(BaseParticle *obj) override
Removes a BaseParticle from the HGrid.
Definition: Mercury3D.cc:401
bool getHGridUpdateEachTimeStep() const final
Gets whether or not the HGrid is updated every time step.
Definition: MercuryBase.cc:163
void addObject(BaseParticle *P) override
Adds a BaseParticle to the ParticleHandler.
Definition: ParticleHandler.cc:150
void removeObject(unsigned int index) override
Removes a BaseParticle from the ParticleHandler.
Definition: ParticleHandler.cc:388
unsigned int getNumberOfObjects() const override
Returns the number of objects in the container. In parallel code this practice is forbidden to avoid ...
Definition: ParticleHandler.cc:1323
BaseParticle * getLargestParticle() const
Returns the pointer of the largest particle in the particle handler. When mercury is running in paral...
Definition: ParticleHandler.cc:528
Definition: ParticleSpecies.h:16
Defines a pair of periodic walls. Inherits from BaseBoundary.
Definition: PeriodicBoundary.h:20
Mdouble getDistance(const BaseParticle &p) const override
Returns the distance of the edge to the particle.
Definition: PeriodicBoundary.cc:176
virtual void shiftPosition(BaseParticle *p) const override
shifts the particle
Definition: PeriodicBoundary.cc:198
virtual bool isClosestToLeftBoundary(const BaseParticle &p) const
Returns TRUE if particle checked is closest to the 'left' edge, and FALSE if it is closest to the 'ri...
Definition: PeriodicBoundary.cc:254
void set(Vec3D normal, Mdouble distanceLeft, Mdouble distanceRight)
Defines a PeriodicBoundary by its normal and positions.
Definition: PeriodicBoundary.cc:63
std::enable_if<!std::is_pointer< typename U::MixedSpeciesType >::value, typename U::MixedSpeciesType * >::type getMixedObject(const U *S, const U *T)
Definition: SpeciesHandler.h:52
Contains material and contact force properties.
Definition: Species.h:14
A spherical particle is the most simple particle used in MercuryDPM.
Definition: SphericalParticle.h:16
Definition: Kernel/Math/Vector.h:30
Mdouble Y
Definition: Kernel/Math/Vector.h:45
Mdouble Z
Definition: Kernel/Math/Vector.h:45
static Mdouble getLengthSquared(const Vec3D &a)
Calculates the squared length of a Vec3D: .
Definition: Kernel/Math/Vector.h:324
static Vec3D cross(const Vec3D &a, const Vec3D &b)
Calculates the cross product of two Vec3D: .
Definition: Vector.cc:143
Mdouble X
the vector components
Definition: Kernel/Math/Vector.h:45
static Mdouble getLength(const Vec3D &a)
Calculates the length of a Vec3D: .
Definition: Vector.cc:350
static Mdouble getDistanceSquared(const Vec3D &a, const Vec3D &b)
Calculates the squared distance between two Vec3D: .
Definition: Kernel/Math/Vector.h:303
void setZero()
Sets all elements to zero.
Definition: Vector.cc:23
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:56
Mdouble getLength() const
Calculates the length of this Vec3D: .
Definition: Vector.cc:339
Definition: matrices.h:74
@ N
Definition: constructor.cpp:22
#define max(a, b)
Definition: datatypes.h:23
const Scalar * a
Definition: level2_cplx_impl.h:32
char char char int int * k
Definition: level2_impl.h:374
EIGEN_STRONG_INLINE EIGEN_DEVICE_FUNC bfloat16 pow(const bfloat16 &a, const bfloat16 &b)
Definition: BFloat16.h:625
double P
Uniform pressure.
Definition: TwenteMeshGluing.cpp:77
double height(const double &x)
Height of domain.
Definition: simple_spine_channel.cc:429
bool found
Definition: MergeRestartFiles.py:24
int delta
Definition: MultiOpt.py:96
string file_name
Definition: Particles2023AnalysisHung.py:321
void normal(const Vector< double > &x, Vector< double > &normal)
Definition: free_surface_rotation.cc:65
Real fabs(const Real &a)
Definition: boostmultiprec.cpp:117
T square(const T val)
squares a number
Definition: ExtendedMath.h:86
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
void cross(const Vector< double > &A, const Vector< double > &B, Vector< double > &C)
Definition: oomph-lib/src/generic/Vector.h:319
std::string format(const std::string &str, const std::vector< std::string > &find, const std::vector< std::string > &replace)
Definition: openglsupport.cpp:217
std::ptrdiff_t j
Definition: tut_arithmetic_redux_minmax.cpp:2