ScaleCoupling< M, O > Class Template Reference

#include <ScaleCoupling.h>

+ Inheritance diagram for ScaleCoupling< M, O >:

Classes

struct  CoupledElement
 Stores properties of a coupled element: pointer to the element and list of particles coupled to it. More...
 
struct  CoupledParticle
 For all particles, stores coupling properties: coupling force, pointer to coupled element and location in coupled element. More...
 

Public Member Functions

const std::vector< CoupledElement > & getCoupledElements ()
 get coupled element More...
 
const std::vector< CoupledParticle > & getCoupledParticles ()
 get coupled particle More...
 
void setPenalty (double penalty)
 Sets penalty parameter. More...
 
void setCouplingWeight (const std::function< double(double x, double y, double z)> &couplingWeight)
 Sets weight function (determines which nodes/el_pts are in coupling zone) More...
 
void solveScaleCoupling ()
 Computes nStep, the ratio of FEM and DEM time steps, then calls solveSurfaceCoupling(nStep) More...
 
- Public Member Functions inherited from BaseCoupling< M, O >
 BaseCoupling ()=default
 
void setName (std::string name)
 
std::string getName () const
 
void removeOldFiles () const
 
void writeEneTimeStep (std::ostream &os) const override
 
void writeEneHeader (std::ostream &os) const override
 
void solveOomph ()
 
void solveMercury (unsigned long nt)
 
void setCGWidth (const double &width)
 
double getCGWidth ()
 
bool useCGMapping ()
 
CGFunctions::LucyXYZ getCGFunction ()
 

Private Types

typedef O::ELEMENT ELEMENT
 type of el_pt in O (e.g. RefineableQDPVDElement<3, 2>) More...
 

Private Member Functions

void solveScaleCoupling (unsigned nStep)
 Solve scale-coupled problem. More...
 
void initialiseCoupledElements ()
 initialises the coupledElements vector More...
 
void computeOneTimeStepScaleCoupling (unsigned nStep)
 What to do in each time step. More...
 
void updateCoupledElements ()
 Updates the coupledElements and coupledParticles vectors: finds which particles interact with which element. More...
 
Vector< Vector< double > > computeProjectionMatrix (const CoupledElement &coupledElement)
 Computes projectionMatrix. More...
 
void computeCouplingForce ()
 Computes coupling force for each element and particle. More...
 
void computeNodalCouplingForces (const CoupledElement &coupledElement, const Vector< Vector< double >> &projectionMatrix)
 Computes coupling force for each node. More...
 
void computeExternalForces (BaseParticle *p) override
 Applies coupling force to MercuryDPM in each time step. More...
 

Private Attributes

std::function< double(double x, double y, double z)> couplingWeight_
 
std::vector< CoupledElementcoupledElements_
 Vector of all coupled elements. More...
 
std::vector< CoupledParticlecoupledParticles_
 The i-th element of this vector describes the coupling properties of the i-th DPM particle. More...
 
double penalty_ = constants::NaN
 Penalty parameter, i.e., proportionality constant between velocity difference and coupling force. More...
 

Member Typedef Documentation

◆ ELEMENT

template<class M , class O >
typedef O::ELEMENT ScaleCoupling< M, O >::ELEMENT
private

type of el_pt in O (e.g. RefineableQDPVDElement<3, 2>)

Member Function Documentation

◆ computeCouplingForce()

template<class M , class O >
void ScaleCoupling< M, O >::computeCouplingForce ( )
inlineprivate

Computes coupling force for each element and particle.

