PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
selfContact.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 "selfContact.h"
12
13#include <stdexcept>
14
15namespace {
16
17util::Point cappedRepulsive(const util::Point &yji, double volj, double Kn,
18 double natural_R) {
19 const double Rji = yji.length();
20 if (!(Rji > 0.) || !(natural_R > 0.))
21 return util::Point();
22
23 double gap = Rji - natural_R;
24 if (gap > 0.)
25 gap = 0.;
26 else {
27 // Cap penetration so a bond that breaks while already deep inside
28 // natural_R cannot inject a discontinuous Kn*(R-natural_R) kick.
29 const double gap_cap = -0.25 * natural_R;
30 if (gap < gap_cap)
31 gap = gap_cap;
32 }
33
34 const double scalar_f = Kn * volj * gap / Rji;
35 return scalar_f * yji;
36}
37
38} // namespace
39
40namespace pd {
41
43 double Kn, double Rc,
44 double /*r0*/) const {
45 return cappedRepulsive(yji, volj, Kn, Rc);
46}
47
49 double Kn, double Rc,
50 double r0) const {
51 // Short-range only: act when current separation < Rc. Natural length is the
52 // unbroken reference distance r0 when available (often r0 > Rc for Mode-I
53 // crack-crossing bonds); otherwise Rc. Using min(r0, Rc) collapsed to Rc
54 // whenever r0 > Rc and made this law identical to broken_bond_kn.
55 const double Rji = yji.length();
56 if (!(Rji > 0.) || !(Rc > 0.) || !(Rji < Rc))
57 return util::Point();
58 const double natural = (r0 > 0.) ? r0 : Rc;
59 return cappedRepulsive(yji, volj, Kn, natural);
60}
61
62util::Point NoneSelfContact::force(const util::Point & /*yji*/, double /*volj*/,
63 double /*Kn*/, double /*Rc*/,
64 double /*r0*/) const {
65 return util::Point();
66}
67
68std::unique_ptr<SelfContact> makeSelfContact(const std::string &name) {
69 if (name == "broken_bond_kn")
70 return std::make_unique<BrokenBondKnSelfContact>();
71 if (name == "reference_gap")
72 return std::make_unique<ReferenceGapSelfContact>();
73 if (name == "none")
74 return std::make_unique<NoneSelfContact>();
75
76 throw std::runtime_error(
77 "Unknown Model.Self_Contact '" + name +
78 "'. Supported: broken_bond_kn, reference_gap, none.");
79}
80
81} // namespace pd
util::Point force(const util::Point &yji, double volj, double Kn, double Rc, double r0) const override
util::Point force(const util::Point &yji, double volj, double Kn, double Rc, double r0) const override
util::Point force(const util::Point &yji, double volj, double Kn, double Rc, double r0) const override
util::Point cappedRepulsive(const util::Point &yji, double volj, double Kn, double natural_R)
Definition pdForce.h:18
std::unique_ptr< SelfContact > makeSelfContact(const std::string &name)
Build self-contact law named by Model.Self_Contact.
A structure to represent 3d vectors.
Definition point.h:30
double length() const
Computes the Euclidean length of the vector.
Definition point.h:124