PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
pairForce.cpp
Go to the documentation of this file.
1/*
2 * -------------------------------------------
3 * Copyright (c) 2021 - 2026 Prashant K. Jha
4 * -------------------------------------------
5 * PeriDEM https://github.com/prashjha/PeriDEM
6 *
7 * Distributed under the Boost Software License, Version 1.0. (See accompanying
8 * file LICENSE)
9 */
10
11#include "pairForce.h"
12
13#include "util/io.h"
14#include "inp/contactPairDeck.h"
15#include "util/function.h"
16
17#include <cmath>
18
19double contact::correctedContactVolume(double volj, double Rji, double Rc,
20 double h) {
21 if (!(volj > 0.) || !(Rc > 0.) || !(h > 0.) || !(Rji > 0.))
22 return volj;
23
24 const double check_up = Rc + 0.5 * h;
25 const double check_low = Rc - 0.5 * h;
26 if (util::isGreater(Rji, check_low)) {
27 volj *= (check_up - Rji) / h;
28 if (volj < 0.)
29 volj = 0.;
30 }
31 return volj;
32}
33
35 const auto yji = p.yj - p.yi;
36 const auto Rji = yji.length();
37 if (!(Rji > 0.) || !util::isLess(Rji, p.deck.d_contactR))
38 return {};
39
40 const auto vji = p.vj - p.vi;
41 auto en = yji / Rji;
42 auto vn_mag = vji * en;
43 auto et = vji - vn_mag * en;
44 if (util::isGreater(et.length(), 0.))
45 et = et / et.length();
46 else
47 et = util::Point();
48
49 auto scalar_f = p.deck.d_Kn * (Rji - p.deck.d_contactR) * p.volj;
50 if (scalar_f > 0.)
51 scalar_f = 0.;
52
53 util::Point f = scalar_f * en;
54 if (p.deck.d_frictionOn)
55 f += p.deck.d_mu * scalar_f * et;
56 return f;
57}
58
60 const auto yji = p.yj - p.yi;
61 const auto Rji = yji.length();
62 if (!(Rji > 0.) || !util::isLess(Rji, p.deck.d_contactR))
63 return {};
64
65 if (!p.deck.d_dampingOn || !(p.voli > 0.) || !(p.deck.d_K > 0.) ||
66 !(p.deck.d_contactR > 0.))
67 return {};
68
69 const auto vji = p.vj - p.vi;
70 auto en = yji / Rji;
71 auto vn_mag = vji * en;
72 if (!util::isLess(vn_mag, 0.))
73 return {};
74
75 const double meq =
77 const double beta_n =
78 p.deck.d_betan * std::sqrt(p.deck.d_K * p.deck.d_contactR * meq);
79 return (beta_n * vn_mag / p.voli) * en;
80}
81
83 return springForce(p) + nodeDampingForce(p);
84}
85
87
89 std::lock_guard<std::mutex> lock(d_mutex);
90 for (auto it = d_hist.begin(); it != d_hist.end();) {
91 if (it->second.stamp != d_stamp)
92 it = d_hist.erase(it);
93 else
94 ++it;
95 }
96}
97
99 const auto yji = p.yj - p.yi;
100 const auto Rji = yji.length();
101 if (!(Rji > 0.) || !util::isLess(Rji, p.deck.d_contactR))
102 return {};
103
104 auto en = yji / Rji;
105 auto scalar_f = p.deck.d_Kn * (Rji - p.deck.d_contactR) * p.volj;
106 if (scalar_f > 0.)
107 scalar_f = 0.;
108
109 util::Point f = scalar_f * en;
110 if (!p.deck.d_frictionOn)
111 return f;
112
113 const double fn_mag = -scalar_f; // scalar_f <= 0 in contact
114 if (!(fn_mag > 0.) || !(p.dt > 0.))
115 return f;
116
117 const auto vji = p.vj - p.vi;
118 auto vt = vji - (vji * en) * en;
119
120 util::Point ft_trial;
121 {
122 std::lock_guard<std::mutex> lock(d_mutex);
123 auto &hist = d_hist[key(p.i, p.j)];
124 hist.stamp = d_stamp;
125 hist.delta_t += vt * p.dt;
126 // Keep tangential history in the current tangent plane.
127 hist.delta_t -= (hist.delta_t * en) * en;
128
129 // Tangential stiffness taken equal to normal Kn (density form × volj).
130 const double Kt = p.deck.d_Kn;
131 const double kt_vol = Kt * p.volj;
132 ft_trial = hist.delta_t * (-kt_vol);
133 const double ft_mag = ft_trial.length();
134 const double ft_max = p.deck.d_mu * fn_mag;
135
136 if (util::isGreater(ft_mag, ft_max) && ft_mag > 0.) {
137 ft_trial *= (ft_max / ft_mag);
138 if (kt_vol > 0.)
139 hist.delta_t = ft_trial * (-1.0 / kt_vol);
140 }
141 }
142
143 f += ft_trial;
144 return f;
145}
virtual util::Point force(const Pair &p)
Definition pairForce.cpp:82
virtual util::Point springForce(const Pair &p)
Definition pairForce.cpp:34
virtual util::Point nodeDampingForce(const Pair &p)
Definition pairForce.cpp:59
util::Point springForce(const Pair &p) override
Definition pairForce.cpp:98
void beginStep() override
Definition pairForce.cpp:86
double correctedContactVolume(double volj, double Rji, double Rc, double h)
Definition pairForce.cpp:19
bool isGreater(const double &a, const double &b)
Returns true if a > b.
Definition function.cpp:15
double equivalentMass(const double &m1, const double &m2)
Compute harmonic mean of m1 and m2.
Definition function.cpp:127
bool isLess(const double &a, const double &b)
Returns true if a < b.
Definition function.cpp:20
One node-node contact pair. Assembly fills this; the law uses it.
Definition pairForce.h:27
double rhoj
Definition pairForce.h:37
double rhoi
Definition pairForce.h:36
util::Point yi
Definition pairForce.h:29
std::size_t i
Definition pairForce.h:30
util::Point vj
Definition pairForce.h:29
std::size_t j
Definition pairForce.h:31
util::Point vi
Definition pairForce.h:29
util::Point yj
Definition pairForce.h:29
const inp::ContactPairDeck & deck
Definition pairForce.h:28
double voli
Definition pairForce.h:34
double volj
Definition pairForce.h:35
double d_contactR
contact radius
bool d_frictionOn
parameters for frictional force
double d_betan
parameters for normal damping force
double d_Kn
parameters for normal force
double d_mu
parameters for frictional force
double d_K
parameters for frictional force
bool d_dampingOn
parameters for normal damping force
A structure to represent 3d vectors.
Definition point.h:30
double length() const
Computes the Euclidean length of the vector.
Definition point.h:124