317  {
318  // first loop over the coupled bulk el_pts
319  for (const auto& coupledElement : coupledElements_)
320  {
321  // construct projection matrix, defined as projectionMatrix_{n,p} = N_{n,p}*V_p / sum_p(N_{n,p}*V_p)
322  // (shape function N, volume V, node n, particle p)
323  Vector<Vector<double>> projectionMatrix = computeProjectionMatrix(coupledElement);
324  // get pointer to the bulk el_pt
325  ELEMENT* el_pt = coupledElement.el_pt;
326  const unsigned nParticles = coupledElement.coupledParticles.size();
327  // get number of nodes in the bulk el_pt
328  const unsigned nnode = coupledElement.el_pt->nnode();
329  // prepare vector of nodal velocities projected from particle centers
330  const unsigned dim = el_pt->dim();
331  // get coupling force at nodal positions, based on penalizing the difference in velocity
332  computeNodalCouplingForces(coupledElement, projectionMatrix);
333  // project coupling forces from nodes to particles (note projectionMatrix^{-1} = projectionMatrix^T)
334  for (unsigned p=0; p < nParticles; p++) {
335  BaseParticle* particle = coupledElement.coupledParticles[p];
336  CoupledParticle& coupledParticle = coupledParticles_[particle->getIndex()];
337  for (unsigned d=0; d < dim; d++) {
338  double forceComponent = 0;
339  for (unsigned n=0; n < nnode; n++) {
340  // note projectionMatrix^{-1} = projectionMatrix^T
341  forceComponent += projectionMatrix[n][p] * el_pt->get_coupling_residual(n, d);
342  }
343  coupledParticle.couplingForce.setComponent(d,forceComponent);
344  }
345  logger(VERBOSE,"Coupling force % on particle %", coupledParticle.couplingForce,p);
346  }
347  }
348  }
const unsigned n
Definition: CG3DPackingUnitTest.cpp:32
Logger< MERCURYDPM_LOGLEVEL > logger("MercuryKernel")
Definition of different loggers with certain modules. A user can define its own custom logger here.
@ VERBOSE
unsigned int getIndex() const
Returns the index of the object in the handler.
Definition: BaseObject.h:118
Definition: BaseParticle.h:54
std::vector< CoupledElement > coupledElements_
Vector of all coupled elements.
Definition: ScaleCoupling.h:59
std::vector< CoupledParticle > coupledParticles_
The i-th element of this vector describes the coupling properties of the i-th DPM particle.
Definition: ScaleCoupling.h:97
void computeNodalCouplingForces(const CoupledElement &coupledElement, const Vector< Vector< double >> &projectionMatrix)
Computes coupling force for each node.
Definition: ScaleCoupling.h:351
Vector< Vector< double > > computeProjectionMatrix(const CoupledElement &coupledElement)
Computes projectionMatrix.
Definition: ScaleCoupling.h:275

References ScaleCoupling< M, O >::CoupledParticle::couplingForce, BaseObject::getIndex(), logger, n, Vec3D::setComponent(), and VERBOSE.

◆ computeExternalForces()

template<class M , class O >
void ScaleCoupling< M, O >::computeExternalForces ( BaseParticle p)
inlineoverrideprivate

Applies coupling force to MercuryDPM in each time step.

420  {
421  if (!p->isFixed())
422  {
423  // Applying the force due to gravity (F = m.g)
424  p->addForce(M::getGravity() * p->getMass());
425  // add particle coupling force 1/w_i*f_i^c to the total force
426  const CoupledParticle& cp = coupledParticles_[p->getIndex()];
427  double couplingWeight = couplingWeight_(p->getPosition().X,p->getPosition().Y,p->getPosition().Z);
428  p->addForce(cp.couplingForce / couplingWeight);
429  }
430  }
const Vec3D & getPosition() const
Returns the position of this BaseInteractable.
Definition: BaseInteractable.h:218
void addForce(const Vec3D &addForce)
Adds an amount to the force on this BaseInteractable.
Definition: BaseInteractable.cc:116
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:93
Mdouble getMass() const
Returns the particle's mass.
Definition: BaseParticle.h:322
std::function< double(double x, double y, double z)> couplingWeight_
Definition: ScaleCoupling.h:48
Mdouble Y
Definition: Vector.h:66
Mdouble Z
Definition: Vector.h:66
Mdouble X
the vector components
Definition: Vector.h:66

References BaseInteractable::addForce(), ScaleCoupling< M, O >::CoupledParticle::couplingForce, BaseObject::getIndex(), BaseParticle::getMass(), BaseInteractable::getPosition(), BaseParticle::isFixed(), Vec3D::X, Vec3D::Y, and Vec3D::Z.

◆ computeNodalCouplingForces()

template<class M , class O >
void ScaleCoupling< M, O >::computeNodalCouplingForces ( const CoupledElement coupledElement,
const Vector< Vector< double >> &  projectionMatrix 
)
inlineprivate

Computes coupling force for each node.

1) compute velocity difference at nodal positions

2) compute nodal coupling force, penalizing the difference in velocity

3) assign it to the coupled bulk element to be used by ELEMENT::fill_in_contribution_to_residuals(...)

