PeriDEM 0.3.0
PeriDEM -- Peridynamics-based high-fidelity model for granular media
Loading...
Searching...
No Matches
contactPairDeck.h
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#ifndef INP_CONTACTPAIRDECK_H
12#define INP_CONTACTPAIRDECK_H
13
14
15#include "deckField.h"
16#include "util/io.h"
17#include "util/json.h"
18
19namespace inp {
28
30 double d_contactR;
31
34
36
37 double d_vMax;
38 double d_deltaMax;
39 double d_Kn;
40 double d_KnFactor;
42
44
45 double d_eps;
46 double d_betan;
50
52
53 double d_mu;
55 double d_K;
57
61 ContactPairDeck(const json &j = json({}))
62 : d_contactR(0.), d_computeContactR(true), d_vMax(0.), d_deltaMax(0.),
63 d_Kn(0.), d_eps(1.), d_betan(0.), d_mu(0.), d_dampingOn(true),
64 d_frictionOn(true), d_KnFactor(1.), d_betanFactor(1.), d_K(0.) {
65 readFromJson(j);
66 };
67
71 ContactPairDeck(double contactR, bool computeContactR = true,
72 bool dampingOn = true, bool frictionOn = true,
73 double Kn = 0., double eps = 1., double mu = 0.,
74 double KnFactor = 1., double betanFactor = 1.,
75 double deltaMax = 1., double vMax = 0.)
76 : d_contactR(contactR), d_computeContactR(computeContactR), d_vMax(vMax), d_deltaMax(deltaMax),
77 d_Kn(Kn), d_eps(eps), d_betan(0.), d_mu(mu), d_dampingOn(dampingOn),
78 d_frictionOn(frictionOn), d_KnFactor(KnFactor), d_betanFactor(betanFactor), d_K(0.) {
79 };
80
94
104 static const std::vector<Field<ContactPairDeck>> &fields() {
105 static const std::vector<Field<ContactPairDeck>> f = {
106 field(&ContactPairDeck::d_KnFactor, "Kn_Factor", 1.,
107 "Normal stiffness is scaled by this"),
108 field(&ContactPairDeck::d_dampingOn, "Damping_On", true,
109 "Apply the normal damping force"),
110 field(&ContactPairDeck::d_eps, "Epsilon", 1.,
111 "Coefficient of restitution", {{}, 0., 1.}),
112 field(&ContactPairDeck::d_betanFactor, "Beta_n_Factor", 1.,
113 "Damping coefficient is scaled by this"),
114 field(&ContactPairDeck::d_frictionOn, "Friction_On", true,
115 "Apply the tangential friction force"),
116 field(&ContactPairDeck::d_mu, "Friction_Coeff", 0.,
117 "Coefficient of friction"),
118 // Left out when it is not set, because a pair without friction
119 // does not use it.
120 field<ContactPairDeck, double>(
121 &ContactPairDeck::d_K, "K", 0.,
122 "Bulk modulus the tangential force is built from", {},
123 [](const double &v) { return v > 1.E-10; }),
124 };
125 return f;
126 }
127
132 static const std::vector<OneOf> &groups() {
133 static const std::vector<OneOf> g = {
134 {"the contact radius",
135 {"Contact_Radius", "Contact_Radius_Factor"}},
136 {"the contact stiffness", {"Kn", "V_Max"}},
137 };
138 return g;
139 }
140
158 static json getExampleJson(const json &given = json::object()) {
159 const std::vector<std::string> extra = {"Contact_Radius",
160 "Contact_Radius_Factor", "Kn",
161 "V_Max", "Delta_Max"};
162 checkKeys(given, fields(), extra);
163
164 json g = given;
165
166 // Damping with no coefficient is no damping.
167 bool dampingOn = g.value("Damping_On", true);
168 double betanFactor = g.value("Beta_n_Factor", 1.);
169 if (dampingOn and betanFactor < 1.E-10)
170 dampingOn = false;
171 if (!dampingOn)
172 betanFactor = 0.;
173 g["Damping_On"] = dampingOn;
174 g["Beta_n_Factor"] = betanFactor;
175
176 if (g.value("Friction_On", true) and
177 g.value("Friction_Coeff", 0.) < 1.E-10)
178 throw std::runtime_error("Friction coefficient can not be zero.");
179
180 if (g.find("Contact_Radius_Factor") != g.end() and
181 g.at("Contact_Radius_Factor").get<double>() < 1.E-10)
182 throw std::runtime_error("Contact radius factor can not be zero.");
183
184 if (g.find("Kn") != g.end() and g.at("Kn").get<double>() < 1.E-10)
185 throw std::runtime_error(
186 "Kn can not be zero. Give V_Max instead to derive it.");
187
188 // The speed is what the stiffness is derived from, so the overlap it
189 // is measured against goes with it.
190 if (g.find("V_Max") != g.end()) {
191 if (g.at("V_Max").get<double>() < 1.E-10)
192 throw std::runtime_error(
193 "Need V_Max parameter for contact force.");
194 if (g.find("Delta_Max") == g.end() or
195 g.at("Delta_Max").get<double>() < 1.E-10)
196 g["Delta_Max"] = 1.;
197 }
198
199 json j = applyGiven(g, fields(), extra);
200 checkGroups(j, groups());
201 return j;
202 }
203
207 void readFromJson(const json &j) {
208
209 if (j.empty())
210 return;
211
212 checkGroups(j, groups());
213 readFields(*this, j, fields());
214
215 // A factor is applied to the mesh size, an absolute radius is not.
216 d_computeContactR = j.find("Contact_Radius_Factor") != j.end();
217 d_contactR = d_computeContactR ? j.at("Contact_Radius_Factor").get<double>()
218 : j.at("Contact_Radius").get<double>();
219
220 // Given a stiffness, the speed that produces the reference overlap
221 // follows from it. Given that speed instead, the stiffness follows in
222 // the contact force.
223 if (j.find("Kn") != j.end()) {
224 d_Kn = j.at("Kn");
225 d_deltaMax = 1.;
226 d_vMax = std::sqrt(d_Kn);
227 } else {
228 d_vMax = j.at("V_Max");
229 d_deltaMax = j.value("Delta_Max", 1.);
230 }
231
232 if (d_betanFactor < 1.E-8)
233 d_dampingOn = false;
234
235 if (!d_dampingOn)
236 d_betanFactor = 0.;
237
238 if (d_frictionOn and d_mu < 1.E-10) {
239 throw std::runtime_error("Friction coefficient can not be zero.");
240 }
241 if (d_frictionOn and d_K < 1.E-10) {
242 throw std::runtime_error("Bulk modulus can not be zero.");
243 }
244 }
245
246
254 std::string printStr(int nt = 0, int lvl = 0) const {
255 auto tabS = util::io::getTabS(nt);
256 std::ostringstream oss;
257 oss << tabS << "------- ContactPairDeck --------" << std::endl << std::endl;
258 oss << tabS << "Contact radius = " << d_contactR << std::endl;
259 oss << tabS << "v_max = " << d_vMax << ", Delta_max = " << d_deltaMax
260 << ", Kn = " << d_Kn << std::endl;
261 oss << tabS << "epsilon = " << d_eps << ", Beta_n = " << d_betan << std::endl;
262 oss << tabS << "Friction coefficient = " << d_mu << std::endl;
263 oss << tabS << "Damping status = " << d_dampingOn << std::endl;
264 oss << tabS << "Kn factor = " << d_KnFactor
265 << ", Beta n factor = " << d_betanFactor << std::endl;
266 oss << tabS << "Bulk modulus = " << d_K << std::endl;
267 oss << tabS << std::endl;
268 return oss.str();
269 }
270
277 void print(int nt = 0, int lvl = 0) const { std::cout << printStr(nt, lvl); }
278 };
279
281} // namespace inp
282
283#endif // INP_CONTACTPAIRDECK_H
nlohmann::ordered_json json
Collection of methods and database related to input.
Definition pairForce.h:20
Field< Deck > field(T Deck::*m, std::string key, T def, std::string doc, Accepts< T > accepts={}, std::function< bool(const T &)> emitIf=[](const T &) { return true;})
Declares a field that maps one key to one member.
Definition deckField.h:144
void readFields(Deck &d, const json &j, const std::vector< Field< Deck > > &fs)
Reads every field of the table from the block.
Definition deckField.h:230
json applyGiven(const json &given, const std::vector< Field< Deck > > &fs, const std::vector< std::string > &extra={})
The default block with the given keys replaced.
Definition deckField.h:443
void checkKeys(const json &given, const std::vector< Field< Deck > > &fs, const std::vector< std::string > &extra={})
Rejects a key that no field declares.
Definition deckField.h:421
void checkGroups(const json &block, const std::vector< OneOf > &groups)
Checks that each group has exactly one of its keys.
Definition deckField.h:317
std::string getTabS(int nt)
Returns tab spaces of a given size.
Definition io.h:82
Structure to read and store particle-particle contact related input data.
double d_contactR
contact radius
ContactPairDeck(double contactR, bool computeContactR=true, bool dampingOn=true, bool frictionOn=true, double Kn=0., double eps=1., double mu=0., double KnFactor=1., double betanFactor=1., double deltaMax=1., double vMax=0.)
Constructor.
void readFromJson(const json &j)
Reads from json object.
bool d_frictionOn
parameters for frictional force
static json getExampleJson(const json &given=json::object())
Returns example JSON object for ModelDeck configuration.
double d_eps
parameters for normal damping force
bool d_computeContactR
Flag that indicates whether contact radius is to be computed.
ContactPairDeck(const ContactPairDeck &cd)
Copy constructor.
void print(int nt=0, int lvl=0) const
Prints the information about the object.
double d_betan
parameters for normal damping force
static const std::vector< OneOf > & groups()
Quantities this deck accepts in more than one form.
double d_betanFactor
parameters for normal damping force
double d_vMax
parameters for normal force
double d_KnFactor
parameters for normal force
double d_Kn
parameters for normal force
std::string printStr(int nt=0, int lvl=0) const
Returns the string containing printable information about the object.
double d_mu
parameters for frictional force
double d_K
parameters for frictional force
static const std::vector< Field< ContactPairDeck > > & fields()
The fields of this deck, declared once.
double d_deltaMax
parameters for normal force
bool d_dampingOn
parameters for normal damping force
ContactPairDeck(const json &j=json({}))
Constructor.