BaseCoupling.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 #ifndef BASE_COUPLING_H
6 #define BASE_COUPLING_H
7 
8 #include "Math/Vector.h"
9 #include "Walls/TriangleWall.h"
11 #include "CG/Functions/Gauss.h"
12 #include "CG/Functions/Lucy.h"
13 #include "CG/Functions/Heaviside.h"
15 #include "Logger.h"
16 
25 template<class M, class O>
26 class BaseCoupling : public M, public O
27 {
28 //protected:
29 // // A reference to the Mercury problem
30 // Mercury3D& m = this;
31 // // A reference to the Oomph problem
32 // SolidProblem<typename OomphProblem::ELEMENT_TYPE>& o = this;
33 
34 public:
35 
36  BaseCoupling() = default;
37 
39  M::setName(name);
40  O::setName(name);
41  }
42 
43  std::string getName() const {
44  return M::getName();
45  }
46 
47  void removeOldFiles() const {
48  M::removeOldFiles();
49  O::removeOldFiles();
50  }
51 
55  void writeEneTimeStep(std::ostream& os) const override
56  {
57  if (M::eneFile.getCounter() == 1 || M::eneFile.getFileType() == FileType::MULTIPLE_FILES ||
58  M::eneFile.getFileType() == FileType::MULTIPLE_FILES_PADDED)
59  {
60  writeEneHeader(os);
61  }
62 
63  const Mdouble m = M::particleHandler.getMass();
64  const Vec3D com = M::particleHandler.getMassTimesPosition();
65  //Ensure the numbers fit into a constant width column: for this we need the precision given by the operating system,
66  //plus a few extra characters for characters like a minus and scientific notation.
67  const static long int width = os.precision() + 6;
68  os << std::setw(width) << M::getTime()
69 // << " " << std::setw(width) << getCoupledMass()
70  << " " << std::setw(width) << M::particleHandler.getMomentum().getX()
71  << " " << std::setw(width) << M::particleHandler.getMomentum().getY()
72  << " " << std::setw(width) << M::particleHandler.getMomentum().getZ()
73  << " " << std::setw(width) << M::particleHandler.getAngularMomentum().getX()
74  << " " << std::setw(width) << M::particleHandler.getAngularMomentum().getY()
75  << " " << std::setw(width) << M::particleHandler.getAngularMomentum().getZ()
76  << " " << std::setw(width) << -Vec3D::dot(M::getGravity(), com)
77  << " " << std::setw(width) << M::particleHandler.getKineticEnergy()
78  << " " << std::setw(width) << M::particleHandler.getRotationalEnergy()
79  //<< " " << std::setw(width) << M::getElasticEnergyCoupled()
80  // we need to write x, y and z coordinates separately, otherwise the width of the columns is incorrect
81  << " " << std::setw(width)
82  << ( m == 0 ? constants::NaN : com.X / m ) //set to nan because 0/0 implementation in gcc and clang differs
83  << " " << std::setw(width) << ( m == 0 ? constants::NaN : com.Y / m )
84  << " " << std::setw(width) << ( m == 0 ? constants::NaN : com.Z / m )
85  << std::endl;
86  }
87 
91  void writeEneHeader(std::ostream& os) const override
92  {
93  //only write if we don't restart
94  if (M::getAppend()) {
95  return;
96  }
97 
98  long width = os.precision() + 6;
99  os << std::setw(width)
100  << "time " << std::setw(width)
101  << "mass " << std::setw(width)
102  << "momentum_X " << std::setw(width)
103  << "momentum_Y " << std::setw(width)
104  << "momentum_Z " << std::setw(width)
105  << "angMomentum_X " << std::setw(width)
106  << "angMomentum_Y " << std::setw(width)
107  << "angMomentum_Z " << std::setw(width)
108  << "gravitEnergy " << std::setw(width) //gravitational potential energy
109  << "traKineticEnergy " << std::setw(width) //translational kinetic energy
110  << "rotKineticEnergy " << std::setw(width) //rotational kE
111  << "elasticEnergy " << std::setw(width)
112  << "centerOfMassX " << std::setw(width)
113  << "centerOfMassY " << std::setw(width)
114  << "centerOfMassZ\n";
115  }
116 
120  void solveOomph(int max_adapt = 0)
121  {
122  O::actionsBeforeOomphTimeStep();
123  // the coupled codes seem to not work if newton_solve is used
124  //this->newton_solve(this->time_pt()->dt());
125  if(max_adapt <= 0)
126  {
127  this->unsteady_newton_solve(this->time_pt()->dt());
128  }
129  else
130  {
131  this->unsteady_newton_solve(this->time_pt()->dt(), max_adapt, false);
132  }
133  checkResidual();
134  }
135 
136  // check whether the maximum residual is zero. If so, the computation has failed and the code will exit.
138  oomph::DoubleVector residual;
139  O::get_residuals(residual);
140  double residualNorm = residual.max();
141  if (residualNorm == 0) {
142  logger(ERROR, "Maximum residuals %; the computation has failed and the code will exit", residualNorm);
143  }
144  }
145 
149  void solveMercury(unsigned long nt)
150  {
151  for (int n = 0; n < nt; ++n)
152  {
153  M::computeOneTimeStep();
154  }
155  }
156 
157  inline void setCGWidth(const double& width)
158  {
159  if (width == 0)
160  {
161  CGMapping_ = false;
162  }
163  else
164  {
165  CGMapping_ = true;
166  // note CG function needs to be nondimensionalized
167  // fixme CG width is not set with respect to particle radius. Should we do that?
168  cgFunction_.setWidth(width);
169  }
170  }
171 
175  inline double getCGWidth()
176  {
177  return cgFunction_.getWidth();
178  }
179 
180  inline bool useCGMapping()
181  { return CGMapping_; }
182 
184  { return cgFunction_; }
185 
186 private:
187  // flag to construct mapping with FEM basis functions (default) or DPM coarse graining
188  bool CGMapping_ = false;
189  // coarse-graining functions and coordinates
191 };
192 
193 #endif //BASE_COUPLING_H
const unsigned n
Definition: CG3DPackingUnitTest.cpp:11
std::string getName(int argc, char *argv[])
Definition: CombineParallelDataFiles.cpp:16
@ MULTIPLE_FILES
each time-step will be written into/read from separate files numbered consecutively: name_....
@ MULTIPLE_FILES_PADDED
each time-step will be written into/read from separate files numbered consecutively,...
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ ERROR
Definition: BaseCoupling.h:27
bool CGMapping_
Definition: BaseCoupling.h:188
void solveOomph(int max_adapt=0)
Definition: BaseCoupling.h:120
CGFunctions::LucyXYZ cgFunction_
Definition: BaseCoupling.h:190
std::string getName() const
Definition: BaseCoupling.h:43
bool useCGMapping()
Definition: BaseCoupling.h:180
void checkResidual()
Definition: BaseCoupling.h:137
void removeOldFiles() const
Definition: BaseCoupling.h:47
double getCGWidth()
Definition: BaseCoupling.h:175
BaseCoupling()=default
void writeEneHeader(std::ostream &os) const override
Definition: BaseCoupling.h:91
void setName(std::string name)
Definition: BaseCoupling.h:38
CGFunctions::LucyXYZ getCGFunction()
Definition: BaseCoupling.h:183
void setCGWidth(const double &width)
Definition: BaseCoupling.h:157
void writeEneTimeStep(std::ostream &os) const override
Definition: BaseCoupling.h:55
void solveMercury(unsigned long nt)
Definition: BaseCoupling.h:149
Mdouble getWidth() const
void setWidth(Mdouble width)
Set the cutoff radius.
Definition: Kernel/Math/Vector.h:30
Mdouble Y
Definition: Kernel/Math/Vector.h:45
Mdouble Z
Definition: Kernel/Math/Vector.h:45
Mdouble X
the vector components
Definition: Kernel/Math/Vector.h:45
static Mdouble dot(const Vec3D &a, const Vec3D &b)
Calculates the dot product of two Vec3D: .
Definition: Vector.cc:56
Mdouble getX() const
Definition: Kernel/Math/Vector.h:431
Definition: double_vector.h:58
double max() const
returns the maximum coefficient
Definition: double_vector.cc:604
int * m
Definition: level2_cplx_impl.h:294
void get_residuals(const Vector< double > &param, const Vector< double > &unknowns, Vector< double > &residuals)
Global residual fct.
Definition: spring_contact.cc:65
const Mdouble NaN
Definition: GeneralDefine.h:22
std::string string(const unsigned &i)
Definition: oomph_definitions.cc:286
string name
Definition: plotDoE.py:33