352  {
353  // return if no particle in cell
354  if (coupledElement.coupledParticles.empty()) return;
355 
356  // a few shortcut variables
357  const ELEMENT* el_pt = coupledElement.el_pt;
358  const unsigned nnode = el_pt->nnode();
359  const unsigned dim = el_pt->dim();
360  const unsigned nParticles = coupledElement.coupledParticles.size();
361 
363  Vector<Vector<double>> nodalVelocityDifference(nnode,Vector<double>(dim,0.0));
364  // get projected nodal velocity field from particle velocities
365  for (unsigned n=0; n < nnode; n++) {
366  for (unsigned d=0; d < dim; d++) {
367  double nodalVelocityDPM = 0;
368  for (unsigned p=0; p < nParticles; p++) {
369  nodalVelocityDPM += projectionMatrix[n][p] * coupledElement.coupledParticles[p]->getVelocity().getComponent(d);
370  }
371  double nodalVelocityFEM = el_pt->dnodal_position_gen_dt(n,0,d);
372  nodalVelocityDifference[n][d] = nodalVelocityDPM-nodalVelocityFEM;
373  }
374  }
375 
377  Vector<Vector<double> > nodalCouplingForces(nnode, Vector<double>(dim, 0.0));
378 
379  // Set up memory for the shape functions
380  Shape psi(nnode);
381  DShape dpsidxi(nnode,dim);
382  const unsigned n_in = el_pt->integral_pt()->nweight();
383  // Loop over the integration points
384  for (unsigned in=0; in<n_in; in++)
385  {
386  // Get the integral weight
387  double w = el_pt->integral_pt()->weight(in);
388  // Call the derivatives of the shape functions (and get Jacobian)
389  double J = el_pt->dshape_lagrangian_at_knot(in,psi,dpsidxi);
390  // Loop over the test functions, nodes of the element
391  for (unsigned n=0; n < nnode; n++)
392  {
393  // Loop over the nodes of the element again
394  for (unsigned nn=0; nn < nnode; nn++)
395  {
396  double volume = penalty_ * psi(nn) * psi(n) * w * J;
397 
398  for (unsigned d=0; d < dim; d++)
399  {
400  //nodalVelocityDifference[n][d] = 1/penalty_/time_pt()->dt(0);
401  double displacement = nodalVelocityDifference[n][d] * O::time_pt()->dt(0);
402  nodalCouplingForces[n][d] -= volume * displacement;
403  //logger(INFO, "w % J % psi % % displacement % nodalCouplingForces % dt %", w, J, psi(nn), psi(n), displacement, nodalCouplingForces[n][d], time_pt()->dt(0));
404  }
405  }
406  }
407  }
408 
410  coupledElement.el_pt->set_coupling_residual(nodalCouplingForces);
411 
412  logger(VERBOSE,"VelocityDifference % % %, coupling force % % % on element %, node 0, particles %",
413  nodalVelocityDifference[0][0], nodalVelocityDifference[0][1], nodalVelocityDifference[0][2],
414  nodalCouplingForces[0][0], nodalCouplingForces[0][1], nodalCouplingForces[0][2],
415  el_pt, coupledElement.coupledParticles.size());
416  }
double penalty_
Penalty parameter, i.e., proportionality constant between velocity difference and coupling force.
Definition: ScaleCoupling.h:100

References ScaleCoupling< M, O >::CoupledElement::coupledParticles, ScaleCoupling< M, O >::CoupledElement::el_pt, logger, n, and VERBOSE.

◆ computeOneTimeStepScaleCoupling()

template<class M , class O >
void ScaleCoupling< M, O >::computeOneTimeStepScaleCoupling ( unsigned  nStep)
inlineprivate

What to do in each time step.

204  {
207  this->solveOomph();
208  this->solveMercury(nStep);
209  };
void solveOomph()
Definition: BaseCoupling.h:141
void solveMercury(unsigned long nt)
Definition: BaseCoupling.h:150
void computeCouplingForce()
Computes coupling force for each element and particle.
Definition: ScaleCoupling.h:316
void updateCoupledElements()
Updates the coupledElements and coupledParticles vectors: finds which particles interact with which e...
Definition: ScaleCoupling.h:212

◆ computeProjectionMatrix()

template<class M , class O >
Vector<Vector<double> > ScaleCoupling< M, O >::computeProjectionMatrix ( const CoupledElement coupledElement)
inlineprivate

Computes projectionMatrix.

Construct mapping with FEM basis functions

276  {
277  Vector<Vector<double>> projectionMatrix;
278  // get constants
279  const unsigned nParticles = coupledElement.coupledParticles.size();
280  const unsigned nnode = coupledElement.el_pt->nnode();
281  const unsigned dim = coupledElement.el_pt->dim();
282 
283  // prepare projection matrix
284  projectionMatrix.resize(nnode,Vector<double>(nParticles,0.0));
285 
287  // storage for position s and shape psi
288  Vector<double> pos(dim,0.0);
289  Shape psi(nnode);
290  // loop over shape functions at the nodes
291  // loop over shape functions at the particles
292  for (unsigned p = 0; p < nParticles; p++) {
293  BaseParticle* particle = coupledElement.coupledParticles[p];
294  // get the shape function evaluated at the center of particle p
295  coupledElement.el_pt->shape(coupledParticles_[particle->getIndex()].s, psi);
296  for (unsigned n=0; n < nnode; n++) {
297  projectionMatrix[n][p] = psi(n) * particle->getVolume();
298  }
299  }
300  // normalize each row of the projection matrix to sum to one
301  for (unsigned n=0; n < nnode; n++) {
302  double sum = 0;
303  for (unsigned p = 0; p<nParticles; p++) {
304  sum += projectionMatrix[n][p];
305  }
306  if (sum != 0) {
307  for (unsigned p = 0; p < nParticles; p++) {
308  projectionMatrix[n][p] /= sum;
309  }
310  }
311  }
312  return projectionMatrix;
313  }
virtual Mdouble getVolume() const
Get Particle volume function, which required a reference to the Species vector. It returns the volume...
Definition: BaseParticle.cc:143

References ScaleCoupling< M, O >::CoupledElement::coupledParticles, ScaleCoupling< M, O >::CoupledElement::el_pt, BaseObject::getIndex(), BaseParticle::getVolume(), and n.

◆ getCoupledElements()

template<class M , class O >
const std::vector<CoupledElement>& ScaleCoupling< M, O >::getCoupledElements ( )
inline

get coupled element

Todo:
check if set
105  {
106  return coupledElements_;
107  }

◆ getCoupledParticles()

template<class M , class O >
const std::vector<CoupledParticle>& ScaleCoupling< M, O >::getCoupledParticles ( )
inline

get coupled particle

110  {
111  return coupledParticles_;
112  }

Referenced by ScaleCoupledBeam::actionsAfterSolve().

◆ initialiseCoupledElements()

template<class M , class O >
void ScaleCoupling< M, O >::initialiseCoupledElements ( )
inlineprivate

initialises the coupledElements vector

178  {
179  // loop through all el_pts, check if any nodes have a fractional coupling weight.
180  // If yes, add the el_pt to the coupledElements_
181  auto nelement = O::mesh_pt()->nelement();
182  for (int e=0; e < nelement; ++e) {
183  bool coupledElement = false;
184  auto* el_pt = dynamic_cast<ELEMENT*>(O::mesh_pt()->finite_element_pt(e));
185  auto nnode = el_pt->nnode();
186  Vector<double> nodalCouplingWeights(nnode);
187  for (int n=0; n < nnode; ++n) {
188  auto* n_pt = dynamic_cast<SolidNode*>(el_pt->node_pt(n));
189  nodalCouplingWeights[n] = couplingWeight_(n_pt->xi(0), n_pt->xi(1), n_pt->xi(2));
190  if (nodalCouplingWeights[n]>0) { // check for nodalCouplingWeights[n]<1 ?
191  coupledElement = true;
192  logger(VERBOSE,"Coupled element at % % %, weight %",n_pt->xi(0), n_pt->xi(1), n_pt->xi(2), nodalCouplingWeights[n]);
193  }
194  }
195  if (coupledElement) {
196  coupledElements_.push_back({el_pt});
197  el_pt->set_coupling_weight(nodalCouplingWeights);
198  }
199  }
200  logger(INFO,"% of % el_pts are coupled", coupledElements_.size(), nelement);
201  }
@ INFO

References INFO, logger, n, and VERBOSE.

◆ setCouplingWeight()

template<class M , class O >
void ScaleCoupling< M, O >::setCouplingWeight ( const std::function< double(double x, double y, double z)> &  couplingWeight)
inline

Sets weight function (determines which nodes/el_pts are in coupling zone)

120  {
121  couplingWeight_ = couplingWeight;
122  }

Referenced by ScaleCoupledBeam::ScaleCoupledBeam().

◆ setPenalty()

template<class M , class O >
void ScaleCoupling< M, O >::setPenalty ( double  penalty)
inline

Sets penalty parameter.

115  {
116  penalty_ = penalty;
117  }

Referenced by ScaleCoupledBeam::ScaleCoupledBeam().

◆ solveScaleCoupling() [1/2]

template<class M , class O >
void ScaleCoupling< M, O >::solveScaleCoupling ( )
inline

Computes nStep, the ratio of FEM and DEM time steps, then calls solveSurfaceCoupling(nStep)

126  {
127  // compute nStep
128  unsigned nStep = O::getOomphTimeStep()/M::getTimeStep();
129  if (nStep==0) {
130  // if oomph has a smaller time step than Mercury
131  logger(INFO, "Set nStep %, change mercuryTimeStep from % to %",
132  nStep, M::getTimeStep(), O::getOomphTimeStep());
133  nStep = 1;
134  M::setTimeStep(O::getOomphTimeStep());
135  } else {
136  logger(INFO, "Set nStep %, change oomphTimeStep from % to %",
137  nStep, O::getOomphTimeStep(), nStep * M::getTimeStep());
138  O::setOomphTimeStep(nStep * M::getTimeStep());
139  }
140  // call solve routine
141  solveScaleCoupling(nStep);
142  }
void solveScaleCoupling()
Computes nStep, the ratio of FEM and DEM time steps, then calls solveSurfaceCoupling(nStep)
Definition: ScaleCoupling.h:125

References INFO, and logger.

Referenced by ScaleCoupledBeam::ScaleCoupledBeam().

◆ solveScaleCoupling() [2/2]

template<class M , class O >
void ScaleCoupling< M, O >::solveScaleCoupling ( unsigned  nStep)
inlineprivate

Solve scale-coupled problem.

148  {
149  // Check main parameters are set
150  logger.assert_always(O::getOomphTimeStep()>0, "Oomph time step not initialised");
151  logger.assert_always(M::getTimeStep()>0, "Mercury time step not initialised");
152  logger.assert_always(std::isfinite(penalty_), "Penalty parameter not set");
153  logger.assert_always((bool)couplingWeight_, "Coupling weight is not set");
154 
155  // Initialise the coupled element vector
157 
158  // This is the main loop advancing over time
159  unsigned nDone = 0; //< last written file number
160  while (M::getTime() < M::getTimeMax())
161  {
162  O::actionsBeforeOomphTimeStep();
163  // solve the coupled problem for one time step
165  // write outputs of the oomphProb; this is slaved to the vtk output of Mercury, i.e. an oomph-lib output get written everytime a Mercury vtk file gets written
166  if (M::getParticlesWriteVTK() && M::getVtkWriter()->getFileCounter() > nDone)
167  {
168  O::writeToVTK();
169  nDone = M::getVtkWriter()->getFileCounter();
170  }
171  }
172 
173  // Write final output files
174  M::finaliseSolve();
175  }
void computeOneTimeStepScaleCoupling(unsigned nStep)
What to do in each time step.
Definition: ScaleCoupling.h:204
void initialiseCoupledElements()
initialises the coupledElements vector
Definition: ScaleCoupling.h:178

References logger.

◆ updateCoupledElements()

template<class M , class O >
void ScaleCoupling< M, O >::updateCoupledElements ( )
inlineprivate

Updates the coupledElements and coupledParticles vectors: finds which particles interact with which element.

1) Find min and max of coupled region

2) update the coupledParticles vector, and the particles vector of each coupledElement

213  {
215  Vector<double> min {constants::inf, constants::inf, constants::inf};
216  Vector<double> max {-constants::inf, -constants::inf, -constants::inf};
217  // loop over all coupled elements
218  for (auto& coupledElement : coupledElements_)
219  {
220  ELEMENT* el_pt = coupledElement.el_pt;
221  const unsigned nnode = el_pt->nnode();
222  const unsigned dim = el_pt->dim(); // /todo I need to use el_pt->ndim=3, not el_pt->ndim=0, why?
223  // Find min and max
224  for (int n=0; n<nnode; ++n) {
225  auto* n_pt = dynamic_cast<SolidNode *>(el_pt->node_pt(n));
226  for (int d = 0; d < dim; ++d) {
227  min[d] = std::min(min[d], n_pt->x(d));
228  max[d] = std::max(max[d], n_pt->x(d));
229  }
230  }
231  }
232  logger(VERBOSE,"Coupling zone: % < x < %, % < y < %, % < z < % ",min[0],max[0],min[1],max[1],min[2],max[2]);
233 
235  // resize the coupledParticles vector
236  coupledParticles_.resize(M::particleHandler.getSize());
237  // now set the coupledElement pointer for each coupledParticles, and the particles vector for each coupledElement
238  for (int p=0; p<coupledParticles_.size(); ++p) {
239  CoupledParticle& coupledParticle = coupledParticles_[p];
240  Vec3D pos = M::particleHandler.getObject(p)->getPosition();
241  // this is the pointer we need to set
242  if (pos.X>=min[0] && pos.X<=max[0] && pos.Y>=min[1] && pos.Y<=max[1] && pos.Z>=min[2] && pos.Z<=max[2]) {
243  logger(VERBOSE,"Particle % of % is in coupling zone",p, M::particleHandler.getSize());
244  // if near the coupling zone
245  Vector<double> x {pos.X, pos.Y, pos.Z};
246  Vector<double>& s = coupledParticle.s;
247  GeomObject* geom_obj_pt;
248  // if el_pt is already set and still valid, keep
249  if (coupledParticle.coupledElement_pt != nullptr) {
250  coupledParticle.coupledElement_pt->el_pt->locate_zeta(x, geom_obj_pt, s);
251  if (geom_obj_pt!=nullptr) {
252  logger(VERBOSE,"Particle % remains coupled with element %",p, coupledParticle.coupledElement_pt->el_pt);
253  continue;
254  }
255  }
256  // otherwise, search for the right element
257  for (auto& coupledElement : coupledElements_) {
258  coupledElement.el_pt->locate_zeta(x,geom_obj_pt,s);
259  if (geom_obj_pt!=nullptr) {
260  logger(VERBOSE,"Coupled particle % to element % at % % %",p, &coupledElement, s[0], s[1], s[2]);
261  //\todo If a containing element is found, we stop; note though, particles on the boundary could belong to multiple elements; also not clear to me whether force should be applied to global basis function or local
262  coupledParticle.setCoupledElement(&coupledElement, M::particleHandler.getObject(p));
263  break;
264  }
265  }
266  } else {
267  // if away from the coupling, set coupledElement to null
268  if (coupledParticle.coupledElement_pt) logger(VERBOSE, "Removed particle % from element %", p, coupledParticle.coupledElement_pt);
269  coupledParticle.removeCoupledElement(M::particleHandler.getObject(p));
270  }
271  }
272  }
Definition: Vector.h:51
const Mdouble inf
Definition: GeneralDefine.h:44

References ScaleCoupling< M, O >::CoupledParticle::coupledElement_pt, ScaleCoupling< M, O >::CoupledElement::el_pt, constants::inf, logger, n, ScaleCoupling< M, O >::CoupledParticle::removeCoupledElement(), ScaleCoupling< M, O >::CoupledParticle::s, ScaleCoupling< M, O >::CoupledParticle::setCoupledElement(), VERBOSE, Vec3D::X, Vec3D::Y, and Vec3D::Z.

Member Data Documentation

◆ coupledElements_

template<class M , class O >
std::vector<CoupledElement> ScaleCoupling< M, O >::coupledElements_
private

Vector of all coupled elements.

◆ coupledParticles_

template<class M , class O >
std::vector<CoupledParticle> ScaleCoupling< M, O >::coupledParticles_
private

The i-th element of this vector describes the coupling properties of the i-th DPM particle.

◆ couplingWeight_

template<class M , class O >
std::function<double(double x,double y,double z)> ScaleCoupling< M, O >::couplingWeight_
private

coupling weight: 0: pure FEM, 1: pure DEM, (0,1): overlap region

◆ penalty_

template<class M , class O >
double ScaleCoupling< M, O >::penalty_ = constants::NaN
private

Penalty parameter, i.e., proportionality constant between velocity difference and coupling force.


The documentation for this class was generated from the following file: